Files
lixiyu-net/pages/search.tsx

93 lines
3.1 KiB
TypeScript
Raw Normal View History

import { SearchInput } from "@/components/search-page/SearchInput";
import { SearchResultList } from "@/components/search-page/SearchResultList";
2024-01-06 11:47:18 +08:00
import { Toaster } from "@/components/ui/toaster";
import { useToast } from "@/components/ui/use-toast";
import { Footer } from "@/components/utils/Footer";
2024-08-16 14:12:30 +08:00
import { ContentContainer, Page } from "@/components/utils/Layout";
2024-01-06 11:47:18 +08:00
import { NavBar } from "@/components/utils/NavBar";
import { PageTitle } from "@/components/utils/PageTitle";
2024-01-06 11:47:18 +08:00
import { SEO } from "@/components/utils/SEO";
import { Config } from "@/data/config";
import { isEmptyString } from "@/lib/utils";
2024-09-26 16:48:47 +08:00
import type { TSearchResultItem } from "@/types/docs.type";
2024-01-06 11:47:18 +08:00
import axios from "axios";
2024-08-12 10:57:33 +08:00
import { isArray } from "lodash";
import type { GetServerSideProps } from "next";
import { SiteLinksSearchBoxJsonLd } from "next-seo";
import { useState } from "react";
2024-01-06 11:47:18 +08:00
2024-08-12 10:57:33 +08:00
type SearchPageProps = { query: string | null };
export default function SearchPage(props: SearchPageProps) {
2024-01-06 11:47:18 +08:00
const [searchResult, setSearchResult] = useState<TSearchResultItem[]>([]);
2024-08-12 10:57:33 +08:00
const [isLoading, setIsLoading] = useState<boolean>(false);
2024-01-06 11:47:18 +08:00
const { toast } = useToast();
2024-08-12 10:57:33 +08:00
const fetchSearchAPI = (param: string): Promise<TSearchResultItem[]> => {
2024-09-28 22:13:37 +08:00
setIsLoading(true);
2024-08-12 10:57:33 +08:00
return axios.get<TSearchResultItem[]>(`/api/search/${param}`).then((response) => response.data);
};
2024-01-06 11:47:18 +08:00
const handleSearch = (word: string) => {
if (isEmptyString(word)) {
toast({
title: "Enter a Keyword",
description: "Please enter one keyword at least.",
});
return;
}
if (word && word.length < 4) {
toast({
title: "Keywords too short",
description: "Keyword length must be at least 4.",
});
return;
}
fetchSearchAPI(word)
2024-08-12 10:57:33 +08:00
.then((data) => {
setSearchResult(data);
if (data.length === 0) {
toast({
title: "Empty Result",
description: "No results were found for this keyword. Try another keyword.",
});
}
})
.catch(() => {
toast({ title: "Network Error", description: "Please try it later." });
})
.finally(() => {
setIsLoading(false);
});
2024-01-06 11:47:18 +08:00
};
return (
<Page>
2024-04-03 22:08:27 +08:00
<SEO description={"Search the posts on your demand."} title={`${Config.SiteTitle} - Search`} />
2024-01-06 11:47:18 +08:00
<Toaster />
<NavBar />
<SiteLinksSearchBoxJsonLd
potentialActions={[
{
target: `https://${Config.SiteDomain}/search?q={search_term_string}`,
queryInput: "search_term_string",
},
]}
url={`https://${Config.SiteDomain}/`}
/>
2024-01-06 11:47:18 +08:00
<ContentContainer>
<PageTitle>{"SEARCH POSTS"}</PageTitle>
<SearchInput isLoading={isLoading} handleSearch={handleSearch} word={props.query} />
<SearchResultList searchResult={searchResult} />
2024-01-06 11:47:18 +08:00
</ContentContainer>
<Footer />
</Page>
);
}
2024-08-12 10:57:33 +08:00
export const getServerSideProps: GetServerSideProps<SearchPageProps> = async (context) => {
let query = context.query.q;
if (isArray(query)) query = query.join(" ");
return { props: { query: query ?? null } };
};