adminFront/src/pages/dashboard/Content/PromocodeManagement/StatisticsModal.tsx

314 lines
8.8 KiB
TypeScript
Raw Normal View History

2024-03-30 20:19:53 +00:00
import { useEffect, useState } from "react";
2024-03-26 15:41:22 +00:00
import {
Box,
Button,
Typography,
Modal,
TextField,
useTheme,
useMediaQuery,
IconButton,
2024-03-26 15:41:22 +00:00
} from "@mui/material";
import { DataGrid, GridLoadingOverlay, GridToolbar } from "@mui/x-data-grid";
import { DatePicker } from "@mui/x-date-pickers/DatePicker";
2024-03-26 15:41:22 +00:00
2024-04-12 13:38:50 +00:00
import { usePrivilegeStore } from "@root/stores/privilegesStore";
2024-03-26 15:41:22 +00:00
import { fadeIn } from "@root/utils/style/keyframes";
2024-04-02 13:21:17 +00:00
import ContentCopyIcon from "@mui/icons-material/ContentCopy";
import type { GridColDef } from "@mui/x-data-grid";
2024-04-02 14:56:23 +00:00
import type { Promocode, PromocodeStatistics } from "@root/model/promocodes";
2024-03-26 15:41:22 +00:00
2024-04-12 09:26:36 +00:00
const host = window.location.hostname;
let isTest = host.includes("s");
2024-03-26 15:41:22 +00:00
type StatisticsModalProps = {
id: string;
to: number;
from: number;
2024-03-26 15:41:22 +00:00
setId: (id: string) => void;
setTo: (date: number) => void;
setFrom: (date: number) => void;
2024-04-02 13:21:17 +00:00
promocodes: Promocode[];
2024-04-02 14:56:23 +00:00
promocodeStatistics: PromocodeStatistics | null | undefined;
createFastLink: (id: string) => Promise<void>;
2024-03-26 15:41:22 +00:00
};
2024-04-02 13:21:17 +00:00
type Row = {
id: number;
link: string;
useCount: number;
};
const COLUMNS: GridColDef<Row, string>[] = [
{
field: "copy",
headerName: "копировать",
width: 50,
sortable: false,
2024-04-02 13:21:17 +00:00
valueGetter: ({ row }) => String(row.useCount),
renderCell: (params) => {
return (
2024-04-02 13:21:17 +00:00
<IconButton
2024-04-12 13:38:50 +00:00
onClick={() =>
navigator.clipboard.writeText(
`https://${isTest ? "s" : ""}hub.pena.digital/?fl=${
params.row.link
}`
)
}
2024-04-02 13:21:17 +00:00
>
<ContentCopyIcon />
</IconButton>
);
},
},
2024-03-26 15:41:22 +00:00
{
field: "link",
headerName: "Ссылка",
width: 320,
sortable: false,
valueGetter: ({ row }) => row.link,
2024-04-02 14:56:23 +00:00
renderCell: ({ value }) =>
value?.split("|").map((link) => <Typography>{link}</Typography>),
2024-03-26 15:41:22 +00:00
},
{
field: "useCount",
headerName: "Использований",
width: 120,
sortable: false,
valueGetter: ({ row }) => String(row.useCount),
},
{
field: "purchasesCount",
headerName: "Покупок",
width: 70,
sortable: false,
2024-04-02 14:56:23 +00:00
valueGetter: ({ row }) => String(0),
2024-03-26 15:41:22 +00:00
},
];
export const StatisticsModal = ({
id,
setId,
setFrom,
from,
to,
setTo,
2024-04-02 14:56:23 +00:00
promocodeStatistics,
2024-04-02 13:21:17 +00:00
promocodes,
2024-04-02 14:56:23 +00:00
createFastLink,
2024-03-26 15:41:22 +00:00
}: 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));
2024-04-02 13:21:17 +00:00
const [rows, setRows] = useState<Row[]>([]);
2024-04-12 13:38:50 +00:00
const { privileges } = usePrivilegeStore();
const currentPrivilegeId = promocodes.find((promocode) => promocode.id === id)
?.bonus.privilege.privilegeID;
const privilegeName =
privileges.find((item) => item.privilegeId === currentPrivilegeId)?.name ??
"Нет привилегии";
const createFastlink = async () => {
2024-04-02 14:56:23 +00:00
await createFastLink(id);
2024-04-02 13:21:17 +00:00
getParseData();
};
2024-03-30 20:19:53 +00:00
const getParseData = async () => {
2024-04-02 14:56:23 +00:00
const rows = promocodes
.find((promocode) => promocode.id === id)
?.fastLinks?.map((link, index) => ({
link,
2024-04-02 13:21:17 +00:00
id: index,
2024-04-02 14:56:23 +00:00
useCount: promocodeStatistics?.usageMap[link] ?? 0,
})) as Row[];
2024-04-02 13:21:17 +00:00
setRows(rows);
};
2024-03-30 20:19:53 +00:00
useEffect(() => {
2024-04-02 13:21:17 +00:00
if (id.length > 0) {
getParseData();
}
if (!id) {
setRows([]);
}
}, [id]);
2024-03-30 20:19:53 +00:00
// 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]);
2024-03-26 15:41:22 +00:00
return (
<Modal
open={Boolean(id)}
onClose={() => {
2024-04-02 13:21:17 +00:00
setId("");
setStartDate(new Date());
setEndDate(new Date());
}}
2024-04-12 13:38:50 +00:00
sx={{
"& > .MuiBox-root": { outline: "none", padding: "32px 32px 16px" },
}}
2024-03-26 15:41:22 +00:00
>
<Box
sx={{
position: "absolute",
top: "50%",
left: "50%",
transform: "translate(-50%, -50%)",
width: "95%",
maxWidth: "600px",
2024-03-27 07:35:28 +00:00
background: "#1F2126",
2024-03-26 15:41:22 +00:00
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",
}}
>
2024-04-02 13:21:17 +00:00
<Button sx={{ maxWidth: "100px" }} onClick={createFastlink}>
2024-03-26 15:41:22 +00:00
Создать короткую ссылку
</Button>
2024-04-02 13:21:17 +00:00
<Button sx={{ maxWidth: "100px" }} onClick={getParseData}>
2024-03-26 15:41:22 +00:00
Обновить статистику
</Button>
</Box>
<Box sx={{ minWidth: "200px" }}>
<Box sx={{ display: "flex", alignItems: "center", gap: "10px" }}>
2024-03-27 07:35:28 +00:00
<Typography sx={{ minWidth: "20px", color: "#FFFFFF" }}>
от
</Typography>
<DatePicker
2024-03-26 15:41:22 +00:00
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",
}}
>
2024-03-27 07:35:28 +00:00
<Typography sx={{ minWidth: "20px", color: "#FFFFFF" }}>
до
</Typography>
<DatePicker
2024-03-26 15:41:22 +00:00
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}
2024-03-30 20:19:53 +00:00
rows={rows}
2024-03-26 15:41:22 +00:00
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`,
},
2024-04-02 14:56:23 +00:00
"& .MuiDataGrid-virtualScrollerContent": { maxHeight: "200px" },
"& .MuiDataGrid-virtualScrollerRenderZone": {
maxHeight: "200px",
overflowY: "auto",
},
2024-03-26 15:41:22 +00:00
}}
components={{
Toolbar: GridToolbar,
LoadingOverlay: GridLoadingOverlay,
}}
rowsPerPageOptions={[10, 25, 50, 100]}
autoHeight
/>
2024-04-12 13:38:50 +00:00
<Typography
sx={{
margin: "10px 0 0",
textAlign: "center",
color: theme.palette.secondary.main,
}}
>
{privilegeName}
</Typography>
2024-03-26 15:41:22 +00:00
</Box>
</Modal>
);
};