крако, привелегии в зустанд, корзина в ките
This commit is contained in:
parent
8a5ff4441b
commit
3741c78391
17
craco.config.js
Normal file
17
craco.config.js
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
const CracoAlias = require("craco-alias");
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
plugins: [
|
||||||
|
{
|
||||||
|
plugin: CracoAlias,
|
||||||
|
options: {
|
||||||
|
source: "tsconfig",
|
||||||
|
// baseUrl SHOULD be specified
|
||||||
|
// plugin does not take it from tsconfig
|
||||||
|
baseUrl: "./src",
|
||||||
|
// tsConfigPath should point to the file where "baseUrl" and "paths" are specified
|
||||||
|
tsConfigPath: "./tsconfig.extend.json"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
6684
package-lock.json
generated
6684
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
12
package.json
12
package.json
@ -21,6 +21,7 @@
|
|||||||
"@types/node": "^16.11.56",
|
"@types/node": "^16.11.56",
|
||||||
"@types/react": "^18.0.18",
|
"@types/react": "^18.0.18",
|
||||||
"@types/react-dom": "^18.0.6",
|
"@types/react-dom": "^18.0.6",
|
||||||
|
"craco": "^0.0.3",
|
||||||
"dayjs": "^1.11.5",
|
"dayjs": "^1.11.5",
|
||||||
"moment": "^2.29.4",
|
"moment": "^2.29.4",
|
||||||
"numeral": "^2.0.6",
|
"numeral": "^2.0.6",
|
||||||
@ -35,10 +36,10 @@
|
|||||||
"zustand": "^4.1.1"
|
"zustand": "^4.1.1"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "react-scripts start",
|
"start": "craco start",
|
||||||
"build": "react-scripts build",
|
"build": "craco build",
|
||||||
"test": "react-scripts test",
|
"test": "craco test",
|
||||||
"eject": "react-scripts eject"
|
"eject": "craco eject"
|
||||||
},
|
},
|
||||||
"eslintConfig": {
|
"eslintConfig": {
|
||||||
"extends": [
|
"extends": [
|
||||||
@ -57,5 +58,8 @@
|
|||||||
"last 1 firefox version",
|
"last 1 firefox version",
|
||||||
"last 1 safari version"
|
"last 1 safari version"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"craco-alias": "^3.0.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
12
src/__tests__/test.test.js
Normal file
12
src/__tests__/test.test.js
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
const puppeteer = require('puppeteer');
|
||||||
|
|
||||||
|
(async () => {
|
||||||
|
const browser = await puppeteer.launch();
|
||||||
|
const page = await browser.newPage();
|
||||||
|
await page.goto('https://news.ycombinator.com', {
|
||||||
|
waitUntil: 'networkidle2',
|
||||||
|
});
|
||||||
|
await page.pdf({ path: 'hn.pdf', format: 'a4' });
|
||||||
|
|
||||||
|
await browser.close();
|
||||||
|
})();
|
87
src/kitUI/basket/calc.ts
Normal file
87
src/kitUI/basket/calc.ts
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
// export const setPromocode = (name: string) => {
|
||||||
|
// let codeNumber = -1;
|
||||||
|
//
|
||||||
|
// promocodeArray.forEach((item, i) => {
|
||||||
|
// if (name != "" && item.name == name) codeNumber = i;
|
||||||
|
// });
|
||||||
|
//
|
||||||
|
// setSelectedPromocode(codeNumber);
|
||||||
|
// }
|
||||||
|
|
||||||
|
export const PositiveInput = (event: any) => {
|
||||||
|
const numberInput = parseInt(event.target.value);
|
||||||
|
if (isNaN(numberInput) || numberInput < 0) {
|
||||||
|
event.target.value = '0'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// export const calcPriseTariff () => {
|
||||||
|
//
|
||||||
|
// // считаем цену в ТАРИФАХ
|
||||||
|
// price = item.price;
|
||||||
|
// percents = 0;
|
||||||
|
// discounts = "";
|
||||||
|
//
|
||||||
|
// // применяем скидки по промокоду
|
||||||
|
// if (selectedPromocode >= 0) {
|
||||||
|
// promocodeArray[selectedPromocode].privileges.forEach((privilege) => {
|
||||||
|
// console.log(item.service)
|
||||||
|
// console.log(privilege.good)
|
||||||
|
// if (item.service == privilege.good) {
|
||||||
|
// appliedDscnts.push(privilege.discount)
|
||||||
|
// price *= (1 - privilege.discount)
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
// } else {
|
||||||
|
// // применяем активные скидки
|
||||||
|
// if (fitDiscounts.length >= 0) {
|
||||||
|
// fitDiscounts.forEach((activeDiscount) => {
|
||||||
|
// const discount = discountsArray[activeDiscount]
|
||||||
|
// discount.privileges.forEach((p) => {
|
||||||
|
// const svcName = item.service.split(' ')[0]
|
||||||
|
// if (p.good == svcName) {
|
||||||
|
// const summary = cartSummary.get(svcName) || {
|
||||||
|
// mbs: 0,
|
||||||
|
// points: 0,
|
||||||
|
// days: 0
|
||||||
|
// }
|
||||||
|
// if (discount.toCapacity === 0 && discount.toTime === 0 && discount.basketMore === 0 && !(discount.incomeMore) ||
|
||||||
|
// discount.toCapacity > 0 && summary.points > discount.toCapacity && item.points > 0 && discount.toTime == 0
|
||||||
|
// || discount.toTime > 0 && summary.days > discount.toTime * 100 && item.time > 0 && discount.toCapacity == 0 ||
|
||||||
|
// discount.toTime > 0 && discount.toCapacity > 0 && summary.days > discount.toTime * 100 && summary.points > discount.toCapacity) {
|
||||||
|
//
|
||||||
|
// price *= (1 - p.discount)
|
||||||
|
// appliedDscnts.push(p.discount)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
// percents = Number(percents.toFixed(2));
|
||||||
|
//
|
||||||
|
// priceBefore = price;
|
||||||
|
// price = price - (price * percents);
|
||||||
|
// prices += price;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // применяем активные скидки за объем корзины
|
||||||
|
// const discountsAfter = (priceBefore: number) => {
|
||||||
|
// const discounts: Array<number> = [];
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// if (fitDiscounts.length >= 0 && !nonCommercial && selectedPromocode < 0) {
|
||||||
|
// fitDiscounts.forEach((activeDiscount) => {
|
||||||
|
// const d = discountsArray[activeDiscount]
|
||||||
|
// console.log(d)
|
||||||
|
// console.log(fieldAddedValue)
|
||||||
|
// if (d.basketMore > 0 && getPrice > d.basketMore && d.basketMore === fitDiscounts.reduce((a, e) => Math.max(a, discountsArray[e].basketMore), 0) ||
|
||||||
|
// d.incomeMore > 0 && parseInt(fieldAddedValue) > d.incomeMore) {
|
||||||
|
// prices *= (1 - d.privileges[0].discount)
|
||||||
|
// discounts.push(d.privileges[0].discount)
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// }
|
372
src/kitUI/basket/index.tsx
Normal file
372
src/kitUI/basket/index.tsx
Normal file
@ -0,0 +1,372 @@
|
|||||||
|
import * as React from "react";
|
||||||
|
import theme from "@theme";
|
||||||
|
import {Button, Paper, ListItemText, IconButton, FormControlLabel, Box, TextField, Typography, Container, Checkbox, List, ListItem, ListItemAvatar, Avatar} from "@mui/material";
|
||||||
|
import ShoppingCartIcon from "@mui/icons-material/ShoppingCart";
|
||||||
|
import DeleteIcon from "@mui/icons-material/Delete";
|
||||||
|
import Input from "@kitUI/input";
|
||||||
|
import useStore, {StoreState} from "../../stores/store";
|
||||||
|
import {useDemoData} from "@mui/x-data-grid-generator";
|
||||||
|
import {GridSelectionModel} from "@mui/x-data-grid";
|
||||||
|
import {ArrayProps} from "../../pages/dashboard/Content/Tariffs/types";
|
||||||
|
import TableHead from "@mui/material/TableHead";
|
||||||
|
import TableRow from "@mui/material/TableRow";
|
||||||
|
import TableCell from "@mui/material/TableCell";
|
||||||
|
import TableBody from "@mui/material/TableBody";
|
||||||
|
import Radio from "@mui/material/Radio";
|
||||||
|
import Skeleton from "@mui/material/Skeleton";
|
||||||
|
import Table from "@mui/material/Table";
|
||||||
|
|
||||||
|
export default (props:any):any => {
|
||||||
|
// const [added, setAdded] = React.useState<number>(0)
|
||||||
|
// const [notCommercial, setNotCommercial] = React.useState<boolean>(false)
|
||||||
|
//
|
||||||
|
// const setPromocode = (name: string) => {
|
||||||
|
// let codeNumber = -1;
|
||||||
|
//
|
||||||
|
// promocodeArray.forEach((item, i) => {
|
||||||
|
// if (name != "" && item.name == name) codeNumber = i;
|
||||||
|
// });
|
||||||
|
//
|
||||||
|
// setSelectedPromocode(codeNumber);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// const PositiveInput = (event: any) => {
|
||||||
|
// const numberInput = parseInt(event.target.value);
|
||||||
|
// if (isNaN(numberInput) || numberInput < 0) {
|
||||||
|
// event.target.value = '0'
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // const getData = localStorage.getItem("tariffs");
|
||||||
|
// // const store = useStore( (state) => state );
|
||||||
|
// //
|
||||||
|
// // if( getData && !store.tariffsArray.length ) {
|
||||||
|
// // const rows:Array<ArrayProps> = JSON.parse(getData);
|
||||||
|
// // if( rows.length ) { store.tariffsArraySet( rows ); };
|
||||||
|
// // }
|
||||||
|
// let priceBefore = 0;
|
||||||
|
// let price = 0;
|
||||||
|
// let prices = 0;
|
||||||
|
// let percents = 0;
|
||||||
|
// let discounts = "";
|
||||||
|
// let discountsSum = "";
|
||||||
|
//
|
||||||
|
// const { discountsArray, discountsArraySet } = useStore<StoreState>((state) => state);
|
||||||
|
// const { discountsActiveArray, discountsActiveArraySet } = useStore<StoreState>((state) => state);
|
||||||
|
//
|
||||||
|
// const [nonCommercial, setNonCommercial] = React.useState(false);
|
||||||
|
//
|
||||||
|
// const { data } = useDemoData({
|
||||||
|
// dataSet: "Commodity",
|
||||||
|
// rowLength: 10,
|
||||||
|
// maxColumns: 5,
|
||||||
|
// });
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// const { tariffsArray } = useStore<StoreState>((state) => state);
|
||||||
|
// const tariffsArrayConverted = tariffsArray.map( (item) => {
|
||||||
|
// if( item.type === "package" && item.tariffs ) {
|
||||||
|
// const result = item.tariffs.reduce( (acc, tariff) => {
|
||||||
|
// acc.service = acc.service? `${acc.service}, ${tariff.service}` : tariff.service;
|
||||||
|
// acc.disk = acc.disk+ tariff.disk;
|
||||||
|
// acc.time = acc.time+ tariff.time;
|
||||||
|
// acc.points = acc.points + tariff.points;
|
||||||
|
// acc.price = acc.price + tariff.price;
|
||||||
|
//
|
||||||
|
// return acc;
|
||||||
|
// }, { service: "", disk: "", time: "", points: "", price: 0 } );
|
||||||
|
//
|
||||||
|
// return { id: item.id, name: item.name, type: item.type, ...result }
|
||||||
|
// } else {
|
||||||
|
// return item;
|
||||||
|
// }
|
||||||
|
// } );
|
||||||
|
//
|
||||||
|
// const { tariffsSelectedRowsData, tariffsSelectedRowsDataSet } = useStore<StoreState>((state) => state);
|
||||||
|
// const onRowsSelectionHandler = ( ids:GridSelectionModel ) => {
|
||||||
|
// const result:Array<ArrayProps> = [];
|
||||||
|
// ids.forEach((id) => tariffsArray.forEach( (row) => {
|
||||||
|
// if(row.id === id) result.push(row);
|
||||||
|
// } ) );
|
||||||
|
//
|
||||||
|
// tariffsSelectedRowsDataSet( result );
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// const { cartRowsData, cartRowsDataSet } = useStore<StoreState>((state) => state);
|
||||||
|
// const handleToBasket = () => {
|
||||||
|
// cartRowsDataSet( tariffsSelectedRowsData );
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// const handleRemoveBasket = ( id:number ) => {
|
||||||
|
// const cartFiltered = cartRowsData.filter( (row) => row.id != id );
|
||||||
|
// cartRowsDataSet( cartFiltered );
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// const fieldPromocode = React.useRef<HTMLInputElement | null>(null);
|
||||||
|
// const checkPromocode = () => {
|
||||||
|
// if( fieldPromocode.current != null ) {
|
||||||
|
// setPromocode( fieldPromocode.current.value );
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// let { promocodeArray, promocodeArraySet } = useStore<StoreState>((state) => state);
|
||||||
|
// const [selectedPromocode, setSelectedPromocode] = React.useState( -1 );
|
||||||
|
//
|
||||||
|
// //promocodeArray = [ ...rowz ];
|
||||||
|
//
|
||||||
|
// const setPromocode = ( name:string ) => {
|
||||||
|
// let codeNumber = -1;
|
||||||
|
//
|
||||||
|
// promocodeArray.forEach( (item, i) => {
|
||||||
|
// if( name != "" && item.name == name ) codeNumber = i;
|
||||||
|
// } );
|
||||||
|
//
|
||||||
|
// setSelectedPromocode( codeNumber );
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// const PositiveInput = (event:any) => {
|
||||||
|
// const numberInput = parseInt(event.target.value);
|
||||||
|
// if(isNaN(numberInput) || numberInput < 0) {event.target.value = '0'}
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// const fieldAdded = React.useRef<HTMLInputElement | null>(null);
|
||||||
|
// const [ fieldAddedValue, setFieldAddedValue ] = React.useState("");
|
||||||
|
//
|
||||||
|
// const changeAdded = (event:any) => {
|
||||||
|
// if( fieldAdded.current != null ) {
|
||||||
|
// if( fieldAdded.current.value != null ) {
|
||||||
|
// setFieldAddedValue( fieldAdded.current.value );
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
// PositiveInput(event)
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// const separator = (amount: number) => {
|
||||||
|
// console.log(amount)
|
||||||
|
//
|
||||||
|
// if( String(amount).length < 4 ) { return amount; }
|
||||||
|
//
|
||||||
|
// let result:Array<string> = [];
|
||||||
|
// const arrs = String(amount).split('.')
|
||||||
|
// const arr = arrs[0].split('').reverse();
|
||||||
|
//
|
||||||
|
// arr.forEach( (item, i:number) => {
|
||||||
|
// result.push( String( arr[ i ] ) );
|
||||||
|
// if( ((i+1) / 3) - Math.round((i+1) / 3) == 0 ) result.push(" ");
|
||||||
|
// });
|
||||||
|
//
|
||||||
|
// if( arrs.length > 1 ) { return result.reverse().join("") +"." +arrs[1]; }
|
||||||
|
// else { return result.reverse().join(""); }
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// const cartSummary = new Map()
|
||||||
|
// cartRowsData.forEach((row) => {
|
||||||
|
// const svcName = row.service.split(" ")[0]
|
||||||
|
// const prev = cartSummary.get(svcName)
|
||||||
|
// console.log(row)
|
||||||
|
// console.log(prev)
|
||||||
|
// if (!prev) {
|
||||||
|
// cartSummary.set(svcName, {
|
||||||
|
// mbs: row.disk,
|
||||||
|
// points: row.points,
|
||||||
|
// days: row.time,
|
||||||
|
// })
|
||||||
|
// } else {
|
||||||
|
// cartSummary.set(svcName, {
|
||||||
|
// mbs: row.disk+prev.mbs,
|
||||||
|
// points: row.points+prev.points,
|
||||||
|
// days: row.time+prev.days,
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
// console.log(cartSummary)
|
||||||
|
//
|
||||||
|
// const fitDiscounts = discountsActiveArray.filter(e => {
|
||||||
|
// const d = discountsArray[e]
|
||||||
|
// const summary = cartSummary.get(d.privileges[0].good.split(' ')[0])
|
||||||
|
// return d.incomeMore*100 < parseInt(fieldAddedValue) && d.incomeMore > 0 ||
|
||||||
|
// d.toTime < (summary ? summary.days : 0) && d.toTime > 0 && d.toCapacity === 0 ||
|
||||||
|
// d.toCapacity > 0 && d.toCapacity < (summary ? summary.points : 0) && d.toTime === 0 ||
|
||||||
|
// d.toCapacity > 0 && d.toTime > 0 && d.toCapacity < (summary ? summary.points : 0) && d.toTime < (summary ? summary.days : 0) ||
|
||||||
|
// !d.toCapacity && !d.toTime && !d.incomeMore && !d.basketMore ||
|
||||||
|
// d.basketMore
|
||||||
|
// }).filter((e,i,a)=>{
|
||||||
|
// const d = discountsArray[e]
|
||||||
|
// if (d.incomeMore) {
|
||||||
|
// return d.incomeMore === a.reduce((a, e) => Math.max(a, discountsArray[e].incomeMore || 0), 0 )
|
||||||
|
// }
|
||||||
|
// if (d.toTime && d.toCapacity) {
|
||||||
|
// return d.toTime === a.reduce((a, e) => Math.max(a, (discountsArray[e].toTime && discountsArray[e].toCapacity) ? discountsArray[e].toTime:0 ), 0 ) && d.toCapacity === a.reduce((a, e) => Math.max(a, (discountsArray[e].toCapacity && discountsArray[e].toTime) ? discountsArray[e].toCapacity : 0 ), 0 )
|
||||||
|
// }
|
||||||
|
// if (d.toTime && !d.toCapacity) {
|
||||||
|
// return d.toTime === a.reduce((a, e) => Math.max(a, discountsArray[e].toTime && !discountsArray[e].toCapacity ? discountsArray[e].toTime : 0), 0 )
|
||||||
|
// }
|
||||||
|
// if (!d.toTime && d.toCapacity) {
|
||||||
|
// return d.toCapacity === a.reduce((a, e) => Math.max(a, discountsArray[e].toCapacity && !discountsArray[e].toTime ? discountsArray[e].toCapacity : 0), 0 )
|
||||||
|
// }
|
||||||
|
// return true
|
||||||
|
// })
|
||||||
|
// console.log(fitDiscounts)
|
||||||
|
//
|
||||||
|
// const discountsAfter = ( getPrice:number ) => {
|
||||||
|
// const discounts:Array<number> = [];
|
||||||
|
// priceBefore = getPrice;
|
||||||
|
//
|
||||||
|
// prices = getPrice;
|
||||||
|
// console.log(getPrice)
|
||||||
|
//
|
||||||
|
// // применяем активные скидки за объем корзины
|
||||||
|
//
|
||||||
|
// if( fitDiscounts.length >= 0 && !nonCommercial && selectedPromocode < 0 ) {
|
||||||
|
// fitDiscounts.forEach( (activeDiscount) => {
|
||||||
|
// const d = discountsArray[activeDiscount]
|
||||||
|
// console.log(d)
|
||||||
|
// console.log(fieldAddedValue)
|
||||||
|
// if (d.basketMore > 0 && getPrice > d.basketMore && d.basketMore === fitDiscounts.reduce((a,e) => Math.max(a, discountsArray[e].basketMore), 0) ||
|
||||||
|
// d.incomeMore > 0 && parseInt(fieldAddedValue) > d.incomeMore) {
|
||||||
|
// prices *= (1-d.privileges[0].discount)
|
||||||
|
// discounts.push(d.privileges[0].discount)
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if( nonCommercial ) {
|
||||||
|
// prices *= 0.2
|
||||||
|
// return `80%`;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// return discounts.map(e => `${(e*100).toFixed(2)}%`).join(' × ') + ` = ${(100 - discounts.reduce((a : number,cv : number) => a*(1-cv), 100)) .toFixed(2)}%`;
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box
|
||||||
|
component="section"
|
||||||
|
sx={{
|
||||||
|
border: "1px solid white",
|
||||||
|
display: "flex",
|
||||||
|
flexDirection: "column",
|
||||||
|
alignItems: "center",
|
||||||
|
width: "100%"
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Typography variant="caption">
|
||||||
|
корзина
|
||||||
|
</Typography>
|
||||||
|
<Paper
|
||||||
|
variant="bar"
|
||||||
|
sx={{display:"flex", alignItems:"center", justifyContent: "space-between"}}
|
||||||
|
>
|
||||||
|
<FormControlLabel
|
||||||
|
label="НКО"
|
||||||
|
control={
|
||||||
|
<Checkbox
|
||||||
|
sx={{
|
||||||
|
color: theme.palette.secondary.main,
|
||||||
|
"&.Mui-checked": {
|
||||||
|
color: theme.palette.secondary.main,
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
sx={{
|
||||||
|
color: theme.palette.secondary.main,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Input
|
||||||
|
label="внесено"
|
||||||
|
type="number"
|
||||||
|
size="small"
|
||||||
|
// onChange={(e:React.ChangeEvent<HTMLInputElement>) => setAdded(Number(e.target.value))}
|
||||||
|
/>
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
border: "1px solid white",
|
||||||
|
padding: "3px",
|
||||||
|
display:"flex",
|
||||||
|
flexDirection:"column"
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Input
|
||||||
|
label="промокод"
|
||||||
|
size="small"
|
||||||
|
|
||||||
|
/>
|
||||||
|
<Button sx={{maxWidth:"140px"}}>применить промокод</Button>
|
||||||
|
</Box>
|
||||||
|
<Button>рассчитать</Button>
|
||||||
|
</Paper>
|
||||||
|
|
||||||
|
|
||||||
|
{/*<Table sx={{*/}
|
||||||
|
{/* width: "90%",*/}
|
||||||
|
{/* margin: "5px",*/}
|
||||||
|
{/* border: "2px solid",*/}
|
||||||
|
{/* borderColor: theme.palette.secondary.main,*/}
|
||||||
|
{/*}} aria-label="simple table">*/}
|
||||||
|
{/* <TableHead>*/}
|
||||||
|
{/* <TableRow sx={{*/}
|
||||||
|
{/* borderBottom: "2px solid",*/}
|
||||||
|
{/* borderColor: theme.palette.grayLight.main,*/}
|
||||||
|
{/* height: "100px"*/}
|
||||||
|
{/* }}>*/}
|
||||||
|
{/* <TableCell>*/}
|
||||||
|
{/* <Typography*/}
|
||||||
|
{/* variant="h4"*/}
|
||||||
|
{/* sx={{*/}
|
||||||
|
{/* color: theme.palette.secondary.main,*/}
|
||||||
|
{/* }}>*/}
|
||||||
|
{/* Имя*/}
|
||||||
|
{/* </Typography>*/}
|
||||||
|
{/* </TableCell>*/}
|
||||||
|
{/* <TableCell>*/}
|
||||||
|
{/* <Typography*/}
|
||||||
|
{/* variant="h4"*/}
|
||||||
|
{/* sx={{*/}
|
||||||
|
{/* color: theme.palette.secondary.main,*/}
|
||||||
|
{/* }}>*/}
|
||||||
|
{/* Описание*/}
|
||||||
|
{/* </Typography>*/}
|
||||||
|
{/* </TableCell>*/}
|
||||||
|
{/* <TableCell>*/}
|
||||||
|
{/* <Typography*/}
|
||||||
|
{/* variant="h4"*/}
|
||||||
|
{/* sx={{*/}
|
||||||
|
{/* color: theme.palette.secondary.main,*/}
|
||||||
|
{/* }}>*/}
|
||||||
|
{/* стоимость*/}
|
||||||
|
{/* </Typography>*/}
|
||||||
|
{/* </TableCell>*/}
|
||||||
|
{/* </TableRow>*/}
|
||||||
|
{/* </TableHead>*/}
|
||||||
|
|
||||||
|
{/* <TableBody>*/}
|
||||||
|
|
||||||
|
|
||||||
|
{/* </TableBody>*/}
|
||||||
|
{/*</Table>*/}
|
||||||
|
|
||||||
|
|
||||||
|
<Typography id="transition-modal-title" variant="h6" sx={{
|
||||||
|
fontWeight: "normal",
|
||||||
|
textAlign: "center",
|
||||||
|
marginTop: "15px",
|
||||||
|
fontSize: "16px"
|
||||||
|
}}>
|
||||||
|
Скидки:
|
||||||
|
</Typography>
|
||||||
|
|
||||||
|
<Typography id="transition-modal-title" variant="h6" sx={{
|
||||||
|
fontWeight: "normal",
|
||||||
|
textAlign: "center",
|
||||||
|
marginTop: "10px"
|
||||||
|
}}>
|
||||||
|
ИТОГО:
|
||||||
|
</Typography>
|
||||||
|
|
||||||
|
</Box>
|
||||||
|
)
|
||||||
|
}
|
26
src/kitUI/datagrid.tsx
Normal file
26
src/kitUI/datagrid.tsx
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
import { DataGrid } from "@mui/x-data-grid";
|
||||||
|
import { styled } from "@mui/material/styles";
|
||||||
|
export default styled(DataGrid)(({ theme }) => ({
|
||||||
|
width: "100%",
|
||||||
|
minHeight: "400px",
|
||||||
|
margin: "10px 0",
|
||||||
|
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
|
||||||
|
},
|
||||||
|
}));
|
16
src/kitUI/input.tsx
Normal file
16
src/kitUI/input.tsx
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import {TextField} from "@mui/material";
|
||||||
|
import { styled } from "@mui/material/styles";
|
||||||
|
export default styled(TextField)(({ theme }) => ({
|
||||||
|
variant: "outlined",
|
||||||
|
height: "40px",
|
||||||
|
size: "small",
|
||||||
|
color: theme.palette.secondary.main,
|
||||||
|
width: "140px",
|
||||||
|
backgroundColor: theme.palette.content.main,
|
||||||
|
"& .MuiFormLabel-root": {
|
||||||
|
color: theme.palette.secondary.main,
|
||||||
|
},
|
||||||
|
"& .Mui-focused": {
|
||||||
|
color: theme.palette.secondary.main,
|
||||||
|
}
|
||||||
|
}));
|
11
src/kitUI/types/privileges.ts
Normal file
11
src/kitUI/types/privileges.ts
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
export type Privilege = {
|
||||||
|
serviceKey: string;
|
||||||
|
name: string;
|
||||||
|
description: string;
|
||||||
|
type: string;
|
||||||
|
price: number;
|
||||||
|
}
|
||||||
|
export interface State {
|
||||||
|
privileges: { [key: string]: Privilege } | {},
|
||||||
|
tariffsUpdate: (element:Privilege) => void
|
||||||
|
}
|
@ -13,7 +13,7 @@ import { DataGrid, GridColDef, GridSelectionModel, GridToolbar } from "@mui/x-da
|
|||||||
import MenuItem from "@mui/material/MenuItem";
|
import MenuItem from "@mui/material/MenuItem";
|
||||||
import Select, { SelectChangeEvent } from "@mui/material/Select";
|
import Select, { SelectChangeEvent } from "@mui/material/Select";
|
||||||
import { PrivilegesProps, DiscountProps } from "./types";
|
import { PrivilegesProps, DiscountProps } from "./types";
|
||||||
import useStore, { StoreState } from "../../../../store";
|
import useStore, { StoreState } from "../../../../stores/store";
|
||||||
import theme from "../../../../theme";
|
import theme from "../../../../theme";
|
||||||
import {styled} from "@mui/material/styles";
|
import {styled} from "@mui/material/styles";
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ import { DataGrid, GridColDef, GridSelectionModel, GridToolbar } from "@mui/x-da
|
|||||||
import MenuItem from "@mui/material/MenuItem";
|
import MenuItem from "@mui/material/MenuItem";
|
||||||
import Select, { SelectChangeEvent } from "@mui/material/Select";
|
import Select, { SelectChangeEvent } from "@mui/material/Select";
|
||||||
import { PrivilegesProps, PromocodeProps } from "./types";
|
import { PrivilegesProps, PromocodeProps } from "./types";
|
||||||
import useStore, { StoreState } from "../../../../store";
|
import useStore, { StoreState } from "../../../../stores/store";
|
||||||
import theme from "../../../../theme";
|
import theme from "../../../../theme";
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,81 +0,0 @@
|
|||||||
import * as React from "react";
|
|
||||||
import { Box, Typography, Button } from "@mui/material";
|
|
||||||
import theme from "../../../../../theme";
|
|
||||||
|
|
||||||
|
|
||||||
export interface MWProps {
|
|
||||||
openModal: (type:number, num: number) => void
|
|
||||||
}
|
|
||||||
|
|
||||||
const Contractor: React.FC<MWProps> = ({ openModal }) => {
|
|
||||||
return (
|
|
||||||
<React.Fragment>
|
|
||||||
<Typography
|
|
||||||
variant="subtitle1"
|
|
||||||
sx={{
|
|
||||||
width: "90%",
|
|
||||||
height: "60px",
|
|
||||||
display: "flex",
|
|
||||||
flexDirection: "column",
|
|
||||||
justifyContent: "center",
|
|
||||||
alignItems: "center",
|
|
||||||
color: theme.palette.secondary.main
|
|
||||||
}}>
|
|
||||||
Сокращатель ссылок
|
|
||||||
</Typography>
|
|
||||||
|
|
||||||
<Box sx={{
|
|
||||||
marginTop: "35px",
|
|
||||||
display: "grid",
|
|
||||||
gridTemplateColumns: "repeat(2, 1fr)",
|
|
||||||
gridGap: "20px",
|
|
||||||
marginBottom: "120px",
|
|
||||||
}}>
|
|
||||||
<Button
|
|
||||||
variant = "contained"
|
|
||||||
onClick={ () => openModal(3, 1) }
|
|
||||||
sx={{
|
|
||||||
backgroundColor: theme.palette.menu.main,
|
|
||||||
padding: '11px 65px',
|
|
||||||
fontWeight: "normal",
|
|
||||||
fontSize: "17px",
|
|
||||||
"&:hover": {
|
|
||||||
backgroundColor: theme.palette.grayMedium.main
|
|
||||||
}
|
|
||||||
}}>
|
|
||||||
Создать тариф <br /> на аналитику время
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
variant = "contained"
|
|
||||||
onClick={ () => openModal(3, 1) }
|
|
||||||
sx={{
|
|
||||||
backgroundColor: theme.palette.menu.main,
|
|
||||||
padding: '11px 65px',
|
|
||||||
fontWeight: "normal",
|
|
||||||
fontSize: "17px",
|
|
||||||
"&:hover": {
|
|
||||||
backgroundColor: theme.palette.grayMedium.main
|
|
||||||
}
|
|
||||||
}}>
|
|
||||||
Создать тариф <br /> на a/b тесты время
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
variant = "contained"
|
|
||||||
sx={{
|
|
||||||
backgroundColor: theme.palette.menu.main,
|
|
||||||
padding: '11px 65px',
|
|
||||||
fontWeight: "normal",
|
|
||||||
fontSize: "17px",
|
|
||||||
"&:hover": {
|
|
||||||
backgroundColor: theme.palette.grayMedium.main
|
|
||||||
}
|
|
||||||
}}>
|
|
||||||
Изменить тариф
|
|
||||||
</Button>
|
|
||||||
</Box>
|
|
||||||
</React.Fragment>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
export default Contractor;
|
|
@ -1,807 +0,0 @@
|
|||||||
import * as React from "react";
|
|
||||||
import { Box, Button, Typography, TextField } from "@mui/material";
|
|
||||||
import { DataGrid, GridColDef, GridSelectionModel, GridToolbar } from "@mui/x-data-grid";
|
|
||||||
import { useDemoData } from "@mui/x-data-grid-generator";
|
|
||||||
import useStore, { StoreState } from "../../../../../store";
|
|
||||||
import { ArrayProps, CartSummary } from "../types";
|
|
||||||
import List from "@mui/material/List";
|
|
||||||
import ListItem from "@mui/material/ListItem";
|
|
||||||
import ListItemAvatar from "@mui/material/ListItemAvatar";
|
|
||||||
import Avatar from "@mui/material/Avatar";
|
|
||||||
import ShoppingCartIcon from "@mui/icons-material/ShoppingCart";
|
|
||||||
import ListItemText from "@mui/material/ListItemText";
|
|
||||||
import IconButton from "@mui/material/IconButton";
|
|
||||||
import DeleteIcon from "@mui/icons-material/Delete";
|
|
||||||
import FormControlLabel from "@mui/material/FormControlLabel";
|
|
||||||
import Checkbox from "@mui/material/Checkbox";
|
|
||||||
import { PrivilegesProps, PromocodeProps } from "../../Promocode/types";
|
|
||||||
import { DiscountProps } from "../../Discounts/types";
|
|
||||||
import theme from "../../../../../theme";
|
|
||||||
|
|
||||||
export interface MWProps {
|
|
||||||
openModal: () => void
|
|
||||||
}
|
|
||||||
|
|
||||||
const columns: GridColDef[] = [
|
|
||||||
{
|
|
||||||
field: "id",
|
|
||||||
headerName: "ID",
|
|
||||||
width: 30,
|
|
||||||
sortable: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: "name",
|
|
||||||
headerName: "Название тарифа",
|
|
||||||
width: 200,
|
|
||||||
sortable: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: "service",
|
|
||||||
headerName: "Сервис",
|
|
||||||
width: 210,
|
|
||||||
sortable: false,
|
|
||||||
},{
|
|
||||||
field: "disk",
|
|
||||||
headerName: "Гигабайты",
|
|
||||||
type: "number",
|
|
||||||
width: 110,
|
|
||||||
sortable: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: "time",
|
|
||||||
headerName: "Время",
|
|
||||||
type: "number",
|
|
||||||
width: 110,
|
|
||||||
sortable: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: "points",
|
|
||||||
headerName: "Объем",
|
|
||||||
width: 110,
|
|
||||||
sortable: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: "price",
|
|
||||||
headerName: "Стоимость",
|
|
||||||
width: 160,
|
|
||||||
sortable: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: "conditions",
|
|
||||||
headerName: "Условия",
|
|
||||||
width: 110,
|
|
||||||
sortable: false,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
const rows = [
|
|
||||||
{ id: 1, name: "Тариф 1", type: "tariff", service: "Шаблонизатор", disk: "100 гб", time: "200 дней", points: "300", price: 100500 },
|
|
||||||
{ id: 2, name: "Тариф 2", type: "tariff", service: "Шаблонизатор", disk: "100 гб", time: "200 дней", points: "300", price: 100500 },
|
|
||||||
{ id: 3, name: "Тариф 3", type: "tariff", service: "Шаблонизатор", disk: "100 гб", time: "200 дней", points: "300", price: 100500 },
|
|
||||||
{ id: 4, name: "Пакет 1", type: "package", tariffs: [
|
|
||||||
{ id: 1, name: "Тариф 1", type: "tariff", service: "Шаблонизатор", disk: "100 гб", time: "200 дней", points: "300", price: 100500 },
|
|
||||||
{ id: 2, name: "Тариф 2", type: "tariff", service: "Шаблонизатор", disk: "100 гб", time: "200 дней", points: "300", price: 100500 },
|
|
||||||
] },
|
|
||||||
];
|
|
||||||
|
|
||||||
const rowz:Array<PromocodeProps> = [
|
|
||||||
{ id: 1, name: "Промокод 1", endless: false, from: "", dueTo: "", privileges: [
|
|
||||||
{
|
|
||||||
good: "Шаблонизатор",
|
|
||||||
discount: 0.15
|
|
||||||
},
|
|
||||||
{
|
|
||||||
good: "Опросник",
|
|
||||||
discount: 0.3
|
|
||||||
}
|
|
||||||
] },
|
|
||||||
{ id: 1, name: "Промокод 2", endless: false, from: "", dueTo: "", privileges: [
|
|
||||||
{
|
|
||||||
good: "Шаблонизатор",
|
|
||||||
discount: 0.4
|
|
||||||
},
|
|
||||||
{
|
|
||||||
good: "Опросник",
|
|
||||||
discount: 0.6
|
|
||||||
}
|
|
||||||
] }
|
|
||||||
];
|
|
||||||
|
|
||||||
const DataGridElement: React.FC<MWProps> = ({ openModal }) => {
|
|
||||||
let priceBefore = 0;
|
|
||||||
let price = 0;
|
|
||||||
let prices = 0;
|
|
||||||
let percents = 0;
|
|
||||||
let discounts = "";
|
|
||||||
let discountsSum = "";
|
|
||||||
|
|
||||||
const { discountsArray, discountsArraySet } = useStore<StoreState>((state) => state);
|
|
||||||
const { discountsActiveArray, discountsActiveArraySet } = useStore<StoreState>((state) => state);
|
|
||||||
|
|
||||||
const [nonCommercial, setNonCommercial] = React.useState(false);
|
|
||||||
|
|
||||||
const { data } = useDemoData({
|
|
||||||
dataSet: "Commodity",
|
|
||||||
rowLength: 10,
|
|
||||||
maxColumns: 5,
|
|
||||||
});
|
|
||||||
|
|
||||||
const { tariffsArray } = useStore<StoreState>((state) => state);
|
|
||||||
const tariffsArrayConverted = tariffsArray.map( (item) => {
|
|
||||||
if( item.type === "package" && item.tariffs ) {
|
|
||||||
const result = item.tariffs.reduce( (acc, tariff) => {
|
|
||||||
acc.service = acc.service? `${acc.service}, ${tariff.service}` : tariff.service;
|
|
||||||
acc.disk = acc.disk+ tariff.disk;
|
|
||||||
acc.time = acc.time+ tariff.time;
|
|
||||||
acc.points = acc.points + tariff.points;
|
|
||||||
acc.price = acc.price + tariff.price;
|
|
||||||
|
|
||||||
return acc;
|
|
||||||
}, { service: "", disk: "", time: "", points: "", price: 0 } );
|
|
||||||
|
|
||||||
return { id: item.id, name: item.name, type: item.type, ...result }
|
|
||||||
} else {
|
|
||||||
return item;
|
|
||||||
}
|
|
||||||
} );
|
|
||||||
|
|
||||||
const { tariffsSelectedRowsData, tariffsSelectedRowsDataSet } = useStore<StoreState>((state) => state);
|
|
||||||
const onRowsSelectionHandler = ( ids:GridSelectionModel ) => {
|
|
||||||
const result:Array<ArrayProps> = [];
|
|
||||||
ids.forEach((id) => tariffsArray.forEach( (row) => {
|
|
||||||
if(row.id === id) result.push(row);
|
|
||||||
} ) );
|
|
||||||
|
|
||||||
tariffsSelectedRowsDataSet( result );
|
|
||||||
};
|
|
||||||
|
|
||||||
const { cartRowsData, cartRowsDataSet } = useStore<StoreState>((state) => state);
|
|
||||||
const handleToBasket = () => {
|
|
||||||
cartRowsDataSet( tariffsSelectedRowsData );
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleRemoveBasket = ( id:number ) => {
|
|
||||||
const cartFiltered = cartRowsData.filter( (row) => row.id != id );
|
|
||||||
cartRowsDataSet( cartFiltered );
|
|
||||||
}
|
|
||||||
|
|
||||||
const fieldPromocode = React.useRef<HTMLInputElement | null>(null);
|
|
||||||
const checkPromocode = () => {
|
|
||||||
if( fieldPromocode.current != null ) {
|
|
||||||
setPromocode( fieldPromocode.current.value );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let { promocodeArray, promocodeArraySet } = useStore<StoreState>((state) => state);
|
|
||||||
const [selectedPromocode, setSelectedPromocode] = React.useState( -1 );
|
|
||||||
|
|
||||||
//promocodeArray = [ ...rowz ];
|
|
||||||
|
|
||||||
const setPromocode = ( name:string ) => {
|
|
||||||
let codeNumber = -1;
|
|
||||||
|
|
||||||
promocodeArray.forEach( (item, i) => {
|
|
||||||
if( name != "" && item.name == name ) codeNumber = i;
|
|
||||||
} );
|
|
||||||
|
|
||||||
setSelectedPromocode( codeNumber );
|
|
||||||
}
|
|
||||||
|
|
||||||
const PositiveInput = (event:any) => {
|
|
||||||
const numberInput = parseInt(event.target.value);
|
|
||||||
if(isNaN(numberInput) || numberInput < 0) {event.target.value = '0'}
|
|
||||||
}
|
|
||||||
|
|
||||||
const fieldAdded = React.useRef<HTMLInputElement | null>(null);
|
|
||||||
const [ fieldAddedValue, setFieldAddedValue ] = React.useState("");
|
|
||||||
|
|
||||||
const changeAdded = (event:any) => {
|
|
||||||
if( fieldAdded.current != null ) {
|
|
||||||
if( fieldAdded.current.value != null ) {
|
|
||||||
setFieldAddedValue( fieldAdded.current.value );
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
PositiveInput(event)
|
|
||||||
};
|
|
||||||
|
|
||||||
const separator = (amount: number) => {
|
|
||||||
console.log(amount)
|
|
||||||
|
|
||||||
if( String(amount).length < 4 ) { return amount; }
|
|
||||||
|
|
||||||
let result:Array<string> = [];
|
|
||||||
const arrs = String(amount).split('.')
|
|
||||||
const arr = arrs[0].split('').reverse();
|
|
||||||
|
|
||||||
arr.forEach( (item, i:number) => {
|
|
||||||
result.push( String( arr[ i ] ) );
|
|
||||||
if( ((i+1) / 3) - Math.round((i+1) / 3) == 0 ) result.push(" ");
|
|
||||||
});
|
|
||||||
|
|
||||||
if( arrs.length > 1 ) { return result.reverse().join("") +"." +arrs[1]; }
|
|
||||||
else { return result.reverse().join(""); }
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const cartSummary = new Map()
|
|
||||||
cartRowsData.forEach((row) => {
|
|
||||||
const svcName = row.service.split(" ")[0]
|
|
||||||
const prev = cartSummary.get(svcName)
|
|
||||||
console.log(row)
|
|
||||||
console.log(prev)
|
|
||||||
if (!prev) {
|
|
||||||
cartSummary.set(svcName, {
|
|
||||||
mbs: row.disk,
|
|
||||||
points: row.points,
|
|
||||||
days: row.time,
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
cartSummary.set(svcName, {
|
|
||||||
mbs: row.disk+prev.mbs,
|
|
||||||
points: row.points+prev.points,
|
|
||||||
days: row.time+prev.days,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
console.log(cartSummary)
|
|
||||||
|
|
||||||
const fitDiscounts = discountsActiveArray.filter(e => {
|
|
||||||
const d = discountsArray[e]
|
|
||||||
const summary = cartSummary.get(d.privileges[0].good.split(' ')[0])
|
|
||||||
return d.incomeMore*100 < parseInt(fieldAddedValue) && d.incomeMore > 0 ||
|
|
||||||
d.toTime < (summary ? summary.days : 0) && d.toTime > 0 && d.toCapacity === 0 ||
|
|
||||||
d.toCapacity > 0 && d.toCapacity < (summary ? summary.points : 0) && d.toTime === 0 ||
|
|
||||||
d.toCapacity > 0 && d.toTime > 0 && d.toCapacity < (summary ? summary.points : 0) && d.toTime < (summary ? summary.days : 0) ||
|
|
||||||
!d.toCapacity && !d.toTime && !d.incomeMore && !d.basketMore ||
|
|
||||||
d.basketMore
|
|
||||||
}).filter((e,i,a)=>{
|
|
||||||
const d = discountsArray[e]
|
|
||||||
if (d.incomeMore) {
|
|
||||||
return d.incomeMore === a.reduce((a, e) => Math.max(a, discountsArray[e].incomeMore || 0), 0 )
|
|
||||||
}
|
|
||||||
if (d.toTime && d.toCapacity) {
|
|
||||||
return d.toTime === a.reduce((a, e) => Math.max(a, (discountsArray[e].toTime && discountsArray[e].toCapacity) ? discountsArray[e].toTime:0 ), 0 ) && d.toCapacity === a.reduce((a, e) => Math.max(a, (discountsArray[e].toCapacity && discountsArray[e].toTime) ? discountsArray[e].toCapacity : 0 ), 0 )
|
|
||||||
}
|
|
||||||
if (d.toTime && !d.toCapacity) {
|
|
||||||
return d.toTime === a.reduce((a, e) => Math.max(a, discountsArray[e].toTime && !discountsArray[e].toCapacity ? discountsArray[e].toTime : 0), 0 )
|
|
||||||
}
|
|
||||||
if (!d.toTime && d.toCapacity) {
|
|
||||||
return d.toCapacity === a.reduce((a, e) => Math.max(a, discountsArray[e].toCapacity && !discountsArray[e].toTime ? discountsArray[e].toCapacity : 0), 0 )
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
console.log(fitDiscounts)
|
|
||||||
|
|
||||||
const discountsAfter = ( getPrice:number ) => {
|
|
||||||
const discounts:Array<number> = [];
|
|
||||||
priceBefore = getPrice;
|
|
||||||
|
|
||||||
prices = getPrice;
|
|
||||||
console.log(getPrice)
|
|
||||||
|
|
||||||
// применяем активные скидки за объем корзины
|
|
||||||
|
|
||||||
if( fitDiscounts.length >= 0 && !nonCommercial && selectedPromocode < 0 ) {
|
|
||||||
fitDiscounts.forEach( (activeDiscount) => {
|
|
||||||
const d = discountsArray[activeDiscount]
|
|
||||||
console.log(d)
|
|
||||||
console.log(fieldAddedValue)
|
|
||||||
if (d.basketMore > 0 && getPrice > d.basketMore && d.basketMore === fitDiscounts.reduce((a,e) => Math.max(a, discountsArray[e].basketMore), 0) ||
|
|
||||||
d.incomeMore > 0 && parseInt(fieldAddedValue) > d.incomeMore) {
|
|
||||||
prices *= (1-d.privileges[0].discount)
|
|
||||||
discounts.push(d.privileges[0].discount)
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if( nonCommercial ) {
|
|
||||||
prices *= 0.2
|
|
||||||
return `80%`;
|
|
||||||
}
|
|
||||||
|
|
||||||
return discounts.map(e => `${(e*100).toFixed(2)}%`).join(' × ') + ` = ${(100 - discounts.reduce((a : number,cv : number) => a*(1-cv), 100)) .toFixed(2)}%`;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Box style={{ width: "93%" }}>
|
|
||||||
<Box style={{ height: 400 }}>
|
|
||||||
<DataGrid
|
|
||||||
checkboxSelection={true}
|
|
||||||
rows={ tariffsArrayConverted }
|
|
||||||
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 sx={{
|
|
||||||
width: "100%",
|
|
||||||
display: "flex",
|
|
||||||
flexDirection: "column",
|
|
||||||
justifyContent: "center",
|
|
||||||
alignItems: "center"
|
|
||||||
}}>
|
|
||||||
<Button
|
|
||||||
variant = "contained"
|
|
||||||
onClick={ () => openModal() }
|
|
||||||
sx={{
|
|
||||||
backgroundColor: theme.palette.menu.main,
|
|
||||||
padding: "6px 30px",
|
|
||||||
fontWeight: "normal",
|
|
||||||
fontSize: "17px",
|
|
||||||
marginTop: "45px",
|
|
||||||
marginBottom: "15px",
|
|
||||||
maxWidth: '320px',
|
|
||||||
width: '100%',
|
|
||||||
"&:hover": {
|
|
||||||
backgroundColor: theme.palette.grayMedium.main
|
|
||||||
}
|
|
||||||
}}>
|
|
||||||
Пакетизировать
|
|
||||||
</Button>
|
|
||||||
|
|
||||||
<Button
|
|
||||||
variant = "contained"
|
|
||||||
onClick={ () => handleToBasket() }
|
|
||||||
sx={{
|
|
||||||
backgroundColor: theme.palette.menu.main,
|
|
||||||
padding: "6px 69px",
|
|
||||||
fontWeight: "normal",
|
|
||||||
fontSize: "17px",
|
|
||||||
marginBottom: "95px",
|
|
||||||
"&:hover": {
|
|
||||||
backgroundColor: theme.palette.grayMedium.main
|
|
||||||
}
|
|
||||||
}}>
|
|
||||||
Сложить в корзину
|
|
||||||
</Button>
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
<Box sx={{
|
|
||||||
display: "flex",
|
|
||||||
flexDirection: "column",
|
|
||||||
justifyContent: "center",
|
|
||||||
alignItems: "center",
|
|
||||||
marginBottom: "45px",
|
|
||||||
}}>
|
|
||||||
<Box sx={{
|
|
||||||
maxWidth: "480px",
|
|
||||||
width: '100%',
|
|
||||||
display: "flex",
|
|
||||||
justifyContent: "space-between",
|
|
||||||
}}>
|
|
||||||
<TextField
|
|
||||||
id = "standard-basic"
|
|
||||||
label = { "Ввести промокод" }
|
|
||||||
variant = "filled"
|
|
||||||
size="small"
|
|
||||||
color = "secondary"
|
|
||||||
sx={{
|
|
||||||
width: "200px",
|
|
||||||
height: "30px",
|
|
||||||
}}
|
|
||||||
InputProps={{
|
|
||||||
style: {
|
|
||||||
backgroundColor: theme.palette.content.main,
|
|
||||||
color: theme.palette.secondary.main,
|
|
||||||
} }}
|
|
||||||
InputLabelProps={{
|
|
||||||
style: {
|
|
||||||
color: theme.palette.secondary.main
|
|
||||||
} }}
|
|
||||||
inputRef={ fieldPromocode }
|
|
||||||
/>
|
|
||||||
|
|
||||||
<Button
|
|
||||||
variant = "contained"
|
|
||||||
onClick={ () => checkPromocode() }
|
|
||||||
sx={{
|
|
||||||
backgroundColor: theme.palette.menu.main,
|
|
||||||
width: "200px",
|
|
||||||
height: "48px",
|
|
||||||
fontWeight: "normal",
|
|
||||||
fontSize: "17px",
|
|
||||||
"&:hover": {
|
|
||||||
backgroundColor: theme.palette.grayMedium.main
|
|
||||||
}
|
|
||||||
}}>
|
|
||||||
Готово
|
|
||||||
</Button>
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
{
|
|
||||||
selectedPromocode >= 0
|
|
||||||
? (
|
|
||||||
<Box>
|
|
||||||
<Box sx={{ marginTop: "35px", display: "flex" }}>
|
|
||||||
<Typography sx={{ color: theme.palette.grayDisabled.main, minWidth: "150px" }}>
|
|
||||||
Введен промокод:
|
|
||||||
</Typography>
|
|
||||||
<Typography sx={{ width: "100%", textAlign: "center" }}>
|
|
||||||
{ promocodeArray[ selectedPromocode ].name }
|
|
||||||
</Typography>
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
<Box sx={{ display: "flex" }}>
|
|
||||||
<Typography sx={{ color: theme.palette.grayDisabled.main, minWidth: "150px" }}>
|
|
||||||
Привилегии:  
|
|
||||||
</Typography>
|
|
||||||
|
|
||||||
<Typography sx={{ width: "100%", textAlign: "center" }}>
|
|
||||||
{
|
|
||||||
promocodeArray[ selectedPromocode ].privileges.map( (item, i) => {
|
|
||||||
let period;
|
|
||||||
|
|
||||||
i < promocodeArray[ selectedPromocode ].privileges.length - 1
|
|
||||||
? period = ", "
|
|
||||||
: period = ""
|
|
||||||
|
|
||||||
return(
|
|
||||||
<>
|
|
||||||
{
|
|
||||||
`${item.good} - ${ Math.round(item.discount * 100) }%${period}`
|
|
||||||
}
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
} )
|
|
||||||
}
|
|
||||||
</Typography>
|
|
||||||
</Box>
|
|
||||||
</Box>
|
|
||||||
) : null
|
|
||||||
}
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
<Box sx={{
|
|
||||||
display: "flex",
|
|
||||||
flexDirection: "column",
|
|
||||||
justifyContent: "center",
|
|
||||||
alignItems: "center",
|
|
||||||
paddingBottom: "45px"
|
|
||||||
}}>
|
|
||||||
<Typography id="transition-modal-title" variant="caption">
|
|
||||||
Корзина
|
|
||||||
</Typography>
|
|
||||||
|
|
||||||
<Box sx={{
|
|
||||||
display: "flex",
|
|
||||||
marginTop: "15px",
|
|
||||||
marginBottom: "15px",
|
|
||||||
maxWidth: "350px",
|
|
||||||
width: '100%',
|
|
||||||
justifyContent: "space-between"
|
|
||||||
}}>
|
|
||||||
<FormControlLabel control={
|
|
||||||
<Checkbox sx={{
|
|
||||||
color: theme.palette.secondary.main,
|
|
||||||
"&.Mui-checked": {
|
|
||||||
color: theme.palette.secondary.main,
|
|
||||||
},
|
|
||||||
}} onClick={ () => setNonCommercial(!nonCommercial) } />
|
|
||||||
} label="НКО" />
|
|
||||||
|
|
||||||
<TextField
|
|
||||||
id = "standard-basic"
|
|
||||||
label = { "Внесено" }
|
|
||||||
variant = "filled"
|
|
||||||
size="small"
|
|
||||||
color = "secondary"
|
|
||||||
type="number"
|
|
||||||
sx={{
|
|
||||||
width: "200px"
|
|
||||||
}}
|
|
||||||
InputProps={{
|
|
||||||
style: {
|
|
||||||
backgroundColor: theme.palette.content.main,
|
|
||||||
color: theme.palette.secondary.main,
|
|
||||||
} }}
|
|
||||||
InputLabelProps={{
|
|
||||||
style: {
|
|
||||||
color: theme.palette.secondary.main
|
|
||||||
} }}
|
|
||||||
inputRef={ fieldAdded }
|
|
||||||
onChange={ changeAdded }
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
<List sx={{
|
|
||||||
border: "1px solid",
|
|
||||||
borderColor: theme.palette.secondary.main,
|
|
||||||
maxWidth: '745px',
|
|
||||||
width: '100%',
|
|
||||||
}}>
|
|
||||||
<ListItem>
|
|
||||||
<ListItemAvatar>
|
|
||||||
<Avatar sx={{ backgroundColor: theme.palette.content.main }}>
|
|
||||||
<ShoppingCartIcon sx={{
|
|
||||||
color: theme.palette.content.main,
|
|
||||||
display: "none"
|
|
||||||
}} />
|
|
||||||
</Avatar>
|
|
||||||
</ListItemAvatar>
|
|
||||||
<ListItemText
|
|
||||||
primary="Название"
|
|
||||||
sx={{
|
|
||||||
textAlign: "center",
|
|
||||||
// minWidth: "250px",
|
|
||||||
maxWidth: "250px",
|
|
||||||
padding: '0 10px'
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<ListItemText
|
|
||||||
primary="Цена"
|
|
||||||
sx={{
|
|
||||||
textAlign: "center",
|
|
||||||
// minWidth: "200px",
|
|
||||||
padding: '0 10px',
|
|
||||||
maxWidth: "200px" }}
|
|
||||||
/>
|
|
||||||
<ListItemText
|
|
||||||
primary="Скидки"
|
|
||||||
sx={{
|
|
||||||
textAlign: "center",
|
|
||||||
// minWidth: "200px",
|
|
||||||
padding: '0 10px',
|
|
||||||
maxWidth: "400px" }}
|
|
||||||
/>
|
|
||||||
<IconButton edge="end" aria-label="delete">
|
|
||||||
<DeleteIcon sx={{
|
|
||||||
color: theme.palette.grayDisabled.main,
|
|
||||||
display: "none"
|
|
||||||
}} />
|
|
||||||
</IconButton>
|
|
||||||
</ListItem>
|
|
||||||
|
|
||||||
{ cartRowsData.map( (item) => {
|
|
||||||
price = item.price
|
|
||||||
const appliedDscnts: number[] = [];
|
|
||||||
if (!nonCommercial) {
|
|
||||||
|
|
||||||
if( item.type == "package" ) {
|
|
||||||
// считаем цену в ПАКЕТАХ
|
|
||||||
price = 0;
|
|
||||||
discounts = "";
|
|
||||||
priceBefore = 0;
|
|
||||||
|
|
||||||
if( item.tariffs ) {
|
|
||||||
item.tariffs.forEach( (tariff) => {
|
|
||||||
let tariffPrice = tariff.price;
|
|
||||||
percents = 0;
|
|
||||||
|
|
||||||
// применяем скидки по промокоду
|
|
||||||
if( selectedPromocode >= 0 ) {
|
|
||||||
promocodeArray[ selectedPromocode ].privileges.forEach( (privilege) => {
|
|
||||||
if( tariff.service == privilege.good ) {
|
|
||||||
percents = percents + privilege.discount;
|
|
||||||
|
|
||||||
if( discounts ) { discounts += " × "; }
|
|
||||||
discounts += `${ Math.round(privilege.discount * 100) }%`;
|
|
||||||
}
|
|
||||||
} )
|
|
||||||
}
|
|
||||||
|
|
||||||
// применяем активные скидки
|
|
||||||
if( discountsActiveArray.length >= 0 && selectedPromocode < 0 ) {
|
|
||||||
discountsActiveArray.forEach( (activeDiscount) => {
|
|
||||||
discountsArray.forEach( (discount, i) => {
|
|
||||||
if( i == activeDiscount ) {
|
|
||||||
discount.privileges.forEach( (privilege) => {
|
|
||||||
if( privilege.discount != 0 ) {
|
|
||||||
|
|
||||||
if( fieldAddedValue ) { // внесено
|
|
||||||
const f = Number(fieldAddedValue);
|
|
||||||
let minDiscount = 100;
|
|
||||||
let minI = -1;
|
|
||||||
|
|
||||||
discountsArray.forEach( (x, ii) => {
|
|
||||||
x.privileges.forEach( (y) => {
|
|
||||||
if( x.active && f - y.discount * 100 < minDiscount
|
|
||||||
&& f - y.discount * 100 > 0 ) {
|
|
||||||
minDiscount = f - y.discount * 100;
|
|
||||||
minI = ii;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
if( minI >= 0 ) {
|
|
||||||
discountsArray[ minI ].privileges.forEach( (y) => {
|
|
||||||
percents = percents + y.discount / discountsActiveArray.length; // костыль
|
|
||||||
|
|
||||||
if( discounts ) { discounts += " × "; }
|
|
||||||
discounts += `${y.discount / discountsActiveArray.length * 100}%`;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
} else { // не внесено
|
|
||||||
if( tariff.service == privilege.good ) {
|
|
||||||
percents = percents + privilege.discount;
|
|
||||||
|
|
||||||
if( discounts ) { discounts += " × "; }
|
|
||||||
discounts += `${ Math.round(privilege.discount * 100) }% `;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// применяем активные скидки по времени объему
|
|
||||||
if( discountsActiveArray.length >= 0 && selectedPromocode < 0 ) {
|
|
||||||
discountsActiveArray.forEach( (activeDiscount) => {
|
|
||||||
discountsArray.forEach( (discount, i) => {
|
|
||||||
if( i == activeDiscount ) {
|
|
||||||
if( tariff.time ) {
|
|
||||||
const dTime = 0.1;
|
|
||||||
percents = percents + dTime;
|
|
||||||
|
|
||||||
if( discounts ) discounts += " × ";
|
|
||||||
//if( dTime != 0.0 ) discounts += `${ Math.round(dTime * 100) }%`;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( tariff.points ) {
|
|
||||||
//const cTime = discountCapacity( tariff.points );
|
|
||||||
//percents = percents + cTime;
|
|
||||||
|
|
||||||
//if( discounts ) discounts += " × ";
|
|
||||||
//if( cTime != 0 ) discounts += `${ Math.round(cTime * 100) }%`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// применяем активные скидки на продукт
|
|
||||||
if( discountsActiveArray.length >= 0 && selectedPromocode < 0 ) {
|
|
||||||
discountsActiveArray.forEach( (activeDiscount) => {
|
|
||||||
discountsArray.forEach( (discount, i) => {
|
|
||||||
if( i == activeDiscount ) {
|
|
||||||
if( tariff.time && tariff.points ) {
|
|
||||||
//const dProduct = discountProduct( tariff.time, tariff.points );
|
|
||||||
//percents = percents + dProduct;
|
|
||||||
|
|
||||||
//if( discounts ) discounts += " × ";
|
|
||||||
//if( dProduct != 0 ) discounts += `${ Math.round(dProduct * 100) }%`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
percents = Number( percents.toFixed(2) );
|
|
||||||
|
|
||||||
priceBefore += tariffPrice;
|
|
||||||
tariffPrice = tariffPrice - (tariffPrice * percents);
|
|
||||||
|
|
||||||
price += tariffPrice;
|
|
||||||
} );
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// считаем цену в ТАРИФАХ
|
|
||||||
price = item.price;
|
|
||||||
percents = 0;
|
|
||||||
discounts = "";
|
|
||||||
|
|
||||||
// применяем скидки по промокоду
|
|
||||||
if( selectedPromocode >= 0 ) {
|
|
||||||
promocodeArray[ selectedPromocode ].privileges.forEach( (privilege) => {
|
|
||||||
console.log(item.service)
|
|
||||||
console.log(privilege.good)
|
|
||||||
if( item.service == privilege.good ) {
|
|
||||||
appliedDscnts.push(privilege.discount)
|
|
||||||
price *= (1 - privilege.discount)
|
|
||||||
}
|
|
||||||
} )
|
|
||||||
} else {
|
|
||||||
// применяем активные скидки
|
|
||||||
if( fitDiscounts.length >= 0 ) {
|
|
||||||
fitDiscounts.forEach( (activeDiscount) => {
|
|
||||||
const discount = discountsArray[activeDiscount]
|
|
||||||
discount.privileges.forEach((p) => {
|
|
||||||
const svcName = item.service.split(' ')[0]
|
|
||||||
if (p.good == svcName) {
|
|
||||||
const summary = cartSummary.get(svcName) || {mbs:0,points:0,days:0}
|
|
||||||
if (discount.toCapacity === 0 && discount.toTime === 0 && discount.basketMore === 0 && !(discount.incomeMore) ||
|
|
||||||
discount.toCapacity > 0 && summary.points > discount.toCapacity && item.points > 0 && discount.toTime == 0
|
|
||||||
|| discount.toTime >0 && summary.days > discount.toTime*100 && item.time > 0 && discount.toCapacity == 0 ||
|
|
||||||
discount.toTime > 0 && discount.toCapacity > 0 && summary.days > discount.toTime*100 && summary.points > discount.toCapacity ){
|
|
||||||
|
|
||||||
price *= (1-p.discount)
|
|
||||||
appliedDscnts.push(p.discount)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
})
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
percents = Number( percents.toFixed(2) );
|
|
||||||
|
|
||||||
priceBefore = price;
|
|
||||||
price = price - (price * percents);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
prices += price;
|
|
||||||
|
|
||||||
return(
|
|
||||||
<ListItem key={ item.id }>
|
|
||||||
<ListItemAvatar>
|
|
||||||
<Avatar sx={{ backgroundColor: theme.palette.secondary.main }}>
|
|
||||||
<ShoppingCartIcon sx={{
|
|
||||||
color: theme.palette.content.main,
|
|
||||||
}} />
|
|
||||||
</Avatar>
|
|
||||||
</ListItemAvatar>
|
|
||||||
<ListItemText
|
|
||||||
primary={ item.name }
|
|
||||||
sx={{ minWidth: "250px", maxWidth: "250px" }}
|
|
||||||
/>
|
|
||||||
<ListItemText
|
|
||||||
primary={ `${separator(price)} ₽` }
|
|
||||||
sx={{ textAlign: "center", minWidth: "200px", maxWidth: "200px" }}
|
|
||||||
/>
|
|
||||||
<ListItemText
|
|
||||||
primary={ `${(appliedDscnts.map(e=>(e*100).toFixed(2)).join(' × '))} = ${(100 - appliedDscnts.reduce((a : number,cv : number) => a*(1-cv), 100)).toFixed(2)}%` }
|
|
||||||
sx={{ textAlign: "center", minWidth: "400px", maxWidth: "400px" }}
|
|
||||||
/>
|
|
||||||
<IconButton edge="end" aria-label="delete" onClick={ () => handleRemoveBasket( item.id ) }>
|
|
||||||
<DeleteIcon sx={{
|
|
||||||
color: theme.palette.secondary.main,
|
|
||||||
}} />
|
|
||||||
</IconButton>
|
|
||||||
</ListItem>
|
|
||||||
)
|
|
||||||
} ) }
|
|
||||||
|
|
||||||
<Typography id="transition-modal-title" variant="h6" sx={{
|
|
||||||
fontWeight: "normal",
|
|
||||||
textAlign: "center",
|
|
||||||
marginTop: "15px",
|
|
||||||
fontSize: "16px"
|
|
||||||
}}>
|
|
||||||
Скидки:   { discountsAfter(prices) }
|
|
||||||
</Typography>
|
|
||||||
|
|
||||||
<Typography id="transition-modal-title" variant="h6" sx={{
|
|
||||||
fontWeight: "normal",
|
|
||||||
textAlign: "center",
|
|
||||||
marginTop: "10px"
|
|
||||||
}}>
|
|
||||||
ИТОГО:   { separator( prices ) } ₽
|
|
||||||
</Typography>
|
|
||||||
|
|
||||||
</List>
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
</Box>
|
|
||||||
</Box>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default DataGridElement;
|
|
@ -1,185 +0,0 @@
|
|||||||
import * as React from "react";
|
|
||||||
import { Box, Modal, Fade, Backdrop, Typography, Button, TextField } from "@mui/material";
|
|
||||||
import { ArrayProps } from "../types";
|
|
||||||
import useStore, { StoreState } from "../../../../../store";
|
|
||||||
import theme from "../../../../../theme";
|
|
||||||
|
|
||||||
|
|
||||||
export interface MWProps {
|
|
||||||
open: boolean
|
|
||||||
type: number
|
|
||||||
variant: number
|
|
||||||
close: () => void
|
|
||||||
}
|
|
||||||
|
|
||||||
const ModalMini = ({open, type, variant, close}: MWProps ) => {
|
|
||||||
let tariffsArray:Array<ArrayProps> = useStore((state) => state.tariffsArray);
|
|
||||||
const { tariffsArraySet } = useStore<StoreState>((state) => state);
|
|
||||||
|
|
||||||
const types = [ "", "Шаблонизатор документов", "Опросник", "Сокращатель ссылок" ];
|
|
||||||
const variants = [ "Количество", "Срок (дней)", "Количество (гб)" ];
|
|
||||||
|
|
||||||
const fieldName = React.useRef<HTMLInputElement | null>(null);
|
|
||||||
const fieldTime = React.useRef<HTMLInputElement | null>(null);
|
|
||||||
const fieldPrice = React.useRef<HTMLInputElement | null>(null);
|
|
||||||
|
|
||||||
const checkTariff = () => {
|
|
||||||
if( fieldName.current != null && fieldTime.current != null && fieldPrice.current != null ) {
|
|
||||||
if( fieldName.current.value && fieldTime.current.value && fieldPrice.current.value ) {
|
|
||||||
const getData = localStorage.getItem("tariffs");
|
|
||||||
|
|
||||||
if( getData != null ) { tariffsArray = JSON.parse(getData); }
|
|
||||||
|
|
||||||
const data = [ 0, 0, 0 ];
|
|
||||||
|
|
||||||
if( variant == 0 ) { data[ 0 ] = parseInt(fieldTime.current.value); }
|
|
||||||
if( variant == 1 ) { data[ 1 ] = parseInt(fieldTime.current.value); }
|
|
||||||
if( variant == 2 ) { data[ 2 ] = parseInt(fieldTime.current.value); }
|
|
||||||
|
|
||||||
const tariffsArrayNew = [...tariffsArray, {
|
|
||||||
"id": new Date().getTime(),
|
|
||||||
"name": fieldName.current.value,
|
|
||||||
"type": "tariff",
|
|
||||||
"service": types[ type ],
|
|
||||||
"disk": data[ 2 ],
|
|
||||||
"time": data[ 1 ],
|
|
||||||
"points": data[ 0 ],
|
|
||||||
"price": +fieldPrice.current.value
|
|
||||||
} ];
|
|
||||||
|
|
||||||
tariffsArraySet( tariffsArrayNew );
|
|
||||||
|
|
||||||
localStorage.setItem( "tariffs", JSON.stringify( tariffsArrayNew ) );
|
|
||||||
close();
|
|
||||||
|
|
||||||
console.log( tariffsArrayNew );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<React.Fragment>
|
|
||||||
<Modal
|
|
||||||
aria-labelledby="transition-modal-title"
|
|
||||||
aria-describedby="transition-modal-description"
|
|
||||||
open={ open }
|
|
||||||
onClose={ () => close() }
|
|
||||||
closeAfterTransition
|
|
||||||
BackdropComponent={Backdrop}
|
|
||||||
BackdropProps={{
|
|
||||||
timeout: 500,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Fade in={open}>
|
|
||||||
<Box sx={{
|
|
||||||
position: "absolute" as "absolute",
|
|
||||||
top: "50%",
|
|
||||||
left: "50%",
|
|
||||||
transform: "translate(-50%, -50%)",
|
|
||||||
width: "350px",
|
|
||||||
height: "350px",
|
|
||||||
bgcolor: theme.palette.menu.main,
|
|
||||||
boxShadow: 24,
|
|
||||||
color: theme.palette.secondary.main,
|
|
||||||
display: "flex",
|
|
||||||
flexDirection: "column",
|
|
||||||
justifyContent: "center",
|
|
||||||
alignItems: "center",
|
|
||||||
}}>
|
|
||||||
<TextField
|
|
||||||
id = "standard-basic"
|
|
||||||
label = { types[ type ] }
|
|
||||||
disabled={ true }
|
|
||||||
variant = "filled"
|
|
||||||
color = "secondary"
|
|
||||||
sx = {{ width: "80%", marginTop: theme.spacing(1) }}
|
|
||||||
InputProps={{
|
|
||||||
style: {
|
|
||||||
backgroundColor: theme.palette.content.main,
|
|
||||||
color: theme.palette.secondary.main,
|
|
||||||
} }}
|
|
||||||
InputLabelProps={{
|
|
||||||
style: {
|
|
||||||
color: theme.palette.secondary.main
|
|
||||||
} }}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<TextField
|
|
||||||
id = "standard-basic"
|
|
||||||
label = { "Название тарифа" }
|
|
||||||
variant = "filled"
|
|
||||||
color = "secondary"
|
|
||||||
sx = {{ width: "80%", marginTop: theme.spacing(1) }}
|
|
||||||
InputProps={{
|
|
||||||
style: {
|
|
||||||
backgroundColor: theme.palette.content.main,
|
|
||||||
color: theme.palette.secondary.main,
|
|
||||||
} }}
|
|
||||||
InputLabelProps={{
|
|
||||||
style: {
|
|
||||||
color: theme.palette.secondary.main
|
|
||||||
} }}
|
|
||||||
inputRef={ fieldName }
|
|
||||||
/>
|
|
||||||
|
|
||||||
<TextField
|
|
||||||
id = "standard-basic"
|
|
||||||
label = { variants[ variant ] }
|
|
||||||
variant = "filled"
|
|
||||||
color = "secondary"
|
|
||||||
sx = {{ width: "80%", marginTop: theme.spacing(1) }}
|
|
||||||
InputProps={{
|
|
||||||
style: {
|
|
||||||
backgroundColor: theme.palette.content.main,
|
|
||||||
color: theme.palette.secondary.main,
|
|
||||||
} }}
|
|
||||||
InputLabelProps={{
|
|
||||||
style: {
|
|
||||||
color: theme.palette.secondary.main
|
|
||||||
} }}
|
|
||||||
inputRef={ fieldTime }
|
|
||||||
/>
|
|
||||||
|
|
||||||
<TextField
|
|
||||||
id = "standard-basic"
|
|
||||||
label = "Цена"
|
|
||||||
variant = "filled"
|
|
||||||
color = "secondary"
|
|
||||||
sx = {{ width: "80%", marginTop: theme.spacing(1) }}
|
|
||||||
InputProps={{
|
|
||||||
style: {
|
|
||||||
backgroundColor: theme.palette.content.main,
|
|
||||||
color: theme.palette.secondary.main,
|
|
||||||
} }}
|
|
||||||
InputLabelProps={{
|
|
||||||
style: {
|
|
||||||
color: theme.palette.secondary.main
|
|
||||||
} }}
|
|
||||||
inputRef={ fieldPrice }
|
|
||||||
/>
|
|
||||||
|
|
||||||
|
|
||||||
<Button
|
|
||||||
variant = "contained"
|
|
||||||
onClick={ () => checkTariff() }
|
|
||||||
sx={{
|
|
||||||
backgroundColor: theme.palette.grayDark.main,
|
|
||||||
marginTop: "30px",
|
|
||||||
height: "42px",
|
|
||||||
fontWeight: "normal",
|
|
||||||
fontSize: "17px",
|
|
||||||
"&:hover": {
|
|
||||||
backgroundColor: theme.palette.grayMedium.main
|
|
||||||
}
|
|
||||||
}}>
|
|
||||||
Применить
|
|
||||||
</Button>
|
|
||||||
</Box>
|
|
||||||
</Fade>
|
|
||||||
</Modal>
|
|
||||||
</React.Fragment>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
export default ModalMini;
|
|
@ -1,92 +0,0 @@
|
|||||||
import * as React from "react";
|
|
||||||
import { Box, Modal, Fade, Backdrop, Button, TextField } from "@mui/material";
|
|
||||||
import theme from "../../../../../theme";
|
|
||||||
|
|
||||||
|
|
||||||
export interface MWProps {
|
|
||||||
open: boolean
|
|
||||||
newPackage: (name: string) => void
|
|
||||||
close: () => void
|
|
||||||
}
|
|
||||||
|
|
||||||
const ModalPackage = ({open, newPackage, close}: MWProps ) => {
|
|
||||||
const fieldName = React.useRef<HTMLInputElement | null>(null);
|
|
||||||
|
|
||||||
const checkName = () => {
|
|
||||||
if( fieldName.current != null ) {
|
|
||||||
newPackage( fieldName.current.value );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<React.Fragment>
|
|
||||||
<Modal
|
|
||||||
aria-labelledby="transition-modal-title"
|
|
||||||
aria-describedby="transition-modal-description"
|
|
||||||
open={ open }
|
|
||||||
onClose={ () => close() }
|
|
||||||
closeAfterTransition
|
|
||||||
BackdropComponent={Backdrop}
|
|
||||||
BackdropProps={{
|
|
||||||
timeout: 500,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Fade in={open}>
|
|
||||||
<Box sx={{
|
|
||||||
position: "absolute" as "absolute",
|
|
||||||
top: "50%",
|
|
||||||
left: "50%",
|
|
||||||
transform: "translate(-50%, -50%)",
|
|
||||||
width: "350px",
|
|
||||||
height: "170px",
|
|
||||||
bgcolor: theme.palette.menu.main,
|
|
||||||
boxShadow: 24,
|
|
||||||
color: theme.palette.secondary.main,
|
|
||||||
display: "flex",
|
|
||||||
flexDirection: "column",
|
|
||||||
justifyContent: "center",
|
|
||||||
alignItems: "center",
|
|
||||||
}}>
|
|
||||||
<TextField
|
|
||||||
id = "standard-basic"
|
|
||||||
label = { "Название пакета" }
|
|
||||||
variant = "filled"
|
|
||||||
color = "secondary"
|
|
||||||
sx = {{ width: "80%", marginTop: theme.spacing(1) }}
|
|
||||||
InputProps={{
|
|
||||||
style: {
|
|
||||||
backgroundColor: theme.palette.content.main,
|
|
||||||
color: theme.palette.secondary.main,
|
|
||||||
} }}
|
|
||||||
InputLabelProps={{
|
|
||||||
style: {
|
|
||||||
color: theme.palette.secondary.main
|
|
||||||
} }}
|
|
||||||
inputRef={ fieldName }
|
|
||||||
/>
|
|
||||||
|
|
||||||
<Button
|
|
||||||
variant = "contained"
|
|
||||||
onClick={ () => checkName() }
|
|
||||||
sx={{
|
|
||||||
backgroundColor: theme.palette.grayDark.main,
|
|
||||||
marginTop: "30px",
|
|
||||||
height: "42px",
|
|
||||||
fontWeight: "normal",
|
|
||||||
fontSize: "17px",
|
|
||||||
"&:hover": {
|
|
||||||
backgroundColor: theme.palette.grayMedium.main
|
|
||||||
}
|
|
||||||
}}>
|
|
||||||
Применить
|
|
||||||
</Button>
|
|
||||||
|
|
||||||
</Box>
|
|
||||||
</Fade>
|
|
||||||
</Modal>
|
|
||||||
</React.Fragment>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
export default ModalPackage;
|
|
@ -1,81 +0,0 @@
|
|||||||
import * as React from "react";
|
|
||||||
import { Box, Typography, Button } from "@mui/material";
|
|
||||||
import theme from "../../../../../theme";
|
|
||||||
|
|
||||||
|
|
||||||
export interface MWProps {
|
|
||||||
openModal: (type:number, num: number) => void
|
|
||||||
}
|
|
||||||
|
|
||||||
const Quiz: React.FC<MWProps> = ({ openModal }) => {
|
|
||||||
return (
|
|
||||||
<React.Fragment>
|
|
||||||
<Typography
|
|
||||||
variant="subtitle1"
|
|
||||||
sx={{
|
|
||||||
width: "90%",
|
|
||||||
height: "60px",
|
|
||||||
display: "flex",
|
|
||||||
flexDirection: "column",
|
|
||||||
justifyContent: "center",
|
|
||||||
alignItems: "center",
|
|
||||||
color: theme.palette.secondary.main
|
|
||||||
}}>
|
|
||||||
Опросник
|
|
||||||
</Typography>
|
|
||||||
|
|
||||||
<Box sx={{
|
|
||||||
marginTop: "35px",
|
|
||||||
display: "grid",
|
|
||||||
gridTemplateColumns: "repeat(2, 1fr)",
|
|
||||||
gridGap: "20px",
|
|
||||||
marginBottom: "120px",
|
|
||||||
}}>
|
|
||||||
<Button
|
|
||||||
variant = "contained"
|
|
||||||
onClick={ () => openModal(2, 1) }
|
|
||||||
sx={{
|
|
||||||
backgroundColor: theme.palette.menu.main,
|
|
||||||
padding: "11px 43px",
|
|
||||||
fontWeight: "normal",
|
|
||||||
fontSize: "17px",
|
|
||||||
"&:hover": {
|
|
||||||
backgroundColor: theme.palette.grayMedium.main
|
|
||||||
}
|
|
||||||
}}>
|
|
||||||
Создать тариф на время
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
variant = "contained"
|
|
||||||
onClick={ () => openModal(2, 0) }
|
|
||||||
sx={{
|
|
||||||
backgroundColor: theme.palette.menu.main,
|
|
||||||
padding: '11px 43px',
|
|
||||||
fontWeight: "normal",
|
|
||||||
fontSize: "17px",
|
|
||||||
"&:hover": {
|
|
||||||
backgroundColor: theme.palette.grayMedium.main
|
|
||||||
}
|
|
||||||
}}>
|
|
||||||
Создать тариф на объем
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
variant = "contained"
|
|
||||||
sx={{
|
|
||||||
backgroundColor: theme.palette.menu.main,
|
|
||||||
padding: '11px 43px',
|
|
||||||
fontWeight: "normal",
|
|
||||||
fontSize: "17px",
|
|
||||||
"&:hover": {
|
|
||||||
backgroundColor: theme.palette.grayMedium.main
|
|
||||||
}
|
|
||||||
}}>
|
|
||||||
Изменить тариф
|
|
||||||
</Button>
|
|
||||||
</Box>
|
|
||||||
</React.Fragment>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
export default Quiz;
|
|
@ -1,95 +0,0 @@
|
|||||||
import * as React from "react";
|
|
||||||
import { Box, Typography, Button } from "@mui/material";
|
|
||||||
import theme from "../../../../../theme";
|
|
||||||
|
|
||||||
|
|
||||||
export interface MWProps {
|
|
||||||
openModal: (type:number, num: number) => void
|
|
||||||
}
|
|
||||||
|
|
||||||
const Templater: React.FC<MWProps> = ({ openModal }) => {
|
|
||||||
return (
|
|
||||||
<React.Fragment>
|
|
||||||
<Typography
|
|
||||||
variant="subtitle1"
|
|
||||||
sx={{
|
|
||||||
width: "90%",
|
|
||||||
height: "60px",
|
|
||||||
display: "flex",
|
|
||||||
flexDirection: "column",
|
|
||||||
justifyContent: "center",
|
|
||||||
alignItems: "center",
|
|
||||||
color: theme.palette.secondary.main
|
|
||||||
}}>
|
|
||||||
Шаблонизатор документов
|
|
||||||
</Typography>
|
|
||||||
|
|
||||||
<Box sx={{
|
|
||||||
marginTop: "35px",
|
|
||||||
display: "grid",
|
|
||||||
gridTemplateColumns: "repeat(2, 1fr)",
|
|
||||||
gridGap: "20px",
|
|
||||||
marginBottom: "120px",
|
|
||||||
}}>
|
|
||||||
<Button
|
|
||||||
variant = "contained"
|
|
||||||
onClick={ () => openModal(1, 1) }
|
|
||||||
sx={{
|
|
||||||
backgroundColor: theme.palette.menu.main,
|
|
||||||
fontWeight: "normal",
|
|
||||||
fontSize: "17px",
|
|
||||||
padding: '11px 25px',
|
|
||||||
"&:hover": {
|
|
||||||
backgroundColor: theme.palette.grayMedium.main
|
|
||||||
}
|
|
||||||
}}>
|
|
||||||
Создать тариф на время
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
variant = "contained"
|
|
||||||
onClick={ () => openModal(1, 0) }
|
|
||||||
sx={{
|
|
||||||
backgroundColor: theme.palette.menu.main,
|
|
||||||
padding: '11px 25px',
|
|
||||||
fontWeight: "normal",
|
|
||||||
fontSize: "17px",
|
|
||||||
"&:hover": {
|
|
||||||
backgroundColor: theme.palette.grayMedium.main
|
|
||||||
}
|
|
||||||
}}>
|
|
||||||
Создать тариф на объем
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
variant = "contained"
|
|
||||||
onClick={ () => openModal(1, 2) }
|
|
||||||
sx={{
|
|
||||||
backgroundColor: theme.palette.menu.main,
|
|
||||||
padding: '11px 25px',
|
|
||||||
fontWeight: "normal",
|
|
||||||
fontSize: "17px",
|
|
||||||
"&:hover": {
|
|
||||||
backgroundColor: theme.palette.grayMedium.main
|
|
||||||
}
|
|
||||||
}}>
|
|
||||||
Создать тариф на гигабайты
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
variant = "contained"
|
|
||||||
sx={{
|
|
||||||
backgroundColor: theme.palette.menu.main,
|
|
||||||
padding: '11px 25px',
|
|
||||||
fontWeight: "normal",
|
|
||||||
fontSize: "17px",
|
|
||||||
"&:hover": {
|
|
||||||
backgroundColor: theme.palette.grayMedium.main
|
|
||||||
}
|
|
||||||
}}>
|
|
||||||
Изменить тариф
|
|
||||||
</Button>
|
|
||||||
</Box>
|
|
||||||
</React.Fragment>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
export default Templater;
|
|
File diff suppressed because it is too large
Load Diff
29
src/pages/dashboard/Content/Tariffs/privilegesDG.tsx
Normal file
29
src/pages/dashboard/Content/Tariffs/privilegesDG.tsx
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
import * as React from "react";
|
||||||
|
import { GridColDef } from "@mui/x-data-grid";
|
||||||
|
import DataGrid from "@kitUI/datagrid";
|
||||||
|
import privilegesStore from "@stores/privileges";
|
||||||
|
|
||||||
|
const columns: GridColDef[] = [
|
||||||
|
{ 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})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<DataGrid
|
||||||
|
checkboxSelection={true}
|
||||||
|
rows={ rows }
|
||||||
|
columns={columns}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
27
src/pages/dashboard/Content/Tariffs/tariffsDG.tsx
Normal file
27
src/pages/dashboard/Content/Tariffs/tariffsDG.tsx
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import * as React from "react";
|
||||||
|
import { GridColDef, GridSelectionModel, GridToolbar } from "@mui/x-data-grid";
|
||||||
|
import DataGrid from "@kitUI/datagrid";
|
||||||
|
|
||||||
|
|
||||||
|
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 },
|
||||||
|
]
|
||||||
|
|
||||||
|
export default () => {
|
||||||
|
|
||||||
|
return (
|
||||||
|
<DataGrid
|
||||||
|
checkboxSelection={true}
|
||||||
|
rows={ [] }
|
||||||
|
columns={columns}
|
||||||
|
components={{ Toolbar: GridToolbar }}
|
||||||
|
// onSelectionModelChange={ (ids) => onRowsSelectionHandler( ids ) }
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
60
src/stores/privileges.ts
Normal file
60
src/stores/privileges.ts
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
import create from "zustand";
|
||||||
|
import {Privilege, State} from "@kitUI/types/privileges";
|
||||||
|
|
||||||
|
const useStore = create<State>()(
|
||||||
|
(set, get) => ({
|
||||||
|
privileges: {
|
||||||
|
p1: {
|
||||||
|
"serviceKey": "templategen",
|
||||||
|
"name": "unlim",
|
||||||
|
"description":"привилегия безлимитного доступа к шаблонизатору на время. в днях",
|
||||||
|
"type":"day",
|
||||||
|
"price": 0.5
|
||||||
|
},
|
||||||
|
p2: {
|
||||||
|
"serviceKey": "templategen",
|
||||||
|
"name": "gencount",
|
||||||
|
"description":"привилегия на определённое количество генераций",
|
||||||
|
"type":"count",
|
||||||
|
"price": 0.1
|
||||||
|
},
|
||||||
|
p3: {
|
||||||
|
"serviceKey": "squiz",
|
||||||
|
"name": "unlim",
|
||||||
|
"description":"привилегия безлимитного доступа к опроснику. в днях",
|
||||||
|
"type":"day",
|
||||||
|
"price": 3.0
|
||||||
|
},
|
||||||
|
p4: {
|
||||||
|
"serviceKey": "squiz",
|
||||||
|
"name": "activequiz",
|
||||||
|
"description":"привилегия создания ограниченного количества опросов",
|
||||||
|
"type":"count",
|
||||||
|
"price": 1.0
|
||||||
|
},
|
||||||
|
p5: {
|
||||||
|
"serviceKey": "dwarfener",
|
||||||
|
"name": "unlim",
|
||||||
|
"description":"привилегия безлимитного доступа к сокращателю на время. в днях",
|
||||||
|
"type":"day",
|
||||||
|
"price": 0.1
|
||||||
|
},
|
||||||
|
p6: {
|
||||||
|
"serviceKey": "dwarfener",
|
||||||
|
"name": "abcount",
|
||||||
|
"description":"привилегия на количество активных ссылок в абтестах",
|
||||||
|
"type":"count",
|
||||||
|
"price": 0.7
|
||||||
|
},
|
||||||
|
p7: {
|
||||||
|
"serviceKey": "dwarfener",
|
||||||
|
"name": "extended",
|
||||||
|
"description":"привилегия расширенной статистики, в днях",
|
||||||
|
"type":"day",
|
||||||
|
"price": 2
|
||||||
|
},
|
||||||
|
},
|
||||||
|
tariffsUpdate: (element:Privilege) => {set((state:State) => ({ privileges: {...state.privileges, ...element} }))}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
export default useStore;
|
@ -1,8 +1,8 @@
|
|||||||
import create from "zustand";
|
import create from "zustand";
|
||||||
import { persist } from "zustand/middleware"
|
import { persist } from "zustand/middleware"
|
||||||
import { ArrayProps } from "./pages/dashboard/Content/Tariffs/types";
|
import { ArrayProps } from "../pages/dashboard/Content/Tariffs/types";
|
||||||
import { PromocodeProps } from "./pages/dashboard/Content/Promocode/types";
|
import { PromocodeProps } from "../pages/dashboard/Content/Promocode/types";
|
||||||
import { DiscountProps } from "./pages/dashboard/Content/Discounts/types";
|
import { DiscountProps } from "../pages/dashboard/Content/Discounts/types";
|
||||||
|
|
||||||
|
|
||||||
const useStore = create<StoreState>()(
|
const useStore = create<StoreState>()(
|
18
src/stores/tariffs.ts
Normal file
18
src/stores/tariffs.ts
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import create from "zustand";
|
||||||
|
import { persist } from "zustand/middleware"
|
||||||
|
|
||||||
|
|
||||||
|
const useStore = create<any>()(
|
||||||
|
persist((set, get) => ({
|
||||||
|
tariffs: {},
|
||||||
|
tariffsUpdate: (element:any) => {set((state:any) => ({ tariffs: {...state.tariffs, ...element} }))},
|
||||||
|
tariffsClear: () => set({tariffs: {}}),
|
||||||
|
}),
|
||||||
|
{
|
||||||
|
name: "tariffs",
|
||||||
|
getStorage: () => localStorage,
|
||||||
|
}
|
||||||
|
));
|
||||||
|
|
||||||
|
|
||||||
|
export default useStore;
|
371
src/theme.ts
371
src/theme.ts
@ -1,180 +1,217 @@
|
|||||||
import { createTheme, PaletteColorOptions } from "@mui/material";
|
import { Theme } from '@mui/material/styles';
|
||||||
|
import {createTheme, PaletteColorOptions} from "@mui/material";
|
||||||
|
import { deepmerge } from '@mui/utils';
|
||||||
//import { createTheme } from "./types";
|
//import { createTheme } from "./types";
|
||||||
|
|
||||||
declare module '@mui/material/Button' {
|
declare module '@mui/material/Button' {
|
||||||
interface ButtonPropsVariantOverrides {
|
interface ButtonPropsVariantOverrides {
|
||||||
enter: true;
|
enter: true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
declare module '@mui/material/Paper' {
|
||||||
|
interface PaperPropsVariantOverrides {
|
||||||
|
bar: true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
declare module '@mui/material/styles' {
|
||||||
|
interface Theme {
|
||||||
|
palette: {
|
||||||
|
primary: {
|
||||||
|
main: string
|
||||||
|
},
|
||||||
|
secondary: {
|
||||||
|
main: string;
|
||||||
|
},
|
||||||
|
menu: {
|
||||||
|
main: string;
|
||||||
|
},
|
||||||
|
content: {
|
||||||
|
main: string;
|
||||||
|
},
|
||||||
|
grayLight: {
|
||||||
|
main: string;
|
||||||
|
},
|
||||||
|
grayDark: {
|
||||||
|
main: string;
|
||||||
|
},
|
||||||
|
grayMedium: {
|
||||||
|
main: string;
|
||||||
|
},
|
||||||
|
grayDisabled: {
|
||||||
|
main: string;
|
||||||
|
},
|
||||||
|
golden: {
|
||||||
|
main: string;
|
||||||
|
},
|
||||||
|
goldenDark: {
|
||||||
|
main: string;
|
||||||
|
},
|
||||||
|
goldenMedium: {
|
||||||
|
main: string;
|
||||||
|
},
|
||||||
|
caption: {
|
||||||
|
main: string;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface PaletteOptions {
|
||||||
|
menu?: PaletteColorOptions;
|
||||||
|
content?: PaletteColorOptions;
|
||||||
|
grayLight?: PaletteColorOptions;
|
||||||
|
grayDark?: PaletteColorOptions;
|
||||||
|
grayMedium?: PaletteColorOptions;
|
||||||
|
grayDisabled?: PaletteColorOptions;
|
||||||
|
golden?: PaletteColorOptions;
|
||||||
|
goldenDark?: PaletteColorOptions;
|
||||||
|
goldenMedium?: PaletteColorOptions;
|
||||||
|
hover?: PaletteColorOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
// allow configuration using `createTheme`
|
||||||
|
interface TypographyVariants {
|
||||||
|
body1: React.CSSProperties;
|
||||||
|
subtitle1: React.CSSProperties;
|
||||||
|
subtitle2: React.CSSProperties;
|
||||||
|
caption: React.CSSProperties;
|
||||||
|
h5: React.CSSProperties;
|
||||||
|
h6: React.CSSProperties;
|
||||||
|
button: React.CSSProperties;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const fontFamily: string = "GilroyRegular";
|
const fontFamily: string = "GilroyRegular";
|
||||||
const fontWeight: string = "600";
|
const fontWeight: string = "600";
|
||||||
|
|
||||||
const theme = createTheme({
|
const options1 = {
|
||||||
palette: {
|
|
||||||
primary: {
|
|
||||||
main: "#111217"
|
|
||||||
},
|
|
||||||
secondary: {
|
|
||||||
main: "#ffffff"
|
|
||||||
},
|
|
||||||
menu: {
|
|
||||||
main: "#2f3339"
|
|
||||||
},
|
|
||||||
content: {
|
|
||||||
main: "#26272c"
|
|
||||||
},
|
|
||||||
grayLight: {
|
|
||||||
main: "#707070"
|
|
||||||
},
|
|
||||||
grayDark: {
|
|
||||||
main: "#45494c"
|
|
||||||
},
|
|
||||||
grayMedium: {
|
|
||||||
main: "#424242"
|
|
||||||
},
|
|
||||||
grayDisabled: {
|
|
||||||
main: "#c0c1c3"
|
|
||||||
},
|
|
||||||
golden: {
|
|
||||||
main: "#eaba5b"
|
|
||||||
},
|
|
||||||
goldenDark: {
|
|
||||||
main: "#fe9903"
|
|
||||||
},
|
|
||||||
goldenMedium: {
|
|
||||||
main: "#2a2b1d"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
typography: {
|
|
||||||
body1: {
|
|
||||||
fontFamily: fontFamily
|
|
||||||
},
|
|
||||||
subtitle1: {
|
|
||||||
fontFamily: fontFamily,
|
|
||||||
fontWeight: fontWeight,
|
|
||||||
fontSize: 25
|
|
||||||
},
|
|
||||||
subtitle2: {
|
|
||||||
fontFamily: fontFamily,
|
|
||||||
fontSize: 25,
|
|
||||||
textAlign: "center"
|
|
||||||
},
|
|
||||||
caption: {
|
|
||||||
fontFamily: fontFamily,
|
|
||||||
fontWeight: fontWeight,
|
|
||||||
fontSize: 21
|
|
||||||
},
|
|
||||||
h5: {
|
|
||||||
fontFamily: fontFamily,
|
|
||||||
fontWeight: fontWeight,
|
|
||||||
fontSize: 35
|
|
||||||
},
|
|
||||||
h6: {
|
|
||||||
fontFamily: fontFamily,
|
|
||||||
fontWeight: fontWeight,
|
|
||||||
fontSize: 18
|
|
||||||
},
|
|
||||||
button: {
|
|
||||||
fontFamily: fontFamily,
|
|
||||||
fontWeight: fontWeight,
|
|
||||||
fontSize: 22
|
|
||||||
},
|
|
||||||
h4: {
|
|
||||||
fontFamily: fontFamily,
|
|
||||||
fontWeight: fontWeight,
|
|
||||||
fontSize: 16
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
components: {
|
|
||||||
MuiButton: {
|
|
||||||
variants: [
|
|
||||||
{
|
|
||||||
props: {
|
|
||||||
variant: 'enter' },
|
|
||||||
style: {
|
|
||||||
backgroundColor: "#26272c",
|
|
||||||
padding: '12px 48px',
|
|
||||||
"&:hover": {
|
|
||||||
backgroundColor: "#2f3339"
|
|
||||||
}
|
|
||||||
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
declare module '@mui/material/styles' {
|
|
||||||
interface Theme {
|
|
||||||
palette: {
|
palette: {
|
||||||
primary: {
|
primary: {
|
||||||
main: string
|
main: "#111217"
|
||||||
},
|
},
|
||||||
secondary: {
|
secondary: {
|
||||||
main: string;
|
main: "#e6e8ec"
|
||||||
},
|
},
|
||||||
menu: {
|
menu: {
|
||||||
main: string;
|
main: "#2f3339"
|
||||||
},
|
},
|
||||||
content: {
|
content: {
|
||||||
main: string;
|
main: "#26272c"
|
||||||
},
|
},
|
||||||
grayLight: {
|
hover: {
|
||||||
main: string;
|
main: "#191a1e"
|
||||||
},
|
},
|
||||||
grayDark: {
|
grayLight: {
|
||||||
main: string;
|
main: "#707070"
|
||||||
},
|
},
|
||||||
grayMedium: {
|
grayDark: {
|
||||||
main: string;
|
main: "#45494c"
|
||||||
},
|
},
|
||||||
grayDisabled: {
|
grayMedium: {
|
||||||
main: string;
|
main: "#424242"
|
||||||
},
|
},
|
||||||
golden: {
|
grayDisabled: {
|
||||||
main: string;
|
main: "#c0c1c3"
|
||||||
},
|
},
|
||||||
goldenDark: {
|
golden: {
|
||||||
main: string;
|
main: "#eaba5b"
|
||||||
},
|
},
|
||||||
goldenMedium: {
|
goldenDark: {
|
||||||
main: string;
|
main: "#fe9903"
|
||||||
},
|
},
|
||||||
caption: {
|
goldenMedium: {
|
||||||
main: string;
|
main: "#2a2b1d"
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
}
|
|
||||||
interface PaletteOptions {
|
|
||||||
menu?: PaletteColorOptions;
|
|
||||||
content?: PaletteColorOptions;
|
|
||||||
grayLight?: PaletteColorOptions;
|
|
||||||
grayDark?: PaletteColorOptions;
|
|
||||||
grayMedium?: PaletteColorOptions;
|
|
||||||
grayDisabled?: PaletteColorOptions;
|
|
||||||
golden?: PaletteColorOptions;
|
|
||||||
goldenDark?: PaletteColorOptions;
|
|
||||||
goldenMedium?: PaletteColorOptions;
|
|
||||||
}
|
|
||||||
// allow configuration using `createTheme`
|
|
||||||
interface TypographyVariants {
|
|
||||||
body1: React.CSSProperties;
|
|
||||||
subtitle1: React.CSSProperties;
|
|
||||||
subtitle2: React.CSSProperties;
|
|
||||||
caption: React.CSSProperties;
|
|
||||||
h5: React.CSSProperties;
|
|
||||||
h6: React.CSSProperties;
|
|
||||||
button: React.CSSProperties;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
const options2 = {
|
||||||
|
typography: {
|
||||||
|
body1: {
|
||||||
|
fontFamily: fontFamily
|
||||||
|
},
|
||||||
|
subtitle1: {
|
||||||
|
fontFamily: fontFamily,
|
||||||
|
fontWeight: fontWeight,
|
||||||
|
fontSize: 25
|
||||||
|
},
|
||||||
|
subtitle2: {
|
||||||
|
fontFamily: fontFamily,
|
||||||
|
fontSize: 25,
|
||||||
|
textAlign: "center"
|
||||||
|
},
|
||||||
|
caption: {
|
||||||
|
fontFamily: fontFamily,
|
||||||
|
fontWeight: fontWeight,
|
||||||
|
fontSize: 21
|
||||||
|
},
|
||||||
|
h5: {
|
||||||
|
fontFamily: fontFamily,
|
||||||
|
fontWeight: fontWeight,
|
||||||
|
fontSize: 35
|
||||||
|
},
|
||||||
|
h6: {
|
||||||
|
fontFamily: fontFamily,
|
||||||
|
fontWeight: fontWeight,
|
||||||
|
fontSize: 18
|
||||||
|
},
|
||||||
|
button: {
|
||||||
|
fontFamily: fontFamily,
|
||||||
|
fontWeight: fontWeight,
|
||||||
|
fontSize: 22
|
||||||
|
},
|
||||||
|
h4: {
|
||||||
|
fontFamily: fontFamily,
|
||||||
|
fontWeight: fontWeight,
|
||||||
|
fontSize: 16
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
components: {
|
||||||
|
MuiButton: {
|
||||||
|
styleOverrides: {
|
||||||
|
root: {
|
||||||
|
color: options1.palette.secondary.main,
|
||||||
|
backgroundColor: options1.palette.menu.main,
|
||||||
|
padding: "12px",
|
||||||
|
fontSize: "13px",
|
||||||
|
"&:hover": {
|
||||||
|
backgroundColor: options1.palette.hover.main,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
variants: [
|
||||||
|
{
|
||||||
|
props: {
|
||||||
|
variant: 'enter'
|
||||||
|
},
|
||||||
|
style: {
|
||||||
|
color: options1.palette.secondary.main,
|
||||||
|
backgroundColor: options1.palette.content.main,
|
||||||
|
padding: '12px 48px',
|
||||||
|
"&:hover": {
|
||||||
|
backgroundColor: options1.palette.hover.main,
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
MuiPaper: {
|
||||||
|
variants: [
|
||||||
|
{
|
||||||
|
props: {
|
||||||
|
variant: "bar"
|
||||||
|
},
|
||||||
|
style: {
|
||||||
|
backgroundColor: options1.palette.grayMedium.main,
|
||||||
|
padding: "15px",
|
||||||
|
width: "100%"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
const theme = createTheme(deepmerge(options1, options2));
|
||||||
export default theme;
|
export default theme;
|
11
tsconfig.extend.json
Normal file
11
tsconfig.extend.json
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"baseUrl": "./src",
|
||||||
|
"paths": {
|
||||||
|
"@theme": ["./theme.ts"],
|
||||||
|
"@root/*": ["./*"],
|
||||||
|
"@kitUI/*": ["./kitUI/*"],
|
||||||
|
"@stores/*": ["./stores/*"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,5 @@
|
|||||||
{
|
{
|
||||||
|
"extends": "./tsconfig.extend.json",
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"target": "es5",
|
"target": "es5",
|
||||||
"lib": [
|
"lib": [
|
||||||
|
Loading…
Reference in New Issue
Block a user