88 lines
3.3 KiB
TypeScript
88 lines
3.3 KiB
TypeScript
import { CardGroupSchema, CardGroupService, CardSummary } from "../../../../client";
|
||
import { FC, useEffect, useMemo, useState } from "react";
|
||
import CardSummaryItem from "../CardSummaryItem/CardSummaryItem.tsx";
|
||
import { Flex, rem, Text, TextInput, useMantineColorScheme } from "@mantine/core";
|
||
import { IconGripHorizontal } from "@tabler/icons-react";
|
||
import { useDebouncedValue } from "@mantine/hooks";
|
||
import { notifications } from "../../../../shared/lib/notifications.ts";
|
||
|
||
type Props = {
|
||
cards: CardSummary[];
|
||
group: CardGroupSchema;
|
||
}
|
||
|
||
export const CardGroupView: FC<Props> = ({ cards, group }) => {
|
||
const theme = useMantineColorScheme();
|
||
const [name, setName] = useState<string>(group.name || "");
|
||
const [debouncedName] = useDebouncedValue(name, 200);
|
||
const totalPrice = useMemo(() => cards.reduce((acc, card) => acc + card.totalPrice, 0), [cards]);
|
||
const totalProducts = useMemo(() => cards.reduce((acc, card) => acc + card.totalProducts, 0), [cards]);
|
||
const updateName = () => {
|
||
if (debouncedName === group.name) return;
|
||
CardGroupService.updateCardGroup({
|
||
requestBody: {
|
||
data: {
|
||
...group,
|
||
name: debouncedName,
|
||
},
|
||
},
|
||
}).then(response => {
|
||
if (response.ok) return;
|
||
setName(group.name || "");
|
||
notifications.guess(response.ok, { message: response.message });
|
||
});
|
||
};
|
||
|
||
useEffect(() => {
|
||
updateName();
|
||
}, [debouncedName]);
|
||
return (
|
||
<Flex
|
||
style={{
|
||
border: "dashed var(--item-border-size) var(--mantine-color-default-border)",
|
||
borderRadius: "0.5rem",
|
||
}}
|
||
|
||
p={rem(5)}
|
||
py={rem(10)}
|
||
bg={theme.colorScheme === "dark" ? "var(--mantine-color-dark-5)" : "var(--mantine-color-gray-1)"}
|
||
gap={rem(10)}
|
||
direction={"column"}>
|
||
<Flex
|
||
justify={"space-between"}
|
||
align={"center"}
|
||
gap={rem(10)}
|
||
px={rem(10)}
|
||
>
|
||
<TextInput
|
||
value={name}
|
||
onChange={event => setName(event.currentTarget.value)}
|
||
variant={"unstyled"}
|
||
/>
|
||
<IconGripHorizontal />
|
||
</Flex>
|
||
<Flex direction={"column"} gap={rem(10)}>
|
||
{cards.map(card => (
|
||
<CardSummaryItem
|
||
color={theme.colorScheme === "dark" ? "var(--mantine-color-dark-6)" : "var(--mantine-color-gray-2)"}
|
||
key={card.id}
|
||
cardSummary={card}
|
||
/>
|
||
))}
|
||
</Flex>
|
||
<Flex
|
||
p={rem(10)}
|
||
direction={"column"}
|
||
bg={theme.colorScheme === "dark" ? "var(--mantine-color-dark-6)" : "var(--mantine-color-gray-2)"}
|
||
style={{ borderRadius: "0.5rem" }}
|
||
>
|
||
<Text
|
||
c={"gray.6"}
|
||
size={"xs"}>Сумма: {totalPrice.toLocaleString("ru-RU")} руб.</Text>
|
||
<Text
|
||
c={"gray.6"}
|
||
size={"xs"}>Всего товаров: {totalProducts.toLocaleString("ru-RU")} шт.</Text>
|
||
</Flex>
|
||
</Flex>
|
||
);
|
||
}; |