feat: cards, attributes and modules

This commit is contained in:
2025-02-19 14:46:13 +04:00
parent cc3e72bf94
commit dc9455966e
286 changed files with 2355 additions and 2168 deletions

View File

@@ -0,0 +1,88 @@
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>
);
};