Guest User

Untitled

a guest
Feb 10th, 2022
114
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import React from 'react';
  2. import { Button } from '@mui/material';
  3. import MainLayout from '../layouts/MainLayout';
  4. import Autocomplete from '@mui/material/Autocomplete';
  5. import TextField from '@mui/material/TextField';
  6. import TableContainer from '@mui/material/TableContainer';
  7. import TableHead from '@mui/material/TableHead';
  8. import TableRow from '@mui/material/TableRow';
  9. import TableCell from '@mui/material/TableCell';
  10. import TableBody from '@mui/material/TableBody';
  11. import Table from '@mui/material/Table';
  12. import { Activity, Product } from '../types/calc';
  13. import { green } from '@mui/material/colors';
  14. import Icon from '@mui/material/Icon';
  15.  
  16. export const getStaticProps = async () => {
  17.   const productsRes = await fetch('http://127.0.0.1:5000/api/products'); // TODO: добавить конфиг, а в него адрес сервера
  18.   const productsData: Product[] = await productsRes.json();
  19.   const activitiesRes = await fetch('http://127.0.0.1:5000/api/activities');
  20.   const activitiesData: Activity[] = await activitiesRes.json();
  21.   return {props:{products: productsData, activities: activitiesData}}
  22. }
  23.  
  24. const Index = ({products, activities}: {products: Product[], activities: Activity[]}) => {
  25.   const productsArr = [
  26.     {
  27.       value: '',
  28.       id: 0,
  29.     },
  30.   ];
  31.   const [productsFields, setProductsFields] = React.useState(productsArr);
  32.   const [categories, setCategories] = React.useState({});
  33.  
  34.   function addProductField() {
  35.     setProductsFields(s => {
  36.       const id = s.length;
  37.       return [...s, {
  38.         value: '',
  39.         id: id,
  40.       }];
  41.     });
  42.   }
  43.  
  44.   function getCategories(item) {
  45.     if (!item.value) {
  46.       return [];
  47.     }
  48.     const product = products.filter(x => x.name == item.value)[0];
  49.     if (!product) {
  50.       return [];
  51.     }
  52.     let categoryArr = [];
  53.     for (const category of product.categories) {
  54.       categoryArr.push({ name: category.name, id: category.id });  // <Item>
  55.     }
  56.     return categoryArr;
  57.   }
  58.  
  59.   let [results, setResults] = React.useState({});
  60.   const categoriesCalc1 = {};
  61.   for (const product of products) {
  62.     for (const category of product.categories) {
  63.       results[category.id] = 0;
  64.       categoriesCalc1[category.id] = { quantity: 0 };
  65.       let conditions = {};
  66.       for (const textCondition of category.textConditions) {
  67.         conditions[category.id + '_' + textCondition.name] = { type: 'textCondition', value: 0 };
  68.       }
  69.       for (const numberCondition of category.numberConditions) {
  70.         conditions[category.id + '_' + numberCondition.name] = { type: 'numberCondition', value: 0 };
  71.       }
  72.       for (const numberConditionMultiply of category.numberConditionsMultiply) {
  73.         conditions[category.id + '_' + numberConditionMultiply.name] = { type: 'numberConditionsMultiply', value: 1 };
  74.       }
  75.       for (const textConditionMultiply of category.textConditionsMultiply) {
  76.         conditions[category.id + '_' + textConditionMultiply.name] = { type: 'textConditionMultiply', value: 1 };
  77.       }
  78.       categoriesCalc1[category.id].conditions = conditions;
  79.     }
  80.   }
  81.   let [categoriesCalc, setCategoriesCalc] = React.useState(categoriesCalc1);
  82.  
  83.   function reCalc(categoryId) {
  84.     let sum = 0;
  85.     let mult = 1;
  86.     for (const key of Object.keys(categoriesCalc[categoryId].conditions)) {
  87.       let condition = categoriesCalc[categoryId].conditions[key];
  88.       switch (condition.type) {
  89.         case 'textCondition' :
  90.           sum += condition.value;
  91.           break;
  92.         case 'numberCondition':
  93.           sum += condition.value;
  94.           break;
  95.         case 'textConditionMultiply':
  96.           mult *= condition.value;
  97.           break;
  98.         case 'numberConditionsMultiply':
  99.           mult *= condition.value;
  100.           break;
  101.       }
  102.     }
  103.     // categoriesCalc[categoryId].setResult(mult * sum * categoriesCalc[String(categoryId)].quantity);
  104.     // categoriesCalc[categoryId].result = mult * sum * categoriesCalc[String(categoryId)].quantity;
  105.     setResults(oldResults => {
  106.       let newResults = oldResults;
  107.       newResults[categoryId] = mult * sum * categoriesCalc[String(categoryId)].quantity;
  108.       return newResults;
  109.     });
  110.     console.log(results)
  111.     console.log(mult * sum * categoriesCalc[String(categoryId)].quantity)
  112.     return results[categoryId];
  113.   }
  114.  
  115.   function zerofyCalc(item) {
  116.     const product = products.filter(x => x.name == item.value)[0];
  117.     for (const category of product.categories) {
  118.       setResults({...results, [category.id]: 0})
  119.       categoriesCalc[category.id].quantity = 0;
  120.       let conditions = {};
  121.       for (const textCondition of category.textConditions) {
  122.         conditions[category.id + '_' + textCondition.name] = { type: 'textCondition', value: 0 };
  123.       }
  124.       for (const numberCondition of category.numberConditions) {
  125.         conditions[category.id + '_' + numberCondition.name] = { type: 'numberCondition', value: 0 };
  126.       }
  127.       for (const numberConditionMultiply of category.numberConditionsMultiply) {
  128.         conditions[category.id + '_' + numberConditionMultiply.name] = { type: 'numberConditionsMultiply', value: 1 };
  129.       }
  130.       for (const textConditionMultiply of category.textConditionsMultiply) {
  131.         conditions[category.id + '_' + textConditionMultiply.name] = { type: 'textConditionMultiply', value: 1 };
  132.       }
  133.       categoriesCalc[category.id].conditions = conditions;
  134.     }
  135.   }
  136.  
  137.   function createConditionAutocomplete(category, condition, onChange) {
  138.     return (<Autocomplete
  139.       // value={item.value}
  140.       onChange={onChange}
  141.       // @ts-ignore
  142.       isOptionEqualToValue={(option, value) => option.name === value.name}
  143.       disablePortal
  144.       id={category.id + '_' + condition.name}
  145.       options={condition.states}
  146.       // @ts-ignore
  147.       getOptionLabel={option => option.name}
  148.       sx={{ width: 200 }}
  149.       renderInput={(params) => <TextField {...params} label="Product" />}
  150.     />);
  151.   }
  152.  
  153.  
  154.   function renderConditions(item, categoryId) {
  155.     const product = products.filter(x => x.name == item.value)[0];
  156.     if (!product) {
  157.       return [];
  158.     }
  159.     const category = product.categories.filter(x => x.id == categoryId)[0];
  160.     if (!category) {
  161.       return [];
  162.     }
  163.     let conditionsNamesArr = [];
  164.     let conditionInputsArr = [];
  165.     function createNumberCondition(condition) {
  166.       conditionsNamesArr.push(condition.name);
  167.       conditionInputsArr.push(<TextField
  168.         id={category.id + '_' + condition.name}
  169.         type="number"
  170.         onChange={(e) => {
  171.           categoriesCalc[categoryId].conditions[String(categoryId) + '_' + condition.name].value = Number(e.target.value);
  172.           reCalc(category.id);
  173.         }}
  174.         InputLabelProps={{
  175.           shrink: true,
  176.         }}
  177.         sx={{ width: 100 }}
  178.       />);
  179.     }
  180.  
  181.     function createTextCondition(condition) {
  182.       conditionsNamesArr.push(condition.name);
  183.       conditionInputsArr.push(createConditionAutocomplete(category, condition, (e, newValue) => {
  184.         categoriesCalc[categoryId].conditions[String(categoryId) + '_' + condition.name].value = newValue ? newValue.hours : 0;
  185.         reCalc(category.id);
  186.       }));
  187.     }
  188.  
  189.     for (const condition of category.textConditions) {
  190.       createTextCondition(condition)
  191.     }
  192.     for (const condition of category.numberConditions) {
  193.       createNumberCondition(condition);
  194.     }
  195.     for (const condition of category.numberConditionsMultiply) {
  196.       createNumberCondition(condition);
  197.     }
  198.     for (const condition of category.textConditionsMultiply) {
  199.       createTextCondition(condition);
  200.     }
  201.  
  202.     return (<Table>
  203.       <TableHead>
  204.         <TableRow>
  205.           {conditionsNamesArr.map(conditionName => {
  206.             return (<TableCell key={category.id + '_' + conditionName}>{conditionName}</TableCell>);
  207.           })}
  208.         </TableRow>
  209.       </TableHead>
  210.       <TableBody>
  211.         <TableRow>
  212.           {conditionInputsArr.map(conditionInput => {
  213.             return (<TableCell key={category.id + '_' + conditionInput.props.id}>{conditionInput}</TableCell>);
  214.           })}
  215.         </TableRow>
  216.       </TableBody>
  217.     </Table>);
  218.   }
  219.  
  220.   const activitiesArr = [
  221.     {
  222.       value: '',
  223.       index: 0,
  224.       id: 0
  225.     }
  226.   ];
  227.   const [activitiesFields, setActivitiesFields] = React.useState(activitiesArr);
  228.  
  229.   function addActivityField() {
  230.     setActivitiesFields(s => {
  231.       const index = s.length;
  232.       return [...s, {
  233.         value: '',
  234.         index: index,
  235.         id: 0
  236.       }];
  237.     });
  238.   }
  239.  
  240.   const activitiesCalc1 = {};
  241.   for (const activity of activities) {
  242.     let [activityResult, setActivityResult] = React.useState(0);
  243.     activitiesCalc1[activity.id] = { result: activityResult, setResult: setActivityResult, quantity: 0, averageHours: (activity.minTime + activity.maxTime) / 2};
  244.   }
  245.   let [activitiesCalc, setActivitiesCalc] = React.useState(activitiesCalc1);
  246.  
  247.   function reCalcActivity(activityId) {
  248.     activitiesCalc[activityId].setResult(activitiesCalc[activityId].quantity*activitiesCalc[activityId].averageHours);
  249.     activitiesCalc[activityId].result = activitiesCalc[activityId].quantity*activitiesCalc[activityId].averageHours;
  250.     return activitiesCalc[activityId].result;
  251.   }
  252.  
  253.   return (
  254.     <>
  255.       <MainLayout>
  256.  
  257.         {productsFields.map((item, index) => {
  258.           return (
  259.             <div key={index + '_product'}>
  260.               <div style={{ display: 'inline-flex' }}>
  261.  
  262.                 <Autocomplete
  263.                   style={{
  264.                     margin: '10px',
  265.                     verticalAlign: 'top',
  266.                   }}
  267.                   // value={item.value}
  268.                   onChange={(e, newValue:Product) => {
  269.                     // const index = Number(e.currentTarget.getAttribute("id"));
  270.                     let newFields = [...productsFields];
  271.  
  272.                     // @ts-ignore
  273.                     newFields[Number(index)].value = newValue ? newValue.name : '';
  274.                     // console.log(JSON.stringify(newFields))
  275.                     if (item.value) {
  276.                       zerofyCalc(item);
  277.                     }
  278.                     setProductsFields(newFields);
  279.                     let newCategories = {...categories};
  280.                     newCategories[index] = getCategories(item);
  281.                     setCategories(newCategories);
  282.                   }
  283.                   }
  284.                   isOptionEqualToValue={(option, value) => option.id === value.id}
  285.                   disablePortal
  286.                   id={String(index)}
  287.                   options={products}
  288.                   getOptionLabel={option => option.name}
  289.                   sx={{ width: 300 }}
  290.                   renderInput={(params) => <TextField {...params} label="Product" />}
  291.                 />
  292.                 {item.value &&
  293.                 <TableContainer
  294.                   style={{
  295.                     minWidth: '200px',
  296.                     display: 'block',
  297.                   }}>
  298.                   <Table>
  299.                     <TableHead>
  300.                       <TableRow key="test">
  301.                         <TableCell>Category</TableCell>
  302.                         <TableCell align="right">Conditions</TableCell>
  303.                         <TableCell align="right">Quantity</TableCell>
  304.                         <TableCell align="right"><b>Efforts Estimation, H:</b></TableCell>
  305.                       </TableRow>
  306.                     </TableHead>
  307.                     <TableBody>
  308.                       {categories[index].map((category, categoryIndex) => {
  309.                         return (
  310.                           <TableRow key={categoryIndex + '_category'}>
  311.                             <TableCell>{category.name}
  312.                               <Button onClick={() => {
  313.                                 let newCategories = {...categories};
  314.                                 newCategories[index].push({...category, id: category.id + 25000});
  315.                                 let product = products.filter(x => x.name == item.value)[0];
  316.                                 if (!product) {
  317.                                   return [];
  318.                                 }
  319.                                 let newCategory = product.categories[category.id];
  320.                                 newCategory.id += 25000;
  321.                                 products[product.id].categories.push(newCategory);
  322.                                 setCategories(newCategories);
  323.                                 categoriesCalc[category.id + 25000] = categoriesCalc[category.id];
  324.                                 categoriesCalc[category.id + 25000].conditions =  categoriesCalc[category.id].conditions;
  325.                               }}><Icon sx={{ color: "green" }}>add_circle</Icon></Button>
  326.                             </TableCell>
  327.                             <TableCell>{renderConditions(item, category.id)}</TableCell>
  328.                             <TableCell><TextField
  329.                               id={categoryIndex + '_quantity'}
  330.                               type="number"
  331.                               onChange={(event) => {
  332.                                 categoriesCalc[category.id].quantity = Number(event.target.value);
  333.  
  334.                                 //categoriesCalc[category.id].setQuantity(Number(event.target.value));
  335.                                 reCalc(category.id);
  336.  
  337.                               }}
  338.                               defaultValue={0}
  339.                               InputLabelProps={{
  340.                                 shrink: true,
  341.                               }}
  342.                               sx={{ width: 100 }}
  343.                             /></TableCell>
  344.                             <TableCell align="right"><p>{results[category.id]}</p></TableCell>
  345.                           </TableRow>
  346.                         );
  347.                       })}
  348.                     </TableBody>
  349.                   </Table>
  350.                 </TableContainer>
  351.  
  352.                 }
  353.               </div>
  354.             </div>
  355.           );
  356.         })}
  357.  
  358.         <Button onClick={addProductField}><Icon sx={{ color: "green" }}>add_circle</Icon></Button>
  359.         {activitiesFields.map((item, index) => {
  360.           return (
  361.             <div key={index + '_activity'}>
  362.               <div style={{ display: 'inline-flex' }}>
  363.                 <Autocomplete
  364.                   style={{
  365.                     margin: '10px'
  366.                   }}
  367.                   onChange={(e, newValue) => {
  368.                     // const index = Number(e.currentTarget.getAttribute("id"));
  369.                     let newFields = [...activitiesFields];
  370.  
  371.                     // @ts-ignore
  372.                     newFields[Number(index)].value = newValue ? newValue.name : '';
  373.                     // @ts-ignore
  374.                     newFields[Number(index)].id = newValue ? newValue.id : 0;
  375.                     // console.log(JSON.stringify(newFields))
  376.                     setActivitiesFields(newFields);
  377.                   }
  378.                   }
  379.                   id={index + '_activity_autocomplete'}
  380.                   isOptionEqualToValue={(option, value) => option.id === value.id}
  381.                   disablePortal
  382.                   options={activities}
  383.                   getOptionLabel={option => option.name}
  384.                   sx={{ width: 300 }}
  385.                   renderInput={(params) => <TextField {...params} label="Activity" />}
  386.                 />
  387.               </div>
  388.               {item.value &&
  389.                 <>
  390.               <div style={{ display: 'inline-flex', verticalAlign: 'bottom' }}>
  391.                 <TextField
  392.                   style={{
  393.                     margin: '10px'
  394.                   }}
  395.                   id={item.id + '_activity_quantity'}
  396.                   type="number"
  397.                   label="Quantity"
  398.                   onChange={(event) => {
  399.                     activitiesCalc[item.id].quantity = Number(event.target.value);
  400.                     reCalcActivity(item.id);
  401.                   }}
  402.                   defaultValue={0}
  403.                   sx={{ width: 100 }}
  404.                 />
  405.               </div>
  406.                 <div style={{ display: 'inline-flex', verticalAlign: '-100%' }}><TextField
  407.                   id={item.id + '_activity_result'}
  408.                   label="Result"
  409.                   value={activitiesCalc[item.id].result}
  410.                   onChange={() => {}}
  411.                   InputProps={{
  412.                     readOnly: true,
  413.                   }}
  414.                   sx={{ width: 100 }}
  415.                 />
  416.                 </div>
  417.  
  418.               </>
  419.               }
  420.  
  421.             </div>
  422.           );
  423.         })
  424.         }
  425.         <Button onClick={addActivityField}><Icon sx={{ color: "green" }}>add_circle</Icon></Button>
  426.       </MainLayout>
  427.     </>
  428.   );
  429. };
  430.  
  431. export default Index;
Advertisement
Add Comment
Please, Sign In to add comment