From ae632f6edf344c462103fe04d5d1818febc6cee4 Mon Sep 17 00:00:00 2001 From: nflnkr Date: Thu, 18 May 2023 23:27:46 +0300 Subject: [PATCH 1/2] rename menu item --- src/pages/dashboard/Menu/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/dashboard/Menu/index.tsx b/src/pages/dashboard/Menu/index.tsx index 9061832..89260af 100644 --- a/src/pages/dashboard/Menu/index.tsx +++ b/src/pages/dashboard/Menu/index.tsx @@ -102,7 +102,7 @@ const Drawer = styled(MuiDrawer, { shouldForwardProp: (prop) => prop !== "open" const links: { path: string; element: JSX.Element; title: string; className: string }[] = [ { path: "/users", element: , title: "Информация о проекте", className: "menu" }, { path: "/entities", element: , title: "Юридические лица", className: "menu" }, - { path: "/tariffs", element: , title: "Шаблонизатор документов", className: "menu" }, + { path: "/tariffs", element: , title: "Тарифы", className: "menu" }, { path: "/discounts", element: , title: "Скидки", className: "menu" }, { path: "/promocode", element: , title: "Промокод", className: "menu" }, { path: "/settingRoles", element: , title: "Настройки", className: "menu" }, From 2084b5619cd5cbfd53ce5db8a5179d456dbded41 Mon Sep 17 00:00:00 2001 From: nflnkr Date: Thu, 18 May 2023 23:31:36 +0300 Subject: [PATCH 2/2] add discount de/activation --- src/kitUI/Cart/Cart.tsx | 6 +- src/kitUI/Cart/calc.ts | 6 +- src/model/cart.ts | 1 + .../dashboard/Content/DiscountManagement.tsx | 97 ++++++------------- src/stores/discounts.ts | 70 +++++++------ 5 files changed, 73 insertions(+), 107 deletions(-) diff --git a/src/kitUI/Cart/Cart.tsx b/src/kitUI/Cart/Cart.tsx index 19835a2..965e910 100644 --- a/src/kitUI/Cart/Cart.tsx +++ b/src/kitUI/Cart/Cart.tsx @@ -95,11 +95,13 @@ export default function Cart({ selectedTariffs }: Props) { if (!isFinite(loyaltyValue)) loyaltyValue = 0; + const activeDiscounts = discounts.filter(discount => !discount.disabled); + const cartData = calcCartData({ user: testUser, purchasesAmount: loyaltyValue, cartItems, - discounts, + discounts: activeDiscounts, isNonCommercial, coupon: couponField, }); @@ -316,7 +318,7 @@ function DiscountTooltip({ discount, cartItemTotal }: { discount: AnyDiscount; cartItemTotal?: CartItemTotal; }) { - const discountText = formatDiscountFactor(findDiscountFactor(discount, cartItemTotal?.tariff.privilege.privilegeId)); + const discountText = formatDiscountFactor(findDiscountFactor(discount)); return ( product.privilegeId === privilegeId); + const product = discount.target.products[0]; if (!product) throw new Error("Discount target product not found"); return product.factor; } case "user": { - const product = discount.target.products.find(product => product.privilegeId === privilegeId); + const product = discount.target.products[0]; if (!product) throw new Error("Discount target product not found"); return product.factor; diff --git a/src/model/cart.ts b/src/model/cart.ts index dbe4975..c809037 100644 --- a/src/model/cart.ts +++ b/src/model/cart.ts @@ -7,6 +7,7 @@ interface DiscountBase { description: string; /** Этап применения скидки */ layer: number; + disabled?: boolean; } export interface PurchasesAmountDiscount extends DiscountBase { diff --git a/src/pages/dashboard/Content/DiscountManagement.tsx b/src/pages/dashboard/Content/DiscountManagement.tsx index 4c55fcd..4a5d7be 100644 --- a/src/pages/dashboard/Content/DiscountManagement.tsx +++ b/src/pages/dashboard/Content/DiscountManagement.tsx @@ -13,10 +13,11 @@ import MenuItem from "@mui/material/MenuItem"; import Select, { SelectChangeEvent } from "@mui/material/Select"; import theme from "../../../theme"; import { styled } from "@mui/material/styles"; -import { useDiscountStore } from "../../../stores/discounts"; +import { activateDiscounts, deactivateDiscounts, setSelectedDiscountIds, useDiscountStore } from "../../../stores/discounts"; import { useState } from "react"; import { DiscountConditionType } from "@root/model/cart"; import { ServiceType } from "@root/model/tariff"; +import { findDiscountFactor, formatDiscountFactor } from "@root/kitUI/Cart/calc"; const BoxButton = styled('div')(({ theme }) => ({ @@ -27,56 +28,6 @@ const BoxButton = styled('div')(({ theme }) => ({ const columns: GridColDef[] = [ - // { - // field: "endless", - // headerName: "Бесконечная", - // width: 120, - // sortable: false, - // }, - // { - // field: "from", - // headerName: "От", - // width: 120, - // sortable: false, - // }, - // { - // field: "dueTo", - // headerName: "До", - // width: 120, - // sortable: false, - // }, - // { - // field: "privileges", - // headerName: "Привилегии", - // width: 210, - // sortable: false, - // }, - // { - // field: "active", - // headerName: "Активна", - // width: 100, - // sortable: false, - // }, - // { - // field: "basketMore", - // headerName: "Корзина больше", - // width: 140, - // sortable: false, - // } - // , - // { - // field: "toTime", - // headerName: "На время", - // width: 140, - // sortable: false, - // } - // , - // { - // field: "toCapacity", - // headerName: "На объем", - // width: 140, - // sortable: false, - // }, { field: "id", headerName: "ID", @@ -101,11 +52,24 @@ const columns: GridColDef[] = [ width: 120, sortable: false, }, + { + field: "factor", + headerName: "Процент скидки", + width: 120, + sortable: false, + }, + { + field: "active", + headerName: "Активна", + width: 120, + sortable: false, + }, ]; const DiscountManagement: React.FC = () => { const discounts = useDiscountStore(state => state.discounts); + const selectedDiscountIds = useDiscountStore(state => state.selectedDiscountIds); const [isInfinite, setIsInfinite] = useState(false); const [serviceType, setServiceType] = useState("templategen"); const [startDate, setStartDate] = useState(new Date()); @@ -127,14 +91,6 @@ const DiscountManagement: React.FC = () => { // TODO } - function activateDiscounts() { - // TODO - } - - function deactivateDiscounts() { - // TODO - } - // const discountsArrayConverted = discounts.map((item) => { // const basketMorePerc = Math.round(Number(item.basketMore) * 100) + "%"; // const toTimePerc = Math.round(Number(item.toTime) * 100) + "%"; @@ -173,16 +129,16 @@ const DiscountManagement: React.FC = () => { // }); const discountsGridData: GridRowsProp = discounts.map(discount => { - return { // TODO + return { id: discount._id, name: discount.name, description: discount.description, conditionType: discount.conditionType, + factor: formatDiscountFactor(findDiscountFactor(discount)), + active: discount.disabled ? "🚫" : "✅", }; }); - console.log(discountsGridData); - return ( <> @@ -263,10 +219,9 @@ const DiscountManagement: React.FC = () => { } }} > - Шаблонизатор - Опросник - Аналитика сокращателя - АБ тесты + Шаблонизатор + Опросник + Аналитика сокращателя { - + { }}> diff --git a/src/stores/discounts.ts b/src/stores/discounts.ts index f1450bf..89740cf 100644 --- a/src/stores/discounts.ts +++ b/src/stores/discounts.ts @@ -1,49 +1,55 @@ import { GridSelectionModel } from "@mui/x-data-grid"; import { AnyDiscount } from "@root/model/cart"; import { create } from "zustand"; -import { devtools, persist } from "zustand/middleware"; +import { devtools } from "zustand/middleware"; import { exampleCartValues } from "./mocks/exampleCartValues"; interface DiscountStore { discounts: AnyDiscount[]; selectedDiscountIds: GridSelectionModel, - addDiscounts: (newDiscounts: AnyDiscount[]) => void; - deleteDiscounts: (discountIds: string[]) => void; - activateDiscounts: (discountIds: string[]) => void; - deactivateDiscounts: (discountIds: string[]) => void; } export const useDiscountStore = create()( devtools( - // persist( - (set, get) => ({ - discounts: exampleCartValues.discounts, - selectedDiscountIds: [], - addDiscounts: newDiscounts => set(state => ({ discounts: [...state.discounts, ...newDiscounts] })), - deleteDiscounts: discountIdsToDelete => set(state => ( - { discounts: state.discounts.filter(discount => !discountIdsToDelete.includes(discount._id)) } - )), - activateDiscounts: discountIds => set(state => { - const filteredDiscounts = state.discounts.filter(discount => discountIds.includes(discount._id)); - - // TODO activate discounts, use immer js? - throw new Error("unimplemented"); - }), - deactivateDiscounts: discountIds => set(state => { - const filteredDiscounts = state.discounts.filter(discount => discountIds.includes(discount._id)); - - // TODO deactivate discounts, use immer js? - throw new Error("unimplemented"); - }), - }), - // { - // name: "discounts", - // getStorage: () => localStorage, - // } - // ), + (set, get) => ({ + discounts: exampleCartValues.discounts, + selectedDiscountIds: [], + }), { name: "Discount store" } ) -); \ No newline at end of file +); + +export const addDiscounts = (newDiscounts: AnyDiscount[]) => useDiscountStore.setState(state => ({ discounts: [...state.discounts, ...newDiscounts] })); + +export const setSelectedDiscountIds = (selectedDiscountIds: DiscountStore["selectedDiscountIds"]) => useDiscountStore.setState({ selectedDiscountIds }); + +export const activateDiscounts = () => useDiscountStore.setState(state => { + const discounts: AnyDiscount[] = []; + state.discounts.forEach(discount => { + if (!state.selectedDiscountIds.includes(discount._id)) return discounts.push(discount); + + discounts.push({ + ...discount, + disabled: false, + }); + }); + + return { discounts }; +}); + +export const deactivateDiscounts = () => useDiscountStore.setState(state => { + const discounts: AnyDiscount[] = []; + state.discounts.forEach(discount => { + if (!state.selectedDiscountIds.includes(discount._id)) return discounts.push(discount); + + discounts.push({ + ...discount, + disabled: true, + }); + }); + + return { discounts }; +}); \ No newline at end of file