adminFront/src/pages/dashboard/Content/Discounts/index.tsx
2023-02-20 14:49:35 +03:00

698 lines
21 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 * as React from "react";
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, GridSelectionModel, GridToolbar } from "@mui/x-data-grid";
import MenuItem from "@mui/material/MenuItem";
import Select, { SelectChangeEvent } from "@mui/material/Select";
import theme from "../../../../theme";
import { styled } from "@mui/material/styles";
import { Discount } from "../../../../model/cart";
import { useDiscountStore } from "../../../../stores/discounts";
const BoxButton = styled('div')(({ theme }) => ({
[theme.breakpoints.down(400)]: {
justifyContent: 'center'
},
}));
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,
},
{
field: "active",
headerName: "Активна",
width: 100,
sortable: false,
},
{
field: "basketMore",
headerName: "Корзина больше",
width: 140,
sortable: false,
}
,
{
field: "toTime",
headerName: "На время",
width: 140,
sortable: false,
}
,
{
field: "toCapacity",
headerName: "На объем",
width: 140,
sortable: false,
}
];
const Discounts: React.FC = () => {
const [checkboxState, setCheckboxState] = React.useState<boolean>(false);
const toggleCheckbox = () => { setCheckboxState(!checkboxState); };
const [value1, setValue1] = React.useState<Date>(new Date());
const [value2, setValue2] = React.useState<Date>(new Date());
const [service, setService] = React.useState("Шаблонизатор");
const handleChange = (event: SelectChangeEvent) => {
setService(event.target.value as string);
};
const discountsArray = useDiscountStore(state => state.discountsArray);
const discountsArraySet = useDiscountStore(state => state.setDiscountsArray);
const discountsActiveArray = useDiscountStore(state => state.discountsActiveArray);
const discountsActiveArraySet = useDiscountStore(state => state.setDiscountsActiveArray);
let discountsActiveArrayUpdated: Array<number>;
const findActiveDiscounts = () => {
const actives: Array<number> = [];
discountsArray.forEach((item, i) => {
if (item.active == true) { actives.push(i); }
});
discountsActiveArrayUpdated = [...actives];
if (JSON.stringify(discountsActiveArray) != JSON.stringify(discountsActiveArrayUpdated)) {
discountsActiveArraySet(discountsActiveArrayUpdated);
}
};
findActiveDiscounts();
const discountsArrayConverted = discountsArray.map((item) => {
const basketMorePerc = Math.round(Number(item.basketMore) * 100) + "%";
const toTimePerc = Math.round(Number(item.toTime) * 100) + "%";
const toCapacityPerc = Math.round(Number(item.toCapacity) * 100) + "%";
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.good} - ${privilege.discount}%`
: `${privilege.good} - ${Math.round(privilege.discount * 100)}%`;
return acc;
}, "");
return {
...item, privileges: result, from: strFrom, dueTo: strDueTo,
basketMore: basketMorePerc, toTime: toTimePerc, toCapacity: toCapacityPerc
};
} else {
return {
...item, from: strFrom, dueTo: strDueTo,
basketMore: basketMorePerc, toTime: toTimePerc, toCapacity: toCapacityPerc
};
}
});
const createDiscount = (name: string,
discount: number,
addedMore: number,
basketMore: number,
toTime: number,
toCapacity: number,) => {
const newDiscount = {
id: new Date().getTime(),
name,
endless: checkboxState,
incomeMore: addedMore,
from: checkboxState ? "" : new Date(value1).getTime() + "",
dueTo: checkboxState ? "" : new Date(value2).getTime() + "",
privileges: [{
good: service,
discount: discount / 100
}],
active: false,
basketMore: basketMore / 100,
toTime: toTime / 100,
toCapacity: toCapacity / 100
} as Discount;
const discountsArrayUpdated = [...discountsArray, newDiscount];
discountsArraySet(discountsArrayUpdated);
};
const fieldName = React.useRef<HTMLInputElement | null>(null);
const fieldDiscount = React.useRef<HTMLInputElement | null>(null);
const fieldAddedMore = React.useRef<HTMLInputElement | null>(null);
const basketMore = React.useRef<HTMLInputElement | null>(null);
const toTime = React.useRef<HTMLInputElement | null>(null);
const toCapacity = React.useRef<HTMLInputElement | null>(null);
// const cleraAddedMore = () => {
// if (fieldAddedMore.current) {
// fieldAddedMore.current.value = "";
// }
// }
const checkFields = () => {
if (fieldName.current != null
&& fieldDiscount.current != null
&& fieldAddedMore.current != null
&& basketMore.current != null
&& toTime.current != null
&& toCapacity.current != null) {
createDiscount(fieldName.current.value,
Number(fieldDiscount.current.value),
Number(fieldAddedMore.current.value),
Number(basketMore.current.value),
Number(toTime.current.value),
Number(toCapacity.current.value));
}
};
const discountsSelectedRowsData = useDiscountStore(state => state.discountsSelectedRowsData);
const discountsSelectedRowsDataSet = useDiscountStore(state => state.setDiscountsSelectedRowsData);
const onRowsSelectionHandler = (ids: GridSelectionModel) => {
const result: Array<Discount> = [];
ids.forEach((id) => discountsArray.forEach((row) => {
if (row.id === id) result.push(row);
}));
discountsSelectedRowsDataSet([...result]);
};
const activation = (value: boolean) => {
discountsArray.forEach((item, i) => {
discountsSelectedRowsData.forEach((selected) => {
if (item.id == selected.id) {
if (value) {
discountsArray[i].active = true;
} else {
discountsArray[i].active = false;
}
}
});
});
discountsArraySet(discountsArray);
};
const PositiveInput = (event: any) => {
const numberInput = parseInt(event.target.value);
if (isNaN(numberInput) || numberInput < 0) { event.target.value = '0'; }
};
return (
<React.Fragment>
<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",
}}
>
<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",
paddingLeft: '10px',
}}>
Условия:
</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}
/>
<TextField
id="standard-basic"
label={"Внесено больше"}
variant="filled"
color="secondary"
type="number"
sx={{
marginTop: "15px"
}}
InputProps={{
style: {
backgroundColor: theme.palette.content.main,
color: theme.palette.secondary.main,
}
}}
InputLabelProps={{
style: {
color: theme.palette.secondary.main
}
}}
inputRef={fieldAddedMore}
onChange={PositiveInput}
/>
<TextField
id="standard-basic"
label={"Объем в корзине"}
variant="filled"
color="secondary"
type="number"
sx={{
marginTop: "15px"
}}
InputProps={{
style: {
backgroundColor: theme.palette.content.main,
color: theme.palette.secondary.main,
}
}}
InputLabelProps={{
style: {
color: theme.palette.secondary.main
}
}}
inputRef={basketMore}
onChange={PositiveInput}
/>
<TextField
id="standard-basic"
label={"На время"}
variant="filled"
color="secondary"
type="number"
sx={{
marginTop: "15px"
}}
InputProps={{
style: {
backgroundColor: theme.palette.content.main,
color: theme.palette.secondary.main,
}
}}
InputLabelProps={{
style: {
color: theme.palette.secondary.main
}
}}
inputRef={toTime}
onChange={PositiveInput}
/>
<TextField
id="standard-basic"
label={"На объем"}
variant="filled"
color="secondary"
type="number"
sx={{
marginTop: "15px"
}}
InputProps={{
style: {
backgroundColor: theme.palette.content.main,
color: theme.palette.secondary.main,
}
}}
InputLabelProps={{
style: {
color: theme.palette.secondary.main
}
}}
inputRef={toCapacity}
onChange={PositiveInput}
/>
<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={() => checkFields()} >
Cоздать
</Button>
</Box>
</Box>
<Box style={{ width: "80%", marginTop: "55px" }}>
<Box style={{ height: 400 }}>
<DataGrid
checkboxSelection={true}
rows={discountsArrayConverted}
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) => onRowsSelectionHandler(ids)}
/>
</Box>
</Box>
<Box sx={{
display: "flex",
flexDirection: "column",
justifyContent: "center",
alignItems: "center",
width: '100%',
marginTop: "45px"
}}>
<BoxButton sx={{
maxWidth: "420px",
width: '100%',
display: "flex",
justifyContent: "space-between",
flexWrap: 'wrap',
}}>
<Button
variant="contained"
onClick={() => activation(false)}
sx={{
backgroundColor: theme.palette.menu.main,
width: "200px",
height: "48px",
fontWeight: "normal",
fontSize: "17px",
marginBottom: '10px',
"&:hover": {
backgroundColor: theme.palette.grayMedium.main
}
}}>
Деактивировать
</Button>
<Button
variant="contained"
onClick={() => activation(true)}
sx={{
backgroundColor: theme.palette.menu.main,
width: "200px",
height: "48px",
fontWeight: "normal",
fontSize: "17px",
"&:hover": {
backgroundColor: theme.palette.grayMedium.main
}
}}>
Применить
</Button>
</BoxButton>
</Box>
</LocalizationProvider>
</React.Fragment>
);
};
export default Discounts;