This commit is contained in:
2024-04-12 07:35:41 +03:00
parent 9815ebbc3b
commit 2d1fdf1ad9
41 changed files with 1199 additions and 85 deletions

View File

@@ -0,0 +1,9 @@
.print-only {
display: none;
}
@media print {
.print-only {
display: block;
}
}

View File

@@ -0,0 +1,132 @@
import {ContextModalProps, modals} from "@mantine/modals";
import {Button, Divider, Flex, NumberInput, rem, Select, Spoiler} from "@mantine/core";
import Barcode from "react-barcode";
import {useEffect, useRef, useState} from "react";
import {useReactToPrint} from "react-to-print";
import {ProductService} from "../../client";
import styles from "./PrintBarcodeModal.module.css";
import {useGetProductById} from "../../api/product/useGetProductById.tsx";
import {notifications} from "../../shared/lib/notifications.ts";
type Props = {
productId: number;
defaultQuantity?: number;
}
const PrintBarcodeModal = ({
innerProps
}: ContextModalProps<Props>) => {
const {productId, defaultQuantity = 1} = innerProps;
const [quantity, setQuantity] = useState(defaultQuantity);
const [barcode, setBarcode] = useState<string | undefined>()
const {product, refetch} = useGetProductById(productId);
const barcodeRef = useRef(null);
const handlePrint = useReactToPrint({
content: () => barcodeRef.current
});
const onAdd = (newBarcode: string) => {
ProductService.addProductBarcode({requestBody: {productId, barcode: newBarcode}})
.then(async ({ok, message}) => {
notifications.guess(ok, {message});
})
}
const onAddClick = () => {
if (!product) return;
modals.openContextModal({
modal: "addBarcode",
title: 'Добавление штрихкода',
withCloseButton: true,
innerProps: {
productId: product.id,
onSubmit: onAdd
}
})
}
const onGenerateClick = () => {
if (!product) return;
ProductService.generateProductBarcode({requestBody: {productId}})
.then(async ({ok, message, barcode}) => {
notifications.guess(ok, {message});
if (!ok) return;
await refetch();
setBarcode(barcode);
})
}
useEffect(() => {
if (!product) return;
if (product.barcodes.length === 1)
setBarcode(product.barcodes[0]);
}, [product]);
return (
<>
<Flex
gap={rem(10)}
direction={"column"}
>
<Select
value={barcode}
onChange={(value) => setBarcode(value || undefined)}
data={product?.barcodes}
label={"Штрихкод"}
placeholder={"Выберите штрихкод"}
/>
<NumberInput
label={"Количество копий"}
placeholder={"Введите количество копий"}
value={quantity}
onChange={(value) => typeof value === "number" && setQuantity(value)}
min={1}
/>
<Spoiler
w={"100%"}
style={{
textAlign: "center",
}}
styles={{control: {width: "100%"}}}
showLabel={"Показать предпросмотр"}
hideLabel={"Скрыть предпросмотр"}
maxHeight={0}>
<div>
{barcode &&
<Barcode value={barcode}/>
}
</div>
</Spoiler>
<Divider
my={rem(10)}
/>
<Flex direction={"column"} gap={rem(10)}>
<Flex gap={rem(10)}>
<Button
onClick={() => onAddClick()}
variant={"default"}
fullWidth>
Добавить вручную
</Button>
<Button
onClick={() => onGenerateClick()}
variant={"default"}
fullWidth>
Сгенерировать
</Button>
</Flex>
<Button
size={"lg"}
disabled={!barcode}
onClick={() => handlePrint()}
>Печать</Button>
</Flex>
</Flex>
<div className={styles['print-only']} ref={barcodeRef}>
{barcode && Array.from({length: quantity}).map((_, index) => (
<Barcode key={index} value={barcode}/>
))}
</div>
</>
)
}
export default PrintBarcodeModal;