yintai-company-home/src/pages/Others/Search.tsx

141 lines
5.5 KiB
TypeScript

import Banner, { type BannerConfig } from "@/components/Banner";
import Section from "@/components/layout/Section";
import styles from "./Search.module.css";
import { useCallback, useEffect, useMemo, useState } from "react";
import { dateFormat } from "@/utils";
import { useStore } from "@/store";
import appApi from "@/api/app";
import Pagination from "@/components/Pagination";
import { Link } from "react-router-dom";
type SearchData = {
id: number;
title: string;
content: string;
createTime: string;
lang: "ZH" | "EN";
path: string;
};
export default function Search() {
const appConfig = useStore((s) => s.appConfig);
const locale = useStore((s) => s.locale);
const supportLocales = useStore((s) => s.supportLocales);
const categoryList = useStore((s) => s.categoryList);
const data = appConfig?.others?.search;
const banner = data?.banner;
const searchTips = data?.tips || {
keyword: "关键词",
placeholder: "请输入",
search: "搜索",
total: "共",
result: "个结果",
}
const [page, setPage] = useState(1);
const [size] = useState(2 * supportLocales.length);
const [total, setTotal] = useState(0);
const categoryId = String(categoryList?.find((item: any) => item.name.includes('集团发布'))?.id ?? '');
const [searched, setSearched] = useState(false);
const [searchKeyword, setSearchKeyword] = useState("");
const [searchData, setSearchData] = useState<SearchData[]>([]);
const localSearchData = useMemo(() => {
return searchData.filter((item) => item.lang.toLowerCase() === locale.split('-')[0]);
}, [searchData, locale]);
const handleSearch = useCallback(() => {
appApi.getNewsList({
page,
size,
title: searchKeyword,
category_id: categoryId,
}).then((res) => {
setSearched(true);
const data = res.data.items.map((item: any) => {
return {
id: item.id,
title: item.title,
content: item.content,
createTime: item.create_time,
lang: item.lang,
path: `/news/detail/${item.id}`,
}
})
setSearchData(data);
setTotal(res.data.total);
});
}, [searchKeyword, page, size, categoryId]);
useEffect(() => {
handleSearch();
}, [page, size]);
return (
<div>
<Banner
title={banner?.title ?? "搜索结果"}
content={(banner as BannerConfig)?.content}
titleSize={(banner as BannerConfig)?.titleSize ?? "large"}
backgroundImage={banner?.backgroundImage ?? "/images/search-banner.png"}
/>
<section className={styles.searchRow}>
<div className={styles.searchRowInner}>
<span className={styles.searchRowTitle}>{searchTips.keyword}</span>
<div className={styles.searchInputWrapper}>
<input
type="text"
placeholder={searchTips.placeholder}
className={styles.searchInput}
value={searchKeyword}
onChange={(e) => setSearchKeyword(e.target.value)}
onKeyDown={(e) => {
if (e.key === "Enter") handleSearch();
}}
/>
{searched && (
<div className={styles.searchKeyword}>
{searchTips.search}:
<span className={styles.searchKeywordKeyword}>
{searchKeyword}&nbsp;
</span>
{searchTips.total}:
<span>{total / 2}</span>
{searchTips.result}
</div>
)}
</div>
<button
type="button"
className={styles.searchBtn}
onClick={handleSearch}
>
{searchTips.search}:
</button>
</div>
</section>
<Section background="" maskBackground="#fff">
<div className={styles.searchItemList}>
{localSearchData.map((item) => (
<Link to={item.path ?? ''} key={item.id} className={styles.searchItem}>
<div className={styles.searchItemTitleRow}>
<span className={styles.searchItemTitle}>{item.title}</span>
<span className={styles.searchItemCreateTime}>
{locale.startsWith("zh")
? dateFormat(item.createTime, "yyyy年MM月dd日")
: dateFormat(item.createTime, "yyyy-MM-dd")
}
</span>
</div>
<div className={styles.searchItemContent}>{item.content}</div>
</Link>
))}
</div>
<Pagination total={total} size={size} page={page} onChange={setPage} />
</Section>
</div>
);
}