diff --git a/src/components/PoDetail/QCDatagrid.tsx b/src/components/PoDetail/QCDatagrid.tsx index 0429b7d..b9947db 100644 --- a/src/components/PoDetail/QCDatagrid.tsx +++ b/src/components/PoDetail/QCDatagrid.tsx @@ -1,71 +1,395 @@ -"use client" - -import { MutableRefObject } from "react"; -import StyledDataGrid from "../StyledDataGrid" -import { GridApiCommunity } from "@mui/x-data-grid/internals"; -import { GridColDef } from "@mui/x-data-grid"; +"use client"; +import { + Dispatch, + MutableRefObject, + SetStateAction, + useCallback, + useEffect, + useMemo, + useState, +} from "react"; +import StyledDataGrid from "../StyledDataGrid"; +import { + FooterPropsOverrides, + GridActionsCellItem, + GridCellParams, + GridColDef, + GridEventListener, + GridRowEditStopReasons, + GridRowId, + GridRowIdGetter, + GridRowModel, + GridRowModes, + GridRowModesModel, + GridRowSelectionModel, + GridToolbarContainer, + GridValidRowModel, + useGridApiRef, +} from "@mui/x-data-grid"; +import { set, useFormContext } from "react-hook-form"; +import SaveIcon from "@mui/icons-material/Save"; +import DeleteIcon from "@mui/icons-material/Delete"; +import CancelIcon from "@mui/icons-material/Cancel"; +import { Add } from "@mui/icons-material"; +import { Box, Button, Typography } from "@mui/material"; import { useTranslation } from "react-i18next"; -import { dummyQCData, QcData } from "./dummyQcTemplate"; -import { Checkbox } from "@mui/material"; +import { + GridApiCommunity, + GridSlotsComponentsProps, +} from "@mui/x-data-grid/internals"; +import { dummyQCData } from "./dummyQcTemplate"; +// T == CreatexxxInputs map of the form's fields +// V == target field input inside CreatexxxInputs, e.g. qcChecks: ItemQc[], V = ItemQc +// E == error +interface ResultWithId { + id: string | number; +} +// export type InputGridProps = { +// [key: string]: any +// } +interface DefaultResult { + _isNew: boolean; + _error: E; +} -interface Props { - // apiRef: MutableRefObject; -}; +interface SelectionResult { + active: boolean; + _isNew: boolean; + _error: E; +} +type Result = DefaultResult | SelectionResult; + +export type TableRow = Partial< + V & { + isActive: boolean | undefined; + _isNew: boolean; + _error: E; + } & ResultWithId +>; + +export interface InputDataGridProps { + apiRef: MutableRefObject; +// checkboxSelection: false | undefined; + _formKey: keyof T; + columns: GridColDef[]; + validateRow: (newRow: GridRowModel>) => E; + needAdd?: boolean; +} + +export interface SelectionInputDataGridProps { + // thinking how do + apiRef: MutableRefObject; +// checkboxSelection: true; + _formKey: keyof T; + columns: GridColDef[]; + validateRow: (newRow: GridRowModel>) => E; +} + +export type Props = + | InputDataGridProps + | SelectionInputDataGridProps; +export class ProcessRowUpdateError extends Error { + public readonly row: T; + public readonly errors: E | undefined; + constructor(row: T, message?: string, errors?: E) { + super(message); + this.row = row; + this.errors = errors; + + Object.setPrototypeOf(this, ProcessRowUpdateError.prototype); + } +} +// T == CreatexxxInputs map of the form's fields +// V == target field input inside CreatexxxInputs, e.g. qcChecks: ItemQc[], V = ItemQc +// E == error +function InputDataGrid({ + apiRef, +// checkboxSelection = false, + _formKey, + columns, + validateRow, +}: Props) { + const { + t, + // i18n: { language }, + } = useTranslation("purchaseOrder"); + const formKey = _formKey.toString(); + const { setValue, getValues } = useFormContext(); + const [rowModesModel, setRowModesModel] = useState({}); + // const apiRef = useGridApiRef(); + const getRowId = useCallback>>( + (row) => row.id! as number, + [], + ); + const formValue = getValues(formKey) + const list: TableRow[] = !formValue || formValue.length == 0 ? dummyQCData : getValues(formKey); + console.log(list) + const [rows, setRows] = useState[]>(() => { + // const list: TableRow[] = getValues(formKey); + console.log(list) + return list && list.length > 0 ? list : []; + }); + console.log(rows) + // const originalRows = list && list.length > 0 ? list : []; + const originalRows = useMemo(() => ( + list && list.length > 0 ? list : [] + ), [list]) + + // const originalRowModel = originalRows.filter((li) => li.isActive).map(i => i.id) as GridRowSelectionModel + const [rowSelectionModel, setRowSelectionModel] = + useState(() => { + // const rowModel = list.filter((li) => li.isActive).map(i => i.id) as GridRowSelectionModel + const rowModel: GridRowSelectionModel = getValues( + `${formKey}_active`, + ) as GridRowSelectionModel; + console.log(rowModel); + return rowModel; + }); + + useEffect(() => { + for (let i = 0; i < rows.length; i++) { + const currRow = rows[i] + setRowModesModel((prevRowModesModel) => ({ + ...prevRowModesModel, + [currRow.id as number]: { mode: GridRowModes.View }, + })); + } + }, [rows]) + + const handleSave = useCallback( + (id: GridRowId) => () => { + setRowModesModel((prevRowModesModel) => ({ + ...prevRowModesModel, + [id]: { mode: GridRowModes.View }, + })); + }, + [], + ); + const onProcessRowUpdateError = useCallback( + (updateError: ProcessRowUpdateError) => { + const errors = updateError.errors; + const row = updateError.row; + console.log(errors); + apiRef.current.updateRows([{ ...row, _error: errors }]); + }, + [apiRef], + ); + + const processRowUpdate = useCallback( + ( + newRow: GridRowModel>, + originalRow: GridRowModel>, + ) => { + ///////////////// + // validation here + const errors = validateRow(newRow); + console.log(newRow); + if (errors) { + throw new ProcessRowUpdateError( + originalRow, + "validation error", + errors, + ); + } + ///////////////// + const { _isNew, _error, ...updatedRow } = newRow; + const rowToSave = { + ...updatedRow, + } as TableRow; /// test + console.log(rowToSave); + setRows((rw) => + rw.map((r) => (getRowId(r) === getRowId(originalRow) ? rowToSave : r)), + ); + return rowToSave; + }, + [validateRow, getRowId], + ); + + const addRow = useCallback(() => { + const newEntry = { id: Date.now(), _isNew: true } as TableRow; + setRows((prev) => [...prev, newEntry]); + setRowModesModel((model) => ({ + ...model, + [getRowId(newEntry)]: { + mode: GridRowModes.Edit, + // fieldToFocus: "team", /// test + }, + })); + }, [getRowId]); + + const reset = useCallback(() => { + setRowModesModel({}); + setRows(originalRows); + }, [originalRows]); -const QcDataGrid: React.FC = ({ - // apiRef - }) => { - const { t } = useTranslation("purchaseOrder"); - - const columns: GridColDef[] = [ - { - field: "qcItem", - headerName: t("qcItem"), - flex: 1, - }, - { - field: "isPassed", - headerName: t("passed"), - flex: 1, - renderCell: (params) => ( - handleCheckboxChange(params.id)} - /> - ), - }, - { - field: "isFailed", - headerName: t("failed"), - flex: 1, - renderCell: (params) => ( - handleCheckboxChange(params.id)} - /> - ), - }, - { - field: "failedQty", - headerName: t("failedQty"), - flex: 1, - editable: true, - }, - { - field: "remarks", - headerName: t("remarks"), - flex: 1, - editable: true, - }, - ] - return ( - - ) + const handleCancel = useCallback( + (id: GridRowId) => () => { + setRowModesModel((model) => ({ + ...model, + [id]: { mode: GridRowModes.View, ignoreModifications: true }, + })); + const editedRow = rows.find((row) => getRowId(row) === id); + if (editedRow?._isNew) { + setRows((rw) => rw.filter((r) => getRowId(r) !== id)); + } else { + setRows((rw) => + rw.map((r) => (getRowId(r) === id ? { ...r, _error: undefined } : r)), + ); + } + }, + [rows, getRowId], + ); + + const handleDelete = useCallback( + (id: GridRowId) => () => { + setRows((prevRows) => prevRows.filter((row) => getRowId(row) !== id)); + }, + [getRowId], + ); + + const _columns = useMemo( + () => [ + ...columns, + { + field: "actions", + type: "actions", + headerName: "", + flex: 0.5, + cellClassName: "actions", + getActions: ({ id }: { id: GridRowId }) => { + const isInEditMode = rowModesModel[id]?.mode === GridRowModes.Edit; + if (isInEditMode) { + return [ + } + label="Save" + key="edit" + sx={{ + color: "primary.main", + }} + onClick={handleSave(id)} + />, + } + label="Cancel" + key="edit" + onClick={handleCancel(id)} + />, + ]; + } + return [ + } + label="Delete" + sx={{ + color: "error.main", + }} + onClick={handleDelete(id)} + color="inherit" + key="edit" + />, + ]; + }, + }, + ], + [columns, rowModesModel, handleSave, handleCancel, handleDelete], + ); + // sync useForm + useEffect(() => { + // console.log(formKey) + // console.log(rows) + setValue(formKey, rows); + }, [formKey, rows, setValue]); + + const footer = ( + + + + + ); + // const handleRowEditStop: GridEventListener<'rowEditStop'> = (params, event) => { + // if (params.reason === GridRowEditStopReasons.rowFocusOut) { + // event.defaultMuiPrevented = true; + // } + // }; + + return ( + } + rowSelectionModel={rowSelectionModel} + apiRef={apiRef} + rows={rows} + columns={columns} + editMode="row" + autoHeight + sx={{ + "--DataGrid-overlayHeight": "100px", + ".MuiDataGrid-row .MuiDataGrid-cell.hasError": { + border: "1px solid", + borderColor: "error.main", + }, + ".MuiDataGrid-row .MuiDataGrid-cell.hasWarning": { + border: "1px solid", + borderColor: "warning.main", + }, + }} + disableColumnMenu + processRowUpdate={processRowUpdate as any} + // onRowEditStop={handleRowEditStop} + rowModesModel={rowModesModel} + onRowModesModelChange={setRowModesModel} + onProcessRowUpdateError={onProcessRowUpdateError} + getCellClassName={(params: GridCellParams>) => { + let classname = ""; + if (params.row._error) { + classname = "hasError"; + } + return classname; + }} + slots={{ + // footer: FooterToolbar, + noRowsOverlay: NoRowsOverlay, + }} + // slotProps={{ + // footer: { child: footer }, + // } + // } + /> + ); } -export default QcDataGrid \ No newline at end of file +const FooterToolbar: React.FC = ({ child }) => { + return {child}; +}; +const NoRowsOverlay: React.FC = () => { + const { t } = useTranslation("home"); + return ( + + {t("Add some entries!")} + + ); +}; +export default InputDataGrid; diff --git a/src/components/PoDetail/QcFormVer2.tsx b/src/components/PoDetail/QcFormVer2.tsx index be0381c..1d85df7 100644 --- a/src/components/PoDetail/QcFormVer2.tsx +++ b/src/components/PoDetail/QcFormVer2.tsx @@ -5,6 +5,7 @@ import { Box, Card, CardContent, + Checkbox, Grid, Stack, Tab, @@ -17,7 +18,7 @@ import { import { useFormContext } from "react-hook-form"; import { useTranslation } from "react-i18next"; import StyledDataGrid from "../StyledDataGrid"; -import { useCallback, useEffect, useMemo, useState } from "react"; +import { Dispatch, SetStateAction, useCallback, useEffect, useMemo, useState } from "react"; import { GridColDef, GridRowIdGetter, @@ -43,22 +44,25 @@ import axiosInstance from "@/app/(main)/axios/axiosInstance"; import EscalationComponent from "./EscalationComponent"; import QcDataGrid from "./QCDatagrid"; import StockInFormVer2 from "./StockInFormVer2"; -import { dummyEscalationHistory } from "./dummyQcTemplate"; +import { dummyEscalationHistory, dummyQCData, QcData } from "./dummyQcTemplate"; +import { ModalFormInput } from "@/app/api/dashboard/actions"; interface Props { itemDetail: StockInLine; qc: QcItemWithChecks[]; disabled: boolean; + qcItems: QcData[] + setQcItems: Dispatch> } type EntryError = | { - [field in keyof PurchaseQcResult]?: string; + [field in keyof QcData]?: string; } | undefined; -type PoQcRow = TableRow, EntryError>; +type QcRow = TableRow, EntryError>; // fetchQcItemCheck -const QcFormVer2: React.FC = ({ qc, itemDetail, disabled }) => { +const QcFormVer2: React.FC = ({ qc, itemDetail, disabled, qcItems, setQcItems }) => { const { t } = useTranslation("purchaseOrder"); const apiRef = useGridApiRef(); const { @@ -76,6 +80,8 @@ const QcFormVer2: React.FC = ({ qc, itemDetail, disabled }) => { const [tabIndex, setTabIndex] = useState(0); const [rowSelectionModel, setRowSelectionModel] = useState() + const [qcResult, setQcResult] = useState(dummyEscalationHistory) + // const [qcItems, setQcItems] = useState(dummyQCData) const column = useMemo( () => [ @@ -137,18 +143,18 @@ const QcFormVer2: React.FC = ({ qc, itemDetail, disabled }) => { // flex: 1, // editable: !disabled, // valueFormatter(params) { - // const row = params.id ? params.api.getRow(params.id) : null; + // const row = params.id ? params.api.getRow(params.id) : null; // if (!row) { // return null; // } // const Qc = qc.find((q) => q.id === row.qcItemId); // return Qc ? `${Qc.code} - ${Qc.name}` : t("Please select QC"); // }, - // renderCell(params: GridRenderCellParams) { + // renderCell(params: GridRenderCellParams) { // console.log(params.value); // return {params.formattedValue}; // }, - // renderEditCell(params: GridRenderEditCellParams) { + // renderEditCell(params: GridRenderEditCellParams) { // const errorMessage = // params.row._error?.[params.field as keyof PurchaseQcResult]; // console.log(errorMessage); @@ -185,7 +191,7 @@ const QcFormVer2: React.FC = ({ qc, itemDetail, disabled }) => { // flex: 1, // editable: !disabled, // type: "number", - // renderEditCell(params: GridRenderEditCellParams) { + // renderEditCell(params: GridRenderEditCellParams) { // // const recordQty = params.row.qty // // if (recordQty !== undefined) { // // setUnrecordQty((prev) => prev - recordQty) @@ -217,23 +223,124 @@ const QcFormVer2: React.FC = ({ qc, itemDetail, disabled }) => { ); /// validate datagrid const validation = useCallback( - (newRow: GridRowModel): EntryError => { + (newRow: GridRowModel): EntryError => { const error: EntryError = {}; - const { qcItemId, failQty } = newRow; - if (!qcItemId || qcItemId <= 0) { - error["qcItemId"] = t("select qc"); - } - if (!failQty || failQty <= 0) { - error["failQty"] = t("enter a failQty"); - } - if (failQty && failQty > itemDetail.acceptedQty) { - error["failQty"] = t("qty too big"); - } + // const { qcItemId, failQty } = newRow; return Object.keys(error).length > 0 ? error : undefined; }, [], ); + function BooleanEditCell(params: GridRenderEditCellParams) { + const apiRef = useGridApiContext(); + const { id, field, value } = params; + + const handleChange = (e: React.ChangeEvent) => { + apiRef.current.setEditCellValue({ id, field, value: e.target.checked }); + apiRef.current.stopCellEditMode({ id, field }); // commit immediately + }; + + return ; +} + + const qcColumns: GridColDef[] = [ + { + field: "qcItem", + headerName: t("qcItem"), + flex: 1, + }, +{ + field: 'isPassed', + headerName: t("passed"), + flex: 1, + renderCell: (params) => ( + e.stopPropagation()} // avoid row selection + onMouseDown={(e) => e.stopPropagation()} // extra guard + onChange={(e) => { + const checked = e.target.checked; + setQcItems((prev) => + prev.map((r) => (r.id === params.id ? { ...r, isPassed: checked } : r)) + ); + }} + size="small" + /> + ), + }, + { + field: "isFailed", + headerName: t("failed"), + flex: 1, + editable: true, + type: "boolean", + renderCell: (params) => ( + e.stopPropagation()} // avoid row selection + onMouseDown={(e) => e.stopPropagation()} // extra guard + onChange={(e) => { + const checked = e.target.checked; + setQcItems((prev) => + prev.map((r) => (r.id === params.id ? { ...r, isFailed: checked } : r)) + ); + }} + size="small" + /> + ), + }, + { + field: "failedQty", + headerName: t("failedQty"), + flex: 1, + // editable: true, + renderCell: (params) => ( + { + const v = e.target.value; + const next = v === '' ? undefined : Number(v); + if (Number.isNaN(next)) return; + setQcItems((prev) => + prev.map((r) => (r.id === params.id ? { ...r, failedQty: next } : r)) + ); + }} + onClick={(e) => e.stopPropagation()} + onMouseDown={(e) => e.stopPropagation()} + onKeyDown={(e) => e.stopPropagation()} + inputProps={{ min: 0 }} + sx={{ width: '100%' }} + /> + ), + }, + { + field: "remarks", + headerName: t("remarks"), + flex: 1, + renderCell: (params) => ( + { + const remarks = e.target.value; + // const next = v === '' ? undefined : Number(v); + // if (Number.isNaN(next)) return; + setQcItems((prev) => + prev.map((r) => (r.id === params.id ? { ...r, remarks: remarks } : r)) + ); + }} + onClick={(e) => e.stopPropagation()} + onMouseDown={(e) => e.stopPropagation()} + onKeyDown={(e) => e.stopPropagation()} + inputProps={{ min: 0 }} + sx={{ width: '100%' }} + /> + ), + }, + ] + useEffect(() => { console.log(itemDetail); const status = "receiving"; @@ -268,10 +375,21 @@ const QcFormVer2: React.FC = ({ qc, itemDetail, disabled }) => { {tabIndex == 0 && ( <> - + {/* + apiRef={apiRef} + columns={qcColumns} + _formKey="qcResult" + validateRow={validation} + /> */} + @@ -296,7 +414,7 @@ const QcFormVer2: React.FC = ({ qc, itemDetail, disabled }) => { { setRowSelectionModel(newRowSelectionModel); diff --git a/src/components/PoDetail/QcStockInModalVer2.tsx b/src/components/PoDetail/QcStockInModalVer2.tsx index 8c260ed..da6a9bc 100644 --- a/src/components/PoDetail/QcStockInModalVer2.tsx +++ b/src/components/PoDetail/QcStockInModalVer2.tsx @@ -1,9 +1,16 @@ "use client"; - import { StockInLine } from "@/app/api/po"; import { ModalFormInput, PurchaseQcResult } from "@/app/api/po/actions"; import { QcItemWithChecks } from "@/app/api/qc"; -import { Box, Button, Grid, Modal, ModalProps, Stack, Typography } from "@mui/material"; +import { + Box, + Button, + Grid, + Modal, + ModalProps, + Stack, + Typography, +} from "@mui/material"; import { Dispatch, SetStateAction, useCallback, useState } from "react"; import { FormProvider, SubmitHandler, useForm } from "react-hook-form"; import { StockInLineRow } from "./PoInputGrid"; @@ -12,8 +19,8 @@ import StockInForm from "./StockInForm"; import StockInFormVer2 from "./StockInFormVer2"; import QcFormVer2 from "./QcFormVer2"; import PutawayForm from "./PutawayForm"; -import { dummyPutawayLine } from "./dummyQcTemplate"; - +import { dummyPutawayLine, dummyQCData } from "./dummyQcTemplate"; +import { useGridApiRef } from "@mui/x-data-grid"; const style = { position: "absolute", top: "50%", @@ -25,9 +32,8 @@ const style = { pb: 10, display: "block", width: { xs: "60%", sm: "60%", md: "60%" }, -// height: { xs: "60%", sm: "60%", md: "60%" }, + // height: { xs: "60%", sm: "60%", md: "60%" }, }; - interface CommonProps extends Omit { // setRows: Dispatch>; setEntries?: Dispatch>; @@ -43,12 +49,10 @@ interface CommonProps extends Omit { >; qc?: QcItemWithChecks[]; warehouse?: any[]; -// type: "qc" | "stockIn" | "escalation" | "putaway" | "reject"; + // type: "qc" | "stockIn" | "escalation" | "putaway" | "reject"; } - -interface Props extends CommonProps{ +interface Props extends CommonProps { itemDetail: StockInLine & { qcResult?: PurchaseQcResult[] }; - } const PoQcStockInModalVer2: React.FC = ({ // type, @@ -62,165 +66,243 @@ const PoQcStockInModalVer2: React.FC = ({ qc, warehouse, }) => { - console.log(warehouse) - const { - t, - i18n: { language }, - } = useTranslation("purchaseOrder"); + console.log(warehouse); + const { + t, + i18n: { language }, + } = useTranslation("purchaseOrder"); +const [qcItems, setQcItems] = useState(dummyQCData) const formProps = useForm({ defaultValues: { ...itemDetail, - putawayLine: dummyPutawayLine + putawayLine: dummyPutawayLine, // receiptDate: itemDetail.receiptDate || dayjs().add(-1, "month").format(INPUT_DATE_FORMAT), // warehouseId: itemDetail.defaultWarehouseId || 0 }, }); - const closeHandler = useCallback>( - (...args) => { - onClose?.(...args); - // reset(); - }, - [onClose], - ); - const [openPutaway, setOpenPutaway] = useState(false) + (...args) => { + onClose?.(...args); + // reset(); + }, + [onClose], + ); + const [openPutaway, setOpenPutaway] = useState(false); const onOpenPutaway = useCallback(() => { setOpenPutaway(true); }, []); - const onClosePutaway = useCallback(() => { setOpenPutaway(false); }, []); - - const [submissionType, setSubmissionType] = useState<"stockIn" | "qc" | "escalate" | undefined>(undefined) - const onSubmit = useCallback>( + // Stock In submission handler + const onSubmitStockIn = useCallback>( async (data, event) => { - console.log(event!.nativeEvent) - // closeHandler({}, "backdropClick"); - // for now go to putaway form - onOpenPutaway() - - // divide 3 section for this submition - // switch (submissionType) { - // submit stock in data - // submit qc data - // submit putaway - // } + console.log("Stock In Submission:", event!.nativeEvent); + // Extract only stock-in related fields + const stockInData = { + // quantity: data.quantity, + // receiptDate: data.receiptDate, + // batchNumber: data.batchNumber, + // expiryDate: data.expiryDate, + // warehouseId: data.warehouseId, + // location: data.location, + // unitCost: data.unitCost, + data: data, + // Add other stock-in specific fields from your form + }; + console.log("Stock In Data:", stockInData); + // Handle stock-in submission logic here + // e.g., call API, update state, etc. + }, + [], + ); + // QC submission handler + const onSubmitQc = useCallback>( + async (data, event) => { + console.log("QC Submission:", event!.nativeEvent); + // Extract only QC related fields + const qcData = { + // qcStatus: data.qcStatus, + // qcComments: data.qcComments, + // qcResult: data.qcResult, + // approvedBy: data.approvedBy, + // qualityGrade: data.qualityGrade, + // defectNotes: data.defectNotes, + data: data, + // Add other QC specific fields from your form + }; + console.log(qcItems) + console.log("QC Data:", qcData); + // Handle QC submission logic here + // After QC approval, open putaway form + // onOpenPutaway(); + }, + [onOpenPutaway, qcItems], + ); + // Email supplier handler + const onSubmitEmailSupplier = useCallback>( + async (data, event) => { + console.log("Email Supplier Submission:", event!.nativeEvent); + // Extract only email supplier related fields + const emailData = { + // supplierEmail: data.supplierEmail, + // issueDescription: data.issueDescription, + // qcComments: data.qcComments, + // defectNotes: data.defectNotes, + // attachments: data.attachments, + // escalationReason: data.escalationReason, + data: data, - }, [submissionType]) + // Add other email-specific fields + }; + console.log("Email Supplier Data:", emailData); + // Handle email supplier logic here + // e.g., send email to supplier, log escalation, etc. + }, + [], + ); + // Putaway submission handler + const onSubmitPutaway = useCallback>( + async (data, event) => { + console.log("Putaway Submission:", event!.nativeEvent); + // Extract only putaway related fields + const putawayData = { + // putawayLine: data.putawayLine, + // putawayLocation: data.putawayLocation, + // binLocation: data.binLocation, + // putawayQuantity: data.putawayQuantity, + // putawayNotes: data.putawayNotes, + data: data, - return ( - <> - {/* {itemDetail !== undefined && ( - - )} */} - - - - {openPutaway ? ( - <> - - - - - - + // Add other putaway specific fields + }; + console.log("Putaway Data:", putawayData); + // Handle putaway submission logic here + // Close modal after successful putaway + closeHandler({}, "backdropClick"); + }, + [closeHandler], + ); + // Print handler + const onPrint = useCallback(() => { + console.log("Print putaway documents"); + // Handle print logic here + window.print(); + }, []); + return ( + <> + + + + {openPutaway ? ( + + + + + + + ) : ( - <> - - - - {t("qc processing")} - - - - - - - - - - - - - - - - - - ) - - } - - - - - - ) -} -export default PoQcStockInModalVer2 \ No newline at end of file + <> + + + + {t("qc processing")} + + + + + + + + + + + + + + + + + + )} + + + + + ); +}; +export default PoQcStockInModalVer2; diff --git a/src/components/PoDetail/StockInForm.tsx b/src/components/PoDetail/StockInForm.tsx index f846388..c14bd74 100644 --- a/src/components/PoDetail/StockInForm.tsx +++ b/src/components/PoDetail/StockInForm.tsx @@ -82,7 +82,7 @@ const StockInForm: React.FC = ({ // receiptDate default tdy setValue("receiptDate", dayjs().add(0, "month").format(INPUT_DATE_FORMAT)); setValue("status", "received"); - }, []); + }, [setValue]); useEffect(() => { console.log(errors); @@ -97,7 +97,7 @@ const StockInForm: React.FC = ({ if (expiryDate) clearErrors(); if (productionDate) clearErrors(); }, [productionDate, expiryDate, clearErrors]); - + return (