173 lines
		
	
	
		
			7.5 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			173 lines
		
	
	
		
			7.5 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
import { FC, useEffect, useState } from "react";
 | 
						||
import { CardService, CardSummary } from "../../../../client";
 | 
						||
import styles from "./CardSummaryItem.module.css";
 | 
						||
 | 
						||
import { ActionIcon, Badge, CopyButton, Flex, Image, Popover, rem, Text, ThemeIcon, Tooltip } from "@mantine/core";
 | 
						||
import { useCardPageContext } from "../../../../pages/CardsPage/contexts/CardPageContext.tsx";
 | 
						||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
 | 
						||
import { faCheck } from "@fortawesome/free-solid-svg-icons";
 | 
						||
import { IconCheck, IconLayoutGridRemove, IconTrash } from "@tabler/icons-react";
 | 
						||
import { useContextMenu } from "mantine-contextmenu";
 | 
						||
import useCardSummaryState from "./useCardSummaryState.tsx";
 | 
						||
import isModuleInProject from "../../../../modules/utils/isModuleInProject.ts";
 | 
						||
import { useProjectsContext } from "../../../../contexts/ProjectsContext.tsx";
 | 
						||
import CardTags from "../CardTags/CardTags.tsx";
 | 
						||
import CardAttributesInSummaryItem from "../CardAttributesInSummaryItem/CardAttributesInSummaryItem.tsx";
 | 
						||
import { ModuleNames } from "../../../../modules/modules.tsx";
 | 
						||
import isDealPaid from "../../../../pages/CardsPage/utils/isDealPaid.ts";
 | 
						||
 | 
						||
type Props = {
 | 
						||
    cardSummary: CardSummary;
 | 
						||
    color?: string
 | 
						||
};
 | 
						||
 | 
						||
const CardSummaryItem: FC<Props> = ({ cardSummary, color }) => {
 | 
						||
    const { showContextMenu } = useContextMenu();
 | 
						||
    const { selectedProject } = useProjectsContext();
 | 
						||
    const { setSelectedCard } = useCardPageContext();
 | 
						||
    const { onDelete, onComplete, onDeleteFromGroup } = useCardSummaryState();
 | 
						||
    const [isPaid, setIsPaid] = useState<boolean>(false);
 | 
						||
 | 
						||
    const isServicesAndProductsIncluded = isModuleInProject(ModuleNames.SERVICES_AND_PRODUCTS, selectedProject);
 | 
						||
    const isClientIncluded = isModuleInProject(ModuleNames.CLIENTS, selectedProject);
 | 
						||
 | 
						||
    const onCardSummaryClick = () => {
 | 
						||
        CardService.getCardById({ cardId: cardSummary.id }).then(card => {
 | 
						||
            setSelectedCard(card);
 | 
						||
        });
 | 
						||
    };
 | 
						||
    const isLockedInsideGroup = () => {
 | 
						||
        return cardSummary.group && !cardSummary.group.billRequests;
 | 
						||
    };
 | 
						||
 | 
						||
    useEffect(() => {
 | 
						||
        setIsPaid(isDealPaid(cardSummary));
 | 
						||
    }, []);
 | 
						||
 | 
						||
    return (
 | 
						||
        <div
 | 
						||
            onContextMenu={showContextMenu([
 | 
						||
                ...isLockedInsideGroup() ? [{
 | 
						||
                    key: "removeFromGroup",
 | 
						||
                    onClick: () => onDeleteFromGroup(cardSummary),
 | 
						||
                    title: "Убрать из группы",
 | 
						||
                    icon: <IconLayoutGridRemove />,
 | 
						||
                }] : [],
 | 
						||
                {
 | 
						||
                    key: "complete",
 | 
						||
                    onClick: () => onComplete(cardSummary),
 | 
						||
                    title: "Завершить",
 | 
						||
                    icon: <IconCheck />,
 | 
						||
                },
 | 
						||
                {
 | 
						||
                    key: "delete",
 | 
						||
                    onClick: () => onDelete(cardSummary),
 | 
						||
                    title: "Удалить",
 | 
						||
                    icon: <IconTrash />,
 | 
						||
                },
 | 
						||
            ])}
 | 
						||
            onClick={() => onCardSummaryClick()}
 | 
						||
            className={styles["container"]}
 | 
						||
            style={{ backgroundColor: color }}
 | 
						||
        >
 | 
						||
            <Flex direction={"column"} flex={1} gap={rem(3)}>
 | 
						||
                {isClientIncluded && (
 | 
						||
                    <Flex justify={"space-between"}>
 | 
						||
                        <Text c={"gray.6"} size={"xs"}>
 | 
						||
                            {cardSummary.clientName}
 | 
						||
                        </Text>
 | 
						||
                    </Flex>
 | 
						||
                )}
 | 
						||
 | 
						||
                <Text
 | 
						||
                    c={"blue.5"}
 | 
						||
                    size={"sm"}>
 | 
						||
                    {cardSummary.name}
 | 
						||
                </Text>
 | 
						||
                {isServicesAndProductsIncluded && (
 | 
						||
                    <Flex
 | 
						||
                        direction={"column"}
 | 
						||
                        justify={"space-between"}
 | 
						||
                    >
 | 
						||
                        <Text
 | 
						||
                            size={"sm"}
 | 
						||
                            c={"gray.6"}>
 | 
						||
                            {cardSummary.shipmentWarehouseName || "Склад не указан"}
 | 
						||
                        </Text>
 | 
						||
                        <Text
 | 
						||
                            c={"gray.6"}
 | 
						||
                            size={"sm"}
 | 
						||
                        >
 | 
						||
                            {cardSummary.totalPrice.toLocaleString("ru-RU")} руб,{" "}
 | 
						||
                        </Text>
 | 
						||
                        <Text
 | 
						||
                            c={"gray.6"}
 | 
						||
                            size={"sm"}>
 | 
						||
                            {cardSummary.totalProducts.toLocaleString("ru-RU")} тов.
 | 
						||
                        </Text>
 | 
						||
                    </Flex>
 | 
						||
                )}
 | 
						||
                <CardAttributesInSummaryItem cardSummary={cardSummary} />
 | 
						||
                {!cardSummary.group?.id && (
 | 
						||
                    <CardTags cardId={cardSummary.id} tags={cardSummary.tags} />
 | 
						||
                )}
 | 
						||
                <Flex align={"center"} justify={"space-between"}>
 | 
						||
                    <Flex align={"center"} gap={rem(5)}>
 | 
						||
                        <CopyButton value={cardSummary.id.toString()}>
 | 
						||
                            {({ copy, copied }) => (
 | 
						||
                                <Popover
 | 
						||
                                    opened={copied}
 | 
						||
                                    withArrow>
 | 
						||
                                    <Popover.Target>
 | 
						||
                                        <div
 | 
						||
                                            onClick={e => {
 | 
						||
                                                e.stopPropagation();
 | 
						||
                                                copy();
 | 
						||
                                            }}
 | 
						||
                                            className={styles["flex-item"]}>
 | 
						||
                                            <Badge
 | 
						||
                                                variant={"light"}
 | 
						||
                                                radius={"sm"}>
 | 
						||
                                                ID: {cardSummary.id}
 | 
						||
                                            </Badge>
 | 
						||
                                        </div>
 | 
						||
                                    </Popover.Target>
 | 
						||
                                    <Popover.Dropdown>
 | 
						||
                                        <Flex
 | 
						||
                                            justify={"center"}
 | 
						||
                                            align={"center"}
 | 
						||
                                            gap={rem(5)}>
 | 
						||
                                            <FontAwesomeIcon
 | 
						||
                                                bounce
 | 
						||
                                                style={{ animationIterationCount: 1 }}
 | 
						||
                                                icon={faCheck}
 | 
						||
                                            />
 | 
						||
                                            <Text size={"xs"}>
 | 
						||
                                                ID сделки скопирован
 | 
						||
                                            </Text>
 | 
						||
                                        </Flex>
 | 
						||
                                    </Popover.Dropdown>
 | 
						||
                                </Popover>
 | 
						||
                            )}
 | 
						||
                        </CopyButton>
 | 
						||
                        {isPaid && (
 | 
						||
                            <Tooltip label={"Оплачен"}>
 | 
						||
                                <ThemeIcon variant={"transparent"}>
 | 
						||
                                    <IconCheck />
 | 
						||
                                </ThemeIcon>
 | 
						||
                            </Tooltip>
 | 
						||
                        )}
 | 
						||
                    </Flex>
 | 
						||
 | 
						||
                    <ActionIcon variant={"transparent"}>
 | 
						||
                        <Image
 | 
						||
                            src={cardSummary.baseMarketplace?.iconUrl || ""}
 | 
						||
                        />
 | 
						||
                    </ActionIcon>
 | 
						||
                </Flex>
 | 
						||
            </Flex>
 | 
						||
        </div>
 | 
						||
    );
 | 
						||
};
 | 
						||
export default CardSummaryItem;
 |