adminFront/src/pages/dashboard/Content/DiscountManagement/CreateDiscount.tsx
nflnkr 473f77568c upgrade kitui
use cart calc functions from kitui
fix cart discount list display
fix types
2024-03-27 17:50:14 +03:00

521 lines
25 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import {
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 { SERVICE_LIST, ServiceType } from "@root/model/tariff";
import {
resetPrivilegeArray,
usePrivilegeStore,
} from "@root/stores/privilegesStore";
import { addDiscount } from "@root/stores/discounts";
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";
import { mutate } from "swr";
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);
usePrivileges({ onNewPrivileges: resetPrivilegeArray });
const initialValues: Values = {
discountNameField: "",
discountDescriptionField: "",
discountFactorField: "",
serviceType: "",
discountType: "purchasesAmount",
purchasesAmountField: "",
cartPurchasesAmountField: "",
discountMinValueField: "",
privilegeIdField: "",
}
const handleCreateDiscount = async(
values: Values,
formikHelpers: FormikHelpers<Values>
) => {
console.log("работаю")
const purchasesAmount = Number(parseFloat(values.purchasesAmountField.replace(",", "."))) * 100;
const discountFactor =
(100 - parseFloat(values.discountFactorField.replace(",", "."))) / 100;
const cartPurchasesAmount = Number(parseFloat(
values.cartPurchasesAmountField.replace(",", ".")) * 100
);
const discountMinValue = Number(parseFloat(
values.discountMinValueField.replace(",", ".")) * 100
);
const [createdDiscountResponse, createdDiscountError] =
await createDiscount({
cartPurchasesAmount,
discountFactor,
discountMinValue,
purchasesAmount,
discountDescription: values.discountDescriptionField,
discountName: values.discountNameField,
startDate: new Date().toISOString(),
endDate: new Date(Date.now() + 1000 * 3600 * 24 * 30).toISOString(),
serviceType: values.serviceType,
discountType: values.discountType,
privilegeId: values.privilegeIdField,
});
if (createdDiscountError) {
console.log("Error creating discount", createdDiscountError);
return enqueueSnackbar(createdDiscountError);
}
if (createdDiscountResponse) {
mutate("discounts");
addDiscount(createdDiscountResponse);
}
}
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}
>
{(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>
);
}