adminFront/src/kitUI/Cart/Cart.tsx
2023-03-09 11:51:51 +03:00

274 lines
11 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import theme from "@theme";
import { Button, Paper, Box, Typography, TableHead, TableRow, TableCell, TableBody, Table, Tooltip, Alert } from "@mui/material";
import Input from "@kitUI/input";
import { useCartStore } from "@root/stores/cart";
import { useState } from "react";
import { GridSelectionModel } from "@mui/x-data-grid";
import { testUser } from "@root/stores/mocks/user";
import { useDiscountStore } from "@root/stores/discounts";
import { calcCartData, createCartItem, findDiscountById, findDiscountFactor, formatDiscountFactor } from "./calc";
import { useTariffStore } from "@root/stores/tariffs";
import { AnyDiscount, CartItemTotal } from "@root/model/cart";
interface Props {
selectedTariffs: GridSelectionModel;
}
export default function Cart({ selectedTariffs }: Props) {
const tariffs = useTariffStore(store => store.tariffs);
const discounts = useDiscountStore(store => store.discounts);
const cartTotal = useCartStore(state => state.cartTotal);
const setCartTotal = useCartStore(store => store.setCartTotal);
const [couponField, setCouponField] = useState<string>("");
const [errorMessage, setErrorMessage] = useState<string | null>(null);
// const [coupon, setCoupon] = useState<string | undefined>();
const cartRows = cartTotal?.items.map(cartItemTotal => {
const service = cartItemTotal.tariff.privilege.serviceKey;
const serviceDiscount = cartTotal.discountsByService[service];
const envolvedDiscountsElement = (
<Box>
{cartItemTotal.envolvedDiscountIds.map((discountId, index, arr) => {
const discount = findDiscountById(discounts, discountId);
return (
<span key={discount._id}>
<DiscountTooltip
discount={discount}
cartItemTotal={cartItemTotal}
/>
{index < arr.length - (serviceDiscount ? 0 : 1) &&
<span>,&nbsp;</span>
}
</span>
);
})}
{serviceDiscount &&
<span>
<DiscountTooltip
discount={serviceDiscount}
cartItemTotal={cartItemTotal}
/>
</span>
}
</Box>
);
const totalIncludingServiceDiscount = cartItemTotal.totalPrice * (serviceDiscount?.target.factor || 1);
return {
id: cartItemTotal.tariff.id,
tariffName: cartItemTotal.tariff.name,
privilegeDesc: cartItemTotal.tariff.privilege.description,
envolvedDiscounts: envolvedDiscountsElement,
price: totalIncludingServiceDiscount,
};
});
const cartDiscounts = cartTotal?.envolvedCartDiscountIds.map(discountId => findDiscountById(discounts, discountId));
const cartDiscountsResultFactor = cartDiscounts && cartDiscounts.reduce((acc, discount) => acc * findDiscountFactor(discount), 1);
const envolvedCartDiscountsElement = cartDiscounts && (
<Box sx={{
display: "inline-flex",
flexWrap: "wrap",
}}>
{cartDiscounts?.map((discount, index, arr) => (
<span key={discount._id}>
<DiscountTooltip
discount={discount}
/>
{index < arr.length - 1 &&
<span>,&nbsp;</span>
}
</span>
))}
&nbsp;
{cartDiscountsResultFactor && `= ${formatDiscountFactor(cartDiscountsResultFactor)}`}
</Box>
);
function handleCalcCartClick() {
const cartTariffs = tariffs.filter(tariff => selectedTariffs.includes(tariff.id));
const cartItems = cartTariffs.map(tariff => createCartItem(tariff));
const cartData = calcCartData(testUser, cartItems, discounts, couponField);
if (cartData instanceof Error) {
setErrorMessage(cartData.message);
return setCartTotal(null);
}
setErrorMessage(null);
setCartTotal(cartData);
}
return (
<Box
component="section"
sx={{
border: "1px solid white",
display: "flex",
flexDirection: "column",
alignItems: "center",
width: "100%",
pb: "20px",
borderRadius: "4px",
}}
>
<Typography variant="caption">
корзина
</Typography>
<Paper
variant="bar"
sx={{ display: "flex", alignItems: "center", justifyContent: "space-between" }}
>
<Box
sx={{
border: "1px solid white",
padding: "3px",
display: "flex",
flexDirection: "column"
}}
>
<Input
label="промокод"
size="small"
value={couponField}
onChange={e => setCouponField(e.target.value)}
InputProps={{
style: {
backgroundColor: theme.palette.content.main,
color: theme.palette.secondary.main,
}
}}
InputLabelProps={{
style: {
color: theme.palette.secondary.main
}
}}
/>
{/* <Button
sx={{ maxWidth: "140px" }}
onClick={() => setCoupon(couponField)}
>применить промокод</Button> */}
</Box>
<Button onClick={handleCalcCartClick}>рассчитать</Button>
</Paper>
{cartTotal?.items && cartTotal.items.length > 0 &&
<>
<Table sx={{
width: "90%",
margin: "5px",
border: "2px solid",
borderColor: theme.palette.secondary.main,
}} aria-label="simple table">
<TableHead>
<TableRow sx={{
borderBottom: "2px solid",
borderColor: theme.palette.grayLight.main,
height: "100px"
}}>
<TableCell>
<Typography
variant="h4"
sx={{ color: theme.palette.secondary.main }}
>Имя</Typography>
</TableCell>
<TableCell>
<Typography
variant="h4"
sx={{ color: theme.palette.secondary.main }}
>Описание</Typography>
</TableCell>
<TableCell>
<Typography
variant="h4"
sx={{ color: theme.palette.secondary.main }}
>Скидки</Typography>
</TableCell>
<TableCell>
<Typography
variant="h4"
sx={{ color: theme.palette.secondary.main }}
>стоимость</Typography>
</TableCell>
</TableRow>
</TableHead>
<TableBody>
{cartRows?.map(row => (
<TableRow
key={row.id}
sx={{
borderBottom: "2px solid",
borderColor: theme.palette.grayLight.main,
}}
>
<TableCell sx={{
color: theme.palette.secondary.main,
}}>{row.tariffName}</TableCell>
<TableCell sx={{
color: theme.palette.secondary.main,
}}>{row.privilegeDesc}</TableCell>
<TableCell sx={{
color: theme.palette.secondary.main,
}}>{row.envolvedDiscounts}</TableCell>
<TableCell sx={{
color: theme.palette.secondary.main,
}}>{row.price.toFixed(2)} </TableCell>
</TableRow>
))}
</TableBody>
</Table>
<Typography id="transition-modal-title" variant="h6" sx={{
fontWeight: "normal",
textAlign: "center",
marginTop: "15px",
fontSize: "16px"
}}>
Скидки корзины: {envolvedCartDiscountsElement}
</Typography>
<Typography id="transition-modal-title" variant="h6" sx={{
fontWeight: "normal",
textAlign: "center",
marginTop: "10px"
}}>
ИТОГО: <span>{cartTotal?.totalPrice.toFixed(2)} </span>
</Typography>
</>
}
{errorMessage !== null &&
<Alert variant="filled" severity="error" sx={{ mt: "20px" }}>
{errorMessage}
</Alert>
}
</Box>
);
}
function DiscountTooltip({ discount, cartItemTotal }: {
discount: AnyDiscount;
cartItemTotal?: CartItemTotal;
}) {
const discountText = formatDiscountFactor(findDiscountFactor(discount, cartItemTotal?.tariff.privilege.privilegeId));
return (
<Tooltip title={
<>
<Typography>Скидка: {discount?.name}</Typography>
<Typography>{discount?.description}</Typography>
<Typography>-------</Typography>
<Typography>layer: {discount?.layer}</Typography>
<Typography>id: {discount?._id}</Typography>
</>
}>
<span>{discountText}</span>
</Tooltip>
);
}