|
|
@@ -0,0 +1,115 @@ |
|
|
|
"use client"; |
|
|
|
|
|
|
|
import { DoResult } from "@/app/api/do" |
|
|
|
import { useRouter } from "next/navigation"; |
|
|
|
import { useCallback, useMemo, useState } from "react"; |
|
|
|
import { useTranslation } from "react-i18next"; |
|
|
|
import { Criterion } from "../SearchBox"; |
|
|
|
import { isEmpty, sortBy, uniqBy, upperFirst } from "lodash"; |
|
|
|
import { Column } from "../SearchResults"; |
|
|
|
import { arrayToDateString, arrayToDayjs } from "@/app/utils/formatUtil"; |
|
|
|
import SearchBox from "../SearchBox/SearchBox"; |
|
|
|
import SearchResults from "../SearchResults/SearchResults"; |
|
|
|
import { EditNote } from "@mui/icons-material"; |
|
|
|
|
|
|
|
type Props = { |
|
|
|
dos: DoResult[] |
|
|
|
} |
|
|
|
|
|
|
|
type SearchQuery = Partial<Omit<DoResult, "id">>; |
|
|
|
type SearchParamNames = keyof SearchQuery; |
|
|
|
|
|
|
|
const DoSearch: React.FC<Props> = ({ |
|
|
|
dos |
|
|
|
}) => { |
|
|
|
|
|
|
|
const [filteredDos, setFilteredDos] = useState<DoResult[]>(dos); |
|
|
|
const { t } = useTranslation("do"); |
|
|
|
const router = useRouter(); |
|
|
|
|
|
|
|
const searchCriteria: Criterion<SearchParamNames>[] = useMemo(() => [ |
|
|
|
{ label: t("Code"), paramName: "code", type: "text" }, |
|
|
|
|
|
|
|
{ label: t("Order Date From"), label2: t("Order Date To"), paramName: "orderDate", type: "dateRange" }, |
|
|
|
{ label: t("Shop Name"), paramName: "shopName", type: "text" }, |
|
|
|
{ |
|
|
|
label: t("Status"), paramName: "status", type: "autocomplete", options: sortBy( |
|
|
|
uniqBy(dos.map((_do) => ({ value: _do.status, label: t(upperFirst(_do.status)) })), "value"), |
|
|
|
"label") |
|
|
|
}, |
|
|
|
], [t, dos]) |
|
|
|
|
|
|
|
const onReset = useCallback(() => { |
|
|
|
setFilteredDos(dos) |
|
|
|
}, [dos]) |
|
|
|
|
|
|
|
const onDetailClick = useCallback( |
|
|
|
(doResult: DoResult) => { |
|
|
|
router.push(`/do/edit?id=${doResult.id}`); |
|
|
|
}, |
|
|
|
[router] |
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
const columns = useMemo<Column<DoResult>[]>(() => [ |
|
|
|
{ |
|
|
|
name: "id", |
|
|
|
label: t("Details"), |
|
|
|
onClick: onDetailClick, |
|
|
|
buttonIcon: <EditNote />, |
|
|
|
}, |
|
|
|
{ |
|
|
|
name: "code", |
|
|
|
label: t("Code") |
|
|
|
}, |
|
|
|
{ |
|
|
|
name: "shopName", |
|
|
|
label: t("Shop Name") |
|
|
|
}, |
|
|
|
{ |
|
|
|
name: "orderDate", |
|
|
|
label: t("Order Date"), |
|
|
|
renderCell: (params) => { |
|
|
|
return params.orderDate ? arrayToDateString(params.orderDate) : "N/A" |
|
|
|
}, |
|
|
|
}, |
|
|
|
{ |
|
|
|
name: "status", |
|
|
|
label: t("Status"), |
|
|
|
renderCell: (params) => { |
|
|
|
return t(upperFirst(params.status)) |
|
|
|
}, |
|
|
|
}, |
|
|
|
], [t]) |
|
|
|
|
|
|
|
return ( |
|
|
|
<> |
|
|
|
<SearchBox |
|
|
|
criteria={searchCriteria} |
|
|
|
onSearch={(query) => { |
|
|
|
setFilteredDos( |
|
|
|
dos.filter( |
|
|
|
(_do) => { |
|
|
|
const doOrderDateStr = arrayToDayjs(_do.orderDate) |
|
|
|
|
|
|
|
return _do.code.toLowerCase().includes(query.code.toLowerCase()) |
|
|
|
&& _do.shopName.toLowerCase().includes(query.shopName.toLowerCase()) |
|
|
|
&& (query.status == "All" || _do.status.toLowerCase().includes(query.status.toLowerCase())) |
|
|
|
&& (isEmpty(query.orderDate) || doOrderDateStr.isSame(query.orderDate) || doOrderDateStr.isAfter(query.orderDate)) |
|
|
|
&& (isEmpty(query.orderDateTo) || doOrderDateStr.isSame(query.orderDateTo) || doOrderDateStr.isBefore(query.orderDateTo)) |
|
|
|
} |
|
|
|
) |
|
|
|
) |
|
|
|
}} |
|
|
|
onReset={onReset} |
|
|
|
/> |
|
|
|
<SearchResults<DoResult> items={filteredDos} columns={columns} pagingController={{ |
|
|
|
pageNum: 0, |
|
|
|
pageSize: 0, |
|
|
|
totalCount: 0, |
|
|
|
}} /> |
|
|
|
</> |
|
|
|
) |
|
|
|
} |
|
|
|
|
|
|
|
export default DoSearch; |