From 031d64642805fec9df9682d13e1853d8439ddceb Mon Sep 17 00:00:00 2001 From: "jason.lam" Date: Fri, 9 May 2025 18:30:52 +0800 Subject: [PATCH] [rough schedule detail] update detail page --- src/app/(main)/scheduling/rough/edit/page.tsx | 49 +++++ src/components/Breadcrumb/Breadcrumb.tsx | 1 + src/components/General/GeneralLoading.tsx | 39 ++++ .../RoughSchedule/RoughSchedileSearchView.tsx | 7 +- .../RoughScheduleDetail/DetailInfoCard.tsx | 101 +++++++++ .../RoughScheduleDetailWrapper.tsx | 50 +++++ .../RoughScheudleDetailView.tsx | 199 ++++++++++++++++++ src/components/RoughScheduleDetail/index.ts | 1 + 8 files changed, 446 insertions(+), 1 deletion(-) create mode 100644 src/app/(main)/scheduling/rough/edit/page.tsx create mode 100644 src/components/General/GeneralLoading.tsx create mode 100644 src/components/RoughScheduleDetail/DetailInfoCard.tsx create mode 100644 src/components/RoughScheduleDetail/RoughScheduleDetailWrapper.tsx create mode 100644 src/components/RoughScheduleDetail/RoughScheudleDetailView.tsx create mode 100644 src/components/RoughScheduleDetail/index.ts diff --git a/src/app/(main)/scheduling/rough/edit/page.tsx b/src/app/(main)/scheduling/rough/edit/page.tsx new file mode 100644 index 0000000..8739b82 --- /dev/null +++ b/src/app/(main)/scheduling/rough/edit/page.tsx @@ -0,0 +1,49 @@ +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"; +import RoughScheduleDetailView from "@/components/RoughScheduleDetail/RoughScheudleDetailView"; + +export const metadata: Metadata = { + title: "Rough Scheduling Detail", +}; + +const roughSchedulingDetail: React.FC = async () => { + const project = TypeEnum.PRODUCT + const { t } = await getServerI18n(project); + // preloadClaims(); + + return ( + <> + + + {t("Rough Scheduling Detail")} + + {/* */} + + }> + + + +); +}; + +export default roughSchedulingDetail; diff --git a/src/components/Breadcrumb/Breadcrumb.tsx b/src/components/Breadcrumb/Breadcrumb.tsx index 02859fe..cc62c09 100644 --- a/src/components/Breadcrumb/Breadcrumb.tsx +++ b/src/components/Breadcrumb/Breadcrumb.tsx @@ -15,6 +15,7 @@ const pathToLabelMap: { [path: string]: string } = { "/settings/qcItem": "Qc Item", "/settings/rss": "Rough Schedule Setting", "/scheduling/rough": "Rough Scheduling", + "/scheduling/rough/edit": "Rough Scheduling Detail", "/scheduling/detail": "Detail Scheduling", }; diff --git a/src/components/General/GeneralLoading.tsx b/src/components/General/GeneralLoading.tsx new file mode 100644 index 0000000..14031b5 --- /dev/null +++ b/src/components/General/GeneralLoading.tsx @@ -0,0 +1,39 @@ +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"; + +export const GeneralLoading: React.FC = () => { + return ( + <> + + + + + + + + + + + CreateMaterial + + + + + + + + + + + ); +}; + +export default GeneralLoading; diff --git a/src/components/RoughSchedule/RoughSchedileSearchView.tsx b/src/components/RoughSchedule/RoughSchedileSearchView.tsx index 5cf3d7d..5b80692 100644 --- a/src/components/RoughSchedule/RoughSchedileSearchView.tsx +++ b/src/components/RoughSchedule/RoughSchedileSearchView.tsx @@ -74,12 +74,17 @@ const RSOverview: React.FC = ({ records }) => { [router] ); + const onDetailClick = (record: any) => { + console.log("[debug] record", record); + router.push(`/scheduling/rough/edit?id=${record.id}`); + } + const columns = useMemo[]>( () => [ { name: "id", label: t("Details"), - onClick: ()=>{}, + onClick: (record)=>onDetailClick(record), buttonIcon: , }, { diff --git a/src/components/RoughScheduleDetail/DetailInfoCard.tsx b/src/components/RoughScheduleDetail/DetailInfoCard.tsx new file mode 100644 index 0000000..79d98e7 --- /dev/null +++ b/src/components/RoughScheduleDetail/DetailInfoCard.tsx @@ -0,0 +1,101 @@ +"use client"; +import { + Box, + Card, + CardContent, + Grid, + Stack, + TextField, + Typography, +} from "@mui/material"; +import { useFormContext } from "react-hook-form"; +import { useTranslation } from "react-i18next"; +import InputDataGrid from "../InputDataGrid"; +import {useCallback, useEffect, useMemo, useState} from "react"; +import { GridColDef, GridRowModel } from "@mui/x-data-grid"; +import { InputDataGridProps, TableRow } from "../InputDataGrid/InputDataGrid"; +import { TypeEnum } from "@/app/utils/typeEnum"; +import { CreateItemInputs } from "@/app/api/settings/item/actions"; +import {NumberInputProps} from "@/components/CreateItem/NumberInputProps"; + +type Props = { + // isEditMode: boolean; + // type: TypeEnum; +}; + +const DetailInfoCard: React.FC = ({ recordDetails, isEditing}) => { + const { + t, + i18n: { language }, + } = useTranslation(); + + const { + register, + formState: { errors, defaultValues, touchedFields }, + } = useFormContext(); + + const [details, setDetails] = useState(null); + + useEffect(()=>{ + console.log("[debug] record details", recordDetails) + setDetails(recordDetails); + },[recordDetails]) + + useEffect(()=>{ + console.log("[debug] isEdit", isEditing) + },[isEditing]) + + return ( + + + + + {t("Schedule Detail")} + + + + + + + + + + + + + + + + ); +}; +export default DetailInfoCard; diff --git a/src/components/RoughScheduleDetail/RoughScheduleDetailWrapper.tsx b/src/components/RoughScheduleDetail/RoughScheduleDetailWrapper.tsx new file mode 100644 index 0000000..1ec14d5 --- /dev/null +++ b/src/components/RoughScheduleDetail/RoughScheduleDetailWrapper.tsx @@ -0,0 +1,50 @@ +import { CreateItemInputs } from "@/app/api/settings/item/actions"; +import { fetchItem } from "@/app/api/settings/item"; +import GeneralLoading from "@/components/General/GeneralLoading"; +import RoughScheduleDetailView from "@/components/RoughScheduleDetail/RoughScheudleDetailView"; +interface SubComponents { + Loading: typeof GeneralLoading; +} + +type Props = { + id?: number + // type: TypeEnum; +}; + +const RoughScheduleDetailWrapper: (id: { id: any }) => Promise = async ({ id: any }) => { + var result + var defaultValues: Partial | undefined + // console.log(type) + var qcChecks + if (id) { + result = await fetchItem(id); + const item = result.item + qcChecks = result.qcChecks + const activeRows = qcChecks.filter(it => it.isActive).map(i => i.id) + console.log(qcChecks) + defaultValues = { + type: item?.type, + id: item?.id, + code: item?.code, + name: item?.name, + description: item?.description, + remarks: item?.remarks, + shelfLife: item?.shelfLife, + countryOfOrigin: item?.countryOfOrigin, + maxQty: item?.maxQty, + qcChecks: qcChecks, + qcChecks_active: activeRows + }; + } + + return ( + + ); +}; +RoughScheduleDetailWrapper.Loading = GeneralLoading; + +export default RoughScheduleDetailWrapper; diff --git a/src/components/RoughScheduleDetail/RoughScheudleDetailView.tsx b/src/components/RoughScheduleDetail/RoughScheudleDetailView.tsx new file mode 100644 index 0000000..960b5c1 --- /dev/null +++ b/src/components/RoughScheduleDetail/RoughScheudleDetailView.tsx @@ -0,0 +1,199 @@ +"use client"; + +import { useCallback, useEffect, useMemo, useState } from "react"; +import { useRouter, useSearchParams } from "next/navigation"; +import { useTranslation } from "react-i18next"; +import { + CreateItemInputs, + saveItem, +} from "@/app/api/settings/item/actions"; +import { + FormProvider, + SubmitErrorHandler, + SubmitHandler, + useForm, +} from "react-hook-form"; +import { deleteDialog } from "../Swal/CustomAlerts"; +import {Box, Button, Grid, Link, Stack, Tab, Tabs, TabsProps, Typography} from "@mui/material"; +import {Add, Check, Close, EditNote} from "@mui/icons-material"; +import {ItemQc, ItemsResult} from "@/app/api/settings/item"; +import { useGridApiRef } from "@mui/x-data-grid"; +import ProductDetails from "@/components/CreateItem/ProductDetails"; +import QcDetails from "@/components/CreateItem/QcDetails"; +import DetailInfoCard from "@/components/RoughScheduleDetail/DetailInfoCard"; + +type Props = { + isEditMode: boolean; + // type: TypeEnum; + defaultValues: Partial | undefined; + qcChecks: ItemQc[] +}; + +const RoughScheduleDetailView: React.FC = ({ + isEditMode, + // type, + defaultValues, + qcChecks +}) => { + // console.log(type) + const apiRef = useGridApiRef(); + const params = useSearchParams() + console.log(params.get("id")) + const [serverError, setServerError] = useState(""); + const [tabIndex, setTabIndex] = useState(0); + const { t } = useTranslation(); + const router = useRouter(); + const [isEdit, setIsEdit] = useState(false); + //const title = "Rough Schedule Detail" + const [mode, redirPath] = useMemo(() => { + // var typeId = TypeEnum.CONSUMABLE_ID + var title = ""; + var mode = ""; + var redirPath = ""; + // if (type === TypeEnum.MATERIAL) { + // typeId = TypeEnum.MATERIAL_ID + // title = "Material"; + // redirPath = "/settings/material"; + // } + // if (type === TypeEnum.PRODUCT) { + // typeId = TypeEnum.PRODUCT_ID + title = "Product"; + redirPath = "scheduling/rough/edit"; + // } + // if (type === TypeEnum.BYPRODUCT) { + // typeId = TypeEnum.BYPRODUCT_ID + // title = "By-Product"; + // redirPath = "/settings/byProduct"; + // } + if (isEditMode) { + mode = "Edit"; + } else { + mode = "Create"; + } + return [mode, redirPath]; + }, [isEditMode]); + // console.log(typeId) + const formProps = useForm({ + defaultValues: defaultValues ? defaultValues : { + }, + }); + const errors = formProps.formState.errors; + + const handleTabChange = useCallback>( + (_e, newValue) => { + setTabIndex(newValue); + }, + [], + ); + + const handleCancel = () => { + router.replace(`/scheduling/rough`); + }; + + const onSubmit = useCallback>( + async (data, event) => { + let hasErrors = false; + console.log(errors) + // console.log(apiRef.current.getCellValue(2, "lowerLimit")) + // apiRef.current. + try { + if (hasErrors) { + setServerError(t("An error has occurred. Please try again later.")); + return false; + } + } catch (e) { + // backend error + setServerError(t("An error has occurred. Please try again later.")); + console.log(e); + } + }, + [apiRef, router, t] + ); + + // multiple tabs + const onSubmitError = useCallback>( + (errors) => {}, + [] + ); + + const onClickEdit = () =>{ + setIsEdit(!isEdit) + } + + return ( + <> + + + {/**/} + {/* */} + {/* {t(`${mode} ${title}`)}*/} + {/* */} + {/**/} + + + + + + + + + + {serverError && ( + + {serverError} + + )} + {tabIndex === 0 && } + {tabIndex === 1 && } + {/* {type === TypeEnum.MATERIAL && } */} + {/* {type === TypeEnum.BYPRODUCT && } */} + + + + + + + + ); +}; +export default RoughScheduleDetailView; diff --git a/src/components/RoughScheduleDetail/index.ts b/src/components/RoughScheduleDetail/index.ts new file mode 100644 index 0000000..b21264d --- /dev/null +++ b/src/components/RoughScheduleDetail/index.ts @@ -0,0 +1 @@ +export { default } from "./RoughScheduleDetailWrapper"; \ No newline at end of file