diff --git a/src/modals/modals.ts b/src/modals/modals.ts index 6bba7c4..cf2c7ff 100644 --- a/src/modals/modals.ts +++ b/src/modals/modals.ts @@ -33,6 +33,7 @@ import AssignUserModal from "../pages/LeadsPage/tabs/EmployeesTab/modals/AssignU import ResidualProductModal from "../pages/ResiduesPage/modals/ResidualProductModal/ResidualProductModal.tsx"; import NewReceiptModal from "../pages/ReceiptPage/components/NewReceipt/modals/NewReceiptModal.tsx"; import ReceiptModal from "../pages/ReceiptPage/components/ReceiptEditing/modals/ReceiptModal.tsx"; +import SelectScannedProductModal from "../pages/ReceiptPage/modals/SelectScannedProductModal.tsx"; export const modals = { enterDeadline: EnterDeadlineModal, @@ -63,6 +64,7 @@ export const modals = { transactionTagsModal: TransactionTagsModal, shippingProductModal: ShippingProductModal, residualProductModal: ResidualProductModal, + selectScannedProductModal: SelectScannedProductModal, newReceiptModal: NewReceiptModal, receiptModal: ReceiptModal, departmentModal: DepartmentModal, diff --git a/src/pages/ReceiptPage/components/NewReceipt/components/AccordionBoxes.tsx b/src/pages/ReceiptPage/components/NewReceipt/components/AccordionBoxes.tsx index 6ea6534..a4fb868 100644 --- a/src/pages/ReceiptPage/components/NewReceipt/components/AccordionBoxes.tsx +++ b/src/pages/ReceiptPage/components/NewReceipt/components/AccordionBoxes.tsx @@ -1,5 +1,5 @@ import { Accordion, ActionIcon, Center } from "@mantine/core"; -import { IconBox, IconPlus, IconTrash } from "@tabler/icons-react"; +import { IconBarcode, IconBox, IconPlayerPause, IconPlus, IconTrash } from "@tabler/icons-react"; import { ReceiptBox, ReceiptPallet } from "../types/types.tsx"; import { useReceiptContext } from "../contexts/ReceiptContext.tsx"; import ReceiptProducts from "./ReceiptProducts.tsx"; @@ -10,7 +10,17 @@ type Props = { } const AccordionBoxes = ({ pallet, palletIdx }: Props) => { - const { boxes, boxesHandlers, onObjectEditClick, palletsHandlers, setBoxData } = useReceiptContext(); + const { + boxes, + boxesHandlers, + onObjectEditClick, + palletsHandlers, + setBoxData, + scanningData, + toggleScanning, + } = useReceiptContext(); + + const { boxId, isScanning } = scanningData; const deleteBox = (boxId: number) => { if (palletIdx && pallet) { @@ -23,9 +33,22 @@ const AccordionBoxes = ({ pallet, palletIdx }: Props) => { const boxActions = (box: ReceiptBox) => { return ( <> + toggleScanning(box.id, pallet?.id)} + mr={"sm"} + disabled={isScanning && box.id !== boxId} + > + {isScanning && box.id === boxId ? ( + + ) : ( + + )} + onObjectEditClick(box, true, pallet)} + disabled={isScanning} mr={"sm"} > @@ -33,6 +56,7 @@ const AccordionBoxes = ({ pallet, palletIdx }: Props) => { deleteBox(box.id)} + disabled={isScanning} mr={"sm"} > @@ -60,6 +84,7 @@ const AccordionBoxes = ({ pallet, palletIdx }: Props) => { products={box.residualProducts} object={box} setObjectData={(box: ReceiptBox) => setBoxData(box, pallet)} + disabled={isScanning} /> diff --git a/src/pages/ReceiptPage/components/NewReceipt/components/AccordionPallets.tsx b/src/pages/ReceiptPage/components/NewReceipt/components/AccordionPallets.tsx index 30bde22..0e18833 100644 --- a/src/pages/ReceiptPage/components/NewReceipt/components/AccordionPallets.tsx +++ b/src/pages/ReceiptPage/components/NewReceipt/components/AccordionPallets.tsx @@ -1,12 +1,22 @@ import { Accordion, ActionIcon, Box, Button, Center, Flex, Group } from "@mantine/core"; -import { IconPlus, IconSpace, IconTrash } from "@tabler/icons-react"; +import { IconBarcode, IconPlayerPause, IconPlus, IconSpace, IconTrash } from "@tabler/icons-react"; import { ReceiptBox, ReceiptPallet } from "../types/types.tsx"; import { useReceiptContext } from "../contexts/ReceiptContext.tsx"; import AccordionBoxes from "./AccordionBoxes.tsx"; import ReceiptProducts from "./ReceiptProducts.tsx"; const AccordionPallets = () => { - const { pallets, palletsHandlers, nextId, onObjectEditClick, setPalletData } = useReceiptContext(); + const { + pallets, + palletsHandlers, + nextId, + onObjectEditClick, + setPalletData, + scanningData, + toggleScanning, + } = useReceiptContext(); + + const { palletId, boxId, isScanning } = scanningData; const deletePallet = (palletId: number) => { palletsHandlers.filter(item => item.id !== palletId); @@ -23,25 +33,44 @@ const AccordionPallets = () => { }; const palletActions = (pallet: ReceiptPallet) => { + const isScanModeVisible = pallet.boxes.length === 0; const isCreateButtonVisible = pallet.boxes.length > 0 || pallet.residualProducts.length > 0; return ( <> - {isCreateButtonVisible && { - if (pallet.residualProducts.length > 0) { - onObjectEditClick(pallet, false); - } else { - createBox(pallet); - } - }} - mr={"sm"} - > - - } + {isScanModeVisible && ( + toggleScanning(undefined, pallet.id)} + mr={"sm"} + disabled={isScanning && (pallet.id !== palletId || !!boxId)} + > + {isScanning && pallet.id === palletId && !boxId ? ( + + ) : ( + + )} + + )} + {isCreateButtonVisible && ( + { + if (pallet.residualProducts.length > 0) { + onObjectEditClick(pallet, false); + } else { + createBox(pallet); + } + }} + disabled={isScanning} + mr={"sm"} + > + + + )} deletePallet(pallet.id)} + disabled={isScanning} mr={"md"} > @@ -55,6 +84,7 @@ const AccordionPallets = () => { ); + const getScanningModeAction = () => { + return ( + toggleScanning(box?.id)} + > + {isScanning ? ( + + ) : ( + + )} + + ); + }; + return ( - - {backButton} - - Короб ID: К{box?.id} - + + + {backButton} + + Короб ID: К{box?.id} + + + {getScanningModeAction()} - + Товар @@ -44,6 +67,7 @@ const ReceiptBoxEditor = ({ boxId }: Props) => { object={box} clientId={clientId} updateObject={fetchBox} + disabled={isScanning} /> ); diff --git a/src/pages/ReceiptPage/components/ReceiptEditing/components/ReceiptPalletEditor.tsx b/src/pages/ReceiptPage/components/ReceiptEditing/components/ReceiptPalletEditor.tsx index ea489ec..3c102dd 100644 --- a/src/pages/ReceiptPage/components/ReceiptEditing/components/ReceiptPalletEditor.tsx +++ b/src/pages/ReceiptPage/components/ReceiptEditing/components/ReceiptPalletEditor.tsx @@ -1,9 +1,9 @@ import useReceiptPallet from "../hooks/useReceiptPallet.tsx"; -import { Button, Flex, Group, Stack, Text, Title } from "@mantine/core"; -import { IconArrowLeft, IconPlus } from "@tabler/icons-react"; +import { ActionIcon, Button, Flex, Group, Stack, Text, Title } from "@mantine/core"; +import { IconArrowLeft, IconBarcode, IconPlayerPause, IconPlus } from "@tabler/icons-react"; import InlineButton from "../../../../../components/InlineButton/InlineButton.tsx"; import ReceiptProducts from "./ReceiptProducts.tsx"; -import AccordionBoxesOnPallet from "./AccordionBoxes.tsx"; +import AccordionBoxesOnPallet from "./AccordionBoxesOnPallet.tsx"; type Props = { palletId: number; @@ -16,9 +16,19 @@ const ReceiptPalletEditor = ({ palletId }: Props) => { clientId, onCreateProductClick, onCreateBoxClick, + barcodesProductsMap, + scanningData, + toggleScanning, } = useReceiptPallet({ palletId }); - if (!pallet) return Паллет c ID P{palletId} не найден; + if (!pallet) { + return Паллет c ID P{palletId} не найден; + } + + const { + isScanning, + boxId, + } = scanningData; const createButtons = () => { const isBoxes = pallet.boxes.length > 0; @@ -27,13 +37,13 @@ const ReceiptPalletEditor = ({ palletId }: Props) => { return ( {(isBoxes || isBoth) && ( - + Короб )} {(isProducts || isBoth) && ( - + Товар @@ -50,6 +60,9 @@ const ReceiptPalletEditor = ({ palletId }: Props) => { pallet={pallet} clientId={clientId} fetchPallet={fetchPallet} + barcodesProductsMap={barcodesProductsMap} + scanningData={scanningData} + toggleScanning={toggleScanning} /> ); } @@ -59,6 +72,7 @@ const ReceiptPalletEditor = ({ palletId }: Props) => { clientId={clientId} object={pallet} updateObject={fetchPallet} + disabled={isScanning} /> ); } @@ -74,14 +88,34 @@ const ReceiptPalletEditor = ({ palletId }: Props) => { ); + const getScanningModeAction = () => { + if (pallet.boxes.length !== 0) return; + + return ( + toggleScanning(undefined, pallet?.id)} + disabled={isScanning && !!boxId} + > + {isScanning && !boxId ? ( + + ) : ( + + )} + + ); + }; return ( - - {backButton} - - Паллет ID: П{pallet?.id} - + + + {backButton} + + Паллет ID: П{pallet?.id} + + + {getScanningModeAction()} {createButtons()} {renderPalletData()} diff --git a/src/pages/ReceiptPage/components/ReceiptEditing/components/ReceiptProducts.tsx b/src/pages/ReceiptPage/components/ReceiptEditing/components/ReceiptProducts.tsx index 09d2ca8..d01a65d 100644 --- a/src/pages/ReceiptPage/components/ReceiptEditing/components/ReceiptProducts.tsx +++ b/src/pages/ReceiptPage/components/ReceiptEditing/components/ReceiptProducts.tsx @@ -9,9 +9,10 @@ type Props = { clientId: number | null; object: ResidualBoxSchema | ResidualPalletSchema | null; updateObject: () => void; + disabled: boolean; } -const ReceiptProducts = ({ clientId, object, updateObject }: Props) => { +const ReceiptProducts = ({ clientId, object, updateObject, disabled }: Props) => { if (!object || !clientId) return; const deleteProduct = (residualProductId: number) => { @@ -37,11 +38,13 @@ const ReceiptProducts = ({ clientId, object, updateObject }: Props) => { deleteProduct(residualProduct.id)} + disabled={disabled} > diff --git a/src/pages/ReceiptPage/components/ReceiptEditing/hooks/useApplyingScannedResult.tsx b/src/pages/ReceiptPage/components/ReceiptEditing/hooks/useApplyingScannedResult.tsx new file mode 100644 index 0000000..49f7237 --- /dev/null +++ b/src/pages/ReceiptPage/components/ReceiptEditing/hooks/useApplyingScannedResult.tsx @@ -0,0 +1,86 @@ +import { notifications } from "../../../../../shared/lib/notifications.ts"; +import { ProductSchema, ResidualBoxSchema, ResidualPalletSchema, ResiduesService } from "../../../../../client"; +import { modals } from "@mantine/modals"; +import findProductInObject from "../../NewReceipt/utils/findProductInObject.tsx"; + +type Props = { + object: ResidualBoxSchema | ResidualPalletSchema | null; + barcodesProductsMap: Map; + refetch: () => void; +} + +const useApplyingScannedResult = ({ + object, + barcodesProductsMap, + refetch, + }: Props) => { + let boxIdValue: number | null = null; + + const onProductSelect = (product: ProductSchema) => { + if (!object) return; + ResiduesService.createResidualProduct({ + requestBody: { + data: { + productId: product.id, + quantity: 1, + palletId: boxIdValue ? null : object.id, + boxId: boxIdValue, + }, + }, + }) + .then(({ ok, message }) => { + notifications.guess(ok, { message }); + refetch(); + }) + .catch(err => console.log(err)); + }; + + const showSelectProductModal = (productsToSelect: ProductSchema[]) => { + modals.openContextModal({ + modal: "selectScannedProductModal", + title: "Выберите товар для данного штрихкода", + withCloseButton: false, + innerProps: { + productsToSelect, + onProductSelect, + }, + }); + }; + + const onScanningFinish = ( + value: string, + boxId?: number, + palletId?: number, + ) => { + if (!object) return; + boxIdValue = boxId ?? null; + let objectValue: ResidualPalletSchema | ResidualBoxSchema = object; + + if (palletId && boxId) { + const pallet = object as ResidualPalletSchema; + const boxOnPallet = pallet.boxes.find(box => box.id === boxId); + if (!boxOnPallet) return; + objectValue = boxOnPallet; + } + + const productsToSelect = barcodesProductsMap.get(value) ?? []; + if (productsToSelect?.length === 0) { + notifications.error({ message: `Товара с штрихкодом ${value} не найдено` }); + return; + } + if (productsToSelect?.length === 1) { + onProductSelect(productsToSelect[0]); + return; + } + const product = findProductInObject(objectValue, productsToSelect); + if (product) { + onProductSelect(product); + return; + } + return showSelectProductModal(productsToSelect); + }; + + return { onScanningFinish }; +}; + +export default useApplyingScannedResult; diff --git a/src/pages/ReceiptPage/components/ReceiptEditing/hooks/useReceiptBox.tsx b/src/pages/ReceiptPage/components/ReceiptEditing/hooks/useReceiptBox.tsx index e12b845..78dbd38 100644 --- a/src/pages/ReceiptPage/components/ReceiptEditing/hooks/useReceiptBox.tsx +++ b/src/pages/ReceiptPage/components/ReceiptEditing/hooks/useReceiptBox.tsx @@ -1,6 +1,9 @@ import { useEffect, useState } from "react"; import { ResidualBoxSchema, ResiduesService } from "../../../../../client"; import { modals } from "@mantine/modals"; +import useBarcodesProductsMap from "../../../hooks/useBarcodesProductsMap.tsx"; +import useScanningMode from "../../../hooks/useScanningMode.tsx"; +import useApplyingScannedResult from "./useApplyingScannedResult.tsx"; type Props = { @@ -27,6 +30,16 @@ const useReceiptBox = ({ boxId }: Props) => { .catch(err => console.log(err)); }; + const { barcodesProductsMap } = useBarcodesProductsMap({ clientId: clientId ?? -1 }); + + const { onScanningFinish } = useApplyingScannedResult({ + object: box, + barcodesProductsMap, + refetch: fetchBox, + }); + + const { scanningData, toggleScanning } = useScanningMode({ onScanningFinish }); + const onCreateProductClick = () => { if (!(box && clientId)) return; modals.openContextModal({ @@ -38,6 +51,7 @@ const useReceiptBox = ({ boxId }: Props) => { isBox: true, object: box, fetchObject: fetchBox, + barcodesProductsMap, }, }); }; @@ -47,6 +61,8 @@ const useReceiptBox = ({ boxId }: Props) => { fetchBox, clientId, onCreateProductClick, + scanningData, + toggleScanning, }; }; diff --git a/src/pages/ReceiptPage/components/ReceiptEditing/hooks/useReceiptPallet.tsx b/src/pages/ReceiptPage/components/ReceiptEditing/hooks/useReceiptPallet.tsx index 4753729..5da13a6 100644 --- a/src/pages/ReceiptPage/components/ReceiptEditing/hooks/useReceiptPallet.tsx +++ b/src/pages/ReceiptPage/components/ReceiptEditing/hooks/useReceiptPallet.tsx @@ -2,6 +2,9 @@ import { useEffect, useState } from "react"; import { ResidualPalletSchema, ResiduesService } from "../../../../../client"; import { modals } from "@mantine/modals"; import { notifications } from "../../../../../shared/lib/notifications.ts"; +import useBarcodesProductsMap from "../../../hooks/useBarcodesProductsMap.tsx"; +import useApplyingScannedResult from "./useApplyingScannedResult.tsx"; +import useScanningMode from "../../../hooks/useScanningMode.tsx"; type Props = { palletId: number; @@ -27,6 +30,16 @@ const useReceiptPallet = ({ palletId }: Props) => { .catch(err => console.log(err)); }; + const { barcodesProductsMap } = useBarcodesProductsMap({ clientId: clientId ?? -1 }); + + const { onScanningFinish } = useApplyingScannedResult({ + object: pallet, + barcodesProductsMap, + refetch: fetchPallet, + }); + + const { scanningData, toggleScanning } = useScanningMode({ onScanningFinish }); + const onCreateProductClick = () => { if (!(pallet && clientId)) return; modals.openContextModal({ @@ -38,6 +51,7 @@ const useReceiptPallet = ({ palletId }: Props) => { isBox: false, object: pallet, fetchObject: fetchPallet, + barcodesProductsMap, }, }); }; @@ -64,6 +78,9 @@ const useReceiptPallet = ({ palletId }: Props) => { clientId, onCreateProductClick, onCreateBoxClick, + barcodesProductsMap, + scanningData, + toggleScanning, }; }; diff --git a/src/pages/ReceiptPage/components/ReceiptEditing/modals/ReceiptModal.tsx b/src/pages/ReceiptPage/components/ReceiptEditing/modals/ReceiptModal.tsx index 393cd6f..0660293 100644 --- a/src/pages/ReceiptPage/components/ReceiptEditing/modals/ReceiptModal.tsx +++ b/src/pages/ReceiptPage/components/ReceiptEditing/modals/ReceiptModal.tsx @@ -14,6 +14,7 @@ type Props = { object: ResidualBoxSchema | ResidualPalletSchema; fetchObject: () => void; isBox: boolean; + barcodesProductsMap: Map; } const ReceiptModal = ({ @@ -25,7 +26,9 @@ const ReceiptModal = ({ clientId, object, fetchObject, + barcodesProductsMap, } = innerProps; + const { isScanning, setIsScanning, scannedValue, setScannedValue } = useScanning(); const initialValues = { product: null, @@ -115,12 +118,12 @@ const ReceiptModal = ({ ); diff --git a/src/pages/ReceiptPage/components/ScanBarcode/ScanBarcode.tsx b/src/pages/ReceiptPage/components/ScanBarcode/ScanBarcode.tsx index 79d1015..c33a838 100644 --- a/src/pages/ReceiptPage/components/ScanBarcode/ScanBarcode.tsx +++ b/src/pages/ReceiptPage/components/ScanBarcode/ScanBarcode.tsx @@ -1,29 +1,28 @@ import { ProductSchema, ResidualBoxSchema, ResidualPalletSchema } from "../../../../client"; -import { useEffect, useState } from "react"; -import useProductsList from "../../../ProductsPage/hooks/useProductsList.tsx"; +import { useState } from "react"; import { Button, Group, Radio, Stack, Text } from "@mantine/core"; import { notifications } from "../../../../shared/lib/notifications.ts"; import { ReceiptBox, ReceiptPallet } from "../NewReceipt/types/types.tsx"; +import findProductInObject from "../NewReceipt/utils/findProductInObject.tsx"; type Props = { onProductSelect: (product?: ProductSchema) => void; - clientId: number; isScanning: boolean; setIsScanning: (isScanning: boolean) => void; scannedValue: string; object: ReceiptBox | ReceiptPallet | ResidualPalletSchema | ResidualBoxSchema; + barcodesProductsMap: Map; } const ScanBarcode = ({ onProductSelect, - clientId, isScanning, setIsScanning, scannedValue, object, + barcodesProductsMap, }: Props) => { - const productsData = useProductsList({ clientId, searchInput: "" }); - const [barcodesProducts, setBarcodesProducts] = useState(new Map()); + let productsToSelect: ProductSchema[] = []; const [selectedProduct, setSelectedProduct] = useState(); @@ -31,38 +30,8 @@ const ScanBarcode = ({ setIsScanning(!isScanning); }; - const productsToBarcodesProducts = () => { - const data = new Map(); - productsData.products.forEach(product => { - product.barcodes.forEach(barcode => { - if (data.has(barcode)) { - data.set(barcode, [...data.get(barcode)!, product]); - } else { - data.set(barcode, [product]); - } - }); - }); - setBarcodesProducts(data); - }; - - useEffect(() => { - if (productsData.products.length !== 0) { - productsToBarcodesProducts(); - } - }, [productsData.isLoading]); - - const findProductInObject = (productsToSelect: ProductSchema[]): ProductSchema | undefined => { - for (let i = 0; i < productsToSelect.length; i++) { - for (let j = 0; j < object.residualProducts.length; j++) { - if (productsToSelect[i].id === object.residualProducts[j].product.id) { - return productsToSelect[i]; - } - } - } - }; - const renderScanningResults = () => { - productsToSelect = barcodesProducts.get(scannedValue) ?? []; + productsToSelect = barcodesProductsMap.get(scannedValue) ?? []; if (productsToSelect?.length === 0) { notifications.error({ message: `Товара с штрихкодом ${scannedValue} не найдено` }); onProductSelect(); @@ -72,7 +41,7 @@ const ScanBarcode = ({ onProductSelect(productsToSelect[0]); return; } - const product = findProductInObject(productsToSelect); + const product = findProductInObject(object, productsToSelect); if (product) { onProductSelect(product); return; diff --git a/src/pages/ReceiptPage/hooks/useBarcodesProductsMap.tsx b/src/pages/ReceiptPage/hooks/useBarcodesProductsMap.tsx new file mode 100644 index 0000000..de7b637 --- /dev/null +++ b/src/pages/ReceiptPage/hooks/useBarcodesProductsMap.tsx @@ -0,0 +1,42 @@ +import useProductsList from "../../ProductsPage/hooks/useProductsList.tsx"; +import { useEffect, useState } from "react"; +import { ProductSchema } from "../../../client"; + +type Props = { + clientId?: number; +} + +const useBarcodesProductsMap = ({ clientId }: Props) => { + const { + products, + isLoading: isProductsLoading, + } = useProductsList({ clientId: clientId ?? 0, searchInput: "" }); + + const [barcodesProductsMap, setBarcodesProductsMap] = useState(new Map()); + + const productsToBarcodesProducts = () => { + const data = new Map(); + products.forEach(product => { + product.barcodes.forEach(barcode => { + if (data.has(barcode)) { + data.set(barcode, [...data.get(barcode)!, product]); + } else { + data.set(barcode, [product]); + } + }); + }); + setBarcodesProductsMap(data); + }; + + useEffect(() => { + if (products.length !== 0) { + productsToBarcodesProducts(); + } + }, [isProductsLoading]); + + return { + barcodesProductsMap, + }; +}; + +export default useBarcodesProductsMap; diff --git a/src/pages/ReceiptPage/hooks/useScanningMode.tsx b/src/pages/ReceiptPage/hooks/useScanningMode.tsx new file mode 100644 index 0000000..d228a06 --- /dev/null +++ b/src/pages/ReceiptPage/hooks/useScanningMode.tsx @@ -0,0 +1,63 @@ +import { useState } from "react"; +import { useWindowEvent } from "@mantine/hooks"; + +export type ScanningData = { + boxId?: number; + palletId?: number; + isScanning: boolean; +} + +type Props = { + onScanningFinish: (value: string, boxId?: number, palletId?: number) => void; +} + +const useScanningMode = ({ onScanningFinish }: Props) => { + const [scanningValue, setScanningValue] = useState(""); + const [boxId, setBoxId] = useState(); + const [palletId, setPalletId] = useState(); + const [isScanning, setIsScanning] = useState(false); + + const setIsScanningValue = (isScanning: boolean) => { + if (!isScanning) { + setScanningValue(""); + setBoxId(undefined); + setPalletId(undefined); + } + setIsScanning(isScanning); + }; + + useWindowEvent("keydown", (event) => { + if (!isScanning) return; + event.preventDefault(); + setScanningValue(prevState => prevState + event.key); + if (["\n", "\r", "Enter"].includes(event.key)) { + onScanningFinish(scanningValue, boxId, palletId); + setScanningValue(""); + } + }); + + const toggleScanning = (boxId?: number, palletId?: number) => { + if (isScanning) { + setBoxId(undefined); + setPalletId(undefined); + } else { + setBoxId(boxId); + setPalletId(palletId); + } + setIsScanningValue(!isScanning); + setScanningValue(""); + }; + + const scanningData: ScanningData = { + boxId, + palletId, + isScanning, + }; + + return { + scanningData, + toggleScanning, + }; +}; + +export default useScanningMode; diff --git a/src/pages/ReceiptPage/modals/SelectScannedProductModal.tsx b/src/pages/ReceiptPage/modals/SelectScannedProductModal.tsx new file mode 100644 index 0000000..faa666b --- /dev/null +++ b/src/pages/ReceiptPage/modals/SelectScannedProductModal.tsx @@ -0,0 +1,61 @@ +import { ContextModalProps } from "@mantine/modals"; +import { Button, Group, Radio, Stack, Text } from "@mantine/core"; +import { ProductSchema } from "../../../client"; +import { notifications } from "../../../shared/lib/notifications.ts"; +import { useState } from "react"; + + +type Props = { + productsToSelect: ProductSchema[]; + onProductSelect: (product: ProductSchema) => void; +} + +const SelectScannedProductModal = ({ + context, + id, + innerProps, + }: ContextModalProps) => { + const { + productsToSelect, + onProductSelect, + } = innerProps; + + const [selectedProduct, setSelectedProduct] = useState(); + + const renderProductsToSelect = () => { + return productsToSelect.map(product => ( + + setSelectedProduct(product)} + /> + + {product.name} + {product.size && {product.size}} + + + )); + }; + + return ( + + {renderProductsToSelect()} + + + ); +}; + +export default SelectScannedProductModal;