| @@ -54,8 +54,7 @@ import QrCodeIcon from "@mui/icons-material/QrCode"; | |||||
| import { downloadFile } from "@/app/utils/commonUtil"; | import { downloadFile } from "@/app/utils/commonUtil"; | ||||
| import { fetchPoQrcode } from "@/app/api/pdf/actions"; | import { fetchPoQrcode } from "@/app/api/pdf/actions"; | ||||
| import { fetchQcResult } from "@/app/api/qc/actions"; | import { fetchQcResult } from "@/app/api/qc/actions"; | ||||
| import PoQcStockInModal from "./PoQcStockInModal"; | |||||
| import { notifyActionSuccess } from "../Toast/Toast"; | |||||
| import PoQcStockInModal from "./PoQcStockInModal" | |||||
| import DoDisturbIcon from "@mui/icons-material/DoDisturb"; | import DoDisturbIcon from "@mui/icons-material/DoDisturb"; | ||||
| interface ResultWithId { | interface ResultWithId { | ||||
| @@ -181,7 +180,6 @@ function PoInputGrid({ | |||||
| ) as StockInLine[] | ) as StockInLine[] | ||||
| ); | ); | ||||
| setBtnIsLoading(false); | setBtnIsLoading(false); | ||||
| notifyActionSuccess(); | |||||
| // do post directly to test | // do post directly to test | ||||
| // openStartModal(); | // openStartModal(); | ||||
| }, 200); | }, 200); | ||||
| @@ -44,6 +44,7 @@ import ReactQrCodeScanner, { | |||||
| ScannerConfig, | ScannerConfig, | ||||
| } from "../ReactQrCodeScanner/ReactQrCodeScanner"; | } from "../ReactQrCodeScanner/ReactQrCodeScanner"; | ||||
| import { QrCodeInfo } from "@/app/api/qrcode"; | import { QrCodeInfo } from "@/app/api/qrcode"; | ||||
| import { useQcCodeScanner } from "../QrCodeScannerProvider/QrCodeScannerProvider"; | |||||
| interface Props { | interface Props { | ||||
| itemDetail: StockInLine; | itemDetail: StockInLine; | ||||
| @@ -210,6 +211,30 @@ const PutawayForm: React.FC<Props> = ({ itemDetail, warehouse, disabled }) => { | |||||
| [onCloseScanner] | [onCloseScanner] | ||||
| ); | ); | ||||
| // QR Code Scanner | |||||
| const scanner = useQcCodeScanner() | |||||
| useEffect(() => { | |||||
| if (isOpenScanner) { | |||||
| scanner.startScan() | |||||
| } else if (!isOpenScanner) { | |||||
| scanner.stopScan() | |||||
| } | |||||
| }, [isOpenScanner]) | |||||
| useEffect(() => { | |||||
| if (scanner.values.length > 0) { | |||||
| console.log(scanner.values[0]) | |||||
| const data: QrCodeInfo = JSON.parse(scanner.values[0]); | |||||
| console.log(data); | |||||
| if (data.warehouseId) { | |||||
| console.log(data.warehouseId); | |||||
| setWarehouseId(data.warehouseId); | |||||
| onCloseScanner(); | |||||
| } | |||||
| scanner.resetScan() | |||||
| } | |||||
| }, [scanner.values]) | |||||
| useEffect(() => { | useEffect(() => { | ||||
| setValue("status", "completed"); | setValue("status", "completed"); | ||||
| }, []); | }, []); | ||||
| @@ -408,7 +433,8 @@ const PutawayForm: React.FC<Props> = ({ itemDetail, warehouse, disabled }) => { | |||||
| <Modal open={isOpenScanner} onClose={closeHandler}> | <Modal open={isOpenScanner} onClose={closeHandler}> | ||||
| <Box sx={style}> | <Box sx={style}> | ||||
| <ReactQrCodeScanner scannerConfig={scannerConfig} /> | |||||
| <Typography variant="h4">{t("Please scan warehouse qr code.")}</Typography> | |||||
| {/* <ReactQrCodeScanner scannerConfig={scannerConfig} /> */} | |||||
| </Box> | </Box> | ||||
| </Modal> | </Modal> | ||||
| </Grid> | </Grid> | ||||
| @@ -19,6 +19,7 @@ import { QrCodeInfo } from "@/app/api/qrcode"; | |||||
| import { Check } from "@mui/icons-material"; | import { Check } from "@mui/icons-material"; | ||||
| import { useTranslation } from "react-i18next"; | import { useTranslation } from "react-i18next"; | ||||
| import { useSearchParams } from "next/navigation"; | import { useSearchParams } from "next/navigation"; | ||||
| import { useQcCodeScanner } from "../QrCodeScannerProvider/QrCodeScannerProvider"; | |||||
| interface Props extends Omit<ModalProps, "children"> { | interface Props extends Omit<ModalProps, "children"> { | ||||
| warehouse: WarehouseResult[]; | warehouse: WarehouseResult[]; | ||||
| @@ -72,6 +73,30 @@ const QrModal: React.FC<Props> = ({ open, onClose, warehouse }) => { | |||||
| [] | [] | ||||
| ); | ); | ||||
| // QR Code Scanner | |||||
| const scanner = useQcCodeScanner() | |||||
| useEffect(() => { | |||||
| if (open && !scanner.isScanning) { | |||||
| scanner.startScan() | |||||
| } else if (!open && scanner.isScanning) { | |||||
| scanner.stopScan() | |||||
| } | |||||
| }, [open]) | |||||
| useEffect(() => { | |||||
| if (scanner.values.length > 0 && !Boolean(itemDetail)) { | |||||
| console.log(scanner.values[0]) | |||||
| const data: QrCodeInfo = JSON.parse(scanner.values[0]); | |||||
| console.log(data); | |||||
| if (data.stockInLineId) { | |||||
| console.log("still got in"); | |||||
| console.log(data.stockInLineId); | |||||
| setStockInLineId(data.stockInLineId); | |||||
| } | |||||
| scanner.resetScan() | |||||
| } | |||||
| }, [scanner.values]) | |||||
| const [itemDetail, setItemDetail] = useState<StockInLine>(); | const [itemDetail, setItemDetail] = useState<StockInLine>(); | ||||
| const [disabledSubmit, setDisabledSubmit] = useState(false); | const [disabledSubmit, setDisabledSubmit] = useState(false); | ||||
| const [unavailableText, setUnavailableText] = useState<string | undefined>(undefined) | const [unavailableText, setUnavailableText] = useState<string | undefined>(undefined) | ||||
| @@ -115,13 +140,13 @@ const QrModal: React.FC<Props> = ({ open, onClose, warehouse }) => { | |||||
| //////////////////////// modify this mess later ////////////////////// | //////////////////////// modify this mess later ////////////////////// | ||||
| const args = { | const args = { | ||||
| id: itemDetail?.id, | |||||
| purchaseOrderId: parseInt(params.get("id")!!), | |||||
| purchaseOrderLineId: itemDetail?.purchaseOrderLineId, | |||||
| itemId: itemDetail?.itemId, | |||||
| acceptedQty: data.acceptedQty, | |||||
| warehouseId: data.warehouseId, | |||||
| // ...data, | |||||
| id: itemDetail?.id, | |||||
| purchaseOrderId: parseInt(params.get("id")!!), | |||||
| purchaseOrderLineId: itemDetail?.purchaseOrderLineId, | |||||
| itemId: itemDetail?.itemId, | |||||
| acceptedQty: data.acceptedQty, | |||||
| warehouseId: data.warehouseId, | |||||
| // ...data, | |||||
| // productionDate: productionDate, | // productionDate: productionDate, | ||||
| } as StockInLineEntry & ModalFormInput; | } as StockInLineEntry & ModalFormInput; | ||||
| ////////////////////////////////////////////////////////////////////// | ////////////////////////////////////////////////////////////////////// | ||||
| @@ -160,28 +185,32 @@ const QrModal: React.FC<Props> = ({ open, onClose, warehouse }) => { | |||||
| > | > | ||||
| <Grid container xs={12}> | <Grid container xs={12}> | ||||
| <Grid item xs={12}> | <Grid item xs={12}> | ||||
| {itemDetail != undefined ? ( | |||||
| unavailableText != undefined ? <Typography variant="h4" marginInlineEnd={2}>{unavailableText}</Typography> | |||||
| : ( | |||||
| <> | |||||
| <PutawayForm itemDetail={itemDetail} warehouse={warehouse} disabled={false}/> | |||||
| <Stack direction="row" justifyContent="flex-end" gap={1}> | |||||
| <Button | |||||
| name="submit" | |||||
| variant="contained" | |||||
| startIcon={<Check />} | |||||
| type="submit" | |||||
| disabled={disabledSubmit} | |||||
| > | |||||
| {t("submit")} | |||||
| </Button> | |||||
| </Stack> | |||||
| </> | |||||
| { | |||||
| itemDetail != undefined ? ( | |||||
| unavailableText != undefined ? <Typography variant="h4" marginInlineEnd={2}>{unavailableText}</Typography> | |||||
| : ( | |||||
| <> | |||||
| <PutawayForm itemDetail={itemDetail} warehouse={warehouse} disabled={false} /> | |||||
| <Stack direction="row" justifyContent="flex-end" gap={1}> | |||||
| <Button | |||||
| name="submit" | |||||
| variant="contained" | |||||
| startIcon={<Check />} | |||||
| type="submit" | |||||
| disabled={disabledSubmit} | |||||
| > | |||||
| {t("submit")} | |||||
| </Button> | |||||
| </Stack> | |||||
| </> | |||||
| ) | |||||
| ) | ) | ||||
| ) : ( | |||||
| <ReactQrCodeScanner scannerConfig={scannerConfig} /> | |||||
| )} | |||||
| : ( | |||||
| // <ReactQrCodeScanner scannerConfig={scannerConfig} /> | |||||
| <Typography variant="h4">{t("Will start binding procedure after scanning item qr code.")}</Typography> | |||||
| ) | |||||
| } | |||||
| </Grid> | </Grid> | ||||
| </Grid> | </Grid> | ||||
| </Box> | </Box> | ||||
| @@ -0,0 +1,99 @@ | |||||
| "use client"; | |||||
| import { ReactNode, createContext, useCallback, useContext, useEffect, useState } from "react"; | |||||
| interface QcCodeScanner { | |||||
| values: string[]; | |||||
| isScanning: boolean; | |||||
| startScan: () => void; | |||||
| stopScan: () => void; | |||||
| resetScan: () => void; | |||||
| } | |||||
| interface QrCodeScannerProviderProps { | |||||
| children: ReactNode; | |||||
| } | |||||
| export const QcCodeScannerContext = createContext<QcCodeScanner | undefined>(undefined) | |||||
| const QrCodeScannerProvider: React.FC<QrCodeScannerProviderProps> = ({ children }) => { | |||||
| const [qcCodeScannerValues, setQrCodeScannerValues] = useState<string[]>([]); | |||||
| const [isScanning, setIsScanning] = useState<boolean>(false); | |||||
| const [keys, setKeys] = useState<string[]>([]); | |||||
| const [leftCurlyBraceCount, setLeftCurlyBraceCount] = useState<number>(0); | |||||
| const [rightCurlyBraceCount, setRightCurlyBraceCount] = useState<number>(0); | |||||
| const resetQrCodeScanner = useCallback(() => { | |||||
| setQrCodeScannerValues(() => []) | |||||
| }, []) | |||||
| const startQrCodeScanner = useCallback(() => { | |||||
| resetQrCodeScanner() | |||||
| setIsScanning(() => true) | |||||
| }, []) | |||||
| const endQrCodeScanner = useCallback(() => { | |||||
| setIsScanning(() => false) | |||||
| }, []) | |||||
| // Check the KeyDown | |||||
| useEffect(() => { | |||||
| if (isScanning) { | |||||
| const handleKeyDown = (event: KeyboardEvent) => { | |||||
| if (event.key.length === 1) { | |||||
| setKeys((key) => [...key, event.key]) | |||||
| } | |||||
| if (event.key === "{") { | |||||
| setLeftCurlyBraceCount((count) => count + 1) | |||||
| } else if (event.key === "}") { | |||||
| setRightCurlyBraceCount((count) => count + 1) | |||||
| } | |||||
| } | |||||
| document.addEventListener('keydown', handleKeyDown); | |||||
| return () => { | |||||
| document.removeEventListener('keydown', handleKeyDown); | |||||
| }; | |||||
| }; | |||||
| }, [isScanning]) | |||||
| // Update Qr Code Scanner Values | |||||
| useEffect(() => { | |||||
| if (leftCurlyBraceCount !== 0 && rightCurlyBraceCount !== 0 && leftCurlyBraceCount === rightCurlyBraceCount) { | |||||
| const startBrace = keys.indexOf('{'); | |||||
| const endBrace = keys.lastIndexOf('}'); | |||||
| setQrCodeScannerValues((value) => [...value, keys.join("").substring(startBrace, endBrace + 1)]) | |||||
| console.log(keys) | |||||
| console.log(qcCodeScannerValues) | |||||
| // reset | |||||
| setKeys(() => []) | |||||
| setLeftCurlyBraceCount(() => 0) | |||||
| setRightCurlyBraceCount(() => 0) | |||||
| } | |||||
| }, [keys, leftCurlyBraceCount, rightCurlyBraceCount]) | |||||
| return ( | |||||
| <QcCodeScannerContext.Provider value={{ | |||||
| values: qcCodeScannerValues, | |||||
| isScanning: isScanning, | |||||
| startScan: startQrCodeScanner, | |||||
| stopScan: endQrCodeScanner, | |||||
| resetScan: resetQrCodeScanner, | |||||
| }}> | |||||
| {children} | |||||
| </QcCodeScannerContext.Provider> | |||||
| ) | |||||
| } | |||||
| export const useQcCodeScanner = (): QcCodeScanner => { | |||||
| const context = useContext(QcCodeScannerContext); | |||||
| if (!context) { | |||||
| throw new Error('useQcCodeScanner must be used within a QcCodeScannerProvider'); | |||||
| } | |||||
| return context; | |||||
| }; | |||||
| export default QrCodeScannerProvider; | |||||