224 lines
		
	
	
		
			8.7 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			224 lines
		
	
	
		
			8.7 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
import { FC } from "react";
 | 
						||
import { DealService, DealSummary } from "../../../client";
 | 
						||
import styles from "./DealSummaryCard.module.css";
 | 
						||
 | 
						||
import {
 | 
						||
    ActionIcon,
 | 
						||
    Badge,
 | 
						||
    CopyButton,
 | 
						||
    Flex,
 | 
						||
    Image,
 | 
						||
    Indicator,
 | 
						||
    IndicatorProps,
 | 
						||
    Popover,
 | 
						||
    rem,
 | 
						||
    Text,
 | 
						||
    ThemeIcon,
 | 
						||
    Tooltip,
 | 
						||
} from "@mantine/core";
 | 
						||
import { useDealPageContext } from "../../../pages/LeadsPage/contexts/DealPageContext.tsx";
 | 
						||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
 | 
						||
import { faCheck } from "@fortawesome/free-solid-svg-icons";
 | 
						||
import { DealStatus } from "../../../shared/enums/DealStatus.ts";
 | 
						||
import { IconCheck, IconLayoutGridRemove, IconTrash } from "@tabler/icons-react";
 | 
						||
import { useContextMenu } from "mantine-contextmenu";
 | 
						||
import useDealSummaryState from "./useDealSummaryState.tsx";
 | 
						||
 | 
						||
type Props = {
 | 
						||
    dealSummary: DealSummary;
 | 
						||
    color?: string
 | 
						||
};
 | 
						||
 | 
						||
const DealSummaryCard: FC<Props> = ({ dealSummary, color }) => {
 | 
						||
    const { showContextMenu } = useContextMenu();
 | 
						||
    const { setSelectedDeal } = useDealPageContext();
 | 
						||
    const { onDelete, onComplete, onDeleteFromGroup } = useDealSummaryState();
 | 
						||
 | 
						||
    const onDealSummaryClick = () => {
 | 
						||
        DealService.getDealById({ dealId: dealSummary.id }).then(deal => {
 | 
						||
            setSelectedDeal(deal);
 | 
						||
        });
 | 
						||
    };
 | 
						||
    const getIndicatorProps = (): IndicatorProps => {
 | 
						||
        if (!dealSummary.deliveryDate)
 | 
						||
            return { disabled: true };
 | 
						||
 | 
						||
        const deliveryDate = new Date(dealSummary.deliveryDate);
 | 
						||
        const currentDate = new Date();
 | 
						||
        const diff = deliveryDate.getTime() - currentDate.getTime();
 | 
						||
        const diffDays = Math.ceil(diff / (1000 * 3600 * 24));
 | 
						||
 | 
						||
        if (dealSummary.status < DealStatus.IN_DELIVERY) {
 | 
						||
            if (diffDays <= 2 && diffDays > 1) {
 | 
						||
                return {
 | 
						||
                    color: "yellow",
 | 
						||
                };
 | 
						||
            }
 | 
						||
            if (diffDays <= 1) {
 | 
						||
                return {
 | 
						||
                    color: "red",
 | 
						||
                };
 | 
						||
            }
 | 
						||
 | 
						||
            return {
 | 
						||
                disabled: false,
 | 
						||
            };
 | 
						||
        }
 | 
						||
        return { disabled: true };
 | 
						||
    };
 | 
						||
    const isPaid = () => {
 | 
						||
        return dealSummary.billRequest?.paid || dealSummary.group?.billRequest?.paid;
 | 
						||
    }
 | 
						||
    return (
 | 
						||
        <Indicator
 | 
						||
            position={"top-end"}
 | 
						||
            withBorder
 | 
						||
            size={15}
 | 
						||
            processing
 | 
						||
            {...getIndicatorProps()}
 | 
						||
        >
 | 
						||
 | 
						||
            <div
 | 
						||
                onContextMenu={showContextMenu([
 | 
						||
                    ...dealSummary.group ? [{
 | 
						||
                        key: "removeFromGroup",
 | 
						||
                        onClick: () => onDeleteFromGroup(dealSummary),
 | 
						||
                        title: "Убрать из группы",
 | 
						||
                        icon: <IconLayoutGridRemove />,
 | 
						||
                    }] : [],
 | 
						||
                    {
 | 
						||
                        key: "complete",
 | 
						||
                        onClick: () => onComplete(dealSummary),
 | 
						||
                        title: "Завершить",
 | 
						||
                        icon: <IconCheck />,
 | 
						||
                    },
 | 
						||
                    {
 | 
						||
                        key: "delete",
 | 
						||
                        onClick: () => onDelete(dealSummary),
 | 
						||
                        title: "Удалить",
 | 
						||
                        icon: <IconTrash />,
 | 
						||
                    },
 | 
						||
                ])}
 | 
						||
                onClick={() => onDealSummaryClick()}
 | 
						||
                className={styles["container"]}
 | 
						||
                style={{ backgroundColor: color }}
 | 
						||
            >
 | 
						||
                <Flex direction={"column"} flex={1} gap={rem(3)}>
 | 
						||
                    <Flex justify={"space-between"}>
 | 
						||
 | 
						||
                        <Text
 | 
						||
                            c={"gray.6"}
 | 
						||
                            size={"xs"}
 | 
						||
 | 
						||
                        >
 | 
						||
                            {dealSummary.clientName}
 | 
						||
                        </Text>
 | 
						||
                    </Flex>
 | 
						||
 | 
						||
                    <Text
 | 
						||
                        c={"blue.5"}
 | 
						||
                        size={"sm"}>
 | 
						||
                        {dealSummary.name}
 | 
						||
                    </Text>
 | 
						||
                    <Flex
 | 
						||
                        // align={"center"}
 | 
						||
                        direction={"column"}
 | 
						||
                        justify={"space-between"}
 | 
						||
                    >
 | 
						||
                        <Text
 | 
						||
                            size={"sm"}
 | 
						||
                            c={"gray.6"}>
 | 
						||
                            {dealSummary.shipmentWarehouseName || "Склад не указан"}
 | 
						||
                        </Text>
 | 
						||
                        <Text
 | 
						||
                            c={"gray.6"}
 | 
						||
                            size={"sm"}
 | 
						||
                        >
 | 
						||
                            {dealSummary.totalPrice.toLocaleString("ru-RU")} руб,{" "}
 | 
						||
                        </Text>
 | 
						||
                        <Text
 | 
						||
                            c={"gray.6"}
 | 
						||
                            size={"sm"}>
 | 
						||
                            {dealSummary.totalProducts.toLocaleString("ru-RU")} тов.
 | 
						||
                        </Text>
 | 
						||
                    </Flex>
 | 
						||
                    <Flex direction={"column"}>
 | 
						||
                        {dealSummary.deliveryDate && (
 | 
						||
                            <Text
 | 
						||
                                c={"blue.5"}
 | 
						||
                                size={"sm"}>
 | 
						||
                                Доставка: {(new Date(dealSummary.deliveryDate)).toLocaleDateString("ru-RU")}
 | 
						||
                            </Text>
 | 
						||
                        )}
 | 
						||
                        {dealSummary.receivingSlotDate && (
 | 
						||
                            <Text
 | 
						||
                                c={"blue.5"}
 | 
						||
                                size={"sm"}>
 | 
						||
                                Слот: {(new Date(dealSummary.receivingSlotDate)).toLocaleDateString("ru-RU")}
 | 
						||
                            </Text>
 | 
						||
                        )}
 | 
						||
                    </Flex>
 | 
						||
                    <Flex align={"center"} justify={"space-between"}>
 | 
						||
                        <Flex align={"center"} gap={rem(5)}>
 | 
						||
                            <CopyButton value={dealSummary.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: {dealSummary.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={dealSummary.baseMarketplace?.iconUrl || ""}
 | 
						||
                            />
 | 
						||
                        </ActionIcon>
 | 
						||
                    </Flex>
 | 
						||
 | 
						||
                </Flex>
 | 
						||
 | 
						||
            </div>
 | 
						||
        </Indicator>
 | 
						||
 | 
						||
    );
 | 
						||
};
 | 
						||
export default DealSummaryCard;
 |