132 lines
4.5 KiB
TypeScript
132 lines
4.5 KiB
TypeScript
import { useForm } from "@mantine/form";
|
||
import { ContextModalProps } from "@mantine/modals";
|
||
import { Button, Flex, NumberInput, rem, Text } from "@mantine/core";
|
||
import getRestProducts from "../utils/getRestProducts.tsx";
|
||
import {
|
||
CardProductSchema,
|
||
CardSchema,
|
||
CreateShippingProductSchema,
|
||
ProductSchema,
|
||
ShippingService,
|
||
UpdateShippingProductSchema,
|
||
} from "../../../../../client";
|
||
import { notifications } from "../../../../../shared/lib/notifications.ts";
|
||
import { ShippingData, ShippingModalForm } from "../types/ShippingProductData.tsx";
|
||
import { useEffect, useState } from "react";
|
||
import ShippingProductSelect from "../components/ShippingProductSelect.tsx";
|
||
|
||
|
||
type Props = {
|
||
updateOnSubmit: () => void;
|
||
card: CardSchema;
|
||
shippingData: Partial<ShippingData>;
|
||
}
|
||
|
||
const ShippingProductModal = ({
|
||
context,
|
||
id,
|
||
innerProps,
|
||
}: ContextModalProps<Props>) => {
|
||
const [restProducts, setRestProducts] = useState<Map<number, CardProductSchema>>(new Map());
|
||
const [restProductsSelectData, setRestProductSelectData] = useState<ProductSchema[]>([]);
|
||
|
||
const getRestProductQuantity = () => {
|
||
if (form.values.product) {
|
||
const restProduct = restProducts.get(form.values.product.id);
|
||
if (restProduct) {
|
||
return restProduct.quantity;
|
||
}
|
||
}
|
||
return 10000;
|
||
};
|
||
|
||
const findProductById = (productId?: number | null) => {
|
||
const cardProduct = innerProps.card.products.find(p => p.product.id === productId);
|
||
return cardProduct ? cardProduct.product : null;
|
||
};
|
||
|
||
const initialValues: ShippingModalForm = {
|
||
quantity: innerProps.shippingData.quantity ?? 0,
|
||
product: findProductById(innerProps.shippingData.productId),
|
||
};
|
||
const form = useForm<ShippingModalForm>({
|
||
initialValues,
|
||
validate: {
|
||
product: product => !product && "Необходимо выбрать товар",
|
||
quantity: quantity => quantity > getRestProductQuantity() ? "Слишком много товара" :
|
||
quantity === 0 && "Слишком мало товара",
|
||
},
|
||
});
|
||
|
||
useEffect(() => {
|
||
const data = getRestProducts({
|
||
card: innerProps.card,
|
||
shippingProductId: (innerProps.shippingData as UpdateShippingProductSchema).shippingProductId,
|
||
});
|
||
setRestProducts(data.restProducts);
|
||
setRestProductSelectData(data.restProductsSelectData);
|
||
}, [innerProps.card]);
|
||
|
||
const onSubmit = () => {
|
||
const data = {
|
||
...innerProps.shippingData,
|
||
...form.values,
|
||
productId: form.values.product?.id,
|
||
} as CreateShippingProductSchema | UpdateShippingProductSchema;
|
||
|
||
ShippingService.updateShippingProduct({
|
||
requestBody: { data },
|
||
})
|
||
.then(({ ok, message }) => {
|
||
notifications.guess(ok, { message: message });
|
||
innerProps.updateOnSubmit();
|
||
if (ok) context.closeContextModal(id);
|
||
})
|
||
.catch(err => console.log(err));
|
||
};
|
||
|
||
const getRestQuantityText = () => {
|
||
if (!form.values.product) return;
|
||
|
||
const restQuantityInDeal = getRestProductQuantity();
|
||
const restQuantity = restQuantityInDeal - form.values.quantity;
|
||
|
||
if (restQuantity >= 0) {
|
||
return <Text>Осталось распределить {restQuantity} шт.</Text>;
|
||
}
|
||
return <Text>Введено слишком большое количество.<br />Доступно {restQuantityInDeal} шт.</Text>;
|
||
};
|
||
|
||
return (
|
||
<form onSubmit={form.onSubmit(() => onSubmit())}>
|
||
<Flex
|
||
direction={"column"}
|
||
gap={rem(10)}
|
||
>
|
||
<ShippingProductSelect
|
||
{...form.getInputProps("product")}
|
||
data={restProductsSelectData}
|
||
/>
|
||
|
||
{getRestQuantityText()}
|
||
|
||
<NumberInput
|
||
label={"Количество"}
|
||
hideControls
|
||
{...form.getInputProps("quantity")}
|
||
min={0}
|
||
/>
|
||
|
||
<Button
|
||
variant={"default"}
|
||
type={"submit"}
|
||
>
|
||
Сохранить
|
||
</Button>
|
||
</Flex>
|
||
</form>
|
||
);
|
||
};
|
||
|
||
export default ShippingProductModal;
|