feat: cards, attributes and modules
This commit is contained in:
88
src/components/Dnd/Cards/CardGroupView/CardGroupView.tsx
Normal file
88
src/components/Dnd/Cards/CardGroupView/CardGroupView.tsx
Normal 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>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user