Merge branch 'renders-refactor' into 'dev'

refactor: rerenders

See merge request frontend/admin!28
This commit is contained in:
Nastya 2023-07-13 10:07:46 +00:00
commit a1c814f182
15 changed files with 246 additions and 318 deletions

@ -1,30 +0,0 @@
import { authStore } from "@root/stores/auth";
import { setDiscounts } from "@root/stores/discounts";
import type { GetDiscountResponse } from "@root/model/discount";
const makeRequest = authStore.getState().makeRequest;
export const useDiscounts = () => {
const requestDiscounts = async () => {
const controller = new AbortController();
makeRequest<never, GetDiscountResponse>({
url: "https://admin.pena.digital/price/discounts",
method: "get",
useToken: true,
bearer: true,
signal: controller.signal,
})
.then((result) => {
setDiscounts(result.Discounts);
})
.catch((error) => {
console.log("Error fetching discounts", error);
});
return () => controller.abort();
};
return { requestDiscounts };
};

@ -1,88 +0,0 @@
import { useState, useEffect } from "react";
import { authStore } from "@root/stores/auth";
import { resetPrivilegeArray } from "@root/stores/privilegesStore";
import { exampleCartValues } from "@stores/mocks/exampleCartValues";
import type { RealPrivilege } from "@root/model/privilege";
export type Privilege = {
createdAt: string;
description: string;
isDeleted: boolean;
name: string;
price: number;
privilegeId: string;
serviceKey: string;
type: "count" | "day" | "mb";
updatedAt: string;
value: string;
_id: string;
};
type SeverPrivilegiesResponse = {
templategen: RealPrivilege[];
};
type UsePrivilegies = {
requestPrivilegies: () => Promise<void>;
isError: boolean;
isLoading: boolean;
errorMessage: string;
};
const baseUrl =
process.env.NODE_ENV === "production"
? "/strator"
: "https://admin.pena.digital/strator";
export const usePrivilegies = (): UsePrivilegies => {
const [privilegies, setPrivilegies] = useState<RealPrivilege[]>([]);
const [isLoading, setIsLoading] = useState(false);
const [isError, setIsError] = useState(false);
const [errorMessage, setErrorMessage] = useState("");
const { makeRequest } = authStore.getState();
useEffect(() => {
let extracted: RealPrivilege[] = [];
for (let serviceKey in privilegies) {
//Приходит объект. В его значениях массивы привилегий для разных сервисов. Высыпаем в общую кучу и обновляем стор
extracted = extracted.concat(privilegies[serviceKey]);
}
let readyArray = extracted.map((privilege) => ({
serviceKey: privilege.serviceKey,
privilegeId: privilege.privilegeId,
name: privilege.name,
description: privilege.description,
type: privilege.type,
price: privilege.price,
value: privilege.value,
id: privilege._id,
}));
resetPrivilegeArray([...readyArray, ...exampleCartValues.privileges]);
}, [privilegies]);
const requestPrivilegies = async () => {
setIsLoading(true);
await makeRequest<never, SeverPrivilegiesResponse>({
url: baseUrl + "/privilege/service",
method: "get",
})
.then(({ templategen }) => setPrivilegies(templategen))
.catch(() => {
setIsError(true);
setErrorMessage("Ошибка при получении привилегий");
})
.finally(() => setIsLoading(false));
};
return {
requestPrivilegies,
isError,
isLoading,
errorMessage,
};
};

@ -1,77 +0,0 @@
import { useEffect, useState } from "react";
import { Tariff, Tariff_BACKEND } from "@root/model/tariff";
import { resetTariffsStore } from "@root/stores/tariffsStore";
import { authStore } from "@root/stores/auth";
type UseGetTariffs = {
requestTariffs: (page?: number, tariffs?: Tariff_BACKEND[]) => Promise<void>;
isLoading: boolean;
};
type GetTariffsResponse = {
totalPages: number;
tariffs: Tariff_BACKEND[];
};
const baseUrl =
process.env.NODE_ENV === "production"
? "/strator"
: "https://admin.pena.digital/strator";
export const useTariffs = (): UseGetTariffs => {
const [isLoading, setIsLoading] = useState(false);
const [tariffsList, setTariffsList] = useState<Tariff_BACKEND[]>([]);
const { makeRequest } = authStore.getState();
useEffect(() => {
const convertedTariffs: Record<string, Tariff> = {};
tariffsList
.filter(({ isDeleted }) => !isDeleted)
.forEach((tariff) => {
convertedTariffs[tariff._id] = {
id: tariff._id,
name: tariff.name,
isCustom: tariff.price ? true : false,
amount: tariff.privilegies[0].amount,
isFront: false,
privilegeId: tariff.privilegies[0].privilegeId,
price: tariff.privilegies[0].price,
isDeleted: tariff.isDeleted,
customPricePerUnit: tariff.price,
};
});
resetTariffsStore(convertedTariffs);
}, [tariffsList]);
const requestTariffs = async (
page: number = 1,
existingTariffs: Tariff_BACKEND[] = []
): Promise<void> => {
setIsLoading(true);
try {
const { tariffs, totalPages } = await makeRequest<
never,
GetTariffsResponse
>({
url: baseUrl + `/tariff/?page=${page}&limit=${100}`,
method: "get",
bearer: true,
});
if (page < totalPages) {
return requestTariffs(page + 1, [...existingTariffs, ...tariffs]);
}
setTariffsList([...existingTariffs, ...tariffs]);
} catch {
throw new Error("Ошибка при получении тарифов");
} finally {
setIsLoading(false);
}
};
return { requestTariffs, isLoading };
};

@ -25,20 +25,19 @@ import {
formatDiscountFactor,
} from "./calc";
import { AnyDiscount, CartItemTotal } from "@root/model/cart";
import { CartItemTotal } from "@root/model/cart";
import { Privilege } from "@root/model/tariff";
import { useDiscountStore, setDiscounts } from "@root/stores/discounts";
import { useCartStore } from "@root/stores/cart";
import { findPrivilegeById } from "@root/stores/privilegesStore";
import { testUser } from "@root/stores/mocks/user";
import { useTariffStore } from "@root/stores/tariffsStore";
import { Discount } from "@root/model/discount";
import { authStore } from "@root/stores/auth";
import { useDiscountStore } from "@root/stores/discounts";
import { requestPrivilegies } from "@root/services/privilegies.service";
import { requestDiscounts } from "@root/services/discounts.service";
interface Props {
requestPrivilegies: () => Promise<void>;
requestDiscounts: () => Promise<() => void>;
selectedTariffs: GridSelectionModel;
}
@ -58,19 +57,13 @@ interface MergedTariff {
isFront: boolean;
}
export default function Cart({
requestPrivilegies,
requestDiscounts,
selectedTariffs,
}: Props) {
export default function Cart({ selectedTariffs }: Props) {
let cartTariffs = Object.values(useTariffStore().tariffs);
// const discounts = useDiscountStore((store) => store.discounts);
const [discounts, setDiscounts] = useState<Discount[]>([]);
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 makeRequest = authStore.getState().makeRequest;
const [errorMessage, setErrorMessage] = useState<string | null>(null);
const [isNonCommercial, setIsNonCommercial] = useState<boolean>(false);
@ -157,17 +150,6 @@ export default function Cart({
await requestPrivilegies();
await requestDiscounts();
//рассчитать
const dis = await makeRequest<unknown>({
url: "https://admin.pena.digital/price/discounts",
method: "get",
useToken: true,
bearer: true,
});
console.log(dis);
// @ts-ignore
setDiscounts(dis.Discounts);
const cartItems = cartTariffs
.filter((tariff) => selectedTariffs.includes(tariff.id))
.map((tariff) => createCartItem(tariff));
@ -178,15 +160,11 @@ export default function Cart({
if (!isFinite(loyaltyValue)) loyaltyValue = 0;
const activeDiscounts = discounts.filter(
(discount) => !discount.Deprecated
);
const cartData = calcCartData({
user: testUser,
purchasesAmount: loyaltyValue,
cartItems,
discounts: activeDiscounts,
discounts,
isNonCommercial,
coupon: couponField,
});

@ -17,7 +17,7 @@ import DeleteIcon from "@mui/icons-material/Delete";
import EditIcon from "@mui/icons-material/Edit";
import { deleteDiscount } from "@root/api/discounts";
import { GridSelectionModel } from "@mui/x-data-grid";
import { useDiscounts } from "@root/hooks/useDiscounts.hook";
import { requestDiscounts } from "@root/services/discounts.service";
import AutorenewIcon from "@mui/icons-material/Autorenew";
const columns: GridColDef[] = [
@ -119,7 +119,6 @@ export default function DiscountDataGrid({ selectedRowsHC }: Props) {
);
const realDiscounts = useDiscountStore((state) => state.discounts);
const editDiscountId = useDiscountStore((state) => state.editDiscountId);
const { requestDiscounts } = useDiscounts();
useEffect(() => {
requestDiscounts();

@ -13,6 +13,7 @@ import {
import { enqueueSnackbar } from "notistack";
import { CustomTextField } from "@root/kitUI/CustomTextField";
import { requestTariffs } from "@root/services/tariffs.service";
import { authStore } from "@root/stores/auth";
import {
@ -22,10 +23,6 @@ import {
import type { Privilege_BACKEND } from "@root/model/tariff";
type CreateTariffProps = {
requestTariffs: () => Promise<void>;
};
type CreateTariffBackendRequest = {
name: string;
price: number;
@ -38,7 +35,7 @@ const baseUrl =
? "/strator"
: "https://admin.pena.digital/strator";
export default function CreateTariff({ requestTariffs }: CreateTariffProps) {
export default function CreateTariff() {
const { makeRequest } = authStore();
const theme = useTheme();

@ -3,8 +3,8 @@ import Box from "@mui/material/Box";
import Button from "@mui/material/Button";
import Typography from "@mui/material/Typography";
import Modal from "@mui/material/Modal";
import { GridSelectionModel } from "@mui/x-data-grid";
import { useTariffStore } from "@root/stores/tariffsStore";
import { requestTariffs } from "@root/services/tariffs.service";
import { enqueueSnackbar } from "notistack";
import { authStore } from "@root/stores/auth";
@ -12,7 +12,6 @@ type DeleteModalProps = {
open: boolean | string;
handleClose: () => void;
selectedTariffs: any;
requestTariffs: () => Promise<void>;
};
type DeleteTariffRequest = {
@ -28,7 +27,6 @@ export default function DeleteModal({
open,
handleClose,
selectedTariffs,
requestTariffs,
}: DeleteModalProps) {
const { makeRequest } = authStore();
const tariffs = useTariffStore((state) => state.tariffs);

@ -9,6 +9,7 @@ import { authStore } from "@root/stores/auth";
import { Privilege, Tariff } from "@root/model/tariff";
import { useTariffStore } from "@root/stores/tariffsStore";
import { findPrivilegeById } from "@root/stores/privilegesStore";
import { requestTariffs } from "@root/services/tariffs.service";
import { enqueueSnackbar } from "notistack";
interface EditProps {
@ -52,13 +53,9 @@ const editTariff = ({
};
interface Props {
tariff: Tariff;
requestTariffs: () => Promise<void>;
}
export default function EditModal({
tariff = undefined,
requestTariffs,
}: Props) {
export default function EditModal({ tariff = undefined }: Props) {
const [open, setOpen] = useState(false);
const [name, setName] = useState("");
const [price, setPrice] = useState("");

@ -3,6 +3,7 @@ import DataGrid from "@kitUI/datagrid";
import { Tooltip, IconButton } from "@mui/material";
import { usePrivilegeStore } from "@root/stores/privilegesStore";
import AutorenewIcon from "@mui/icons-material/Autorenew";
import { requestPrivilegies } from "@root/services/privilegies.service";
const columns: GridColDef[] = [
{ field: "id", headerName: "id", width: 150 },
@ -12,13 +13,8 @@ const columns: GridColDef[] = [
{ field: "price", headerName: "Стоимость", width: 100 },
];
type Props = {
requestPrivilegies: () => Promise<void>;
};
export default function Privileges({ requestPrivilegies }: Props) {
export default function Privileges() {
const privileges = usePrivilegeStore((state) => state.privileges);
// const { mergedPrivileges } = useCombinedPrivileges();
const privilegesGridData = privileges
.filter((privilege) => !privilege.isDeleted)
.map((privilege) => ({

@ -0,0 +1,26 @@
import { useState } from "react";
import { Typography } from "@mui/material";
import { GridSelectionModel } from "@mui/x-data-grid";
import Cart from "@root/kitUI/Cart/Cart";
import TariffsDG from "./tariffsDG";
export default function TariffsInfo() {
const [selectedTariffs, setSelectedTariffs] = useState<GridSelectionModel>(
[]
);
return (
<>
<Typography variant="h6" mt="20px">
Список тарифов
</Typography>
<TariffsDG
selectedTariffs={selectedTariffs}
handleSelectionChange={setSelectedTariffs}
/>
<Cart selectedTariffs={selectedTariffs} />
</>
);
}

@ -1,26 +1,15 @@
import { useState, useEffect } from "react";
import { useEffect } from "react";
import { Container, Typography } from "@mui/material";
import { GridSelectionModel } from "@mui/x-data-grid";
import Cart from "@root/kitUI/Cart/Cart";
import { requestTariffs } from "@root/services/tariffs.service";
import { requestPrivilegies } from "@root/services/privilegies.service";
import { useTariffs } from "@root/hooks/useTariffs.hook";
import { usePrivilegies } from "@root/hooks/usePrivilegies.hook";
import { useDiscounts } from "@root/hooks/useDiscounts.hook";
import TariffsDG from "./tariffsDG";
import CreateTariff from "./CreateTariff";
import Privileges from "./Privileges/Privileges";
import ChangePriceModal from "./Privileges/ChangePriceModal";
import TariffsInfo from "./TariffsInfo";
export default function Tariffs() {
const [selectedTariffs, setSelectedTariffs] = useState<GridSelectionModel>(
[]
);
const { requestTariffs } = useTariffs();
const { requestPrivilegies } = usePrivilegies();
const { requestDiscounts } = useDiscounts();
useEffect(() => {
requestTariffs();
requestPrivilegies();
@ -37,27 +26,10 @@ export default function Tariffs() {
}}
>
<Typography variant="h6">Список привилегий</Typography>
<Privileges requestPrivilegies={requestPrivilegies} />
<Privileges />
<ChangePriceModal />
<CreateTariff requestTariffs={requestTariffs} />
<Typography variant="h6" mt="20px">
Список тарифов
</Typography>
<TariffsDG
selectedTariffs={selectedTariffs}
handleSelectionChange={setSelectedTariffs}
requestTariffs={requestTariffs}
/>
<Cart
requestPrivilegies={requestPrivilegies}
requestDiscounts={requestDiscounts}
selectedTariffs={selectedTariffs}
/>
<CreateTariff />
<TariffsInfo />
</Container>
);
}

@ -1,5 +1,5 @@
// @ts-nocheck
import React from "react";
import React, { useEffect } from "react";
import { useState } from "react";
import { GridColDef, GridSelectionModel, GridToolbar } from "@mui/x-data-grid";
import { Box, Button, IconButton, Tooltip } from "@mui/material";
@ -15,21 +15,57 @@ import DeleteModal from "@root/pages/dashboard/Content/Tariffs/DeleteModal";
import EditModal from "./EditModal";
import { Tariff } from "@root/model/tariff";
import AutorenewIcon from "@mui/icons-material/Autorenew";
import { requestTariffs } from "@root/services/tariffs.service";
interface Props {
selectedTariffs: GridSelectionModel;
handleSelectionChange: (selectionModel: GridSelectionModel) => void;
requestTariffs: () => Promise<void>;
}
export default function TariffsDG({
selectedTariffs,
handleSelectionChange,
requestTariffs,
}: Props) {
const tariffs = Object.values(useTariffStore().tariffs);
const tariffs = useTariffStore((state) => state.tariffs);
const [openDeleteModal, setOpenDeleteModal] = useState(false);
const [changingTariff, setChangingTariff] = useState<Tariff | undefined>();
const [gridData, setGridData] = useState([]);
useEffect(() => {
const data = Object.values(tariffs)
?.map((tariff) => {
console.log(tariff);
const privilege = findPrivilegeById(tariff.privilegeId);
return {
id: tariff.id,
name: tariff.name,
serviceName:
privilege?.serviceKey == "templategen"
? "Шаблонизатор"
: privilege?.serviceKey,
privilegeName: privilege?.name,
amount: tariff.amount,
pricePerUnit: tariff.isCustom
? (tariff.customPricePerUnit || 0) / 100
: (tariff?.price || 0) / 100,
type:
findPrivilegeById(tariff.privilegeId)?.value === "шаблон"
? "штука"
: findPrivilegeById(tariff.privilegeId)?.value,
customPricePerUnit: tariff.customPricePerUnit === 0 ? "Нет" : "Да",
total: tariff.amount
? (tariff.amount *
(tariff.isCustom
? tariff.customPricePerUnit || 0 * tariff.amount
: findPrivilegeById(tariff.privilegeId)?.price || 0)) /
100
: 0,
};
})
.sort((item, previous) => (!item?.isFront && previous?.isFront ? 1 : -1));
setGridData(data);
}, [tariffs]);
console.log(selectedTariffs);
@ -77,38 +113,6 @@ export default function TariffsDG({
},
];
const gridData = tariffs
?.map((tariff) => {
console.log(tariff);
const privilege = findPrivilegeById(tariff.privilegeId);
return {
id: tariff.id,
name: tariff.name,
serviceName:
privilege?.serviceKey == "templategen"
? "Шаблонизатор"
: privilege?.serviceKey,
privilegeName: privilege?.name,
amount: tariff.amount,
pricePerUnit: tariff.isCustom
? (tariff.customPricePerUnit || 0) / 100
: (tariff?.price || 0) / 100,
type:
findPrivilegeById(tariff.privilegeId)?.value === "шаблон"
? "штука"
: findPrivilegeById(tariff.privilegeId)?.value,
customPricePerUnit: tariff.customPricePerUnit === 0 ? "Нет" : "Да",
total: tariff.amount
? (tariff.amount *
(tariff.isCustom
? tariff.customPricePerUnit || 0 * tariff.amount
: findPrivilegeById(tariff.privilegeId)?.price || 0)) /
100
: 0,
};
})
.sort((item, previous) => (!item?.isFront && previous?.isFront ? 1 : -1));
// console.log(gridData)
return (
@ -153,9 +157,8 @@ export default function TariffsDG({
closeDeleteModal();
}}
selectedTariffs={selectedTariffs}
requestTariffs={requestTariffs}
/>
<EditModal tariff={changingTariff} requestTariffs={requestTariffs} />
<EditModal tariff={changingTariff} />
</>
);
}

@ -0,0 +1,32 @@
import { setDiscounts } from "@root/stores/discounts";
import { authStore } from "@root/stores/auth";
import type { GetDiscountResponse, Discount } from "@root/model/discount";
const baseUrl =
process.env.NODE_ENV === "production"
? "/price"
: "https://admin.pena.digital/price";
const { makeRequest } = authStore.getState();
const filterDiscounts = (discounts: Discount[]) => {
const activeDiscounts = discounts.filter((discount) => !discount.Deprecated);
setDiscounts(activeDiscounts);
};
export const requestDiscounts = async (): Promise<void> => {
try {
const { Discounts } = await makeRequest<never, GetDiscountResponse>({
url: baseUrl + "/discounts",
method: "get",
useToken: true,
bearer: true,
});
filterDiscounts(Discounts);
} catch {
throw new Error("Ошибка при получении скидок");
}
};

@ -0,0 +1,63 @@
import { authStore } from "@root/stores/auth";
import { resetPrivilegeArray } from "@root/stores/privilegesStore";
import { exampleCartValues } from "@stores/mocks/exampleCartValues";
import type { RealPrivilege } from "@root/model/privilege";
export type Privilege = {
createdAt: string;
description: string;
isDeleted: boolean;
name: string;
price: number;
privilegeId: string;
serviceKey: string;
type: "count" | "day" | "mb";
updatedAt: string;
value: string;
_id: string;
};
type SeverPrivilegiesResponse = {
templategen: RealPrivilege[];
};
const baseUrl =
process.env.NODE_ENV === "production"
? "/strator"
: "https://admin.pena.digital/strator";
const { makeRequest } = authStore.getState();
const mutatePrivilegies = (privilegies: RealPrivilege[]) => {
let extracted: RealPrivilege[] = [];
for (let serviceKey in privilegies) {
//Приходит объект. В его значениях массивы привилегий для разных сервисов. Высыпаем в общую кучу и обновляем стор
extracted = extracted.concat(privilegies[serviceKey]);
}
let readyArray = extracted.map((privilege) => ({
serviceKey: privilege.serviceKey,
privilegeId: privilege.privilegeId,
name: privilege.name,
description: privilege.description,
type: privilege.type,
price: privilege.price,
value: privilege.value,
id: privilege._id,
}));
resetPrivilegeArray([...readyArray, ...exampleCartValues.privileges]);
};
export const requestPrivilegies = async () => {
await makeRequest<never, SeverPrivilegiesResponse>({
url: baseUrl + "/privilege/service",
method: "get",
})
.then(({ templategen }) => mutatePrivilegies(templategen))
.catch(() => {
console.log("Ошибка при получении привилегий");
});
};

@ -0,0 +1,62 @@
import { resetTariffsStore } from "@root/stores/tariffsStore";
import { authStore } from "@root/stores/auth";
import type { Tariff, Tariff_BACKEND } from "@root/model/tariff";
type GetTariffsResponse = {
totalPages: number;
tariffs: Tariff_BACKEND[];
};
const baseUrl =
process.env.NODE_ENV === "production"
? "/strator"
: "https://admin.pena.digital/strator";
const { makeRequest } = authStore.getState();
const mutateTariffs = (tariffs: Tariff_BACKEND[]) => {
const convertedTariffs: Record<string, Tariff> = {};
tariffs
.filter(({ isDeleted }) => !isDeleted)
.forEach((tariff) => {
convertedTariffs[tariff._id] = {
id: tariff._id,
name: tariff.name,
isCustom: tariff.price ? true : false,
amount: tariff.privilegies[0].amount,
isFront: false,
privilegeId: tariff.privilegies[0].privilegeId,
price: tariff.privilegies[0].price,
isDeleted: tariff.isDeleted,
customPricePerUnit: tariff.price,
};
});
resetTariffsStore(convertedTariffs);
};
export const requestTariffs = async (
page: number = 1,
existingTariffs: Tariff_BACKEND[] = []
): Promise<void> => {
try {
const { tariffs, totalPages } = await makeRequest<
never,
GetTariffsResponse
>({
url: baseUrl + `/tariff/?page=${page}&limit=${100}`,
method: "get",
bearer: true,
});
if (page < totalPages) {
return requestTariffs(page + 1, [...existingTariffs, ...tariffs]);
}
mutateTariffs([...existingTariffs, ...tariffs]);
} catch {
throw new Error("Ошибка при получении тарифов");
}
};