301 lines
9.2 KiB
TypeScript
301 lines
9.2 KiB
TypeScript
![]() |
import { useEffect, useState } from "react";
|
|||
|
import {
|
|||
|
Typography,
|
|||
|
TextField,
|
|||
|
Button,
|
|||
|
RadioGroup,
|
|||
|
Radio,
|
|||
|
FormControlLabel,
|
|||
|
Select,
|
|||
|
} from "@mui/material";
|
|||
|
import { Formik, Field, Form } from "formik";
|
|||
|
import { DesktopDatePicker } from "@mui/x-date-pickers/DesktopDatePicker";
|
|||
|
import MenuItem from "@mui/material/MenuItem";
|
|||
|
import theme from "../../../../theme";
|
|||
|
import { requestPrivileges } from "@root/services/privilegies.service";
|
|||
|
import { usePrivilegeStore } from "@root/stores/privilegesStore";
|
|||
|
import { useCartStore } from "@root/stores/cart";
|
|||
|
|
|||
|
import type { TextFieldProps } from "@mui/material";
|
|||
|
|
|||
|
type BonusType = "discount" | "privilege";
|
|||
|
type LayerType = "privilege" | "service";
|
|||
|
type FormValues = {
|
|||
|
codeword: string;
|
|||
|
description: string;
|
|||
|
greetings: string;
|
|||
|
dueTo: string;
|
|||
|
activationCount: string;
|
|||
|
privilegeId: string;
|
|||
|
amount: string;
|
|||
|
layer: string;
|
|||
|
factor: string;
|
|||
|
target: string;
|
|||
|
threshold: string;
|
|||
|
};
|
|||
|
|
|||
|
type CustomTextFieldProps = {
|
|||
|
name: string;
|
|||
|
label: string;
|
|||
|
required?: boolean;
|
|||
|
};
|
|||
|
|
|||
|
const CustomTextField = ({
|
|||
|
name,
|
|||
|
label,
|
|||
|
required = false,
|
|||
|
}: CustomTextFieldProps) => (
|
|||
|
<Field
|
|||
|
name={name}
|
|||
|
label={label}
|
|||
|
required={required}
|
|||
|
variant="filled"
|
|||
|
color="secondary"
|
|||
|
as={TextField}
|
|||
|
sx={{ width: "100%", marginTop: "15px" }}
|
|||
|
InputProps={{
|
|||
|
style: {
|
|||
|
backgroundColor: theme.palette.content.main,
|
|||
|
color: theme.palette.secondary.main,
|
|||
|
},
|
|||
|
}}
|
|||
|
InputLabelProps={{
|
|||
|
style: { color: theme.palette.secondary.main },
|
|||
|
}}
|
|||
|
/>
|
|||
|
);
|
|||
|
|
|||
|
export const CreatePromocodeForm = () => {
|
|||
|
const [dueTo, setDueTo] = useState<Date | null>(new Date());
|
|||
|
const [bonusType, setBonusType] = useState<BonusType>("discount");
|
|||
|
const [layerType, setLayerType] = useState<LayerType>("privilege");
|
|||
|
|
|||
|
const { privileges } = usePrivilegeStore();
|
|||
|
const { cartData } = useCartStore();
|
|||
|
|
|||
|
const initialValues: FormValues = {
|
|||
|
codeword: "",
|
|||
|
description: "",
|
|||
|
greetings: "",
|
|||
|
dueTo: "",
|
|||
|
activationCount: "",
|
|||
|
privilegeId: "",
|
|||
|
amount: "",
|
|||
|
layer: "",
|
|||
|
factor: "",
|
|||
|
target: "",
|
|||
|
threshold: "",
|
|||
|
};
|
|||
|
|
|||
|
useEffect(() => {
|
|||
|
requestPrivileges();
|
|||
|
}, []);
|
|||
|
|
|||
|
const createPromocode = (values: FormValues) => {
|
|||
|
console.log(values);
|
|||
|
};
|
|||
|
|
|||
|
return (
|
|||
|
<Formik initialValues={initialValues} onSubmit={createPromocode}>
|
|||
|
{(props) => (
|
|||
|
<Form
|
|||
|
style={{
|
|||
|
width: "100%",
|
|||
|
maxWidth: "600px",
|
|||
|
}}
|
|||
|
>
|
|||
|
<CustomTextField name="codeword" label="Кодовое слово" required />
|
|||
|
<CustomTextField name="description" label="Описание" required />
|
|||
|
<CustomTextField
|
|||
|
name="greetings"
|
|||
|
label="Приветственное сообщение"
|
|||
|
required
|
|||
|
/>
|
|||
|
<Typography
|
|||
|
variant="h4"
|
|||
|
sx={{
|
|||
|
height: "40px",
|
|||
|
fontWeight: "normal",
|
|||
|
marginTop: "15px",
|
|||
|
color: theme.palette.secondary.main,
|
|||
|
}}
|
|||
|
>
|
|||
|
Время существования промокода
|
|||
|
</Typography>
|
|||
|
<Field
|
|||
|
name="dueTo"
|
|||
|
as={DesktopDatePicker}
|
|||
|
inputFormat="DD/MM/YYYY"
|
|||
|
value={dueTo}
|
|||
|
onChange={(date: Date | null) => {
|
|||
|
if (date) {
|
|||
|
setDueTo(date);
|
|||
|
}
|
|||
|
}}
|
|||
|
renderInput={(params: TextFieldProps) => <TextField {...params} />}
|
|||
|
InputProps={{
|
|||
|
sx: {
|
|||
|
height: "40px",
|
|||
|
color: theme.palette.secondary.main,
|
|||
|
border: "1px solid",
|
|||
|
borderColor: theme.palette.secondary.main,
|
|||
|
"& .MuiSvgIcon-root": { color: theme.palette.secondary.main },
|
|||
|
},
|
|||
|
}}
|
|||
|
/>
|
|||
|
<CustomTextField
|
|||
|
name="activationCount"
|
|||
|
label="Количество активаций промокода"
|
|||
|
/>
|
|||
|
<RadioGroup
|
|||
|
row
|
|||
|
name="bonusType"
|
|||
|
value={bonusType}
|
|||
|
sx={{ marginTop: "15px" }}
|
|||
|
onChange={({ target }: React.ChangeEvent<HTMLInputElement>) => {
|
|||
|
setBonusType(target.value as BonusType);
|
|||
|
}}
|
|||
|
onBlur={props.handleBlur}
|
|||
|
>
|
|||
|
<FormControlLabel
|
|||
|
value="discount"
|
|||
|
control={<Radio color="secondary" />}
|
|||
|
label="Скидка"
|
|||
|
/>
|
|||
|
<FormControlLabel
|
|||
|
value="privilege"
|
|||
|
control={<Radio color="secondary" />}
|
|||
|
label="Привилегия"
|
|||
|
/>
|
|||
|
</RadioGroup>
|
|||
|
{bonusType === "discount" && (
|
|||
|
<>
|
|||
|
<RadioGroup
|
|||
|
row
|
|||
|
name="layer"
|
|||
|
value={layerType}
|
|||
|
sx={{ marginTop: "15px" }}
|
|||
|
onChange={({ target }: React.ChangeEvent<HTMLInputElement>) => {
|
|||
|
setLayerType(target.value as LayerType);
|
|||
|
}}
|
|||
|
onBlur={props.handleBlur}
|
|||
|
>
|
|||
|
<FormControlLabel
|
|||
|
value="privilege"
|
|||
|
control={<Radio color="secondary" />}
|
|||
|
label="Привилегия"
|
|||
|
/>
|
|||
|
<FormControlLabel
|
|||
|
value="service"
|
|||
|
control={<Radio color="secondary" />}
|
|||
|
label="Сервис"
|
|||
|
/>
|
|||
|
</RadioGroup>
|
|||
|
<CustomTextField name="factor" label="Процент скидки" required />
|
|||
|
<Typography
|
|||
|
variant="h4"
|
|||
|
sx={{
|
|||
|
height: "40px",
|
|||
|
fontWeight: "normal",
|
|||
|
marginTop: "15px",
|
|||
|
padding: "0 12px",
|
|||
|
color: theme.palette.secondary.main,
|
|||
|
}}
|
|||
|
>
|
|||
|
{layerType === "privilege"
|
|||
|
? "Выбор привилегии"
|
|||
|
: "Выбор сервиса"}
|
|||
|
</Typography>
|
|||
|
<Field
|
|||
|
name="target"
|
|||
|
as={Select}
|
|||
|
label={layerType === "privilege" ? "Привилегия" : "Сервис"}
|
|||
|
sx={{
|
|||
|
width: "100%",
|
|||
|
border: "2px solid",
|
|||
|
color: theme.palette.secondary.main,
|
|||
|
borderColor: theme.palette.secondary.main,
|
|||
|
"&.Mui-focused .MuiOutlinedInput-notchedOutline": {
|
|||
|
border: "none",
|
|||
|
},
|
|||
|
".MuiSvgIcon-root ": { fill: theme.palette.secondary.main },
|
|||
|
}}
|
|||
|
children={
|
|||
|
layerType === "privilege"
|
|||
|
? privileges.map(({ name, privilegeId }) => (
|
|||
|
<MenuItem key={privilegeId} value={privilegeId}>
|
|||
|
{name}
|
|||
|
</MenuItem>
|
|||
|
))
|
|||
|
: cartData?.services.map(({ serviceKey }) => (
|
|||
|
<MenuItem key={serviceKey} value={serviceKey}>
|
|||
|
{serviceKey}
|
|||
|
</MenuItem>
|
|||
|
))
|
|||
|
}
|
|||
|
/>
|
|||
|
<CustomTextField
|
|||
|
name="threshold"
|
|||
|
label="При каком значении применяется скидка"
|
|||
|
required
|
|||
|
/>
|
|||
|
</>
|
|||
|
)}
|
|||
|
{bonusType === "privilege" && (
|
|||
|
<>
|
|||
|
<Typography
|
|||
|
variant="h4"
|
|||
|
sx={{
|
|||
|
height: "40px",
|
|||
|
fontWeight: "normal",
|
|||
|
marginTop: "15px",
|
|||
|
padding: "0 12px",
|
|||
|
color: theme.palette.secondary.main,
|
|||
|
}}
|
|||
|
>
|
|||
|
Выбор привилегии
|
|||
|
</Typography>
|
|||
|
<Field
|
|||
|
name="privilegeId"
|
|||
|
as={Select}
|
|||
|
label="Привилегия"
|
|||
|
sx={{
|
|||
|
width: "100%",
|
|||
|
border: "2px solid",
|
|||
|
color: theme.palette.secondary.main,
|
|||
|
borderColor: theme.palette.secondary.main,
|
|||
|
"&.Mui-focused .MuiOutlinedInput-notchedOutline": {
|
|||
|
border: "none",
|
|||
|
},
|
|||
|
".MuiSvgIcon-root ": { fill: theme.palette.secondary.main },
|
|||
|
}}
|
|||
|
children={privileges.map(({ name, privilegeId }) => (
|
|||
|
<MenuItem key={privilegeId} value={privilegeId}>
|
|||
|
{name}
|
|||
|
</MenuItem>
|
|||
|
))}
|
|||
|
/>
|
|||
|
<CustomTextField name="amount" label="Количество" required />
|
|||
|
</>
|
|||
|
)}
|
|||
|
<Button
|
|||
|
variant="contained"
|
|||
|
sx={{
|
|||
|
display: "block",
|
|||
|
padding: "10px",
|
|||
|
margin: "15px auto 0",
|
|||
|
fontWeight: "normal",
|
|||
|
fontSize: "18px",
|
|||
|
backgroundColor: theme.palette.menu.main,
|
|||
|
"&:hover": { backgroundColor: theme.palette.grayMedium.main },
|
|||
|
}}
|
|||
|
type="submit"
|
|||
|
>
|
|||
|
Cоздать
|
|||
|
</Button>
|
|||
|
</Form>
|
|||
|
)}
|
|||
|
</Formik>
|
|||
|
);
|
|||
|
};
|