FPSMS-frontend
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

660 lines
27 KiB

  1. "use client";
  2. import {
  3. Box,
  4. Button,
  5. Grid,
  6. Modal,
  7. ModalProps,
  8. Stack,
  9. TextField,
  10. Typography,
  11. Paper,
  12. Divider,
  13. } from "@mui/material";
  14. import { useCallback, useEffect, useLayoutEffect, useMemo, useState } from "react";
  15. import ReactQrCodeScanner, {
  16. ScannerConfig,
  17. } from "../ReactQrCodeScanner/ReactQrCodeScanner";
  18. import { FormProvider, SubmitHandler, useForm } from "react-hook-form";
  19. import {
  20. fetchStockInLineInfo,
  21. StockInLineEntry,
  22. updateStockInLine,
  23. } from "@/app/api/stockIn/actions";
  24. import { ModalFormInput, StockInLine } from "@/app/api/stockIn";
  25. import { WarehouseResult } from "@/app/api/warehouse";
  26. // import { QrCodeInfo } from "@/app/api/qrcde";
  27. import { Check, QrCode, ErrorOutline, CheckCircle } from "@mui/icons-material";
  28. import { useTranslation } from "react-i18next";
  29. import { useSearchParams } from "next/navigation";
  30. import { useQrCodeScannerContext } from "../QrCodeScannerProvider/QrCodeScannerProvider";
  31. import LoadingComponent from "../General/LoadingComponent";
  32. import StockInForm from "../StockIn/StockInForm";
  33. import { arrayToDateString, INPUT_DATE_FORMAT } from "@/app/utils/formatUtil";
  34. import { QrCodeScanner } from "../QrCodeScannerProvider/QrCodeScannerProvider";
  35. import { msg } from "../Swal/CustomAlerts";
  36. import { PutAwayRecord } from ".";
  37. import FgStockInForm from "../StockIn/FgStockInForm";
  38. import Swal from "sweetalert2";
  39. interface Props extends Omit<ModalProps, "children"> {
  40. warehouse: WarehouseResult[];
  41. stockInLineId: number;
  42. warehouseId: number;
  43. scanner: QrCodeScanner;
  44. addPutAwayHistory: (putAwayData: PutAwayRecord) => void;
  45. }
  46. const style = {
  47. position: "absolute",
  48. top: "50%",
  49. left: "50%",
  50. transform: "translate(-50%, -50%)",
  51. bgcolor: "background.paper",
  52. pt: { xs: 0.5, sm: 1, md: 1.5 },
  53. px: { xs: 1, sm: 1.5, md: 2 },
  54. pb: { xs: 0.5, sm: 1, md: 1.5 },
  55. width: { xs: "95%", sm: "85%", md: "75%", lg: "70%" },
  56. maxWidth: "900px",
  57. maxHeight: { xs: "98vh", sm: "95vh", md: "90vh" },
  58. overflow: "hidden",
  59. display: "flex",
  60. flexDirection: "column",
  61. };
  62. const scannerStyle = {
  63. position: "absolute",
  64. top: "50%",
  65. left: "50%",
  66. transform: "translate(-50%, -50%)",
  67. bgcolor: "background.paper",
  68. pt: { xs: 2, sm: 3, md: 4 },
  69. px: { xs: 2, sm: 3, md: 4 },
  70. pb: { xs: 6, sm: 7, md: 8 },
  71. width: { xs: "85%", sm: "70%", md: "60%" },
  72. maxWidth: "600px",
  73. };
  74. const PutAwayModal: React.FC<Props> = ({ open, onClose, warehouse, stockInLineId, warehouseId, scanner, addPutAwayHistory }) => {
  75. const { t } = useTranslation("putAway");
  76. const [serverError, setServerError] = useState("");
  77. const params = useSearchParams();
  78. const [isOpenScanner, setIsOpenScanner] = useState<boolean>(false);
  79. const [firstWarehouseId, setFirstWarehouseId] = useState<number | null>(null);
  80. const [warehouseMismatchError, setWarehouseMismatchError] = useState<string>("");
  81. const [firstWarehouseInfo, setFirstWarehouseInfo] = useState<{name: string, code: string} | null>(null);
  82. const [itemDetail, setItemDetail] = useState<StockInLine>();
  83. const [totalPutAwayQty, setTotalPutAwayQty] = useState<number>(0);
  84. const [unavailableText, setUnavailableText] = useState<string | undefined>(
  85. undefined,
  86. );
  87. const [putQty, setPutQty] = useState<number>(itemDetail?.acceptedQty ?? 0);
  88. const [verified, setVerified] = useState<boolean>(false);
  89. const [qtyError, setQtyError] = useState<string>("");
  90. const defaultNewValue = useMemo(() => {
  91. // console.log("%c ItemDetail", "color:purple", itemDetail);
  92. return (
  93. {
  94. ...itemDetail,
  95. // status: itemDetail.status ?? "pending",
  96. // dnDate: arrayToDateString(itemDetail?.dnDate, "input")?? undefined,
  97. // // putAwayLines: dummyPutAwayLine,
  98. // // putAwayLines: itemDetail.putAwayLines.map((line) => (return {...line, printQty: 1})) ?? [],
  99. // putAwayLines: itemDetail.putAwayLines?.map((line) => ({...line, printQty: 1, _isNew: false})) ?? [],
  100. // // qcResult: (itemDetail.qcResult && itemDetail.qcResult?.length > 0) ? itemDetail.qcResult : [],//[...dummyQCData],
  101. // escResult: (itemDetail.escResult && itemDetail.escResult?.length > 0) ? itemDetail.escResult : [],
  102. productionDate: itemDetail?.productionDate ? arrayToDateString(itemDetail?.productionDate, "input") : undefined,
  103. expiryDate: itemDetail?.expiryDate ? arrayToDateString(itemDetail?.expiryDate, "input") : undefined,
  104. receiptDate: itemDetail?.receiptDate ? arrayToDateString(itemDetail?.receiptDate, "input") : undefined,
  105. acceptQty: itemDetail?.acceptedQty ?? 0,
  106. defaultWarehouseId: itemDetail?.defaultWarehouseId ?? 1,
  107. } as ModalFormInput
  108. )
  109. }, [itemDetail])
  110. const formProps = useForm<ModalFormInput>({
  111. defaultValues: {
  112. ...defaultNewValue,
  113. },
  114. });
  115. const errors = formProps.formState.errors;
  116. useEffect(() => {
  117. if (itemDetail) {
  118. startScanner();
  119. }
  120. }, [itemDetail])
  121. const closeHandler = useCallback<NonNullable<ModalProps["onClose"]>>(
  122. (...args) => {
  123. setVerified(false);
  124. setItemDetail(undefined);
  125. setTotalPutAwayQty(0);
  126. onClose?.(...args);
  127. // reset();
  128. },
  129. [onClose],
  130. );
  131. const scannerCloseHandler = useCallback<NonNullable<ModalProps["onClose"]>>(
  132. (...args) => {
  133. setIsOpenScanner(false);
  134. scanner.stopScan();
  135. console.log("%c Scanning stopped ", "color:cyan");
  136. },
  137. [],
  138. );
  139. const startScanner = () => {
  140. // setIsOpenScanner(true);
  141. scanner.startScan();
  142. console.log("%c Scanning started ", "color:cyan");
  143. };
  144. const openScanner = () => {
  145. setIsOpenScanner(true);
  146. scanner.startScan();
  147. console.log("%c Scanning started ", "color:cyan");
  148. };
  149. useEffect(() => {
  150. if (warehouseId > 0 && firstWarehouseId !== null) {
  151. if (warehouseId !== firstWarehouseId) {
  152. const firstWh = warehouse.find((w) => w.id == firstWarehouseId);
  153. const scannedWh = warehouse.find((w) => w.id == warehouseId);
  154. setWarehouseMismatchError("倉庫不匹配!必須使用首次上架的倉庫");
  155. setVerified(false);
  156. } else {
  157. setWarehouseMismatchError("");
  158. if (scanner.isScanning) {
  159. setIsOpenScanner(false);
  160. setVerified(true);
  161. msg("貨倉掃瞄成功!");
  162. scanner.resetScan();
  163. }
  164. }
  165. } else if (warehouseId > 0 && firstWarehouseId === null) {
  166. // First put away - no validation needed
  167. if (scanner.isScanning) {
  168. setIsOpenScanner(false);
  169. setVerified(true);
  170. msg("貨倉掃瞄成功!");
  171. scanner.resetScan();
  172. }
  173. }
  174. }, [warehouseId, firstWarehouseId])
  175. const warehouseDisplay = useMemo(() => {
  176. const targetWarehouseId = firstWarehouseId || warehouseId || 1;
  177. const wh = warehouse.find((w) => w.id == warehouseId) ?? warehouse.find((w) => w.id == 1);
  178. return <>{wh?.name} <br/> [{wh?.code}]</>;
  179. }, [warehouse, warehouseId, firstWarehouseId,verified]);
  180. // useEffect(() => { // Restart scanner for changing warehouse
  181. // if (warehouseId > 0) {
  182. // scanner.startScan();
  183. // console.log("%c Scanner restarted", "color:cyan");
  184. // }
  185. // }, [isOpenScanner])
  186. useLayoutEffect(() => {
  187. if (itemDetail !== undefined) {
  188. if (itemDetail.status == "received") {
  189. formProps.reset({
  190. ...defaultNewValue
  191. })
  192. const total = itemDetail.putAwayLines?.reduce((sum, p) => sum + p.qty, 0) ?? 0;
  193. setPutQty(itemDetail?.acceptedQty - total);
  194. // ✅ Get first warehouse from existing put away lines
  195. const firstPutAwayLine = itemDetail.putAwayLines?.[0];
  196. if (firstPutAwayLine?.warehouseId) {
  197. setFirstWarehouseId(firstPutAwayLine.warehouseId);
  198. // ✅ Store first warehouse info for display
  199. const firstWh = warehouse.find((w) => w.id == firstPutAwayLine.warehouseId);
  200. if (firstWh) {
  201. setFirstWarehouseInfo({
  202. name: firstWh.name || "",
  203. code: firstWh.code || ""
  204. });
  205. }
  206. } else {
  207. setFirstWarehouseId(null);
  208. setFirstWarehouseInfo(null);
  209. }
  210. console.log("%c Loaded data:", "color:lime", defaultNewValue);
  211. } else {
  212. switch (itemDetail.status) {
  213. case "pending": alert("此貨品有待品檢"); break;
  214. case "rejected": alert("此貨品已被拒收"); break;
  215. case "escalated": alert("此貨品已被上報"); break;
  216. case "partially_completed": alert("此貨品已部分上架"); break;
  217. case "completed": alert("此貨品已上架"); break;
  218. default: alert("此貨品暫時無法上架"); break;
  219. }
  220. closeHandler({}, "backdropClick");
  221. }
  222. }
  223. }, [open, itemDetail, defaultNewValue])
  224. const fetchStockInLine = useCallback(
  225. async (stockInLineId: number) => {
  226. setUnavailableText(undefined);
  227. try {
  228. const res = await fetchStockInLineInfo(stockInLineId);
  229. console.log("%c Fetched Stock In Line Info:", "color:gold", res);
  230. const total = res.putAwayLines?.reduce((sum, p) => sum + p.qty, 0) ?? 0;
  231. setTotalPutAwayQty(total);
  232. setItemDetail(res);
  233. } catch (e) {
  234. console.log("%c Error when fetching Stock In Line: ", "color:red", e);
  235. alert("錯誤的二維碼");
  236. closeHandler({}, "backdropClick");
  237. }
  238. },
  239. [formProps, itemDetail, fetchStockInLineInfo],
  240. );
  241. useEffect(() => {
  242. if (stockInLineId) { fetchStockInLine(stockInLineId); }
  243. }, [stockInLineId]);
  244. const validateQty = useCallback((qty : number = putQty) => {
  245. // if (isNaN(putQty) || putQty === undefined || putQty === null || typeof(putQty) != "number") {
  246. // setQtyError(t("value must be a number"));
  247. // } else
  248. if (!Number.isInteger(qty)) {
  249. setQtyError(t("value must be integer"));
  250. }
  251. //if (qty > itemDetail?.demandQty!! - totalPutAwayQty) {
  252. //setQtyError(`${t("putQty must not greater than")} ${
  253. // itemDetail?.demandQty!! - totalPutAwayQty}` );
  254. //}
  255. if (qty > itemDetail?.acceptedQty!! - totalPutAwayQty) {
  256. setQtyError(`${t("putQty must not greater than")} ${
  257. itemDetail?.acceptedQty!! - totalPutAwayQty}` );
  258. }
  259. else
  260. // if (qty > itemDetail?.acceptedQty!!) {
  261. // setQtyError(`${t("putQty must not greater than")} ${
  262. // itemDetail?.acceptedQty}` );
  263. // } else
  264. if (qty < 1) {
  265. setQtyError(t("minimal value is 1"));
  266. } else {
  267. setQtyError("");
  268. }
  269. console.log("%c Validated putQty:", "color:yellow", putQty);
  270. },[setQtyError, putQty, itemDetail])
  271. const onSubmit = useCallback<SubmitHandler<ModalFormInput>>(
  272. async (data, event) => {
  273. // console.log("errors", errors);
  274. // const lotLine = {
  275. // warehouseId: warehouseId,
  276. // qty: acceptQty;
  277. // }
  278. try {
  279. if (firstWarehouseId !== null && warehouseId !== firstWarehouseId) {
  280. setWarehouseMismatchError("倉庫不匹配!必須使用首次上架的倉庫");
  281. return;
  282. }
  283. const args = {
  284. // ...itemDetail,
  285. id: itemDetail?.id,
  286. purchaseOrderId: itemDetail?.purchaseOrderId,
  287. purchaseOrderLineId: itemDetail?.purchaseOrderLineId,
  288. itemId: itemDetail?.itemId,
  289. acceptedQty: itemDetail?.acceptedQty,
  290. acceptQty: itemDetail?.acceptedQty,
  291. status: "received",
  292. // purchaseOrderId: parseInt(params.get("id")!),
  293. // purchaseOrderLineId: itemDetail?.purchaseOrderLineId,
  294. // itemId: itemDetail?.itemId,
  295. // acceptedQty: data.acceptedQty,
  296. // status: data.status,
  297. // ...data,
  298. // productionDate: productionDate,
  299. // for putaway data
  300. inventoryLotLines: [{
  301. warehouseId: warehouseId,
  302. qty: putQty,
  303. }],
  304. // data.putAwayLines?.filter((line) => line._isNew !== false)
  305. } as StockInLineEntry & ModalFormInput;
  306. console.log(args);
  307. // return
  308. // if (formProps.formState.errors) {
  309. // setServerError(t("An error has occurred. Please try again later."));
  310. // return false;
  311. // }
  312. if (qtyError !== "") {
  313. return;
  314. }
  315. console.log("%c Submitting Data:", "color:blue", args);
  316. const res = await updateStockInLine(args);
  317. if (Boolean(res.id)) {
  318. // update entries
  319. console.log("%c Update Success:", "color:green", res);
  320. // add loading
  321. const putAwayData = {
  322. itemName: itemDetail?.itemName,
  323. itemCode: itemDetail?.itemNo,
  324. poCode: itemDetail?.poCode,
  325. joCode: itemDetail?.joCode,
  326. lotNo: itemDetail?.lotNo,
  327. warehouseCode: warehouse.find((w) => w.id == warehouseId)?.code,
  328. warehouse: warehouse.find((w) => w.id == warehouseId)?.name,
  329. putQty: putQty,
  330. uom: itemDetail?.uom?.udfudesc,
  331. } as PutAwayRecord;
  332. addPutAwayHistory(putAwayData);
  333. msg("貨品上架成功!");
  334. closeHandler({}, "backdropClick");
  335. }
  336. // console.log(res);
  337. // if (res)
  338. } catch (e) {
  339. // server error
  340. setServerError(t("An error has occurred. Please try again later."));
  341. console.log(e);
  342. }
  343. },
  344. [t, itemDetail, putQty, warehouseId, firstWarehouseId],
  345. );
  346. return (
  347. <FormProvider {...formProps}>
  348. <Modal open={open} onClose={closeHandler}>
  349. <Box
  350. sx={style}
  351. component="form"
  352. onSubmit={formProps.handleSubmit(onSubmit)}
  353. >
  354. <Box sx={{ overflow: "hidden", flex: 1, display: "flex", flexDirection: "column" }}>
  355. <Grid container xs={12}>
  356. <Grid item xs={12}>
  357. {itemDetail != undefined ? (
  358. <>
  359. <Stack direction="column" justifyContent="flex-end" gap={0.25} sx={{ mb: 0.5 }}>
  360. <Typography variant="h4" sx={{ fontSize: { xs: "0.95rem", sm: "1.1rem", md: "1.3rem" }, mb: 0.25, lineHeight: 1.2 }}>
  361. 處理上架
  362. </Typography>
  363. <Box sx={{ "& .MuiFormControl-root": { mb: 0.5 }, "& .MuiTextField-root": { mb: 0.5 }, "& .MuiGrid-item": { mb: 0.25 } }}>
  364. <Grid item xs={12}>
  365. {itemDetail.jobOrderId ? (
  366. <FgStockInForm itemDetail={itemDetail} disabled={true} putawayMode={true}/>
  367. ) : (
  368. <StockInForm itemDetail={itemDetail} disabled={true} putawayMode={true}/>
  369. )}
  370. </Grid>
  371. </Box>
  372. <Paper sx={{ mt: 0.5, padding: { xs: 0.5, sm: 0.75, md: 1 }, width: "100%", backgroundColor: verified ? '#bceb19' : '#FCD34D' }}>
  373. <Grid
  374. container
  375. spacing={{ xs: 0.5, sm: 0.75, md: 1 }}
  376. direction="row"
  377. justifyContent="space-between"
  378. alignItems="stretch"
  379. sx={{ width: '100%' }}
  380. >
  381. <Grid item xs={12} sm={5}>
  382. <Box sx={{
  383. mb: { xs: 0.25, md: 0.5 },
  384. p: { xs: 0.5, sm: 0.75, md: 1 },
  385. backgroundColor: verified ? '#bceb19' : '#FCD34D',
  386. borderRadius: 0,
  387. display: 'flex',
  388. flexDirection: 'row',
  389. gap: 0.25,
  390. flexWrap: 'wrap'
  391. }}
  392. >
  393. <Grid container>
  394. {verified? (
  395. <>
  396. <CheckCircle sx={{
  397. color:"green",
  398. fontSize: { xs: "16px", sm: "20px", md: "24px" },
  399. mr: 0.25
  400. }}/>
  401. <Typography
  402. variant="h5"
  403. component="h2"
  404. sx={{
  405. fontWeight: 'bold',
  406. color: 'black',
  407. fontSize: { xs: "0.75rem", sm: "0.9rem", md: "1rem" },
  408. lineHeight: 1.2
  409. }}
  410. noWrap
  411. >
  412. 掃瞄完成
  413. </Typography>
  414. </>
  415. ) : (
  416. <>
  417. <ErrorOutline sx={{
  418. color:"red",
  419. fontSize: { xs: "16px", sm: "20px", md: "24px" },
  420. mr: 0.25
  421. }}/>
  422. <Typography
  423. variant="h5"
  424. component="h2"
  425. sx={{
  426. fontWeight: 'bold',
  427. color: 'black',
  428. fontSize: { xs: "0.75rem", sm: "0.9rem", md: "1rem" },
  429. lineHeight: 1.2
  430. }}
  431. noWrap
  432. >
  433. {warehouseMismatchError || (firstWarehouseId !== null && warehouseId > 0 && warehouseId !== firstWarehouseId)
  434. ? "倉庫不匹配!請掃瞄首次上架的倉庫"
  435. : "請掃瞄倉庫二維碼"}
  436. </Typography>
  437. </>
  438. )
  439. }
  440. <QrCode sx={{ fontSize: { xs: "16px", sm: "20px", md: "24px" } }}/>
  441. </Grid>
  442. <Grid container>
  443. <Typography
  444. variant="h4"
  445. sx={{
  446. fontWeight: 'bold',
  447. color: 'black',
  448. fontSize: { xs: "0.85rem", sm: "1rem", md: "1.25rem" },
  449. lineHeight: 1.2
  450. }}
  451. noWrap
  452. >
  453. {warehouseDisplay} <Box component="span" sx={{ fontSize: { xs: "0.95rem", sm: "1.2rem", md: "1.5rem" }, color: "black" }}>{verified ? "" : `(建議)`}</Box>
  454. </Typography>
  455. </Grid>
  456. </Box>
  457. </Grid>
  458. <Grid item xs={12} sm={3}>
  459. <Box sx={{
  460. height: '100%',
  461. p: { xs: 0.25, sm: 0.5, md: 0.75 },
  462. textAlign: 'center',
  463. display: "flex",
  464. flexDirection: "column",
  465. justifyContent: "center",
  466. }}>
  467. <TextField
  468. type="number"
  469. label={t("putQty")}
  470. fullWidth
  471. size="small"
  472. sx={{
  473. flex: 1,
  474. "& .MuiInputBase-input": {
  475. padding: { xs: "6px 6px 1px", sm: "8px 8px 2px", md: "10px 10px 3px" },
  476. fontSize: { xs: "16px", sm: "22px", md: "32px" },
  477. fontWeight: "bold",
  478. height: { xs: "32px", sm: "40px", md: "48px" },
  479. },
  480. "& .MuiInputBase-root": {
  481. height: "100%",
  482. borderColor: "black",
  483. },
  484. "& .MuiInputLabel-root": {
  485. fontSize: { xs: "10px", sm: "12px", md: "18px" },
  486. top: "-2px",
  487. color: "black",
  488. },
  489. "& .MuiFormHelperText-root": {
  490. fontSize: { xs: "9px", sm: "10px", md: "14px" },
  491. marginTop: "2px",
  492. lineHeight: "1.1",
  493. },
  494. }}
  495. // defaultValue={itemDetail?.demandQty!! - totalPutAwayQty}
  496. // defaultValue={itemDetail.demandQty}
  497. defaultValue={itemDetail?.acceptedQty!! - totalPutAwayQty}
  498. onChange={(e) => {
  499. const value = e.target.value;
  500. validateQty(Number(value));
  501. setPutQty(Number(value));
  502. }}
  503. onKeyDown={(e) => {
  504. // Prevent non-numeric characters
  505. if (["e", "E", "+", "-", "."].includes(e.key)) {
  506. e.preventDefault();
  507. }
  508. }}
  509. // onBlur={(e) => {
  510. // const value = e.target.value;
  511. // setPutQty(Number(value));
  512. // validateQty(Number(value));
  513. // }}
  514. // disabled={true}
  515. // {...register("acceptedQty", {
  516. // required: "acceptedQty required!",
  517. // })}
  518. error={qtyError !== ""}
  519. helperText={qtyError}
  520. />
  521. </Box>
  522. </Grid>
  523. <Grid item xs={12} sm={4}>
  524. <Box
  525. sx={{
  526. p: { xs: 0.25, sm: 0.5, md: 0.75 },
  527. textAlign: 'center',
  528. height: '100%', // Ensure D stretches to full height
  529. display: 'flex',
  530. alignItems: 'center',
  531. justifyContent: 'center',
  532. }}>
  533. <Button
  534. id="putawaySubmit"
  535. type="submit"
  536. variant="contained"
  537. startIcon={<Check sx={{ fontSize: { xs: "14px", sm: "16px", md: "20px" } }} />}
  538. color="secondary"
  539. size="small"
  540. sx={{
  541. height: "100%",
  542. flex: "0 0 auto",
  543. padding: { xs: "3px 6px", sm: "4px 8px", md: "6px 12px" },
  544. fontSize: { xs: "9px", sm: "11px", md: "18px" },
  545. whiteSpace: "nowrap",
  546. textAlign: "center",
  547. border: "1.5px solid", // Add outline
  548. borderColor: "blue",
  549. minHeight: { xs: "32px", sm: "36px", md: "40px" },
  550. "&:hover": {
  551. borderColor: "grey.200", // Slightly different color on hover
  552. backgroundColor: "secondary.dark", // Darker background on hover
  553. },
  554. "&:disabled": {
  555. borderColor: "grey.400", // Visible outline even when disabled
  556. opacity: 0.7, // Slightly faded but still visible
  557. },
  558. }}
  559. // onClick={formProps.handleSubmit()}
  560. disabled={!verified || qtyError != ""}
  561. >
  562. {t("confirm putaway")}
  563. </Button>
  564. </Box>
  565. {/* <Button
  566. id="scanWarehouse"
  567. variant="contained"
  568. startIcon={<QrCode />}
  569. color="primary"
  570. // sx={{ mx: 3, minWidth : "120px", height: "80px",
  571. // padding: "12px 12px", fontSize: "24px"}}
  572. sx={{
  573. flex: "0 0 auto",
  574. padding: "8px 16px",
  575. fontSize: { xs: "16px", sm: "20px", md: "24px" },
  576. whiteSpace: "nowrap",
  577. textAlign: "center",}}
  578. onClick={openScanner}>
  579. {t("scan warehouse")}
  580. </Button> */}
  581. </Grid>
  582. </Grid>
  583. </Paper>
  584. </Stack>
  585. </>
  586. ) : (
  587. // <ReactQrCodeScanner scannerConfig={scannerConfig} />
  588. <>
  589. <Typography variant="h4" sx={{ fontSize: { xs: "0.95rem", sm: "1.1rem", md: "1.3rem" } }}>
  590. {t("scan loading")}
  591. </Typography>
  592. <LoadingComponent/>
  593. </>
  594. )}
  595. </Grid>
  596. </Grid>
  597. </Box>
  598. <Modal open={isOpenScanner} onClose={scannerCloseHandler}>
  599. <Box sx={scannerStyle}>
  600. <Typography variant="h4" sx={{
  601. display: 'flex',
  602. flexDirection: 'column',
  603. justifyContent: 'center',
  604. margin: 0,
  605. alignItems: 'center',
  606. textAlign: 'center',
  607. fontSize: { xs: "0.95rem", sm: "1.1rem", md: "1.3rem" }
  608. }}
  609. >
  610. {t("Please scan warehouse qr code")}
  611. </Typography>
  612. {/* <ReactQrCodeScanner scannerConfig={scannerConfig} /> */}
  613. </Box>
  614. </Modal>
  615. </Box>
  616. </Modal>
  617. </FormProvider>
  618. );
  619. };
  620. export default PutAwayModal;