Merge branch 'dev' into 'main'

Dev

See merge request frontend/admin!17
This commit is contained in:
Mikhail 2023-05-18 20:41:36 +00:00
commit 58fa8e8154
6 changed files with 74 additions and 108 deletions

@ -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 (
<Tooltip title={

@ -223,20 +223,20 @@ export function createCartItem(tariff: Tariff): CartItem {
return { tariff, price, id: "someId" };
}
export function findDiscountFactor(discount: AnyDiscount, privilegeId?: string) {
export function findDiscountFactor(discount: AnyDiscount): number {
switch (discount.conditionType) {
case "cartPurchasesAmount":
return discount.factor;
case "purchasesAmount":
return discount.factor;
case "privilege": {
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;
}
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;

@ -7,6 +7,7 @@ interface DiscountBase {
description: string;
/** Этап применения скидки */
layer: number;
disabled?: boolean;
}
export interface PurchasesAmountDiscount extends DiscountBase {

@ -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<boolean>(false);
const [serviceType, setServiceType] = useState<ServiceType>("templategen");
const [startDate, setStartDate] = useState<Date>(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 (
<>
<LocalizationProvider dateAdapter={AdapterDayjs}>
@ -263,10 +219,9 @@ const DiscountManagement: React.FC = () => {
}
}}
>
<MenuItem value={"Шаблонизатор"}>Шаблонизатор</MenuItem>
<MenuItem value={"Опросник"}>Опросник</MenuItem>
<MenuItem value={"Аналитика сокращателя"}>Аналитика сокращателя</MenuItem>
<MenuItem value={"АБ тесты"}>АБ тесты</MenuItem>
<MenuItem value={"templategen"}>Шаблонизатор</MenuItem>
<MenuItem value={"squiz"}>Опросник</MenuItem>
<MenuItem value={"dwarfener"}>Аналитика сокращателя</MenuItem>
</Select>
<TextField
@ -515,11 +470,13 @@ const DiscountManagement: React.FC = () => {
</Box>
<Box style={{ width: "80%", marginTop: "55px" }}>
<Box style={{ height: 400 }}>
<Box style={{ height: 600 }}>
<DataGrid
checkboxSelection={true}
rows={discountsGridData}
columns={columns}
selectionModel={selectedDiscountIds}
onSelectionModelChange={setSelectedDiscountIds}
sx={{
color: theme.palette.secondary.main,
"& .MuiDataGrid-iconSeparator": {
@ -563,7 +520,7 @@ const DiscountManagement: React.FC = () => {
}}>
<Button
variant="contained"
onClick={activateDiscounts}
onClick={deactivateDiscounts}
sx={{
backgroundColor: theme.palette.menu.main,
width: "200px",
@ -580,7 +537,7 @@ const DiscountManagement: React.FC = () => {
<Button
variant="contained"
onClick={deactivateDiscounts}
onClick={activateDiscounts}
sx={{
backgroundColor: theme.palette.menu.main,
width: "200px",
@ -591,7 +548,7 @@ const DiscountManagement: React.FC = () => {
backgroundColor: theme.palette.grayMedium.main
}
}}>
Применить
Активировать
</Button>
</BoxButton>
</Box>

@ -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: <PersonOutlineOutlinedIcon />, title: "Информация о проекте", className: "menu" },
{ path: "/entities", element: <SettingsOutlinedIcon />, title: "Юридические лица", className: "menu" },
{ path: "/tariffs", element: <BathtubOutlinedIcon />, title: "Шаблонизатор документов", className: "menu" },
{ path: "/tariffs", element: <BathtubOutlinedIcon />, title: "Тарифы", className: "menu" },
{ path: "/discounts", element: <AddPhotoAlternateOutlinedIcon />, title: "Скидки", className: "menu" },
{ path: "/promocode", element: <NaturePeopleOutlinedIcon />, title: "Промокод", className: "menu" },
{ path: "/settingRoles", element: <SettingsIcon />, title: "Настройки", className: "menu" },

@ -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<DiscountStore>()(
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"
}
)
);
);
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 };
});