add contract page with dynamic form elements
This commit is contained in:
@@ -1,62 +1,57 @@
|
||||
import { ActionIcon, Group, TextInput, Tooltip } from "@mantine/core";
|
||||
import { DatePickerInput } from "@mantine/dates";
|
||||
import { IconX } from "@tabler/icons-react";
|
||||
import { t } from "@/config/i18n";
|
||||
import type { ShipmentInputs } from "@/services/resources/shipments";
|
||||
import { Accordion, Group, Text } from "@mantine/core";
|
||||
import type { Shipment } from "@/services/resources/shipments";
|
||||
import { ProductForm } from "@/components/Products/Form";
|
||||
import type { UseFormReturnType } from "@mantine/form";
|
||||
import { useMemo } from "react";
|
||||
import { computePrices } from "@/pages/Contract";
|
||||
|
||||
export type ShipmentFormProps = {
|
||||
inputForm: UseFormReturnType<Record<string, string | number>>;
|
||||
shipment: Shipment;
|
||||
index: number;
|
||||
setShipmentElement: (index: number, shipment: ShipmentInputs) => void;
|
||||
deleteShipmentElement: (index: number) => void;
|
||||
shipment: ShipmentInputs;
|
||||
}
|
||||
|
||||
export default function ShipmentForm({
|
||||
index,
|
||||
setShipmentElement,
|
||||
deleteShipmentElement,
|
||||
shipment
|
||||
shipment,
|
||||
index,
|
||||
inputForm,
|
||||
}: ShipmentFormProps) {
|
||||
return (
|
||||
<Group justify="space-between" key={`shipment_${index}`}>
|
||||
<Group grow maw="80%">
|
||||
<TextInput
|
||||
label={t("shipment name", {capfirst: true})}
|
||||
placeholder={t("shipment name", {capfirst: true})}
|
||||
radius="sm"
|
||||
withAsterisk
|
||||
value={shipment.name || ""}
|
||||
onChange={(event) => {
|
||||
const value = event.target.value;
|
||||
setShipmentElement(index, {...shipment, name: value})
|
||||
}}
|
||||
/>
|
||||
<DatePickerInput
|
||||
label={t("shipment date", {capfirst: true})}
|
||||
placeholder={t("shipment date", {capfirst: true})}
|
||||
radius="sm"
|
||||
withAsterisk
|
||||
value={shipment.date || null}
|
||||
onChange={(event) => {
|
||||
const value = event || "";
|
||||
setShipmentElement(index, {...shipment, date: value})
|
||||
}}
|
||||
/>
|
||||
</Group>
|
||||
<Tooltip label={t("remove shipment", {capfirst: true})}>
|
||||
<ActionIcon
|
||||
flex={{base: "1", md: "0"}}
|
||||
style={{alignSelf: "flex-end"}}
|
||||
color="red"
|
||||
aria-label={t("remove shipment", {capfirst: true})}
|
||||
onClick={() => {
|
||||
deleteShipmentElement(index)
|
||||
}}
|
||||
>
|
||||
<IconX/>
|
||||
</ActionIcon>
|
||||
</Tooltip>
|
||||
</Group>
|
||||
const shipmentPrice = useMemo(() => {
|
||||
const values = Object
|
||||
.entries(inputForm.getValues())
|
||||
.filter(([key]) =>
|
||||
key.includes("planned") &&
|
||||
key.split("-")[1] === String(shipment.id)
|
||||
);
|
||||
return computePrices(values, shipment.products);
|
||||
}, [inputForm, shipment.products]);
|
||||
|
||||
)
|
||||
return (
|
||||
<Accordion.Item value={String(index)}>
|
||||
<Accordion.Control>
|
||||
<Group justify="space-between">
|
||||
<Text>{shipment.name}</Text>
|
||||
<Text>{
|
||||
Intl.NumberFormat(
|
||||
"fr-FR",
|
||||
{style: "currency", currency: "EUR"}
|
||||
).format(shipmentPrice)
|
||||
}</Text>
|
||||
<Text mr="lg">{shipment.date}</Text>
|
||||
</Group>
|
||||
</Accordion.Control>
|
||||
<Accordion.Panel>
|
||||
{
|
||||
shipment?.products.map((product) => (
|
||||
<ProductForm
|
||||
key={product.id}
|
||||
product={product}
|
||||
shipment={shipment}
|
||||
inputForm={inputForm}
|
||||
/>
|
||||
))
|
||||
}
|
||||
</Accordion.Panel>
|
||||
</Accordion.Item>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user