diff --git a/src/app/(main)/scheduling/detail/page.tsx b/src/app/(main)/scheduling/detail/page.tsx new file mode 100644 index 0000000..d6eced6 --- /dev/null +++ b/src/app/(main)/scheduling/detail/page.tsx @@ -0,0 +1,48 @@ +import { TypeEnum } from "@/app/utils/typeEnum"; +import ItemsSearch from "@/components/ItemsSearch"; +import { getServerI18n } from "@/i18n"; +import Add from "@mui/icons-material/Add"; +import Button from "@mui/material/Button"; +import Stack from "@mui/material/Stack"; +import Typography from "@mui/material/Typography"; +import { Metadata } from "next"; +import Link from "next/link"; +import { Suspense } from "react"; + +export const metadata: Metadata = { + title: "Detail Scheduling", +}; + +const detailScheduling: React.FC = async () => { + const project = TypeEnum.PRODUCT + const { t } = await getServerI18n(project); + // preloadClaims(); + + return ( + <> + + + {t("Detail Scheduling")} + + {/* */} + + }> + + + + ); +}; + +export default detailScheduling; diff --git a/src/app/(main)/scheduling/page.tsx b/src/app/(main)/scheduling/page.tsx new file mode 100644 index 0000000..a819690 --- /dev/null +++ b/src/app/(main)/scheduling/page.tsx @@ -0,0 +1,11 @@ +import { Metadata } from "next"; + +export const metadata: Metadata = { + title: "Scheduling", +}; + +const Scheduling: React.FC = async () => { + return null; +}; + +export default Scheduling; diff --git a/src/app/(main)/scheduling/rough/page.tsx b/src/app/(main)/scheduling/rough/page.tsx new file mode 100644 index 0000000..a6237e4 --- /dev/null +++ b/src/app/(main)/scheduling/rough/page.tsx @@ -0,0 +1,48 @@ +import { TypeEnum } from "@/app/utils/typeEnum"; +import RoughSchedule from "@/components/RoughSchedule"; +import { getServerI18n } from "@/i18n"; +import Add from "@mui/icons-material/Add"; +import Button from "@mui/material/Button"; +import Stack from "@mui/material/Stack"; +import Typography from "@mui/material/Typography"; +import { Metadata } from "next"; +import Link from "next/link"; +import { Suspense } from "react"; + +export const metadata: Metadata = { + title: "Rough Scheduling", +}; + +const roughScheduling: React.FC = async () => { + const project = TypeEnum.PRODUCT + const { t } = await getServerI18n(project); + // preloadClaims(); + + return ( + <> + + + {t("Rough Scheduling")} + + {/* */} + + }> + + + + ); +}; + +export default roughScheduling; diff --git a/src/components/Breadcrumb/Breadcrumb.tsx b/src/components/Breadcrumb/Breadcrumb.tsx index 1c8bf07..02859fe 100644 --- a/src/components/Breadcrumb/Breadcrumb.tsx +++ b/src/components/Breadcrumb/Breadcrumb.tsx @@ -14,6 +14,8 @@ const pathToLabelMap: { [path: string]: string } = { "/tasks/create": "Create Task Template", "/settings/qcItem": "Qc Item", "/settings/rss": "Rough Schedule Setting", + "/scheduling/rough": "Rough Scheduling", + "/scheduling/detail": "Detail Scheduling", }; const Breadcrumb = () => { diff --git a/src/components/NavigationContent/NavigationContent.tsx b/src/components/NavigationContent/NavigationContent.tsx index 4b80162..ad9be3c 100644 --- a/src/components/NavigationContent/NavigationContent.tsx +++ b/src/components/NavigationContent/NavigationContent.tsx @@ -166,6 +166,23 @@ const NavigationContent: React.FC = () => { }, ], }, + { + icon: , + label: "Scheduling", + path: "", + children: [ + { + icon: , + label: "Rough Scheduling", + path: "/scheduling/rough", + }, + { + icon: , + label: "Detail Scheduling", + path: "/scheduling/detail", + }, + ], + }, { icon: , label: "Settings", diff --git a/src/components/RoughSchedule/RoughSchedileSearchView.tsx b/src/components/RoughSchedule/RoughSchedileSearchView.tsx new file mode 100644 index 0000000..5cf3d7d --- /dev/null +++ b/src/components/RoughSchedule/RoughSchedileSearchView.tsx @@ -0,0 +1,194 @@ +"use client"; + +import React, {useCallback, useEffect, useMemo, useState} from "react"; +import SearchBox, { Criterion } from "../SearchBox"; +import { ItemsResult} from "@/app/api/settings/item"; +import SearchResults, { Column } from "../SearchResults"; +import { EditNote } from "@mui/icons-material"; +import { useRouter, useSearchParams } from "next/navigation"; +import { GridDeleteIcon } from "@mui/x-data-grid"; +import { TypeEnum } from "@/app/utils/typeEnum"; +import axios from "axios"; +import {BASE_API_URL, NEXT_PUBLIC_API_URL} from "@/config/api"; +import { useTranslation } from "react-i18next"; +import axiosInstance from "@/app/(main)/axios/axiosInstance"; +import Qs from 'qs'; +import EditableSearchResults from "@/components/SearchResults/EditableSearchResults"; // Make sure to import Qs + +type RecordStructure ={ + id: number, + schedulePeriod: string, + scheduleAt: string +}; + +type Props = { + records: RecordStructure[]; +}; + +type SearchQuery = Partial>; +type SearchParamNames = keyof SearchQuery; + +const RSOverview: React.FC = ({ records }) => { + const [filteredItems, setFilteredItems] = useState(records ?? []); + const { t } = useTranslation("items"); + const router = useRouter(); + const [filterObj, setFilterObj] = useState({}); + const [tempSelectedValue, setTempSelectedValue] = useState({}); + const [pagingController, setPagingController] = useState({ + pageNum: 1, + pageSize: 10, + totalCount: 0, + }) + + const [mode, redirPath] = useMemo(() => { + // var typeId = TypeEnum.CONSUMABLE_ID + var title = ""; + var mode = "Search"; + var redirPath = ""; + title = "Product"; + redirPath = "/scheduling/rough"; + return [mode, redirPath]; + }, []); + + const searchCriteria: Criterion[] = useMemo( + () => { + var searchCriteria: Criterion[] = [ + { label: t("Schedule Period"), paramName: "schedulePeriod", type: "dateRange" }, + { label: t("Scheduled At"), paramName: "scheduleAt", type: "date" }, + { label: t("Product Count"), paramName: "productCount", type: "input" }, + ] + return searchCriteria + }, + [t, records] + ); + + // const onDetailClick = useCallback( + // (item: ItemsResult) => { + // router.push(`/settings/items/edit?id=${item.id}`); + // }, + // [router] + // ); + + const onDeleteClick = useCallback( + (item: ItemsResult) => {}, + [router] + ); + + const columns = useMemo[]>( + () => [ + { + name: "id", + label: t("Details"), + onClick: ()=>{}, + buttonIcon: , + }, + { + name: "scheduledPeriod", + label: "Rough Schedule Period", + }, + { + name: "scheduledAt", + label: t("Scheduled At"), + }, + { + name: "productCount", + label: t("Product Count(s)"), + }, + // { + // name: "action", + // label: t(""), + // buttonIcon: , + // onClick: onDeleteClick, + // }, + ], + [filteredItems] + ); + + useEffect(() => { + refetchData(filterObj); + + }, [filterObj, pagingController.pageNum, pagingController.pageSize]); + + const refetchData = async (filterObj: SearchQuery) => { + + const authHeader = axiosInstance.defaults.headers['Authorization']; + if (!authHeader) { + return; // Exit the function if the token is not set + } + + const params ={ + pageNum: pagingController.pageNum, + pageSize: pagingController.pageSize, + ...filterObj, + ...tempSelectedValue, + } + + try { + const response = await axiosInstance.get(`${NEXT_PUBLIC_API_URL}/items/getRecordByPage`, { + params, + paramsSerializer: (params) => { + return Qs.stringify(params, { arrayFormat: 'repeat' }); + }, + }); + //setFilteredItems(response.data.records); + setFilteredItems([ + { + id: 1, + scheduledPeriod: "2025-05-11 to 2025-05-17", + scheduledAt: "2025-05-07", + productCount: 13, + }, + { + id: 2, + scheduledPeriod: "2025-05-18 to 2025-05-24", + scheduledAt: "2025-05-14", + productCount: 15, + }, + { + id: 3, + scheduledPeriod: "2025-05-25 to 2025-05-31", + scheduledAt: "2025-05-21", + productCount: 13, + }, + ]) + setPagingController({ + ...pagingController, + totalCount: response.data.total + }) + return response; // Return the data from the response + } catch (error) { + console.error('Error fetching items:', error); + throw error; // Rethrow the error for further handling + } + }; + + const onReset = useCallback(() => { + //setFilteredItems(items ?? []); + setFilterObj({}); + setTempSelectedValue({}); + refetchData(); + }, [records]); + + return ( + <> + { + setFilterObj({ + ...query + }) + }} + onReset={onReset} + /> + + items={filteredItems} + columns={columns} + setPagingController={setPagingController} + pagingController={pagingController} + isAutoPaging={false} + /> + + ); +}; + +export default RSOverview; diff --git a/src/components/RoughSchedule/RoughScheduleLoading.tsx b/src/components/RoughSchedule/RoughScheduleLoading.tsx new file mode 100644 index 0000000..62db673 --- /dev/null +++ b/src/components/RoughSchedule/RoughScheduleLoading.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 RoughScheduleLoading: React.FC = () => { + return ( + <> + + + + + + + + + + + + + + + + + + + + + + ); +}; + +export default RoughScheduleLoading; diff --git a/src/components/RoughSchedule/RoughScheduleWrapper.tsx b/src/components/RoughSchedule/RoughScheduleWrapper.tsx new file mode 100644 index 0000000..2a4ba2b --- /dev/null +++ b/src/components/RoughSchedule/RoughScheduleWrapper.tsx @@ -0,0 +1,19 @@ +import { fetchAllItems, } from "@/app/api/settings/item"; +import {RoughScheduleLoading} from "./RoughScheduleLoading"; +import RSOverview from "./RoughSchedileSearchView"; + +interface SubComponents { + Loading: typeof RoughScheduleLoading; +} + +const RoughScheduleWrapper: ({}: {}) => Promise = async ({ + // type, + }) => { + // console.log(type) + var result = await fetchAllItems() + return ; +}; + +RoughScheduleWrapper.Loading = RoughScheduleLoading; + +export default RoughScheduleWrapper; diff --git a/src/components/RoughSchedule/index.ts b/src/components/RoughSchedule/index.ts new file mode 100644 index 0000000..d3f27f8 --- /dev/null +++ b/src/components/RoughSchedule/index.ts @@ -0,0 +1 @@ +export { default } from "./RoughScheduleWrapper"; \ No newline at end of file diff --git a/src/components/SearchBox/SearchBox.tsx b/src/components/SearchBox/SearchBox.tsx index b1a5512..23fc2f7 100644 --- a/src/components/SearchBox/SearchBox.tsx +++ b/src/components/SearchBox/SearchBox.tsx @@ -196,6 +196,22 @@ function SearchBox({ )} + {c.type === "date" && ( + + + + + + + + )} ); })}