diff --git a/src/components/NavigationContent/NavigationContent.tsx b/src/components/NavigationContent/NavigationContent.tsx index 3fc03a1..afe3cc2 100644 --- a/src/components/NavigationContent/NavigationContent.tsx +++ b/src/components/NavigationContent/NavigationContent.tsx @@ -52,7 +52,7 @@ const NavigationContent: React.FC = () => { { icon: , label: "Pick Order", - path: "/pickorder", + path: "/pickOrder", }, // { // icon: , diff --git a/src/components/Orderstatus/PoSearch.tsx b/src/components/Orderstatus/PoSearch.tsx new file mode 100644 index 0000000..c50ac0e --- /dev/null +++ b/src/components/Orderstatus/PoSearch.tsx @@ -0,0 +1,212 @@ +"use client"; + +import { PoResult } from "@/app/api/po"; +import { useCallback, useEffect, useMemo, useState } from "react"; +import { useTranslation } from "react-i18next"; +import { useRouter, useSearchParams } from "next/navigation"; +import SearchBox, { Criterion } from "../SearchBox"; +import SearchResults, { Column } from "../SearchResults"; +import { EditNote } from "@mui/icons-material"; +import { Button, Grid, Tab, Tabs, TabsProps, Typography } from "@mui/material"; +import QrModal from "../PoDetail/QrModal"; +import { WarehouseResult } from "@/app/api/warehouse"; +import NotificationIcon from "@mui/icons-material/NotificationImportant"; +import { useSession } from "next-auth/react"; +import { defaultPagingController } from "../SearchResults/SearchResults"; +import { fetchPoListClient, testing } from "@/app/api/po/actions"; +import dayjs from "dayjs"; +import { OUTPUT_DATE_FORMAT } from "@/app/utils/formatUtil"; +import arraySupport from "dayjs/plugin/arraySupport"; +dayjs.extend(arraySupport); + +type Props = { + po: PoResult[]; + warehouse: WarehouseResult[]; + totalCount: number; +}; +type SearchQuery = Partial>; +type SearchParamNames = keyof SearchQuery; + +// cal offset (pageSize) +// cal limit (pageSize) +const PoSearch: React.FC = ({ + po, + warehouse, + totalCount: initTotalCount, +}) => { + const [filteredPo, setFilteredPo] = useState(po); + const [filterArgs, setFilterArgs] = useState>({}); + const { t } = useTranslation("purchaseOrder"); + const router = useRouter(); + const [pagingController, setPagingController] = useState( + defaultPagingController + ); + const [totalCount, setTotalCount] = useState(initTotalCount); + const searchCriteria: Criterion[] = useMemo(() => { + var searchCriteria: Criterion[] = [ + { label: t("Code"), paramName: "code", type: "text" }, + { + label: t("Status"), + paramName: "status", + type: "select-labelled", + options: [ + {label: t(`pending`), value: `pending`}, + {label: t(`receiving`), value: `receiving`}, + {label: t(`completed`), value: `completed`}, + ] + }, + { + label: t("Escalated"), + paramName: "escalated", + type: "select", + options: [t("Escalated"), t("NotEscalated")], + }, + ]; + return searchCriteria; + }, [t, po]); + + const onDetailClick = useCallback( + (po: PoResult) => { + router.push(`/po/edit?id=${po.id}`); + }, + [router] + ); + + const onDeleteClick = useCallback((po: PoResult) => {}, [router]); + + const columns = useMemo[]>( + () => [ + { + name: "id", + label: t("Details"), + onClick: onDetailClick, + buttonIcon: , + }, + { + name: "code", + label: t("Code"), + }, + { + name: "orderDate", + label: t("OrderDate"), + renderCell: (params) => { + return dayjs(params.orderDate) + // .add(-1, "month") + .format(OUTPUT_DATE_FORMAT); + }, + }, + { + name: "supplier", + label: t("Supplier"), + }, + { + name: "status", + label: t("Status"), + renderCell: (params) => { + return t(`${params.status.toLowerCase()}`); + }, + }, + { + name: "escalated", + label: t("Escalated"), + renderCell: (params) => { + console.log(params.escalated) + return params.escalated ? ( + + ) : undefined; + }, + }, + ], + [filteredPo] + ); + + const onReset = useCallback(() => { + setFilteredPo(po); + }, [po]); + + const [isOpenScanner, setOpenScanner] = useState(false); + const onOpenScanner = useCallback(() => { + setOpenScanner(true); + }, []); + + const onCloseScanner = useCallback(() => { + setOpenScanner(false); + }, []); + + const newPageFetch = useCallback( + async ( + pagingController: Record, + filterArgs: Record + ) => { + console.log(pagingController); + console.log(filterArgs); + const params = { + ...pagingController, + ...filterArgs, + }; + const res = await fetchPoListClient(params); + // const res = await testing(params); + if (res) { + console.log(res); + setFilteredPo(res.records); + setTotalCount(res.total); + } + }, + [fetchPoListClient] + ); + + useEffect(() => { + newPageFetch(pagingController, filterArgs); + }, [newPageFetch, pagingController, filterArgs]); + return ( + <> + + + + {t("Purchase Order")} + + + + + + + + <> + { + console.log(query) + setFilterArgs({ + code: query.code, + status: query.status === "All" ? "" : query.status, + escalated: query.escalated === 'All' ? undefined : query.escalated === t("Escalated") + }); + // setFilteredPo((prev) => + // po.filter((p) => { + // return ( + // p.code.toLowerCase().includes(query.code.toLowerCase()) && + // (query.status === "All" || t(`${p.status.toLowerCase()}`) === query.status) && + // (query.escalated === "All" || (p.escalated === Boolean((query.escalated) === t("Escalated")))) + // ) + // }) + // ); + }} + onReset={onReset} + /> + + items={filteredPo} + columns={columns} + pagingController={pagingController} + setPagingController={setPagingController} + totalCount={totalCount} + isAutoPaging={false} + /> + + + ); +}; +export default PoSearch; diff --git a/src/components/Orderstatus/PoSearchLoading.tsx b/src/components/Orderstatus/PoSearchLoading.tsx new file mode 100644 index 0000000..cab2a37 --- /dev/null +++ b/src/components/Orderstatus/PoSearchLoading.tsx @@ -0,0 +1,40 @@ +import Card from "@mui/material/Card"; +import CardContent from "@mui/material/CardContent"; +import Skeleton from "@mui/material/Skeleton"; +import Stack from "@mui/material/Stack"; +import React from "react"; + +// Can make this nicer +export const PoSearchLoading: React.FC = () => { + return ( + <> + + + + + + + + + + + + + + + + + + + + + + ); +}; + +export default PoSearchLoading; diff --git a/src/components/Orderstatus/PoSearchWrapper.tsx b/src/components/Orderstatus/PoSearchWrapper.tsx new file mode 100644 index 0000000..4505f2d --- /dev/null +++ b/src/components/Orderstatus/PoSearchWrapper.tsx @@ -0,0 +1,53 @@ +import { fetchAllItems } from "@/app/api/settings/item"; +// import ItemsSearch from "./ItemsSearch"; +// import ItemsSearchLoading from "./ItemsSearchLoading"; +import { SearchParams } from "@/app/utils/fetchUtil"; +import { TypeEnum } from "@/app/utils/typeEnum"; +import { notFound } from "next/navigation"; +import PoSearchLoading from "./PoSearchLoading"; +import PoSearch from "./PoSearch"; +import { fetchPoList, PoResult } from "@/app/api/po"; +import dayjs from "dayjs"; +import arraySupport from "dayjs/plugin/arraySupport"; +import { OUTPUT_DATE_FORMAT } from "@/app/utils/formatUtil"; +import { fetchWarehouseList } from "@/app/api/warehouse"; +import { defaultPagingController } from "../SearchResults/SearchResults"; +dayjs.extend(arraySupport); + +interface SubComponents { + Loading: typeof PoSearchLoading; +} + +type Props = { + // type: TypeEnum; +}; + +const PoSearchWrapper: React.FC & SubComponents = async ( + { + // type, + } +) => { + // console.log(defaultPagingController) + const [ + po, + warehouse, + ] = await Promise.all([ + fetchPoList({ + "pageNum": 1, + "pageSize": 10, + }), + // fetchPoList(), + fetchWarehouseList(), + ]); + const fixPoDate = po.records.map((p) => { + return ({ + ...p, + orderDate: dayjs(p.orderDate).add(-1, "month").format(OUTPUT_DATE_FORMAT) + }) + }) + return ; +}; + +PoSearchWrapper.Loading = PoSearchLoading; + +export default PoSearchWrapper; diff --git a/src/components/Orderstatus/index.ts b/src/components/Orderstatus/index.ts new file mode 100644 index 0000000..4ac7af9 --- /dev/null +++ b/src/components/Orderstatus/index.ts @@ -0,0 +1 @@ +export { default } from "./PoSearchWrapper"; diff --git a/src/i18n/zh/common.json b/src/i18n/zh/common.json index 9d9468b..33fdeb4 100644 --- a/src/i18n/zh/common.json +++ b/src/i18n/zh/common.json @@ -1,6 +1,6 @@ { - "dashboard": "儀表板", + "dashboard": "資訊展示面板", "Edit": "編輯", "Search Criteria": "搜尋條件", @@ -15,7 +15,7 @@ "Add some entries!": "添加條目", "Add Record": "新增", "Clean Record": "重置", - "Dashboard": "儀表板", + "Dashboard": "資訊展示面板", "Raw Material": "原材料", "Delivery": "交貨單", "Scheduling": "排程", diff --git a/src/i18n/zh/dashboard.json b/src/i18n/zh/dashboard.json index d80cb57..4f6e429 100644 --- a/src/i18n/zh/dashboard.json +++ b/src/i18n/zh/dashboard.json @@ -1,3 +1,4 @@ { - "Dashboard": "儀表板" -} \ No newline at end of file + "Dashboard": "資訊展示面板", + "Order status": "訂單狀態" +}