adminFront/src/pages/dashboard/Content/PromocodeManagement/StatisticsModal.tsx
2024-04-13 02:42:30 +03:00

334 lines
9.9 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 { useEffect, useState } from "react";
import {
Box,
Button,
Typography,
Modal,
TextField,
useTheme,
useMediaQuery,
IconButton,
} from "@mui/material";
import { DataGrid, GridLoadingOverlay, GridToolbar } from "@mui/x-data-grid";
import { DatePicker } from "@mui/x-date-pickers/DatePicker";
import { usePrivilegeStore } from "@root/stores/privilegesStore";
import { fadeIn } from "@root/utils/style/keyframes";
import ContentCopyIcon from "@mui/icons-material/ContentCopy";
import type { GridColDef } from "@mui/x-data-grid";
import type { Promocode, PromocodeStatistics } from "@root/model/promocodes";
const host = window.location.hostname;
let isTest = host.includes("s");
type StatisticsModalProps = {
id: string;
to: number;
from: number;
setId: (id: string) => void;
setTo: (date: number) => void;
setFrom: (date: number) => void;
promocodes: Promocode[];
promocodeStatistics: PromocodeStatistics | null | undefined;
createFastLink: (id: string) => Promise<void>;
};
type Row = {
id: number;
link: string;
useCount: number;
};
const COLUMNS: GridColDef<Row, string>[] = [
{
field: "copy",
headerName: "копировать",
width: 50,
sortable: false,
valueGetter: ({ row }) => String(row.useCount),
renderCell: (params) => {
return (
<IconButton
onClick={() =>
navigator.clipboard.writeText(
`https://${isTest ? "s" : ""}hub.pena.digital/?fl=${params.row.link
}`
)
}
>
<ContentCopyIcon />
</IconButton>
);
},
},
{
field: "link",
headerName: "Ссылка",
width: 320,
sortable: false,
valueGetter: ({ row }) => row.link,
renderCell: ({ value }) =>
value?.split("|").map((link) => <Typography>{link}</Typography>),
},
{
field: "useCount",
headerName: "Использований",
width: 120,
sortable: false,
valueGetter: ({ row }) => String(row.useCount),
},
{
field: "purchasesCount",
headerName: "Покупок",
width: 70,
sortable: false,
valueGetter: ({ row }) => String(0),
},
];
export const StatisticsModal = ({
id,
setId,
setFrom,
from,
to,
setTo,
promocodeStatistics,
promocodes,
createFastLink,
}: StatisticsModalProps) => {
const [startDate, setStartDate] = useState<Date>(new Date());
const [endDate, setEndDate] = useState<Date>(new Date());
const theme = useTheme();
const isMobile = useMediaQuery(theme.breakpoints.down(550));
const [rows, setRows] = useState<Row[]>([]);
const { privileges } = usePrivilegeStore();
const currentPrivilegeId = promocodes.find((promocode) => promocode.id === id)
?.bonus.privilege.privilegeID;
const privilege =
privileges.find((item) => item.privilegeId === currentPrivilegeId);
const promocode =
promocodes.find((item) => item.id === id);
console.log(promocode)
const createFastlink = async () => {
await createFastLink(id);
getParseData();
};
const getParseData = async () => {
const rows = promocodes
.find((promocode) => promocode.id === id)
?.fastLinks?.map((link, index) => ({
link,
id: index,
useCount: promocodeStatistics?.usageMap[link] ?? 0,
})) as Row[];
setRows(rows);
};
useEffect(() => {
if (id.length > 0) {
getParseData();
}
if (!id) {
setRows([]);
}
}, [id]);
// const formatTo = to === null ? 0 : moment(to).unix()
// const formatFrom = from === null ? 0 : moment(from).unix()
// useEffect(() => {
// (async () => {
// const gottenGeneral = await promocodeStatistics(id, startDate, endDate)
// setGeneral(gottenGeneral[0])
// })()
// }, [to, from]);
return (
<Modal
open={Boolean(id)}
onClose={() => {
setId("");
setStartDate(new Date());
setEndDate(new Date());
}}
sx={{
"& > .MuiBox-root": { outline: "none", padding: "32px 32px 16px" },
}}
>
<Box
sx={{
position: "absolute",
top: "50%",
left: "50%",
transform: "translate(-50%, -50%)",
width: "95%",
maxWidth: "600px",
background: "#1F2126",
border: "2px solid gray",
borderRadius: "6px",
boxShadow: 24,
p: 4,
}}
>
<Box
sx={{
display: "flex",
gap: "30px",
justifyContent: "center",
alignItems: "center",
flexDirection: isMobile ? "column" : "row",
}}
>
<Box
sx={{
display: "flex",
gap: "30px",
justifyContent: "center",
alignItems: "center",
}}
>
<Button sx={{ maxWidth: "100px" }} onClick={createFastlink}>
Создать короткую ссылку
</Button>
<Button sx={{ maxWidth: "100px" }} onClick={getParseData}>
Обновить статистику
</Button>
</Box>
<Box sx={{ minWidth: "200px" }}>
<Box sx={{ display: "flex", alignItems: "center", gap: "10px" }}>
<Typography sx={{ minWidth: "20px", color: "#FFFFFF" }}>
от
</Typography>
<DatePicker
inputFormat="DD/MM/YYYY"
value={startDate}
onChange={(date) => date && setStartDate(date)}
renderInput={(params) => (
<TextField
{...params}
sx={{ background: "#1F2126", borderRadius: "5px" }}
/>
)}
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",
alignItems: "center",
gap: "10px",
marginTop: "10px",
}}
>
<Typography sx={{ minWidth: "20px", color: "#FFFFFF" }}>
до
</Typography>
<DatePicker
inputFormat="DD/MM/YYYY"
value={endDate}
onChange={(date) => date && setEndDate(date)}
renderInput={(params) => (
<TextField
{...params}
sx={{ background: "#1F2126", borderRadius: "5px" }}
/>
)}
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>
</Box>
<DataGrid
disableSelectionOnClick={true}
rows={rows}
columns={COLUMNS}
sx={{
marginTop: "30px",
background: "#1F2126",
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 },
"& .MuiDataGrid-overlay": {
backgroundColor: "rgba(255, 255, 255, 0.1)",
animation: `${fadeIn} 0.5s ease-out`,
},
"& .MuiDataGrid-virtualScrollerContent": { maxHeight: "200px" },
"& .MuiDataGrid-virtualScrollerRenderZone": {
maxHeight: "200px",
overflowY: "auto",
},
}}
components={{
Toolbar: GridToolbar,
LoadingOverlay: GridLoadingOverlay,
}}
rowsPerPageOptions={[10, 25, 50, 100]}
autoHeight
/>
{
privilege === undefined ?
<Typography
sx={{
margin: "10px 0 0",
textAlign: "center",
color: theme.palette.secondary.main,
}}
>
Нет привилегии
</Typography>
:
<Box
sx={{
color: "#e6e8ec",
display: "flex",
flexDirection: "column",
margin: "20px 0",
}}
>
<Typography>название привилегии: {privilege.name}</Typography>
<Typography>{promocode?.activationCount} активаций из {promocode?.activationLimit}</Typography>
<Typography>приветствие: "{promocode?.greetings}"</Typography>
{promocode?.bonus?.discount?.factor !== undefined && <Typography>скидка: {100 - (promocode?.bonus?.discount?.factor * 100)}%</Typography>}
{<Typography>количество привилегии: {promocode?.bonus?.privilege?.amount}</Typography>}
{promocode?.dueTo !== undefined && promocode.dueTo > 0 && <Typography>действует до: {new Date(promocode.dueTo).toLocaleString()}</Typography>}
</Box>
}
</Box>
</Modal>
);
};