add tariffs page functionality

This commit is contained in:
nflnkr 2023-03-06 16:26:55 +03:00
parent 4d4daaa1aa
commit e057333c0d
4 changed files with 237 additions and 1017 deletions

@ -0,0 +1,165 @@
import { Typography, Container, Button, Select, MenuItem, FormControl, InputLabel, TextField, useTheme, Box } from "@mui/material";
import { Tariff } from "@root/model/tariff";
import { usePrivilegeStore } from "@root/stores/privileges";
import { useTariffStore } from "@root/stores/tariffs";
import { nanoid } from "nanoid";
import { ChangeEvent, HTMLInputTypeAttribute, useState } from "react";
export default function CreateTariff() {
const theme = useTheme();
const privileges = usePrivilegeStore(store => store.privileges);
const addTariffs = useTariffStore(store => store.addTariffs);
const [nameField, setNameField] = useState<string>("");
const [amountField, setAmountField] = useState<string>("");
const [customPriceField, setCustomPriceField] = useState<string>("");
const [privilegeIdField, setPrivilegeIdField] = useState<string | "">("");
const privilege = privileges.find(p => p.privilegeId === privilegeIdField);
function handleCreateTariffClick() {
const amount = Number(amountField);
const customPricePerUnit = Number(customPriceField);
if (isNaN(amount) || !privilege) return;
const newTariff: Tariff = {
id: nanoid(5),
name: nameField,
amount,
privilege,
customPricePerUnit: customPricePerUnit ? customPricePerUnit : undefined,
};
addTariffs([newTariff]);
}
return (
<Container sx={{
p: "20px",
border: "1px solid rgba(224, 224, 224, 1)",
borderRadius: "4px",
display: "flex",
flexDirection: "column",
gap: "12px",
}}>
<Typography variant="h6" sx={{ textAlign: "center", mb: "16px" }}>Создание кастомного тарифа</Typography>
<FormControl
fullWidth
sx={{
height: "52px",
color: theme.palette.secondary.main,
"& .MuiInputLabel-outlined": {
color: theme.palette.secondary.main,
},
"& .MuiInputLabel-outlined.MuiInputLabel-shrink": {
color: theme.palette.secondary.main,
}
}}
>
<InputLabel
id="privilege-select-label"
sx={{
color: theme.palette.secondary.main,
fontSize: "16px",
lineHeight: "19px",
}}
>Привелегия</InputLabel>
<Select
labelId="privilege-select-label"
id="privilege-select"
value={privilegeIdField}
label="Привелегия"
onChange={e => setPrivilegeIdField(e.target.value)}
sx={{
color: theme.palette.secondary.main,
borderColor: theme.palette.secondary.main,
"&.Mui-focused .MuiOutlinedInput-notchedOutline": {
borderColor: theme.palette.secondary.main,
border: "1px solid",
},
".MuiSvgIcon-root ": {
fill: theme.palette.secondary.main,
}
}}
inputProps={{ sx: { pt: "12px" } }}
>
{privileges.map((privilege, index) => (
<MenuItem key={index} value={privilege.privilegeId}>
{privilege.description}
</MenuItem>
))}
</Select>
</FormControl>
{privilege &&
<Box sx={{
display: "flex",
flexDirection: "column",
}}>
<Typography>Имя: <span>{privilege.name}</span></Typography>
<Typography>Сервис: <span>{privilege.serviceKey}</span></Typography>
<Typography>Единица: <span>{privilege.type}</span></Typography>
<Typography>Стандартная цена за единицу: <span>{privilege.pricePerUnit}</span></Typography>
</Box>
}
<CustomTextField
id="tariff-name"
label="Название тарифа"
value={nameField}
setValue={e => setNameField(e.target.value)}
/>
<CustomTextField
id="tariff-amount"
label="Кол-во единиц привилегии"
value={amountField}
setValue={e => setAmountField(e.target.value)}
type="number"
/>
<CustomTextField
id="tariff-custom-price"
label="Кастомная цена за единицу (не обязательно)"
value={customPriceField}
setValue={e => setCustomPriceField(e.target.value)}
type="number"
/>
<Button
onClick={handleCreateTariffClick}
disabled={privilegeIdField === "" || amountField === "" || nameField === ""}
>Создать</Button>
</Container>
);
}
function CustomTextField({ id, label, value, type, setValue }: {
id: string;
label: string;
value: number | string | null;
type?: HTMLInputTypeAttribute;
setValue: (e: ChangeEvent<HTMLInputElement>) => void;
}) {
const theme = useTheme();
return (
<TextField
fullWidth
id={id}
label={label}
variant="filled"
color="secondary"
type={type}
InputProps={{
style: {
backgroundColor: theme.palette.content.main,
color: theme.palette.secondary.main,
}
}}
InputLabelProps={{
style: {
color: theme.palette.secondary.main
}
}}
value={value ? value : ""}
onChange={setValue}
/>
);
}

File diff suppressed because it is too large Load Diff

@ -1,28 +1,32 @@
import * as React from "react";
import { GridColDef } from "@mui/x-data-grid";
import DataGrid from "@kitUI/datagrid";
import privilegesStore from "@stores/privileges";
import { usePrivilegeStore } from "@stores/privileges";
const columns: GridColDef[] = [
{ field: 'id', headerName: 'id', width: 40 },
{ field: 'name', headerName: 'Привелегия', width: 150 },
{ field: 'description', headerName: 'Описание', width: 550 },//инфо из гитлаба.
{ field: 'type', headerName: 'Тип', width: 150 },
{ field: 'price', headerName: 'Стоимость', width: 50 }
]
export default () => {
const {privileges} = privilegesStore()
let rows = []
if (Object.keys(privileges).length !== 0) {
for (let [id, value] of Object.entries(privileges)) {
rows.push({id:id,name:value.name,description:value.description,type:value.type,price:value.price})
}
}
];
export default function PrivilegesDG() {
const privileges = usePrivilegeStore(state => state.privileges);
const privilegesGridData = privileges.map(privilege => ({
id: privilege.privilegeId,
name: privilege.name,
description: privilege.description,
type: privilege.type,
price: privilege.pricePerUnit,
}));
return (
<DataGrid
checkboxSelection={true}
rows={ rows }
// checkboxSelection={true}
rows={privilegesGridData}
columns={columns}
/>
);

@ -1,27 +1,46 @@
import * as React from "react";
import { GridColDef, GridSelectionModel, GridToolbar } from "@mui/x-data-grid";
import DataGrid from "@kitUI/datagrid";
import { useTariffStore } from "@root/stores/tariffs";
import { SERVICE_LIST } from "@root/model/tariff";
const columns: GridColDef[] = [
{ field: 'id', headerName: 'ID', width: 150 },
{ field: 'id', headerName: 'Название тарифа', width: 150 },
{ field: 'id', headerName: 'Сервис', width: 150 },//инфо из гитлаба.
{ field: 'id', headerName: 'Гигабайты', width: 150 },
{ field: 'id', headerName: 'Привелегия', width: 150 },
{ field: 'id', headerName: 'Количество привелегии', width: 150 },
{ field: 'id', headerName: 'Условия', width: 150 },
]
{ field: 'id', headerName: 'ID', width: 100 },
{ field: 'name', headerName: 'Название тарифа', width: 150 },
{ field: 'serviceName', headerName: 'Сервис', width: 150 },//инфо из гитлаба.
{ field: 'privilege', headerName: 'Привелегия', width: 150 },
{ field: 'amount', headerName: 'Количество', width: 110 },
{ field: 'type', headerName: 'Единица', width: 100 },
{ field: 'pricePerUnit', headerName: 'Цена за ед.', width: 100 },
{ field: 'isCustomPrice', headerName: 'Кастомная цена', width: 130 },
];
export default () => {
interface Props {
handleSelectionChange: (selectionModel: GridSelectionModel) => void;
}
export default function TariffsDG({ handleSelectionChange }: Props) {
const tariffs = useTariffStore(state => state.tariffs);
const gridData = tariffs.map(tariff => ({
id: tariff.id,
name: tariff.name,
serviceName: SERVICE_LIST.find(service => service.serviceKey === tariff.privilege.serviceKey)?.displayName,
privilege: `(${tariff.privilege.privilegeId}) ${tariff.privilege.description}`,
amount: tariff.amount,
type: tariff.privilege.type === "count" ? "день" : "шт.",
pricePerUnit: tariff.customPricePerUnit ?? tariff.privilege.pricePerUnit,
isCustomPrice: tariff.customPricePerUnit === undefined ? "Нет" : "Да",
}));
return (
<DataGrid
checkboxSelection={true}
rows={ [] }
rows={gridData}
columns={columns}
components={{ Toolbar: GridToolbar }}
// onSelectionModelChange={ (ids) => onRowsSelectionHandler( ids ) }
onSelectionModelChange={handleSelectionChange}
/>
);
}