Удаление и добавление тарифов в таблицу: Список тарифов
This commit is contained in:
parent
d40b241e5b
commit
19ccbdaf4e
@ -47,61 +47,13 @@ root.render(
|
||||
<SnackbarProvider>
|
||||
<BrowserRouter>
|
||||
<Routes>
|
||||
<Route
|
||||
path="/"
|
||||
element={
|
||||
<PublicRoute>
|
||||
<Signin />
|
||||
</PublicRoute>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="/signin"
|
||||
element={
|
||||
<PublicRoute>
|
||||
<Signin />
|
||||
</PublicRoute>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="/signup"
|
||||
element={
|
||||
<PublicRoute>
|
||||
<Signup />
|
||||
</PublicRoute>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="/restore"
|
||||
element={
|
||||
<PublicRoute>
|
||||
<Restore />
|
||||
</PublicRoute>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="/dispatch"
|
||||
element={
|
||||
<PublicRoute>
|
||||
<Sections />
|
||||
</PublicRoute>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
element={
|
||||
<PrivateRoute>
|
||||
<Dashboard />
|
||||
</PrivateRoute>
|
||||
}
|
||||
>
|
||||
<Route
|
||||
path="/settingRoles"
|
||||
element={
|
||||
<PrivateRoute>
|
||||
<SettingRoles />
|
||||
</PrivateRoute>
|
||||
}
|
||||
/>
|
||||
<Route path="/" element={<Signin />} />
|
||||
<Route path="/signin" element={<Signin />} />
|
||||
<Route path="/signup" element={<Signup />} />
|
||||
<Route path="/restore" element={<Restore />} />
|
||||
<Route path="/dispatch" element={<Sections />} />
|
||||
<Route element={<Dashboard />}>
|
||||
<Route path="/settingRoles" element={<SettingRoles />} />
|
||||
{componentsArray.map((element: any) => (
|
||||
<Route key={element} path={element[0]} element={element[1]} />
|
||||
))}
|
||||
|
@ -1,5 +1,19 @@
|
||||
import theme from "@theme";
|
||||
import { Button, Paper, Box, Typography, TableHead, TableRow, TableCell, TableBody, Table, Tooltip, Alert, Checkbox, FormControlLabel } from "@mui/material";
|
||||
import {
|
||||
Button,
|
||||
Paper,
|
||||
Box,
|
||||
Typography,
|
||||
TableHead,
|
||||
TableRow,
|
||||
TableCell,
|
||||
TableBody,
|
||||
Table,
|
||||
Tooltip,
|
||||
Alert,
|
||||
Checkbox,
|
||||
FormControlLabel,
|
||||
} from "@mui/material";
|
||||
import Input from "@kitUI/input";
|
||||
import { useCartStore } from "@root/stores/cart";
|
||||
import { useState } from "react";
|
||||
@ -11,326 +25,341 @@ import { useTariffStore } from "@root/stores/tariffs";
|
||||
import { AnyDiscount, CartItemTotal } from "@root/model/cart";
|
||||
import { findPrivilegeById } from "@root/stores/privileges";
|
||||
|
||||
|
||||
interface Props {
|
||||
selectedTariffs: GridSelectionModel;
|
||||
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 [loyaltyField, setLoyaltyField] = useState<string>("");
|
||||
const [errorMessage, setErrorMessage] = useState<string | null>(null);
|
||||
const [isNonCommercial, setIsNonCommercial] = useState<boolean>(false);
|
||||
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 [loyaltyField, setLoyaltyField] = useState<string>("");
|
||||
const [errorMessage, setErrorMessage] = useState<string | null>(null);
|
||||
const [isNonCommercial, setIsNonCommercial] = useState<boolean>(false);
|
||||
|
||||
const cartRows = cartTotal?.items.map(cartItemTotal => {
|
||||
const privilege = findPrivilegeById(cartItemTotal.tariff.privilegeId);
|
||||
const cartRows = cartTotal?.items.map((cartItemTotal) => {
|
||||
const privilege = findPrivilegeById(cartItemTotal.tariff.privilegeId);
|
||||
|
||||
const service = privilege?.serviceKey;
|
||||
const serviceDiscount = service ? cartTotal.discountsByService[service] : null;
|
||||
const service = privilege?.serviceKey;
|
||||
const serviceDiscount = service ? cartTotal.discountsByService[service] : null;
|
||||
|
||||
const envolvedDiscountsElement = (
|
||||
<Box>
|
||||
{cartItemTotal.envolvedDiscounts.map((discount, index, arr) => (
|
||||
<span key={discount._id}>
|
||||
<DiscountTooltip
|
||||
discount={discount}
|
||||
cartItemTotal={cartItemTotal}
|
||||
/>
|
||||
{index < arr.length - (serviceDiscount ? 0 : 1) &&
|
||||
<span>, </span>
|
||||
}
|
||||
</span>
|
||||
))}
|
||||
{serviceDiscount &&
|
||||
<span>
|
||||
<DiscountTooltip
|
||||
discount={serviceDiscount}
|
||||
cartItemTotal={cartItemTotal}
|
||||
/>
|
||||
</span>
|
||||
}
|
||||
</Box>
|
||||
);
|
||||
const envolvedDiscountsElement = (
|
||||
<Box>
|
||||
{cartItemTotal.envolvedDiscounts.map((discount, index, arr) => (
|
||||
<span key={discount._id}>
|
||||
<DiscountTooltip discount={discount} cartItemTotal={cartItemTotal} />
|
||||
{index < arr.length - (serviceDiscount ? 0 : 1) && <span>, </span>}
|
||||
</span>
|
||||
))}
|
||||
{serviceDiscount && (
|
||||
<span>
|
||||
<DiscountTooltip discount={serviceDiscount} cartItemTotal={cartItemTotal} />
|
||||
</span>
|
||||
)}
|
||||
</Box>
|
||||
);
|
||||
|
||||
const totalIncludingServiceDiscount = cartItemTotal.totalPrice * (serviceDiscount?.target.factor || 1);
|
||||
const totalIncludingServiceDiscount = cartItemTotal.totalPrice * (serviceDiscount?.target.factor || 1);
|
||||
|
||||
return {
|
||||
id: cartItemTotal.tariff.id,
|
||||
tariffName: cartItemTotal.tariff.name,
|
||||
privilegeDesc: privilege?.description ?? "Привилегия не найдена",
|
||||
envolvedDiscounts: envolvedDiscountsElement,
|
||||
price: totalIncludingServiceDiscount,
|
||||
};
|
||||
return {
|
||||
id: cartItemTotal.tariff.id,
|
||||
tariffName: cartItemTotal.tariff.name,
|
||||
privilegeDesc: privilege?.description ?? "Привилегия не найдена",
|
||||
envolvedDiscounts: envolvedDiscountsElement,
|
||||
price: totalIncludingServiceDiscount,
|
||||
};
|
||||
});
|
||||
|
||||
const cartDiscounts = cartTotal?.envolvedCartDiscounts;
|
||||
const cartDiscountsResultFactor =
|
||||
cartDiscounts &&
|
||||
cartDiscounts?.length > 1 &&
|
||||
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>, </span>}
|
||||
</span>
|
||||
))}
|
||||
|
||||
{cartDiscountsResultFactor && `= ${formatDiscountFactor(cartDiscountsResultFactor)}`}
|
||||
</Box>
|
||||
);
|
||||
|
||||
function handleCalcCartClick() {
|
||||
const cartTariffs = tariffs.filter((tariff) => selectedTariffs.includes(tariff.id));
|
||||
const cartItems = cartTariffs.map((tariff) => createCartItem(tariff));
|
||||
|
||||
let loyaltyValue = parseInt(loyaltyField);
|
||||
|
||||
if (!isFinite(loyaltyValue)) loyaltyValue = 0;
|
||||
|
||||
const activeDiscounts = discounts.filter((discount) => !discount.disabled);
|
||||
|
||||
const cartData = calcCartData({
|
||||
user: testUser,
|
||||
purchasesAmount: loyaltyValue,
|
||||
cartItems,
|
||||
discounts: activeDiscounts,
|
||||
isNonCommercial,
|
||||
coupon: couponField,
|
||||
});
|
||||
|
||||
const cartDiscounts = cartTotal?.envolvedCartDiscounts;
|
||||
const cartDiscountsResultFactor = cartDiscounts && cartDiscounts?.length > 1 && 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>, </span>
|
||||
}
|
||||
</span>
|
||||
))}
|
||||
|
||||
{cartDiscountsResultFactor && `= ${formatDiscountFactor(cartDiscountsResultFactor)}`}
|
||||
</Box>
|
||||
);
|
||||
|
||||
function handleCalcCartClick() {
|
||||
const cartTariffs = tariffs.filter(tariff => selectedTariffs.includes(tariff.id));
|
||||
const cartItems = cartTariffs.map(tariff => createCartItem(tariff));
|
||||
|
||||
let loyaltyValue = parseInt(loyaltyField);
|
||||
|
||||
if (!isFinite(loyaltyValue)) loyaltyValue = 0;
|
||||
|
||||
const activeDiscounts = discounts.filter(discount => !discount.disabled);
|
||||
|
||||
const cartData = calcCartData({
|
||||
user: testUser,
|
||||
purchasesAmount: loyaltyValue,
|
||||
cartItems,
|
||||
discounts: activeDiscounts,
|
||||
isNonCommercial,
|
||||
coupon: couponField,
|
||||
});
|
||||
|
||||
if (cartData instanceof Error) {
|
||||
setErrorMessage(cartData.message);
|
||||
return setCartTotal(null);
|
||||
}
|
||||
|
||||
setErrorMessage(null);
|
||||
setCartTotal(cartData);
|
||||
if (cartData instanceof Error) {
|
||||
setErrorMessage(cartData.message);
|
||||
return setCartTotal(null);
|
||||
}
|
||||
|
||||
return (
|
||||
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",
|
||||
gap: "20px",
|
||||
}}
|
||||
>
|
||||
<FormControlLabel
|
||||
checked={isNonCommercial}
|
||||
onChange={(e, checked) => setIsNonCommercial(checked)}
|
||||
control={
|
||||
<Checkbox
|
||||
sx={{
|
||||
color: theme.palette.secondary.main,
|
||||
"&.Mui-checked": {
|
||||
color: theme.palette.secondary.main,
|
||||
},
|
||||
}}
|
||||
/>
|
||||
}
|
||||
label="НКО"
|
||||
sx={{
|
||||
color: theme.palette.secondary.main,
|
||||
}}
|
||||
/>
|
||||
<Box
|
||||
component="section"
|
||||
sx={{
|
||||
border: "1px solid white",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
alignItems: "center",
|
||||
width: "100%",
|
||||
pb: "20px",
|
||||
borderRadius: "4px",
|
||||
}}
|
||||
sx={{
|
||||
border: "1px solid white",
|
||||
padding: "3px",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
}}
|
||||
>
|
||||
<Typography variant="caption">
|
||||
корзина
|
||||
</Typography>
|
||||
<Paper
|
||||
variant="bar"
|
||||
sx={{
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "space-between",
|
||||
gap: "20px",
|
||||
}}
|
||||
>
|
||||
<FormControlLabel
|
||||
checked={isNonCommercial}
|
||||
onChange={(e, checked) => setIsNonCommercial(checked)}
|
||||
control={<Checkbox
|
||||
sx={{
|
||||
color: theme.palette.secondary.main,
|
||||
"&.Mui-checked": {
|
||||
color: theme.palette.secondary.main,
|
||||
},
|
||||
}}
|
||||
/>}
|
||||
label="НКО"
|
||||
sx={{
|
||||
color: theme.palette.secondary.main,
|
||||
}}
|
||||
/>
|
||||
<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
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
{cartTotal?.couponState && (
|
||||
cartTotal.couponState === "applied" ?
|
||||
<Alert severity="success">Купон применен!</Alert>
|
||||
:
|
||||
<Alert severity="error">Подходящий купон не найден!</Alert>
|
||||
)}
|
||||
<Box
|
||||
sx={{
|
||||
border: "1px solid white",
|
||||
padding: "3px",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
ml: "auto",
|
||||
}}
|
||||
>
|
||||
<Input
|
||||
label="лояльность"
|
||||
size="small"
|
||||
type="number"
|
||||
value={loyaltyField}
|
||||
onChange={e => setLoyaltyField(e.target.value)}
|
||||
InputProps={{
|
||||
style: {
|
||||
backgroundColor: theme.palette.content.main,
|
||||
color: theme.palette.secondary.main,
|
||||
}
|
||||
}}
|
||||
InputLabelProps={{
|
||||
style: {
|
||||
color: theme.palette.secondary.main
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</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>
|
||||
}
|
||||
|
||||
<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,
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
);
|
||||
{cartTotal?.couponState &&
|
||||
(cartTotal.couponState === "applied" ? (
|
||||
<Alert severity="success">Купон применен!</Alert>
|
||||
) : (
|
||||
<Alert severity="error">Подходящий купон не найден!</Alert>
|
||||
))}
|
||||
<Box
|
||||
sx={{
|
||||
border: "1px solid white",
|
||||
padding: "3px",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
ml: "auto",
|
||||
}}
|
||||
>
|
||||
<Input
|
||||
label="лояльность"
|
||||
size="small"
|
||||
type="number"
|
||||
value={loyaltyField}
|
||||
onChange={(e) => setLoyaltyField(e.target.value)}
|
||||
InputProps={{
|
||||
style: {
|
||||
backgroundColor: theme.palette.content.main,
|
||||
color: theme.palette.secondary.main,
|
||||
},
|
||||
}}
|
||||
InputLabelProps={{
|
||||
style: {
|
||||
color: theme.palette.secondary.main,
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</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));
|
||||
function DiscountTooltip({ discount, cartItemTotal }: { discount: AnyDiscount; cartItemTotal?: CartItemTotal }) {
|
||||
const discountText = formatDiscountFactor(findDiscountFactor(discount));
|
||||
|
||||
return (
|
||||
<Tooltip title={
|
||||
<>
|
||||
<Typography>Скидка: {discount?.name}</Typography>
|
||||
<Typography>{discount?.description}</Typography>
|
||||
</>
|
||||
}>
|
||||
<span>{discountText}</span>
|
||||
</Tooltip>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<Tooltip
|
||||
title={
|
||||
<>
|
||||
<Typography>Скидка: {discount?.name}</Typography>
|
||||
<Typography>{discount?.description}</Typography>
|
||||
</>
|
||||
}
|
||||
>
|
||||
<span>{discountText}</span>
|
||||
</Tooltip>
|
||||
);
|
||||
}
|
||||
|
@ -35,9 +35,9 @@ export default function CreateTariff() {
|
||||
};
|
||||
|
||||
addTariffs([newTariff]);
|
||||
}
|
||||
|
||||
console.log(mergedPrivileges);
|
||||
console.log(newTariff);
|
||||
}
|
||||
|
||||
return (
|
||||
<Container
|
||||
|
@ -1,23 +1,13 @@
|
||||
import * as React from "react";
|
||||
import { GridColDef, GridSelectionModel, GridToolbar } from "@mui/x-data-grid";
|
||||
|
||||
import DataGrid from "@kitUI/datagrid";
|
||||
|
||||
import { useTariffStore } from "@root/stores/tariffs";
|
||||
import { deleteTariffs, useTariffStore } from "@root/stores/tariffs";
|
||||
import { SERVICE_LIST } from "@root/model/tariff";
|
||||
import { findPrivilegeById } from "@root/stores/privileges";
|
||||
import { IconButton } from "@mui/material";
|
||||
|
||||
const columns: GridColDef[] = [
|
||||
{ field: "id", headerName: "ID", width: 100 },
|
||||
{ field: "name", headerName: "Название тарифа", width: 150 },
|
||||
{ field: "serviceName", headerName: "Сервис", width: 150 }, //инфо из гитлаба.
|
||||
{ field: "privilege", headerName: "Привелегия", width: 150 },
|
||||
{ field: "amount", headerName: "Количество", width: 110 },
|
||||
{ field: "type", headerName: "Единица", width: 100 },
|
||||
{ field: "pricePerUnit", headerName: "Цена за ед.", width: 100 },
|
||||
{ field: "isCustomPrice", headerName: "Кастомная цена", width: 130 },
|
||||
{ field: "total", headerName: "Сумма", width: 130 },
|
||||
];
|
||||
import BackspaceIcon from "@mui/icons-material/Backspace";
|
||||
|
||||
interface Props {
|
||||
handleSelectionChange: (selectionModel: GridSelectionModel) => void;
|
||||
@ -26,6 +16,35 @@ interface Props {
|
||||
export default function TariffsDG({ handleSelectionChange }: Props) {
|
||||
const tariffs = useTariffStore((state) => state.tariffs);
|
||||
|
||||
const columns: GridColDef[] = [
|
||||
{ field: "id", headerName: "ID", width: 100 },
|
||||
{ field: "name", headerName: "Название тарифа", width: 150 },
|
||||
{ field: "serviceName", headerName: "Сервис", width: 150 }, //инфо из гитлаба.
|
||||
{ field: "privilege", headerName: "Привелегия", width: 150 },
|
||||
{ field: "amount", headerName: "Количество", width: 110 },
|
||||
{ field: "type", headerName: "Единица", width: 100 },
|
||||
{ field: "pricePerUnit", headerName: "Цена за ед.", width: 100 },
|
||||
{ field: "isCustomPrice", headerName: "Кастомная цена", width: 130 },
|
||||
{ field: "total", headerName: "Сумма", width: 60 },
|
||||
{
|
||||
field: "delete",
|
||||
headerName: "Удаление",
|
||||
width: 60,
|
||||
renderCell: ({ row }) => {
|
||||
return (
|
||||
<IconButton
|
||||
onClick={() => {
|
||||
console.log(row.id);
|
||||
deleteTariffs(row.id);
|
||||
}}
|
||||
>
|
||||
<BackspaceIcon />
|
||||
</IconButton>
|
||||
);
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
const gridData = tariffs.map((tariff) => ({
|
||||
id: tariff.id,
|
||||
name: tariff.name,
|
||||
@ -36,7 +55,7 @@ export default function TariffsDG({ handleSelectionChange }: Props) {
|
||||
findPrivilegeById(tariff.privilegeId)?.description ?? "Привилегия не найдена"
|
||||
}`,
|
||||
amount: tariff.amount,
|
||||
type: findPrivilegeById(tariff.privilegeId)?.type === "count" ? "день" : "шт.",
|
||||
type: console.log(tariff.id),
|
||||
pricePerUnit: tariff.customPricePerUnit ?? findPrivilegeById(tariff.privilegeId)?.price,
|
||||
isCustomPrice: tariff.customPricePerUnit === undefined ? "Нет" : "Да",
|
||||
total: tariff.amount * (tariff.customPricePerUnit ?? findPrivilegeById(tariff.privilegeId)?.price ?? 0),
|
||||
@ -47,6 +66,7 @@ export default function TariffsDG({ handleSelectionChange }: Props) {
|
||||
checkboxSelection={true}
|
||||
rows={gridData}
|
||||
columns={columns}
|
||||
getRowId={(row) => row.id}
|
||||
components={{ Toolbar: GridToolbar }}
|
||||
onSelectionModelChange={handleSelectionChange}
|
||||
/>
|
||||
|
@ -2,26 +2,25 @@ import { create } from "zustand";
|
||||
import { devtools, persist } from "zustand/middleware";
|
||||
import { CartTotal } from "@root/model/cart";
|
||||
|
||||
|
||||
interface CartStore {
|
||||
cartTotal: CartTotal | null;
|
||||
setCartTotal: (newCartTotal: CartTotal | null) => void;
|
||||
cartTotal: CartTotal | null;
|
||||
setCartTotal: (newCartTotal: CartTotal | null) => void;
|
||||
}
|
||||
|
||||
export const useCartStore = create<CartStore>()(
|
||||
devtools(
|
||||
// persist(
|
||||
(set, get) => ({
|
||||
cartTotal: null,
|
||||
setCartTotal: newCartTotal => set({ cartTotal: newCartTotal })
|
||||
}),
|
||||
// {
|
||||
// name: "cart",
|
||||
// getStorage: () => localStorage,
|
||||
// }
|
||||
// ),
|
||||
{
|
||||
name: "Cart store"
|
||||
}
|
||||
)
|
||||
);
|
||||
devtools(
|
||||
// persist(
|
||||
(set, get) => ({
|
||||
cartTotal: null,
|
||||
setCartTotal: (newCartTotal) => set({ cartTotal: newCartTotal }),
|
||||
}),
|
||||
// {
|
||||
// name: "cart",
|
||||
// getStorage: () => localStorage,
|
||||
// }
|
||||
// ),
|
||||
{
|
||||
name: "Cart store",
|
||||
}
|
||||
)
|
||||
);
|
||||
|
@ -1,22 +1,27 @@
|
||||
import { Tariff } from "@root/model/tariff";
|
||||
import { create } from "zustand";
|
||||
import { devtools } from "zustand/middleware";
|
||||
import { persist } from "zustand/middleware";
|
||||
import { exampleTariffs } from "./mocks/tariffs";
|
||||
|
||||
|
||||
interface TariffStore {
|
||||
tariffs: Tariff[];
|
||||
tariffs: Tariff[];
|
||||
}
|
||||
|
||||
export const useTariffStore = create<TariffStore>()(
|
||||
devtools(
|
||||
(set, get) => ({
|
||||
tariffs: exampleTariffs,
|
||||
}),
|
||||
{
|
||||
name: "Tariff store"
|
||||
}
|
||||
)
|
||||
persist(
|
||||
(set, get) => ({
|
||||
tariffs: exampleTariffs,
|
||||
}),
|
||||
{
|
||||
name: "Tariff store",
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
export const addTariffs = (newTariffs: Tariff[]) => useTariffStore.setState(state => ({ tariffs: [...state.tariffs, ...newTariffs] }));
|
||||
export const addTariffs = (newTariffs: Tariff[]) =>
|
||||
useTariffStore.setState((state) => ({ tariffs: [...state.tariffs, ...newTariffs] }));
|
||||
|
||||
export const deleteTariffs = (tariffId: string) =>
|
||||
useTariffStore.setState((state) => ({
|
||||
tariffs: state.tariffs.filter((tariff) => tariff.id !== tariffId),
|
||||
}));
|
||||
|
Loading…
Reference in New Issue
Block a user