Merge branch 'dev' into 'main'

Dev

See merge request frontend/admin!49
This commit is contained in:
Nastya 2023-12-13 10:13:02 +00:00
commit 9b69097e49
7 changed files with 725 additions and 444 deletions

@ -82,7 +82,7 @@ export function createDiscountObject({
case "privilege":
discount.Layer = 1;
discount.Condition.Product = privilegeId;
discount.Condition.Term = discountMinValue;
discount.Condition.Term = discountMinValue / 100;
discount.Target.Products = [
{
Factor: discountFactor,

@ -1,11 +1,15 @@
import { SxProps, TextField, Theme, useTheme } from "@mui/material";
import { HTMLInputTypeAttribute, ChangeEvent } from "react";
import {InputBaseProps} from "@mui/material/InputBase";
export function CustomTextField({ id, label, value, type, sx, onChange: setValue }: {
export function CustomTextField({ id, label, value, name, onBlur,error, type, sx, onChange: setValue }: {
id: string;
label: string;
value: number | string | null;
name?: string;
onBlur?: InputBaseProps['onBlur'];
error?: boolean;
type?: HTMLInputTypeAttribute;
sx?: SxProps<Theme>;
onChange: (e: ChangeEvent<HTMLInputElement>) => void;
@ -18,6 +22,9 @@ export function CustomTextField({ id, label, value, type, sx, onChange: setValue
id={id}
label={label}
variant="filled"
name={name}
onBlur={onBlur}
error={error}
color="secondary"
type={type}
sx={sx}

@ -222,4 +222,4 @@ const SigninForm = () => {
);
};
export default SigninForm;
export default SigninForm;

@ -1,8 +1,9 @@
import * as React from "react";
import { Box, Typography } from "@mui/material";
import {Box, Button, Typography} from "@mui/material";
import { ThemeProvider } from "@mui/material";
import theme from "../../theme";
import CssBaseline from '@mui/material/CssBaseline';
import {Link} from "react-router-dom";
const Error404: React.FC = () => {
@ -46,6 +47,13 @@ const Error404: React.FC = () => {
4
</Typography>
</Box>
<Box>
<Link
to="/users">
<Button>На главную</Button>
</Link>
</Box>
</Box>
</Box>
</ThemeProvider>

@ -1,20 +1,18 @@
import {
Box,
Typography,
Button,
useTheme,
FormControl,
FormLabel,
RadioGroup,
FormControlLabel,
Radio,
InputLabel,
Box,
Typography,
Button,
useTheme,
FormControl,
FormLabel,
RadioGroup,
FormControlLabel,
Radio,
InputLabel, TextField,
} from "@mui/material";
import MenuItem from "@mui/material/MenuItem";
import Select, { SelectChangeEvent } from "@mui/material/Select";
import { useState } from "react";
import { SERVICE_LIST, ServiceType } from "@root/model/tariff";
import { CustomTextField } from "@root/kitUI/CustomTextField";
import {
resetPrivilegeArray,
usePrivilegeStore,
@ -24,76 +22,67 @@ import { enqueueSnackbar } from "notistack";
import { DiscountType, discountTypes } from "@root/model/discount";
import { createDiscount } from "@root/api/discounts";
import usePrivileges from "@root/utils/hooks/usePrivileges";
import { Formik, Field, Form, FormikHelpers } from "formik";
interface Values {
discountNameField: string,
discountDescriptionField: string,
discountFactorField: string,
serviceType: string,
discountType: DiscountType,
purchasesAmountField: string,
cartPurchasesAmountField: string,
discountMinValueField: string,
privilegeIdField: string,
}
export default function CreateDiscount() {
const theme = useTheme();
const privileges = usePrivilegeStore((state) => state.privileges);
const [serviceType, setServiceType] = useState<ServiceType>("templategen");
const [discountType, setDiscountType] =
useState<DiscountType>("purchasesAmount");
const [discountNameField, setDiscountNameField] = useState<string>("");
const [discountDescriptionField, setDiscountDescriptionField] =
useState<string>("");
const [privilegeIdField, setPrivilegeIdField] = useState<string | "">("");
const [discountFactorField, setDiscountFactorField] = useState<string>("0");
const [purchasesAmountField, setPurchasesAmountField] = useState<string>("0");
const [cartPurchasesAmountField, setCartPurchasesAmountField] =
useState<string>("0");
const [discountMinValueField, setDiscountMinValueField] =
useState<string>("0");
usePrivileges({ onNewPrivileges: resetPrivilegeArray });
const handleDiscountTypeChange = (
event: React.ChangeEvent<HTMLInputElement>
const initialValues: Values = {
discountNameField: "",
discountDescriptionField: "",
discountFactorField: "",
serviceType: "",
discountType: "purchasesAmount",
purchasesAmountField: "",
cartPurchasesAmountField: "",
discountMinValueField: "",
privilegeIdField: "",
}
const handleCreateDiscount = async(
values: Values,
formikHelpers: FormikHelpers<Values>
) => {
setDiscountType(event.target.value as DiscountType);
};
const handleServiceTypeChange = (event: SelectChangeEvent) => {
setServiceType(event.target.value as ServiceType);
};
async function handleCreateDiscount() {
const purchasesAmount = parseFloat(purchasesAmountField.replace(",", "."));
console.log("работаю")
const purchasesAmount = Number(parseFloat(values.purchasesAmountField.replace(",", "."))) * 100;
const discountFactor =
(100 - parseFloat(discountFactorField.replace(",", "."))) / 100;
const cartPurchasesAmount = parseFloat(
cartPurchasesAmountField.replace(",", ".")
(100 - parseFloat(values.discountFactorField.replace(",", "."))) / 100;
const cartPurchasesAmount = Number(parseFloat(
values.cartPurchasesAmountField.replace(",", ".")) * 100
);
const discountMinValue = parseFloat(
discountMinValueField.replace(",", ".")
const discountMinValue = Number(parseFloat(
values.discountMinValueField.replace(",", ".")) * 100
);
if (!isFinite(purchasesAmount))
return enqueueSnackbar("Поле purchasesAmount не число");
if (!isFinite(discountFactor))
return enqueueSnackbar("Поле discountFactor не число");
if (!isFinite(cartPurchasesAmount))
return enqueueSnackbar("Поле cartPurchasesAmount не число");
if (!isFinite(discountMinValue))
return enqueueSnackbar("Поле discountMinValue не число");
if (discountType === "privilege" && !privilegeIdField)
return enqueueSnackbar("Привилегия не выбрана");
if (!discountNameField) return enqueueSnackbar('Поле "Имя" пустое');
if (!discountDescriptionField)
return enqueueSnackbar('Поле "Описание" пустое');
if (discountFactor < 0)
return enqueueSnackbar("Процент скидки не может быть больше 100");
const [createdDiscountResponse, createdDiscountError] =
await createDiscount({
cartPurchasesAmount,
discountFactor,
discountMinValue,
purchasesAmount,
discountDescription: discountDescriptionField,
discountName: discountNameField,
discountDescription: values.discountDescriptionField,
discountName: values.discountNameField,
startDate: new Date().toISOString(),
endDate: new Date(Date.now() + 1000 * 3600 * 24 * 30).toISOString(),
serviceType,
discountType,
privilegeId: privilegeIdField,
serviceType: values.serviceType,
discountType: values.discountType,
privilegeId: values.privilegeIdField,
});
if (createdDiscountError) {
@ -107,226 +96,423 @@ export default function CreateDiscount() {
}
}
return (
<Box
sx={{
display: "flex",
flexDirection: "column",
justifyContent: "left",
alignItems: "left",
marginTop: "15px",
width: "100%",
padding: "16px",
maxWidth: "600px",
gap: "1em",
}}
>
<CustomTextField
id="discount-name"
label="Название"
value={discountNameField}
onChange={(e) => setDiscountNameField(e.target.value)}
/>
<CustomTextField
id="discount-desc"
label="Описание"
value={discountDescriptionField}
onChange={(e) => setDiscountDescriptionField(e.target.value)}
/>
<Typography
variant="h4"
sx={{
width: "90%",
fontWeight: "normal",
color: theme.palette.grayDisabled.main,
paddingLeft: "10px",
}}
>
Условия:
</Typography>
<CustomTextField
id="discount-factor"
label="Процент скидки"
value={discountFactorField}
type="number"
onChange={(e) => setDiscountFactorField(e.target.value)}
/>
<FormControl>
<FormLabel
id="discount-type"
sx={{
color: "white",
"&.Mui-focused": {
color: "white",
},
}}
const validateFulledFields = (values: Values) => {
const errors = {} as any;
if (values.discountNameField.length === 0) {
errors.discountNameField = 'Поле "Имя" пустое'
}
if (values.discountDescriptionField.length === 0) {
errors.discountDescriptionField = 'Поле "Описание" пустое'
}
if (((100 - parseFloat(values.discountFactorField.replace(",", "."))) / 100) < 0) {
errors.discountFactorField = "Процент скидки не может быть больше 100"
}
if (!isFinite(((100 - parseFloat(values.discountFactorField.replace(",", "."))) / 100))) {
errors.discountFactorField = 'Поле "Процент скидки" не число'
}
if (values.discountType === "privilege" && !values.privilegeIdField) {
errors.privilegeIdField = "Привилегия не выбрана"
}
if (values.discountType === "service" && !values.serviceType) {
errors.serviceType = "Сервис не выбран"
}
if (values.discountType === "purchasesAmount" && !isFinite(parseFloat(values.purchasesAmountField.replace(",", ".")))) {
errors.purchasesAmountField = 'Поле "Внесено больше" не число'
}
if (values.discountType === "cartPurchasesAmount" && !isFinite(parseFloat(values.cartPurchasesAmountField.replace(",", ".")))) {
errors.cartPurchasesAmountField = 'Поле "Объём в корзине" не число'
}
if (values.discountType === ("service" || "privilege") && !isFinite(parseFloat(values.discountMinValueField.replace(",", ".")))) {
errors.discountMinValueField = 'Поле "Минимальное значение" не число'
}
console.log(errors)
return errors;
}
return (
<Formik
initialValues={initialValues}
onSubmit={handleCreateDiscount}
validate={validateFulledFields}
>
Тип скидки
</FormLabel>
<RadioGroup
row
aria-labelledby="discount-type"
name="discount-type"
value={discountType}
onChange={handleDiscountTypeChange}
>
{Object.keys(discountTypes).map((type) => (
<FormControlLabel
key={type}
value={type}
control={<Radio color="secondary" />}
label={discountTypes[type as DiscountType]}
/>
))}
</RadioGroup>
</FormControl>
{discountType === "purchasesAmount" && (
<CustomTextField
id="discount-purchases"
label="Внесено больше"
type="number"
sx={{
marginTop: "15px",
}}
value={purchasesAmountField}
onChange={(e) => setPurchasesAmountField(e.target.value)}
/>
)}
{discountType === "cartPurchasesAmount" && (
<CustomTextField
id="discount-cart-purchases"
label="Объем в корзине"
type="number"
sx={{
marginTop: "15px",
}}
value={cartPurchasesAmountField}
onChange={(e) => setCartPurchasesAmountField(e.target.value)}
/>
)}
{discountType === "service" && (
<>
<Select
labelId="discount-service-label"
id="discount-service"
value={serviceType}
onChange={handleServiceTypeChange}
sx={{
color: theme.palette.secondary.main,
borderColor: theme.palette.secondary.main,
"&.Mui-focused .MuiOutlinedInput-notchedOutline": {
borderColor: theme.palette.secondary.main,
},
".MuiSvgIcon-root ": {
fill: theme.palette.secondary.main,
},
}}
>
{SERVICE_LIST.map((service) => (
<MenuItem key={service.serviceKey} value={service.serviceKey}>
{service.displayName}
</MenuItem>
))}
</Select>
<CustomTextField
id="discount-min-value"
label="Минимальное значение"
type="number"
sx={{
marginTop: "15px",
}}
value={discountMinValueField}
onChange={(e) => setDiscountMinValueField(e.target.value)}
/>
</>
)}
{discountType === "privilege" && (
<>
<FormControl
fullWidth
sx={{
color: theme.palette.secondary.main,
"& .MuiInputLabel-outlined": {
color: theme.palette.secondary.main,
},
"& .MuiInputLabel-outlined.MuiInputLabel-shrink": {
color: theme.palette.secondary.main,
},
}}
>
<InputLabel
id="privilege-select-label"
sx={{
color: theme.palette.secondary.main,
fontSize: "16px",
lineHeight: "19px",
}}
>
Привилегия
</InputLabel>
<Select
labelId="privilege-select-label"
id="privilege-select"
value={privilegeIdField}
label="Привилегия"
onChange={(e) => setPrivilegeIdField(e.target.value)}
sx={{
color: theme.palette.secondary.main,
borderColor: theme.palette.secondary.main,
"&.Mui-focused .MuiOutlinedInput-notchedOutline": {
borderColor: theme.palette.secondary.main,
},
".MuiSvgIcon-root ": {
fill: theme.palette.secondary.main,
},
}}
inputProps={{ sx: { pt: "12px" } }}
>
{privileges.map((privilege, index) => (
<MenuItem key={index} value={privilege.privilegeId}>
{privilege.description}
</MenuItem>
))}
</Select>
</FormControl>
<CustomTextField
id="discount-min-value"
label="Минимальное значение"
type="number"
sx={{
marginTop: "15px",
}}
value={discountMinValueField}
onChange={(e) => setDiscountMinValueField(e.target.value)}
/>
</>
)}
<Box
sx={{
width: "90%",
marginTop: "55px",
display: "flex",
flexDirection: "column",
justifyContent: "center",
alignItems: "center",
}}
>
<Button
variant="contained"
sx={{
backgroundColor: theme.palette.menu.main,
height: "52px",
fontWeight: "normal",
fontSize: "17px",
"&:hover": {
backgroundColor: theme.palette.grayMedium.main,
},
}}
onClick={handleCreateDiscount}
>
Cоздать
</Button>
</Box>
</Box>
);
{(props) => (
<Form style={{width: "100%", display: "flex", justifyContent: "center"}}>
<Box
sx={{
display: "flex",
flexDirection: "column",
justifyContent: "left",
alignItems: "left",
marginTop: "15px",
width: "100%",
padding: "16px",
maxWidth: "600px",
gap: "1em",
}}
>
<Field
as={TextField}
id="discount-name"
label="Название"
variant="filled"
name="discountNameField"
error={props.touched.discountNameField && !!props.errors.discountNameField}
helperText={
<Typography sx={{fontSize: "12px", width: "200px"}}>
{props.errors.discountNameField}
</Typography>
}
InputProps={{
style: {
backgroundColor: theme.palette.content.main,
color: theme.palette.secondary.main,
}
}}
InputLabelProps={{
style: {
color: theme.palette.secondary.main
}
}}
/>
<Field
as={TextField}
id="discount-desc"
label="Описание"
variant="filled"
name="discountDescriptionField"
type="text"
error={props.touched.discountDescriptionField && !!props.errors.discountDescriptionField}
helperText={
<Typography sx={{fontSize: "12px", width: "200px"}}>
{props.errors.discountDescriptionField}
</Typography>
}
InputProps={{
style: {
backgroundColor: theme.palette.content.main,
color: theme.palette.secondary.main,
}
}}
InputLabelProps={{
style: {
color: theme.palette.secondary.main
}
}}
/>
<Typography
variant="h4"
sx={{
width: "90%",
fontWeight: "normal",
color: theme.palette.grayDisabled.main,
paddingLeft: "10px",
}}
>
Условия:
</Typography>
<Field
as={TextField}
id="discount-factor"
label="Процент скидки"
variant="filled"
name="discountFactorField"
error={props.touched.discountFactorField && !!props.errors.discountFactorField}
value={props.values.discountFactorField}
helperText={
<Typography sx={{fontSize: "12px", width: "200px"}}>
{props.errors.discountFactorField}
</Typography>
}
InputProps={{
style: {
backgroundColor: theme.palette.content.main,
color: theme.palette.secondary.main,
}
}}
InputLabelProps={{
style: {
color: theme.palette.secondary.main
}
}}
/>
<FormControl>
<FormLabel
id="discount-type"
sx={{
color: "white",
"&.Mui-focused": {
color: "white",
},
}}
>
Тип скидки
</FormLabel>
<RadioGroup
row
aria-labelledby="discount-type"
name="discountType"
value={props.values.discountType}
onChange={(
event: React.ChangeEvent<HTMLInputElement>
) => {
props.setFieldValue("discountType", event.target.value as DiscountType);
}}
onBlur={props.handleBlur}
>
{Object.keys(discountTypes).map((type) => (
<FormControlLabel
key={type}
value={type}
control={<Radio color="secondary"/>}
label={discountTypes[type as DiscountType]}
/>
))}
</RadioGroup>
</FormControl>
{props.values.discountType === "purchasesAmount" && (
<TextField
id="discount-purchases"
name="purchasesAmountField"
variant="filled"
error={props.touched.purchasesAmountField && !!props.errors.purchasesAmountField}
label="Внесено больше"
onChange={(e) => {
props.setFieldValue("purchasesAmountField", e.target.value.replace(/[^\d]/g, ''))
}}
value={props.values.purchasesAmountField}
onBlur={props.handleBlur}
sx={{
marginTop: "15px",
}}
helperText={
<Typography sx={{fontSize: "12px", width: "200px"}}>
{props.errors.purchasesAmountField}
</Typography>
}
InputProps={{
style: {
backgroundColor: theme.palette.content.main,
color: theme.palette.secondary.main,
}
}}
InputLabelProps={{
style: {
color: theme.palette.secondary.main
}
}}
/>
)}
{props.values.discountType === "cartPurchasesAmount" && (
<TextField
id="discount-cart-purchases"
label="Объем в корзине"
name="cartPurchasesAmountField"
variant="filled"
error={props.touched.cartPurchasesAmountField && !!props.errors.cartPurchasesAmountField}
onChange={(e) => {
props.setFieldValue("cartPurchasesAmountField", e.target.value.replace(/[^\d]/g, ''))
}}
value={props.values.cartPurchasesAmountField}
onBlur={props.handleBlur}
sx={{
marginTop: "15px",
}}
helperText={
<Typography sx={{fontSize: "12px", width: "200px"}}>
{props.errors.cartPurchasesAmountField}
</Typography>
}
InputProps={{
style: {
backgroundColor: theme.palette.content.main,
color: theme.palette.secondary.main,
}
}}
InputLabelProps={{
style: {
color: theme.palette.secondary.main
}
}}
/>
)}
{props.values.discountType === "service" && (
<>
<Select
labelId="discount-service-label"
id="discount-service"
name="serviceType"
onBlur={props.handleBlur}
onChange={(e) => {
props.setFieldValue("serviceType", e.target.value as ServiceType);
}}
error={props.touched.serviceType && !!props.errors.serviceType}
sx={{
color: theme.palette.secondary.main,
borderColor: theme.palette.secondary.main,
"&.Mui-focused .MuiOutlinedInput-notchedOutline": {
borderColor: theme.palette.secondary.main,
},
".MuiSvgIcon-root ": {
fill: theme.palette.secondary.main,
},
}}
>
{SERVICE_LIST.map((service) => (
<MenuItem key={service.serviceKey} value={service.serviceKey}>
{service.displayName}
</MenuItem>
))}
</Select>
<TextField
id="discount-min-value"
name="discountMinValueField"
label="Минимальное значение"
onBlur={props.handleBlur}
variant="filled"
onChange={(e) => {
props.setFieldValue("discountMinValueField", e.target.value.replace(/[^\d]/g, ''))
}}
value={props.values.discountMinValueField}
error={props.touched.discountMinValueField && !!props.errors.discountMinValueField}
sx={{
marginTop: "15px",
}}
helperText={
<Typography sx={{fontSize: "12px", width: "200px"}}>
{props.errors.discountMinValueField}
</Typography>
}
InputProps={{
style: {
backgroundColor: theme.palette.content.main,
color: theme.palette.secondary.main,
}
}}
InputLabelProps={{
style: {
color: theme.palette.secondary.main
}
}}
/>
</>
)}
{props.values.discountType === "privilege" && (
<>
<FormControl
fullWidth
sx={{
color: theme.palette.secondary.main,
"& .MuiInputLabel-outlined": {
color: theme.palette.secondary.main,
},
"& .MuiInputLabel-outlined.MuiInputLabel-shrink": {
color: theme.palette.secondary.main,
},
}}
>
<InputLabel
id="privilege-select-label"
sx={{
color: theme.palette.secondary.main,
fontSize: "16px",
lineHeight: "19px",
}}
>
Привилегия
</InputLabel>
<Select
labelId="privilege-select-label"
id="privilege-select"
name="privilegeIdField"
onBlur={props.handleBlur}
onChange={(e) => {
props.setFieldValue("privilegeIdField", e.target.value);
}}
error={props.touched.privilegeIdField && !!props.errors.privilegeIdField}
label="Привилегия"
sx={{
color: theme.palette.secondary.main,
borderColor: theme.palette.secondary.main,
"&.Mui-focused .MuiOutlinedInput-notchedOutline": {
borderColor: theme.palette.secondary.main,
},
".MuiSvgIcon-root ": {
fill: theme.palette.secondary.main,
},
}}
inputProps={{sx: {pt: "12px"}}}
>
{privileges.map((privilege, index) => (
<MenuItem key={index} value={privilege.privilegeId}>
{privilege.description}
</MenuItem>
))}
</Select>
</FormControl>
<TextField
id="discount-min-value"
name="discountMinValueField"
label="Минимальное значение"
onBlur={props.handleBlur}
variant="filled"
onChange={(e) => {
props.setFieldValue("discountMinValueField", e.target.value.replace(/[^\d]/g, ''))
}}
value={props.values.discountMinValueField}
error={props.touched.discountMinValueField && !!props.errors.discountMinValueField}
sx={{
marginTop: "15px",
}}
helperText={
<Typography sx={{fontSize: "12px", width: "200px"}}>
{props.errors.discountMinValueField}
</Typography>
}
InputProps={{
style: {
backgroundColor: theme.palette.content.main,
color: theme.palette.secondary.main,
}
}}
InputLabelProps={{
style: {
color: theme.palette.secondary.main
}
}}
/>
</>
)}
<Box
sx={{
width: "90%",
marginTop: "55px",
display: "flex",
flexDirection: "column",
justifyContent: "center",
alignItems: "center",
}}
>
<Button
variant="contained"
type='submit'
sx={{
backgroundColor: theme.palette.menu.main,
height: "52px",
fontWeight: "normal",
fontSize: "17px",
"&:hover": {
backgroundColor: theme.palette.grayMedium.main,
},
}}
>
Создать
</Button>
</Box>
</Box>
</Form>
)}
</Formik>
);
}

@ -1,4 +1,3 @@
import { useState } from "react";
import {
Typography,
Container,
@ -8,11 +7,9 @@ import {
FormControl,
InputLabel,
useTheme,
Box,
Box, TextField,
} from "@mui/material";
import { enqueueSnackbar } from "notistack";
import { CustomTextField } from "@root/kitUI/CustomTextField";
import { requestTariffs } from "@root/services/tariffs.service";
import { createTariff } from "@root/api/tariffs";
@ -20,56 +17,67 @@ import {
findPrivilegeById,
usePrivilegeStore,
} from "@root/stores/privilegesStore";
import { PrivilegeWithAmount } from "@frontend/kitui";
import { currencyFormatter } from "@root/utils/currencyFormatter";
import { Formik, Field, Form, FormikHelpers } from "formik";
interface Values {
nameField: string,
amountField: string,
customPriceField: string,
privilegeIdField: string,
privilege: PrivilegeWithAmount | null
}
export default function CreateTariff() {
const theme = useTheme();
const privileges = usePrivilegeStore((store) => store.privileges);
const [nameField, setNameField] = useState<string>("");
const [amountField, setAmountField] = useState<string>("");
const [customPriceField, setCustomPriceField] = useState<string>("");
const [privilegeIdField, setPrivilegeIdField] = useState<string>("");
const checkFulledFields = (values: Values) => {
const errors = {} as any;
const privilege = findPrivilegeById(privilegeIdField);
if (values.nameField.length === 0) {
errors.nameField = "Пустое название тарифа"
}
if (values.amountField.length === 0) {
errors.amountField = "Пустое кол-во едениц привилегии"
}
if (values.privilegeIdField.length === 0) {
errors.privilegeIdField = "Не выбрана привилегия"
}
console.log(errors)
return errors;
const checkFulledFields = () => {
if (nameField.length === 0) {
enqueueSnackbar("Пустое название тарифа");
return false;
}
if (amountField.length === 0) {
enqueueSnackbar("Пустое кол-во едениц привилегии");
return false;
}
if (privilegeIdField.length === 0) {
enqueueSnackbar("Не выбрана привилегия");
return false;
}
if (!privilege) {
enqueueSnackbar("Привилегия с таким id не найдена");
return false;
}
return true;
};
const createTariffBackend = async () => {
if (checkFulledFields() && privilege !== null) {
const initialValues: Values = {
nameField: "",
amountField: "",
customPriceField: "",
privilegeIdField: "",
privilege: null
};
const createTariffBackend = async (
values: Values,
formikHelpers: FormikHelpers<Values>
) => {
if (values.privilege !== null) {
const [_, createdTariffError] = await createTariff({
name: nameField,
price: Number(customPriceField) * 100,
name: values.nameField,
price: Number(values.customPriceField) * 100,
isCustom: false,
privileges: [
{
name: privilege.name,
privilegeId: privilege.privilegeId ?? "",
serviceKey: privilege.serviceKey,
description: privilege.description,
type: privilege.type,
value: privilege.value ?? "",
price: privilege.price,
amount: Number(amountField),
name: values.privilege.name,
privilegeId: values.privilege.privilegeId ?? "",
serviceKey: values.privilege.serviceKey,
description: values.privilege.description,
type: values.privilege.type,
value: values.privilege.value ?? "",
price: values.privilege.price,
amount: Number(values.amountField),
},
],
});
@ -80,9 +88,10 @@ export default function CreateTariff() {
enqueueSnackbar("Тариф создан");
requestTariffs();
await requestTariffs();
}
};
// const createTariffFrontend = () => {
// if (checkFulledFields() && privilege !== null) {
// updateTariffStore({
@ -97,122 +106,194 @@ export default function CreateTariff() {
// }
return (
<Container
sx={{
p: "20px",
border: "1px solid rgba(224, 224, 224, 1)",
borderRadius: "4px",
display: "flex",
flexDirection: "column",
gap: "12px",
}}
>
<Typography variant="h6" sx={{ textAlign: "center", mb: "16px" }}>
Создание тарифа
</Typography>
<FormControl
fullWidth
sx={{
height: "52px",
color: theme.palette.secondary.main,
"& .MuiInputLabel-outlined": {
color: theme.palette.secondary.main,
},
"& .MuiInputLabel-outlined.MuiInputLabel-shrink": {
color: theme.palette.secondary.main,
},
}}
<Formik
initialValues={initialValues}
validate={checkFulledFields}
onSubmit={createTariffBackend}
>
<InputLabel
id="privilege-select-label"
sx={{
color: theme.palette.secondary.main,
fontSize: "16px",
lineHeight: "19px",
}}
>
Привилегия
</InputLabel>
<Select
labelId="privilege-select-label"
id="privilege-select"
value={privilegeIdField}
label="Привилегия"
onChange={(e) => setPrivilegeIdField(e.target.value)}
sx={{
color: theme.palette.secondary.main,
borderColor: theme.palette.secondary.main,
"&.Mui-focused .MuiOutlinedInput-notchedOutline": {
borderColor: theme.palette.secondary.main,
border: "1px solid",
},
".MuiSvgIcon-root ": {
fill: theme.palette.secondary.main,
},
}}
inputProps={{ sx: { pt: "12px" } }}
>
{privileges.map((privilege) => (
<MenuItem
data-cy={`select-option-${privilege.description}`}
key={privilege.description}
value={privilege._id}
>
{privilege.description}
</MenuItem>
))}
</Select>
</FormControl>
{privilege && (
<Box
sx={{
display: "flex",
flexDirection: "column",
}}
>
<Typography>
Имя: <span>{privilege.name}</span>
</Typography>
<Typography>
Сервис: <span>{privilege.serviceKey}</span>
</Typography>
<Typography>
Единица: <span>{privilege.type}</span>
</Typography>
<Typography>
Стандартная цена за единицу: <span>{currencyFormatter.format(privilege.price / 100)}</span>
</Typography>
</Box>
)}
<CustomTextField
id="tariff-name"
label="Название тарифа"
value={nameField}
onChange={(e) => setNameField(e.target.value)}
/>
<CustomTextField
id="tariff-amount"
label="Кол-во единиц привилегии"
value={amountField}
onChange={(e) => setAmountField(e.target.value)}
type="number"
/>
<CustomTextField
id="tariff-custom-price"
label="Кастомная цена (не обязательно)"
value={customPriceField}
onChange={(e) => setCustomPriceField(e.target.value)}
type="number"
/>
<Button
className="btn_createTariffBackend"
type="button"
onClick={() => {
createTariffBackend();
}}
>
Создать
</Button>
</Container>
{(props) => (
<Form style={{width: "100%"}} >
<Container
sx={{
p: "20px",
border: "1px solid rgba(224, 224, 224, 1)",
borderRadius: "4px",
display: "flex",
flexDirection: "column",
gap: "12px",
}}
>
<Typography variant="h6" sx={{ textAlign: "center", mb: "16px" }}>
Создание тарифа
</Typography>
<FormControl
fullWidth
sx={{
height: "52px",
color: theme.palette.secondary.main,
"& .MuiInputLabel-outlined": {
color: theme.palette.secondary.main,
},
"& .MuiInputLabel-outlined.MuiInputLabel-shrink": {
color: theme.palette.secondary.main,
},
}}
>
<InputLabel
id="privilege-select-label"
sx={{
color: theme.palette.secondary.main,
fontSize: "16px",
lineHeight: "19px",
}}
>
Привилегия
</InputLabel>
<Select
labelId="privilege-select-label"
id="privilege-select"
value={props.values.privilegeIdField}
label="Привилегия"
error={props.touched.privilegeIdField && !!props.errors.privilegeIdField}
onChange={(e) => {
props.setFieldValue("privilegeIdField", e.target.value)
props.setFieldValue("privilege", findPrivilegeById(e.target.value))
if (props.values.privilege === null)
return enqueueSnackbar("Привилегия не найдена");
}}
onBlur={props.handleBlur}
sx={{
color: theme.palette.secondary.main,
borderColor: theme.palette.secondary.main,
"&.Mui-focused .MuiOutlinedInput-notchedOutline": {
borderColor: theme.palette.secondary.main,
border: "1px solid",
},
".MuiSvgIcon-root ": {
fill: theme.palette.secondary.main,
},
}}
inputProps={{ sx: { pt: "12px" } }}
>
{privileges.map((privilege) => (
<MenuItem
data-cy={`select-option-${privilege.description}`}
key={privilege.description}
value={privilege._id}
>
{privilege.description}
</MenuItem>
))}
</Select>
</FormControl>
{props.values.privilege && (
<Box
sx={{
display: "flex",
flexDirection: "column",
}}
>
<Typography>
Имя: <span>{props.values.privilege.name}</span>
</Typography>
<Typography>
Сервис: <span>{props.values.privilege.serviceKey}</span>
</Typography>
<Typography>
Единица: <span>{props.values.privilege.type}</span>
</Typography>
<Typography>
Стандартная цена за единицу: <span>{currencyFormatter.format(props.values.privilege.price / 100)}</span>
</Typography>
</Box>
)}
<Field
as={TextField}
id="tariff-name"
name="nameField"
variant="filled"
label="Название тарифа"
type="text"
error={props.touched.nameField && !!props.errors.nameField}
helperText={
<Typography sx={{ fontSize: "12px", width: "200px" }}>
{props.errors.nameField}
</Typography>
}
InputProps={{
style: {
backgroundColor: theme.palette.content.main,
color: theme.palette.secondary.main,
}
}}
InputLabelProps={{
style: {
color: theme.palette.secondary.main
}
}}
/>
<TextField
id="amountField"
name="amountField"
variant="filled"
onChange={(e) => {
props.setFieldValue("amountField", e.target.value.replace(/[^\d]/g,''))
}}
value={props.values.amountField}
onBlur={props.handleBlur}
label="Кол-во единиц привилегии"
error={props.touched.amountField && !!props.errors.amountField}
helperText={
<Typography sx={{ fontSize: "12px", width: "200px" }}>
{props.errors.amountField}
</Typography>
}
InputProps={{
style: {
backgroundColor: theme.palette.content.main,
color: theme.palette.secondary.main,
}
}}
InputLabelProps={{
style: {
color: theme.palette.secondary.main
}
}}
/>
<TextField
id="tariff-custom-price"
name="customPriceField"
variant="filled"
onChange={(e) => {
props.setFieldValue("customPriceField", e.target.value.replace(/[^\d]/g,''))
}}
value={props.values.customPriceField}
onBlur={props.handleBlur}
label="Кастомная цена (не обязательно)"
InputProps={{
style: {
backgroundColor: theme.palette.content.main,
color: theme.palette.secondary.main,
}
}}
InputLabelProps={{
style: {
color: theme.palette.secondary.main
}
}}
/>
<Button
className="btn_createTariffBackend"
type="submit"
disabled={props.isSubmitting}
>
Создать
</Button>
</Container>
</Form>
)}
</Formik>
);
}

@ -106,7 +106,6 @@ const links: { path: string; element: JSX.Element; title: string; className: str
{ path: "/discounts", element: <AddPhotoAlternateOutlinedIcon />, title: "Скидки", className: "menu" },
{ path: "/promocode", element: <NaturePeopleOutlinedIcon />, title: "Промокод", className: "menu" },
{ path: "/settingRoles", element: <SettingsIcon />, title: "Настройки", className: "menu" },
{ path: "/jjj", element: <CameraIcon />, title: "Камера", className: "menu" },
{ path: "/support", element: <HeadsetMicOutlinedIcon />, title: "Служба поддержки", className: "menu" },
];