2024-09-28 00:18:55 +08:00
|
|
|
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";
|
2024-09-28 00:18:55 +08:00
|
|
|
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";
|
2024-01-06 20:20:05 +08:00
|
|
|
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";
|
2024-08-14 12:57:22 +08:00
|
|
|
import type { GetServerSideProps } from "next";
|
2024-09-28 00:18:55 +08:00
|
|
|
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
|
|
|
|
2024-09-28 00:18:55 +08:00
|
|
|
const handleSearch = (word: string) => {
|
|
|
|
|
if (isEmptyString(word)) {
|
|
|
|
|
toast({
|
|
|
|
|
title: "Enter a Keyword",
|
|
|
|
|
description: "Please enter one keyword at least.",
|
|
|
|
|
});
|
2024-01-06 20:20:05 +08:00
|
|
|
return;
|
|
|
|
|
}
|
2024-09-28 00:18:55 +08:00
|
|
|
if (word && word.length < 4) {
|
|
|
|
|
toast({
|
|
|
|
|
title: "Keywords too short",
|
|
|
|
|
description: "Keyword length must be at least 4.",
|
|
|
|
|
});
|
2024-01-09 16:57:42 +08:00
|
|
|
return;
|
|
|
|
|
}
|
2024-09-28 00:18:55 +08:00
|
|
|
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 />
|
2024-01-09 16:48:48 +08:00
|
|
|
<NavBar />
|
2024-09-28 00:18:55 +08:00
|
|
|
<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>
|
2024-09-28 00:18:55 +08:00
|
|
|
<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 } };
|
|
|
|
|
};
|