diff --git a/src/index.tsx b/src/index.tsx index cb0597d..30ae104 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -47,61 +47,13 @@ root.render( - - - - } - /> - - - - } - /> - - - - } - /> - - - - } - /> - - - - } - /> - - - - } - > - - - - } - /> + } /> + } /> + } /> + } /> + } /> + }> + } /> {componentsArray.map((element: any) => ( ))} diff --git a/src/kitUI/Cart/Cart.tsx b/src/kitUI/Cart/Cart.tsx index 3cbd5fa..9870f72 100644 --- a/src/kitUI/Cart/Cart.tsx +++ b/src/kitUI/Cart/Cart.tsx @@ -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(""); - const [loyaltyField, setLoyaltyField] = useState(""); - const [errorMessage, setErrorMessage] = useState(null); - const [isNonCommercial, setIsNonCommercial] = useState(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(""); + const [loyaltyField, setLoyaltyField] = useState(""); + const [errorMessage, setErrorMessage] = useState(null); + const [isNonCommercial, setIsNonCommercial] = useState(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 = ( - - {cartItemTotal.envolvedDiscounts.map((discount, index, arr) => ( - - - {index < arr.length - (serviceDiscount ? 0 : 1) && - - } - - ))} - {serviceDiscount && - - - - } - - ); + const envolvedDiscountsElement = ( + + {cartItemTotal.envolvedDiscounts.map((discount, index, arr) => ( + + + {index < arr.length - (serviceDiscount ? 0 : 1) && } + + ))} + {serviceDiscount && ( + + + + )} + + ); - 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 && ( + + {cartDiscounts?.map((discount, index, arr) => ( + + + {index < arr.length - 1 && } + + ))} +   + {cartDiscountsResultFactor && `= ${formatDiscountFactor(cartDiscountsResultFactor)}`} + + ); + + 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 && ( - - {cartDiscounts?.map((discount, index, arr) => ( - - - {index < arr.length - 1 && - - } - - ))} -   - {cartDiscountsResultFactor && `= ${formatDiscountFactor(cartDiscountsResultFactor)}`} - - ); - - 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 ( + + корзина + + setIsNonCommercial(checked)} + control={ + + } + label="НКО" + sx={{ + color: theme.palette.secondary.main, + }} + /> - - корзина - - - setIsNonCommercial(checked)} - control={} - label="НКО" - sx={{ - color: theme.palette.secondary.main, - }} - /> - - setCouponField(e.target.value)} - InputProps={{ - style: { - backgroundColor: theme.palette.content.main, - color: theme.palette.secondary.main, - } - }} - InputLabelProps={{ - style: { - color: theme.palette.secondary.main - } - }} - /> - - {cartTotal?.couponState && ( - cartTotal.couponState === "applied" ? - Купон применен! - : - Подходящий купон не найден! - )} - - setLoyaltyField(e.target.value)} - InputProps={{ - style: { - backgroundColor: theme.palette.content.main, - color: theme.palette.secondary.main, - } - }} - InputLabelProps={{ - style: { - color: theme.palette.secondary.main - } - }} - /> - - - - - {cartTotal?.items && cartTotal.items.length > 0 && - <> - - - - - Имя - - - Описание - - - Скидки - - - стоимость - - - - - {cartRows?.map(row => ( - - {row.tariffName} - {row.privilegeDesc} - {row.envolvedDiscounts} - {row.price.toFixed(2)} ₽ - - ))} - -
- - - Скидки корзины: {envolvedCartDiscountsElement} - - - - ИТОГО: {cartTotal?.totalPrice.toFixed(2)} ₽ - - - } - - {errorMessage !== null && - - {errorMessage} - - } - + setCouponField(e.target.value)} + InputProps={{ + style: { + backgroundColor: theme.palette.content.main, + color: theme.palette.secondary.main, + }, + }} + InputLabelProps={{ + style: { + color: theme.palette.secondary.main, + }, + }} + />
- ); + {cartTotal?.couponState && + (cartTotal.couponState === "applied" ? ( + Купон применен! + ) : ( + Подходящий купон не найден! + ))} + + setLoyaltyField(e.target.value)} + InputProps={{ + style: { + backgroundColor: theme.palette.content.main, + color: theme.palette.secondary.main, + }, + }} + InputLabelProps={{ + style: { + color: theme.palette.secondary.main, + }, + }} + /> + + +
+ + {cartTotal?.items && cartTotal.items.length > 0 && ( + <> + + + + + + Имя + + + + + Описание + + + + + Скидки + + + + + стоимость + + + + + + {cartRows?.map((row) => ( + + + {row.tariffName} + + + {row.privilegeDesc} + + + {row.envolvedDiscounts} + + + {row.price.toFixed(2)} ₽ + + + ))} + +
+ + + Скидки корзины: {envolvedCartDiscountsElement} + + + + ИТОГО: {cartTotal?.totalPrice.toFixed(2)} ₽ + + + )} + + {errorMessage !== null && ( + + {errorMessage} + + )} +
+ ); } -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 ( - - Скидка: {discount?.name} - {discount?.description} - - }> - {discountText} - - ); -} \ No newline at end of file + return ( + + Скидка: {discount?.name} + {discount?.description} + + } + > + {discountText} + + ); +} diff --git a/src/pages/dashboard/Content/Tariffs/CreateTariff.tsx b/src/pages/dashboard/Content/Tariffs/CreateTariff.tsx index 756fb65..44e99d1 100644 --- a/src/pages/dashboard/Content/Tariffs/CreateTariff.tsx +++ b/src/pages/dashboard/Content/Tariffs/CreateTariff.tsx @@ -35,9 +35,9 @@ export default function CreateTariff() { }; addTariffs([newTariff]); - } - console.log(mergedPrivileges); + console.log(newTariff); + } return ( 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 ( + { + console.log(row.id); + deleteTariffs(row.id); + }} + > + + + ); + }, + }, + ]; + 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} /> diff --git a/src/stores/cart.ts b/src/stores/cart.ts index a0d7e69..bdd04a2 100644 --- a/src/stores/cart.ts +++ b/src/stores/cart.ts @@ -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()( - devtools( - // persist( - (set, get) => ({ - cartTotal: null, - setCartTotal: newCartTotal => set({ cartTotal: newCartTotal }) - }), - // { - // name: "cart", - // getStorage: () => localStorage, - // } - // ), - { - name: "Cart store" - } - ) -); \ No newline at end of file + devtools( + // persist( + (set, get) => ({ + cartTotal: null, + setCartTotal: (newCartTotal) => set({ cartTotal: newCartTotal }), + }), + // { + // name: "cart", + // getStorage: () => localStorage, + // } + // ), + { + name: "Cart store", + } + ) +); diff --git a/src/stores/tariffs.ts b/src/stores/tariffs.ts index 1aad0c6..ec4598e 100644 --- a/src/stores/tariffs.ts +++ b/src/stores/tariffs.ts @@ -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()( - 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] })); \ No newline at end of file +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), + }));