This commit is contained in:
GokaPek 2023-12-21 23:14:45 +04:00
parent efc2bd6e7d
commit f49f0d234c
15 changed files with 115 additions and 198 deletions

File diff suppressed because one or more lines are too long

View File

@ -15,6 +15,7 @@
"react": "^18.2.0",
"react-bootstrap": "^2.9.1",
"react-bootstrap-icons": "^1.10.3",
"react-custom-scrollbars": "^4.2.1",
"react-dom": "^18.2.0",
"react-hot-toast": "^2.4.1",
"react-icons": "^4.12.0",
@ -1160,6 +1161,11 @@
"acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
}
},
"node_modules/add-px-to-style": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/add-px-to-style/-/add-px-to-style-1.0.0.tgz",
"integrity": "sha512-YMyxSlXpPjD8uWekCQGuN40lV4bnZagUwqa2m/uFv1z/tNImSk9fnXVMUI5qwME/zzI3MMQRvjZ+69zyfSSyew=="
},
"node_modules/ajv": {
"version": "6.12.6",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
@ -1864,6 +1870,16 @@
"node": ">=6.0.0"
}
},
"node_modules/dom-css": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/dom-css/-/dom-css-2.1.0.tgz",
"integrity": "sha512-w9kU7FAbaSh3QKijL6n59ofAhkkmMJ31GclJIz/vyQdjogfyxcB6Zf8CZyibOERI5o0Hxz30VmJS7+7r5fEj2Q==",
"dependencies": {
"add-px-to-style": "1.0.0",
"prefix-style": "2.0.1",
"to-camel-case": "1.0.0"
}
},
"node_modules/dom-helpers": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz",
@ -4507,6 +4523,11 @@
"node": ">=4"
}
},
"node_modules/performance-now": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
"integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow=="
},
"node_modules/picocolors": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
@ -4580,6 +4601,11 @@
"node": "^10 || ^12 || >=14"
}
},
"node_modules/prefix-style": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/prefix-style/-/prefix-style-2.0.1.tgz",
"integrity": "sha512-gdr1MBNVT0drzTq95CbSNdsrBDoHGlb2aDJP/FoY+1e+jSDPOb1Cv554gH2MGiSr2WTcXi/zu+NaFzfcHQkfBQ=="
},
"node_modules/prelude-ls": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
@ -4673,6 +4699,14 @@
}
]
},
"node_modules/raf": {
"version": "3.4.1",
"resolved": "https://registry.npmjs.org/raf/-/raf-3.4.1.tgz",
"integrity": "sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==",
"dependencies": {
"performance-now": "^2.1.0"
}
},
"node_modules/range-parser": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
@ -4748,6 +4782,20 @@
"react": ">=16.8.6"
}
},
"node_modules/react-custom-scrollbars": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/react-custom-scrollbars/-/react-custom-scrollbars-4.2.1.tgz",
"integrity": "sha512-VtJTUvZ7kPh/auZWIbBRceGPkE30XBYe+HktFxuMWBR2eVQQ+Ur6yFJMoaYcNpyGq22uYJ9Wx4UAEcC0K+LNPQ==",
"dependencies": {
"dom-css": "^2.0.0",
"prop-types": "^15.5.10",
"raf": "^3.1.0"
},
"peerDependencies": {
"react": "^0.14.0 || ^15.0.0 || ^16.0.0",
"react-dom": "^0.14.0 || ^15.0.0 || ^16.0.0"
}
},
"node_modules/react-dom": {
"version": "18.2.0",
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz",
@ -5432,6 +5480,14 @@
"integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
"dev": true
},
"node_modules/to-camel-case": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/to-camel-case/-/to-camel-case-1.0.0.tgz",
"integrity": "sha512-nD8pQi5H34kyu1QDMFjzEIYqk0xa9Alt6ZfrdEMuHCFOfTLhDG5pgTu/aAM9Wt9lXILwlXmWP43b8sav0GNE8Q==",
"dependencies": {
"to-space-case": "^1.0.0"
}
},
"node_modules/to-fast-properties": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
@ -5441,6 +5497,19 @@
"node": ">=4"
}
},
"node_modules/to-no-case": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/to-no-case/-/to-no-case-1.0.2.tgz",
"integrity": "sha512-Z3g735FxuZY8rodxV4gH7LxClE4H0hTIyHNIHdk+vpQxjLm0cwnKXq/OFVZ76SOQmto7txVcwSCwkU5kqp+FKg=="
},
"node_modules/to-space-case": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/to-space-case/-/to-space-case-1.0.0.tgz",
"integrity": "sha512-rLdvwXZ39VOn1IxGL3V6ZstoTbwLRckQmn/U8ZDLuWwIXNpuZDhQ3AiRUlhTbOXFVE9C+dR51wM0CBDhk31VcA==",
"dependencies": {
"to-no-case": "^1.0.0"
}
},
"node_modules/toidentifier": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",

View File

@ -19,6 +19,7 @@
"react": "^18.2.0",
"react-bootstrap": "^2.9.1",
"react-bootstrap-icons": "^1.10.3",
"react-custom-scrollbars": "^4.2.1",
"react-dom": "^18.2.0",
"react-hot-toast": "^2.4.1",
"react-icons": "^4.12.0",

View File

@ -1,5 +1,5 @@
import { Button, ButtonGroup, Card } from 'react-bootstrap';
import { DashLg, PlusLg, XLg } from 'react-bootstrap-icons';
import { DashLg, XLg } from 'react-bootstrap-icons';
import imgPlaceholder from '../../assets/200.png';
import './Cart.css';
import useCart from './CartHook';
@ -7,8 +7,6 @@ import useCart from './CartHook';
const Cart = () => {
const {
cart,
getCartSum,
addToCart,
removeFromCart,
clearCart,
} = useCart();
@ -27,20 +25,10 @@ const Cart = () => {
<Card.Body className='p-2 d-flex flex-column flex-sm-row align-items-center'>
<div className='cart-item flex-fill'>
<img className='cart-image' src={cartItem.image || imgPlaceholder} alt="Cart Image" />
{cartItem.type.name}
{cartItem.book_name}
</div>
<div className='cart-item mt-2 mt-sm-0 d-flex flex-column align-items-center align-items-sm-end'>
<div>
{cartItem.price}
{' * '}
{cartItem.count}
{' = '}
{parseFloat(cartItem.price * cartItem.count).toFixed(2)}
</div>
<ButtonGroup className='mt-2 mt-sm-1' aria-label="Cart counter">
<Button variant="primary" onClick={() => addToCart(cartItem)}>
<PlusLg />
</Button>
<Button variant="danger" onClick={() => removeFromCart(cartItem)}>
<DashLg />
</Button>
@ -49,9 +37,6 @@ const Cart = () => {
</Card.Body>
</Card>)
}
<div className='mb-2 col-12 col-md-8 col-lg-6 d-flex justify-content-end'>
<strong>Итого: {getCartSum()} &#8381;</strong>
</div>
</div>
);
};

View File

@ -10,7 +10,7 @@ const setCartCount = (cart, item, value) => {
const addToCart = (cart, item) => {
const existsItem = cart.find((cartItem) => cartItem.id === item.id);
if (existsItem !== undefined) {
return setCartCount(cart, item, 1);
return cart;
}
return [...cart, { ...item, count: 1 }];
};

View File

@ -14,7 +14,6 @@ const Input = ({
Input.propTypes = {
name: PropTypes.string,
book_name: PropTypes.string,
label: PropTypes.string,
value: PropTypes.string,
onChange: PropTypes.func,

View File

@ -20,7 +20,6 @@ const Select = ({
Select.propTypes = {
values: PropTypes.array,
name: PropTypes.string,
book_name: PropTypes.string,
label: PropTypes.string,
value: PropTypes.string,
onChange: PropTypes.func,

View File

@ -30,10 +30,10 @@ const LinesForm = ({ id }) => {
<LinesItemForm item={item} handleChange={handleChange} />
<Form.Group className='row justify-content-center m-0 mt-3'>
<Button className='col-5 col-lg-2 m-0 me-2' variant='secondary' onClick={() => onBack()}>
Назад
Back
</Button>
<Button className='col-5 col-lg-2 m-0 ms-2' type='submit' variant='primary'>
Сохранить
Save
</Button>
</Form.Group>
</Form>

View File

@ -14,16 +14,18 @@ const LinesItemForm = ({ item, handleChange }) => {
<img id='image-preview' className='rounded' alt='placeholder'
src={item.image || imgPlaceholder} />
</div>
<Input name='book_name' label='Name' value={item.book_name} onChange={handleChange}
type='text' required />
<Select values={types} name='typeId' label='Type' value={item.typeId} onChange={handleChange}
required />
<Input name='price' label='Price' value={item.price} onChange={handleChange}
type='number' min='50.0' step='1.0' required />
<Input name='count' label='Количество' value={item.count} onChange={handleChange}
type='number' min='1' step='1' required />
<Input name='image' label='Изображение' onChange={handleChange}
type='file' accept='image/*' />
<div style={{ height: 300, overflow: 'auto' }}>
<Input name='book_name' label='Name' value={item.book_name} onChange={handleChange}
type='text' required />
<Select values={types} name='typeId' label='Type' value={item.typeId} onChange={handleChange}
required />
<Input name='author_name' label='Author' value={item.author_name} onChange={handleChange}
type='text' required />
<Input name='price' label='Price' value={item.price} onChange={handleChange}
type='number' min='50.0' step='1.0' required />
<Input name='image' label='Image' onChange={handleChange}
type='file' accept='image/*' />
</div>
</>
);
};

View File

@ -1,4 +1,3 @@
/* eslint-disable prefer-destructuring */
import { useState } from 'react';
import toast from 'react-hot-toast';
import getBase64FromFile from '../../utils/Base64';
@ -16,17 +15,15 @@ const useLinesItemForm = (id, linesChangeHandle) => {
const getLineObject = (formData) => {
const typeId = parseInt(formData.typeId, 10);
// eslint-disable-next-line camelcase
const book_name = formData.book_name;
const bookname = formData.book_name;
const authorname = formData.author_name;
const price = parseFloat(formData.price).toFixed(2);
const count = parseInt(formData.count, 10);
const image = formData.image.startsWith('data:image') ? formData.image : '';
return {
typeId: typeId.toString(),
// eslint-disable-next-line object-shorthand, camelcase
book_name: book_name,
book_name: bookname,
author_name: authorname,
price: price.toString(),
count: count.toString(),
image,
};
};

View File

@ -5,6 +5,7 @@ const useLinesItem = (id) => {
const emptyItem = {
id: '',
book_name: '',
author_name: '',
typeId: '',
price: '0',
count: '0',

View File

@ -7,10 +7,10 @@ const LinesTable = ({ children }) => {
<thead>
<tr>
<th scope='col'></th>
<th scope='col' className='w-25'>Товар</th>
<th scope='col' className='w-25'>Цена</th>
<th scope='col' className='w-25'>Колич.</th>
<th scope='col' className='w-25'>Сумма</th>
<th scope='col' className='w-25'>Name</th>
<th scope='col' className='w-25'>Category</th>
<th scope='col' className='w-25'>Author</th>
<th scope='col' className='w-25'>Price</th>
<th scope='col'></th>
<th scope='col'></th>
<th scope='col'></th>

View File

@ -0,0 +1,4 @@
#image {
max-width: 200px;
max-height: 100;
}

View File

@ -2,6 +2,7 @@ import PropTypes from 'prop-types';
import {
PencilFill, Trash3, Heart,
} from 'react-bootstrap-icons';
import './LinesTableRow.css';
const LinesTableRow = ({
index, line, onAddCart, onDelete, onEdit,
@ -16,8 +17,9 @@ const LinesTableRow = ({
<th scope="row">{index + 1}</th>
<td>{line.book_name}</td>
<td>{line.type.name}</td>
<td>{line.author_name}</td>
<td>{parseFloat(line.price).toFixed(2)}</td>
<td>{line.count}</td>
<td><img src={line.image} id='image' alt={line.book_name} /></td>
<td><a href="#" onClick={(event) => handleAnchorClick(event, onAddCart)}><Heart /></a></td>
<td><a href="#" onClick={(event) => handleAnchorClick(event, onEdit)}><PencilFill /></a></td>
<td><a href="#" onClick={(event) => handleAnchorClick(event, onDelete)}><Trash3 /></a></td>

View File

@ -19,10 +19,10 @@ const ModalForm = ({
<Modal.Footer className='m-0 pt-2 pb-2 ps-3 pe-3 row justify-content-center'>
<Button variant='secondary' className='col-5 m-0 me-2'
onClick={() => onClose()}>
Отмена
Close
</Button>
<Button variant='primary' className='col-5 m-0 ms-2' type='submit'>
Сохранить
Save
</Button>
</Modal.Footer>
</Form>