feat: CreatePromocodeForm
This commit is contained in:
parent
77c2d834c9
commit
bd6dfc182e
@ -20,7 +20,7 @@ import Users from "@pages/dashboard/Content/Users";
|
|||||||
import Entities from "@pages/dashboard/Content/Entities";
|
import Entities from "@pages/dashboard/Content/Entities";
|
||||||
import Tariffs from "@pages/dashboard/Content/Tariffs";
|
import Tariffs from "@pages/dashboard/Content/Tariffs";
|
||||||
import DiscountManagement from "@root/pages/dashboard/Content/DiscountManagement/DiscountManagement";
|
import DiscountManagement from "@root/pages/dashboard/Content/DiscountManagement/DiscountManagement";
|
||||||
import PromocodeManagement from "@pages/dashboard/Content/PromocodeManagement";
|
import { PromocodeManagement } from "@root/pages/dashboard/Content/PromocodeManagement";
|
||||||
import { SettingRoles } from "@pages/Setting/SettingRoles";
|
import { SettingRoles } from "@pages/Setting/SettingRoles";
|
||||||
import Support from "@pages/dashboard/Content/Support/Support";
|
import Support from "@pages/dashboard/Content/Support/Support";
|
||||||
|
|
||||||
@ -104,7 +104,11 @@ root.render(
|
|||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
{componentsArray.map((element) => (
|
{componentsArray.map((element) => (
|
||||||
<Route key={element[0]} path={element[0]} element={element[1]} />
|
<Route
|
||||||
|
key={element[0]}
|
||||||
|
path={element[0]}
|
||||||
|
element={element[1]}
|
||||||
|
/>
|
||||||
))}
|
))}
|
||||||
</Route>
|
</Route>
|
||||||
|
|
||||||
|
@ -1,436 +0,0 @@
|
|||||||
import { Box, Typography, TextField, Checkbox, Button } from "@mui/material";
|
|
||||||
import { LocalizationProvider } from "@mui/x-date-pickers/LocalizationProvider";
|
|
||||||
import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs";
|
|
||||||
import { DesktopDatePicker } from "@mui/x-date-pickers/DesktopDatePicker";
|
|
||||||
import Table from "@mui/material/Table";
|
|
||||||
import TableBody from "@mui/material/TableBody";
|
|
||||||
import TableCell from "@mui/material/TableCell";
|
|
||||||
import TableRow from "@mui/material/TableRow";
|
|
||||||
import TableContainer from "@mui/material/TableContainer";
|
|
||||||
import Paper from "@mui/material/Paper";
|
|
||||||
import { DataGrid, GridColDef, GridToolbar } from "@mui/x-data-grid";
|
|
||||||
import MenuItem from "@mui/material/MenuItem";
|
|
||||||
import Select, { SelectChangeEvent } from "@mui/material/Select";
|
|
||||||
import theme from "../../../theme";
|
|
||||||
import { usePromocodeStore } from "../../../stores/promocodes";
|
|
||||||
import { useRef, useState } from "react";
|
|
||||||
import { ServiceType } from "@root/model/tariff";
|
|
||||||
|
|
||||||
|
|
||||||
const columns: GridColDef[] = [
|
|
||||||
{
|
|
||||||
field: "id",
|
|
||||||
headerName: "ID",
|
|
||||||
width: 30,
|
|
||||||
sortable: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: "name",
|
|
||||||
headerName: "Название промокода",
|
|
||||||
width: 200,
|
|
||||||
sortable: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
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,
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
const PromocodeManagement: React.FC = () => {
|
|
||||||
const [checkboxState, setCheckboxState] = useState<boolean>(false);
|
|
||||||
const toggleCheckbox = () => { setCheckboxState(!checkboxState); };
|
|
||||||
|
|
||||||
const [value1, setValue1] = useState<Date>(new Date());
|
|
||||||
const [value2, setValue2] = useState<Date>(new Date());
|
|
||||||
|
|
||||||
const [service, setService] = useState<ServiceType>("templategen");
|
|
||||||
const handleChange = (event: SelectChangeEvent) => {
|
|
||||||
setService(event.target.value as ServiceType);
|
|
||||||
};
|
|
||||||
|
|
||||||
const promocodes = usePromocodeStore(state => state.promocodes);
|
|
||||||
const addPromocodes = usePromocodeStore(state => state.addPromocodes);
|
|
||||||
|
|
||||||
function createPromocode() {
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
// const promocodeArrayConverted = promocodes.map((item) => {
|
|
||||||
// const dateFrom = item.from ? new Date(Number(item.from)) : "";
|
|
||||||
// const dateDueTo = item.from ? new Date(Number(item.dueTo)) : "";
|
|
||||||
|
|
||||||
// const strFrom = dateFrom
|
|
||||||
// ? `${dateFrom.getDate()}.${dateFrom.getMonth()}.${dateFrom.getFullYear()}`
|
|
||||||
// : "-";
|
|
||||||
|
|
||||||
// const strDueTo = dateDueTo
|
|
||||||
// ? `${dateDueTo.getDate()}.${dateDueTo.getMonth()}.${dateDueTo.getFullYear()}`
|
|
||||||
// : "-";
|
|
||||||
|
|
||||||
// if (item.privileges.length) {
|
|
||||||
// const result = item.privileges.reduce((acc, privilege) => {
|
|
||||||
// acc = acc
|
|
||||||
// ? `${acc}, ${privilege.serviceKey} - ${privilege.discount}%`
|
|
||||||
// : `${privilege.serviceKey} - ${privilege.discount * 100}%`;
|
|
||||||
|
|
||||||
// return acc;
|
|
||||||
// }, "");
|
|
||||||
|
|
||||||
// return { ...item, privileges: result, from: strFrom, dueTo: strDueTo };
|
|
||||||
// } else {
|
|
||||||
// return { ...item, from: strFrom, dueTo: strDueTo };
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
|
|
||||||
// const createPromocode = (name: string, discount: number) => {
|
|
||||||
// const newPromocode = {
|
|
||||||
// id: new Date().getTime(),
|
|
||||||
// name,
|
|
||||||
// endless: checkboxState,
|
|
||||||
// from: checkboxState ? "" : new Date(value1).getTime() + "",
|
|
||||||
// dueTo: checkboxState ? "" : new Date(value2).getTime() + "",
|
|
||||||
// privileges: [{
|
|
||||||
// good: service,
|
|
||||||
// discount: discount / 100
|
|
||||||
// }]
|
|
||||||
// };
|
|
||||||
|
|
||||||
// const promocodeArrayUpdated = [...promocodes, newPromocode];
|
|
||||||
// addPromocodes(promocodeArrayUpdated);
|
|
||||||
// };
|
|
||||||
|
|
||||||
const promocodeGridData = promocodes.map(procomode => {
|
|
||||||
// TODO
|
|
||||||
})
|
|
||||||
|
|
||||||
const fieldName = useRef<HTMLInputElement | null>(null);
|
|
||||||
const fieldDiscount = useRef<HTMLInputElement | null>(null);
|
|
||||||
|
|
||||||
// const checkFields = () => {
|
|
||||||
// if (fieldName.current != null && fieldDiscount.current != null) {
|
|
||||||
// createPromocode(fieldName.current.value, Number(fieldDiscount.current.value));
|
|
||||||
// }
|
|
||||||
// };
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<LocalizationProvider dateAdapter={AdapterDayjs}>
|
|
||||||
<Typography
|
|
||||||
variant="subtitle1"
|
|
||||||
sx={{
|
|
||||||
width: "90%",
|
|
||||||
height: "60px",
|
|
||||||
display: "flex",
|
|
||||||
flexDirection: "column",
|
|
||||||
justifyContent: "center",
|
|
||||||
alignItems: "center",
|
|
||||||
color: theme.palette.secondary.main
|
|
||||||
}}>
|
|
||||||
ПРОМОКОД
|
|
||||||
</Typography>
|
|
||||||
|
|
||||||
<Box sx={{
|
|
||||||
display: "flex",
|
|
||||||
flexDirection: "column",
|
|
||||||
justifyContent: "left",
|
|
||||||
alignItems: "left",
|
|
||||||
marginTop: "15px",
|
|
||||||
}}>
|
|
||||||
{/*<Typography */}
|
|
||||||
{/* variant="h4" */}
|
|
||||||
{/* sx={{*/}
|
|
||||||
{/* width: "90%",*/}
|
|
||||||
{/* height: "40px",*/}
|
|
||||||
{/* fontWeight: "normal",*/}
|
|
||||||
{/* color: theme.palette.grayDisabled.main,*/}
|
|
||||||
{/* marginTop: "35px"*/}
|
|
||||||
{/*}}>*/}
|
|
||||||
{/* Название:*/}
|
|
||||||
{/*</Typography>*/}
|
|
||||||
<TextField
|
|
||||||
id="standard-basic"
|
|
||||||
label={"Название"}
|
|
||||||
variant="filled"
|
|
||||||
color="secondary"
|
|
||||||
sx={{
|
|
||||||
height: "30px",
|
|
||||||
}}
|
|
||||||
InputProps={{
|
|
||||||
style: {
|
|
||||||
backgroundColor: theme.palette.content.main,
|
|
||||||
color: theme.palette.secondary.main,
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
InputLabelProps={{
|
|
||||||
style: {
|
|
||||||
color: theme.palette.secondary.main
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
inputRef={fieldName}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<Typography
|
|
||||||
variant="h4"
|
|
||||||
sx={{
|
|
||||||
width: "90%",
|
|
||||||
height: "40px",
|
|
||||||
fontWeight: "normal",
|
|
||||||
color: theme.palette.grayDisabled.main,
|
|
||||||
marginTop: "75px"
|
|
||||||
}}>
|
|
||||||
Условия:
|
|
||||||
</Typography>
|
|
||||||
|
|
||||||
<Select
|
|
||||||
labelId="demo-simple-select-label"
|
|
||||||
id="demo-simple-select"
|
|
||||||
value={service}
|
|
||||||
label="Age"
|
|
||||||
onChange={handleChange}
|
|
||||||
sx={{
|
|
||||||
color: theme.palette.secondary.main,
|
|
||||||
border: "1px solid",
|
|
||||||
borderColor: theme.palette.secondary.main,
|
|
||||||
"&.Mui-focused .MuiOutlinedInput-notchedOutline": {
|
|
||||||
borderColor: theme.palette.secondary.main
|
|
||||||
},
|
|
||||||
".MuiSvgIcon-root ": {
|
|
||||||
fill: theme.palette.secondary.main,
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<MenuItem value={"Шаблонизатор документов"}>Шаблонизатор</MenuItem>
|
|
||||||
<MenuItem value={"Опросник"}>Опросник</MenuItem>
|
|
||||||
<MenuItem value={"Аналитика сокращателя"}>Аналитика сокращателя</MenuItem>
|
|
||||||
<MenuItem value={"АБ тесты"}>АБ тесты</MenuItem>
|
|
||||||
</Select>
|
|
||||||
|
|
||||||
<TextField
|
|
||||||
id="standard-basic"
|
|
||||||
label={"Процент скидки"}
|
|
||||||
variant="filled"
|
|
||||||
color="secondary"
|
|
||||||
sx={{
|
|
||||||
marginTop: "15px"
|
|
||||||
}}
|
|
||||||
InputProps={{
|
|
||||||
style: {
|
|
||||||
backgroundColor: theme.palette.content.main,
|
|
||||||
color: theme.palette.secondary.main,
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
InputLabelProps={{
|
|
||||||
style: {
|
|
||||||
color: theme.palette.secondary.main
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
inputRef={fieldDiscount}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<TableContainer component={Paper} sx={{
|
|
||||||
width: "100%",
|
|
||||||
marginTop: "35px",
|
|
||||||
backgroundColor: theme.palette.content.main
|
|
||||||
}}>
|
|
||||||
<Table aria-label="simple table">
|
|
||||||
<TableBody>
|
|
||||||
<TableRow sx={{ border: "1px solid white" }} >
|
|
||||||
<TableCell component="th" scope="row" sx={{ color: theme.palette.secondary.main }}>
|
|
||||||
Работает, если заплатите 100500 денег
|
|
||||||
</TableCell>
|
|
||||||
</TableRow>
|
|
||||||
<TableRow sx={{ border: "1px solid white" }} >
|
|
||||||
<TableCell component="th" scope="row" sx={{ color: theme.palette.secondary.main }}>
|
|
||||||
Вы должны будете продать душу дьяволу
|
|
||||||
</TableCell>
|
|
||||||
</TableRow>
|
|
||||||
</TableBody>
|
|
||||||
</Table>
|
|
||||||
</TableContainer>
|
|
||||||
|
|
||||||
<Typography
|
|
||||||
variant="h4"
|
|
||||||
sx={{
|
|
||||||
width: "90%",
|
|
||||||
height: "40px",
|
|
||||||
fontWeight: "normal",
|
|
||||||
color: theme.palette.grayDisabled.main,
|
|
||||||
marginTop: "55px"
|
|
||||||
}}>
|
|
||||||
Дата действия:
|
|
||||||
</Typography>
|
|
||||||
|
|
||||||
<Box
|
|
||||||
sx={{
|
|
||||||
width: "100%",
|
|
||||||
display: "flex",
|
|
||||||
flexWrap: 'wrap'
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Typography sx={{
|
|
||||||
width: "35px",
|
|
||||||
display: "flex",
|
|
||||||
flexDirection: "column",
|
|
||||||
justifyContent: "center",
|
|
||||||
alignItems: "left",
|
|
||||||
}}>С</Typography>
|
|
||||||
|
|
||||||
<DesktopDatePicker
|
|
||||||
inputFormat="DD/MM/YYYY"
|
|
||||||
value={value1}
|
|
||||||
onChange={(e) => { if (e) { setValue1(e); } }}
|
|
||||||
renderInput={(params) => <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 }
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<Typography sx={{
|
|
||||||
width: "65px",
|
|
||||||
display: "flex",
|
|
||||||
flexDirection: "column",
|
|
||||||
justifyContent: "center",
|
|
||||||
alignItems: "center",
|
|
||||||
}}>по</Typography>
|
|
||||||
|
|
||||||
<DesktopDatePicker
|
|
||||||
inputFormat="DD/MM/YYYY"
|
|
||||||
value={value2}
|
|
||||||
onChange={(e) => { if (e) { setValue2(e); } }}
|
|
||||||
renderInput={(params) => <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 }
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
|
|
||||||
<Box sx={{
|
|
||||||
display: "flex",
|
|
||||||
width: "90%",
|
|
||||||
marginTop: theme.spacing(2),
|
|
||||||
}}>
|
|
||||||
<Box sx={{
|
|
||||||
width: "20px",
|
|
||||||
height: "42px",
|
|
||||||
display: "flex",
|
|
||||||
flexDirection: "column",
|
|
||||||
justifyContent: "left",
|
|
||||||
alignItems: "left",
|
|
||||||
marginRight: theme.spacing(1)
|
|
||||||
}}>
|
|
||||||
<Checkbox sx={{
|
|
||||||
color: theme.palette.secondary.main,
|
|
||||||
"&.Mui-checked": {
|
|
||||||
color: theme.palette.secondary.main,
|
|
||||||
},
|
|
||||||
}} onClick={() => toggleCheckbox()} />
|
|
||||||
</Box>
|
|
||||||
<Box sx={{
|
|
||||||
display: "flex",
|
|
||||||
flexDirection: "column",
|
|
||||||
justifyContent: "center",
|
|
||||||
alignItems: "center"
|
|
||||||
}}>
|
|
||||||
Бессрочно
|
|
||||||
</Box>
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
<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={createPromocode} >
|
|
||||||
Cоздать
|
|
||||||
</Button>
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
<Box style={{ width: "80%", marginTop: "55px" }}>
|
|
||||||
<Box style={{ height: 400 }}>
|
|
||||||
<DataGrid
|
|
||||||
checkboxSelection={true}
|
|
||||||
rows={promocodeGridData}
|
|
||||||
columns={columns}
|
|
||||||
sx={{
|
|
||||||
color: theme.palette.secondary.main,
|
|
||||||
"& .MuiDataGrid-iconSeparator": {
|
|
||||||
display: "none"
|
|
||||||
},
|
|
||||||
"& .css-levciy-MuiTablePagination-displayedRows": {
|
|
||||||
color: theme.palette.secondary.main
|
|
||||||
},
|
|
||||||
"& .MuiSvgIcon-root": {
|
|
||||||
color: theme.palette.secondary.main
|
|
||||||
},
|
|
||||||
"& .MuiTablePagination-selectLabel": {
|
|
||||||
color: theme.palette.secondary.main
|
|
||||||
},
|
|
||||||
"& .MuiInputBase-root": {
|
|
||||||
color: theme.palette.secondary.main
|
|
||||||
},
|
|
||||||
"& .MuiButton-text": {
|
|
||||||
color: theme.palette.secondary.main
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
components={{ Toolbar: GridToolbar }}
|
|
||||||
onSelectionModelChange={(ids) => console.log("datagrid select")}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
</LocalizationProvider>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
export default PromocodeManagement;
|
|
@ -0,0 +1,300 @@
|
|||||||
|
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>
|
||||||
|
);
|
||||||
|
};
|
@ -0,0 +1,56 @@
|
|||||||
|
import { Box } from "@mui/material";
|
||||||
|
import { DataGrid, GridColDef, GridToolbar } from "@mui/x-data-grid";
|
||||||
|
|
||||||
|
import { usePromocodeStore } from "@root/stores/promocodes";
|
||||||
|
|
||||||
|
import theme from "@root/theme";
|
||||||
|
|
||||||
|
const columns: GridColDef[] = [
|
||||||
|
{ field: "id", headerName: "ID", width: 30, sortable: false },
|
||||||
|
{
|
||||||
|
field: "name",
|
||||||
|
headerName: "Название промокода",
|
||||||
|
width: 200,
|
||||||
|
sortable: false,
|
||||||
|
},
|
||||||
|
{ 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,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export const PromocodesList = () => {
|
||||||
|
const { promocodes } = usePromocodeStore();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box style={{ width: "80%", marginTop: "55px" }}>
|
||||||
|
<Box style={{ height: 400 }}>
|
||||||
|
<DataGrid
|
||||||
|
checkboxSelection={true}
|
||||||
|
rows={promocodes}
|
||||||
|
columns={columns}
|
||||||
|
sx={{
|
||||||
|
color: theme.palette.secondary.main,
|
||||||
|
"& .MuiDataGrid-iconSeparator": { display: "none" },
|
||||||
|
"& .css-levciy-MuiTablePagination-displayedRows": {
|
||||||
|
color: theme.palette.secondary.main,
|
||||||
|
},
|
||||||
|
"& .MuiSvgIcon-root": { color: theme.palette.secondary.main },
|
||||||
|
"& .MuiTablePagination-selectLabel": {
|
||||||
|
color: theme.palette.secondary.main,
|
||||||
|
},
|
||||||
|
"& .MuiInputBase-root": { color: theme.palette.secondary.main },
|
||||||
|
"& .MuiButton-text": { color: theme.palette.secondary.main },
|
||||||
|
}}
|
||||||
|
components={{ Toolbar: GridToolbar }}
|
||||||
|
onSelectionModelChange={(ids) => console.log("datagrid select")}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
};
|
30
src/pages/dashboard/Content/PromocodeManagement/index.tsx
Normal file
30
src/pages/dashboard/Content/PromocodeManagement/index.tsx
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
import { Typography } from "@mui/material";
|
||||||
|
import { LocalizationProvider } from "@mui/x-date-pickers/LocalizationProvider";
|
||||||
|
import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs";
|
||||||
|
|
||||||
|
import { PromocodesList } from "./PromocodesList";
|
||||||
|
import { CreatePromocodeForm } from "./CreatePromocodeForm";
|
||||||
|
|
||||||
|
import theme from "@root/theme";
|
||||||
|
|
||||||
|
export const PromocodeManagement = () => (
|
||||||
|
<LocalizationProvider dateAdapter={AdapterDayjs}>
|
||||||
|
<Typography
|
||||||
|
variant="subtitle1"
|
||||||
|
sx={{
|
||||||
|
width: "90%",
|
||||||
|
height: "60px",
|
||||||
|
display: "flex",
|
||||||
|
flexDirection: "column",
|
||||||
|
justifyContent: "center",
|
||||||
|
alignItems: "center",
|
||||||
|
textTransform: "uppercase",
|
||||||
|
color: theme.palette.secondary.main,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Создание промокода
|
||||||
|
</Typography>
|
||||||
|
<CreatePromocodeForm />
|
||||||
|
<PromocodesList />
|
||||||
|
</LocalizationProvider>
|
||||||
|
);
|
Loading…
Reference in New Issue
Block a user