| @@ -54,8 +54,7 @@ import QrCodeIcon from "@mui/icons-material/QrCode"; | |||
| import { downloadFile } from "@/app/utils/commonUtil"; | |||
| import { fetchPoQrcode } from "@/app/api/pdf/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"; | |||
| interface ResultWithId { | |||
| @@ -181,7 +180,6 @@ function PoInputGrid({ | |||
| ) as StockInLine[] | |||
| ); | |||
| setBtnIsLoading(false); | |||
| notifyActionSuccess(); | |||
| // do post directly to test | |||
| // openStartModal(); | |||
| }, 200); | |||
| @@ -44,6 +44,7 @@ import ReactQrCodeScanner, { | |||
| ScannerConfig, | |||
| } from "../ReactQrCodeScanner/ReactQrCodeScanner"; | |||
| import { QrCodeInfo } from "@/app/api/qrcode"; | |||
| import { useQcCodeScanner } from "../QrCodeScannerProvider/QrCodeScannerProvider"; | |||
| interface Props { | |||
| itemDetail: StockInLine; | |||
| @@ -210,6 +211,30 @@ const PutawayForm: React.FC<Props> = ({ itemDetail, warehouse, disabled }) => { | |||
| [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(() => { | |||
| setValue("status", "completed"); | |||
| }, []); | |||
| @@ -408,7 +433,8 @@ const PutawayForm: React.FC<Props> = ({ itemDetail, warehouse, disabled }) => { | |||
| <Modal open={isOpenScanner} onClose={closeHandler}> | |||
| <Box sx={style}> | |||
| <ReactQrCodeScanner scannerConfig={scannerConfig} /> | |||
| <Typography variant="h4">{t("Please scan warehouse qr code.")}</Typography> | |||
| {/* <ReactQrCodeScanner scannerConfig={scannerConfig} /> */} | |||
| </Box> | |||
| </Modal> | |||
| </Grid> | |||
| @@ -19,6 +19,7 @@ import { QrCodeInfo } from "@/app/api/qrcode"; | |||
| import { Check } from "@mui/icons-material"; | |||
| import { useTranslation } from "react-i18next"; | |||
| import { useSearchParams } from "next/navigation"; | |||
| import { useQcCodeScanner } from "../QrCodeScannerProvider/QrCodeScannerProvider"; | |||
| interface Props extends Omit<ModalProps, "children"> { | |||
| 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 [disabledSubmit, setDisabledSubmit] = useState(false); | |||
| const [unavailableText, setUnavailableText] = useState<string | undefined>(undefined) | |||
| @@ -115,13 +140,13 @@ const QrModal: React.FC<Props> = ({ open, onClose, warehouse }) => { | |||
| //////////////////////// modify this mess later ////////////////////// | |||
| 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, | |||
| } as StockInLineEntry & ModalFormInput; | |||
| ////////////////////////////////////////////////////////////////////// | |||
| @@ -160,28 +185,32 @@ const QrModal: React.FC<Props> = ({ open, onClose, warehouse }) => { | |||
| > | |||
| <Grid container 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> | |||
| </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; | |||