This commit is contained in:
@@ -9,7 +9,7 @@
|
||||
"version": "0.0.0",
|
||||
"dependencies": {
|
||||
"@splidejs/react-splide": "^0.7.12",
|
||||
"axios": "^1.19.0",
|
||||
"axios": "^1.20.0",
|
||||
"bootstrap": "^5.3.8",
|
||||
"react": "^19.2.8",
|
||||
"react-dom": "^19.2.8",
|
||||
@@ -19,7 +19,7 @@
|
||||
"devDependencies": {
|
||||
"@types/react": "^19.2.18",
|
||||
"@types/react-dom": "^19.2.5",
|
||||
"@vitejs/plugin-react": "^6.1.0",
|
||||
"@vitejs/plugin-react": "^6.1.1",
|
||||
"oxlint": "^1.80.0",
|
||||
"sass-embedded": "^1.103.1",
|
||||
"vite": "^8.2.2"
|
||||
@@ -1022,9 +1022,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@vitejs/plugin-react": {
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-6.1.0.tgz",
|
||||
"integrity": "sha512-qd2BzUBehkov86WFhg0JkEFEYyCLG9uPCe6qWTY/kRlss9OvJrOF2UbIWT7p+8IzZHkEu0DNGHc4HSv+JdDLsw==",
|
||||
"version": "6.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-6.1.1.tgz",
|
||||
"integrity": "sha512-yxLaQV9gkhS8ezJqCM6+ndU7mDY6gqAg75NQ+0IjwEI8IYOmQCgkRwHKVSfWXW076DsqMo0Dk+0FK1U+M5RgFw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@@ -1070,9 +1070,9 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/axios": {
|
||||
"version": "1.19.0",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.19.0.tgz",
|
||||
"integrity": "sha512-ht/iuYZXEjFxLH/Hkezgd7m6JKlHHXEUSneaDz8uZe1Gj5QZtCnpyDsckvAiEnT89OEbCLmnte4R4sn7P0EKFw==",
|
||||
"version": "1.20.0",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.20.0.tgz",
|
||||
"integrity": "sha512-r8aOh8j9cGKpgQAqpzrUHnSIc6a59Y3Xf/cv8sy1DrHCkZHzQGEuoq1tARk6qSyDdtQGSDgpb9kFlruzPvrgwg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"follow-redirects": "^1.16.0",
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@splidejs/react-splide": "^0.7.12",
|
||||
"axios": "^1.19.0",
|
||||
"axios": "^1.20.0",
|
||||
"bootstrap": "^5.3.8",
|
||||
"react": "^19.2.8",
|
||||
"react-dom": "^19.2.8",
|
||||
@@ -21,7 +21,7 @@
|
||||
"devDependencies": {
|
||||
"@types/react": "^19.2.18",
|
||||
"@types/react-dom": "^19.2.5",
|
||||
"@vitejs/plugin-react": "^6.1.0",
|
||||
"@vitejs/plugin-react": "^6.1.1",
|
||||
"oxlint": "^1.80.0",
|
||||
"sass-embedded": "^1.103.1",
|
||||
"vite": "^8.2.2"
|
||||
|
||||
@@ -7,10 +7,13 @@ const InputAmount = (props) => {
|
||||
|
||||
// EventHandlers ================
|
||||
const handleChange = (e) => {
|
||||
console.log(e); // Event-Objekte wurden um React Methoden und Eigenschaften erweitert. (SyntheticBaseEvent anstatt InputEvent)
|
||||
console.log(e.target.value);
|
||||
};
|
||||
const inputValue = e.target.value;
|
||||
const numericRegExp = new RegExp(/^-?\d*$/); // regular expression for numbers (including optional minus sign)
|
||||
|
||||
if (!numericRegExp.test(inputValue)) return;
|
||||
// setAmount(inputValue);
|
||||
props.onHandleAmount(inputValue);
|
||||
};
|
||||
const handleClickDec = (e) => {
|
||||
// Guard
|
||||
if (amount < min) return;
|
||||
|
||||
@@ -1,22 +1,108 @@
|
||||
import { useCallback, useMemo, useReducer, useState } from 'react';
|
||||
import RowProduct from './content/RowProduct';
|
||||
|
||||
// Reducer (bei größerer Applikaitonsstuktur ausgelagert)
|
||||
const initialState = (props) => {
|
||||
// Validierung und Error Checks
|
||||
return { items: props.items || [] };
|
||||
};
|
||||
|
||||
const reducer = (state, action) => {
|
||||
const { type, payload } = action;
|
||||
switch (type) {
|
||||
case 'UPDATE_AMOUNT':
|
||||
return {
|
||||
...state,
|
||||
items: state.items.map((item) =>
|
||||
item._id === payload.id
|
||||
? { ...item, stock: payload.amount } //
|
||||
: item,
|
||||
),
|
||||
};
|
||||
case 'UPDATE_PRICE':
|
||||
return {
|
||||
...state,
|
||||
items: state.items.map((item) =>
|
||||
item._id === payload.id
|
||||
? { ...item, price: payload.price } //
|
||||
: item,
|
||||
),
|
||||
};
|
||||
default:
|
||||
console.warn('no action found');
|
||||
return state;
|
||||
}
|
||||
};
|
||||
|
||||
const TableProducts = (props) => {
|
||||
const {
|
||||
items = [
|
||||
{
|
||||
_id: '1',
|
||||
title: 'Example Product 1',
|
||||
sku: 'ABC1234',
|
||||
stock: 2,
|
||||
price: 15.2,
|
||||
},
|
||||
],
|
||||
} = props;
|
||||
// const {
|
||||
// items = [
|
||||
// {
|
||||
// _id: '1',
|
||||
// title: 'Example Product 1',
|
||||
// sku: 'ABC1234',
|
||||
// stock: 2,
|
||||
// price: 15.2,
|
||||
// },
|
||||
// ],
|
||||
// } = props;
|
||||
|
||||
const [{ items }, dispatch] = useReducer(reducer, initialState(props));
|
||||
|
||||
// const [items, setItems] = useState(
|
||||
// props.items || [
|
||||
// {
|
||||
// _id: '1',
|
||||
// title: 'Example Product 1',
|
||||
// sku: 'ABC1234',
|
||||
// stock: 2,
|
||||
// price: 15.2,
|
||||
// },
|
||||
// ],
|
||||
// );
|
||||
|
||||
// EventHandler ============
|
||||
const handleAmount = useCallback((amount, id) => {
|
||||
dispatch({ type: 'UPDATE_AMOUNT', payload: { amount, id } });
|
||||
|
||||
// setItems((prevItems) => {
|
||||
// return prevItems.map((item) => (item._id === id ? { ...item, stock: amount } : item));
|
||||
// });
|
||||
}, []);
|
||||
|
||||
const handlePrice = useCallback((price, id) => {
|
||||
dispatch({ type: 'UPDATE_PRICE', payload: { price, id } });
|
||||
|
||||
// setItems((prevItems) => {
|
||||
// return prevItems.map((item) => (item._id === id ? { ...item, price: price } : item));
|
||||
// });
|
||||
}, []);
|
||||
|
||||
// Functions ===============
|
||||
const totalPrice = useMemo(() => {
|
||||
// [0, {stock: 2, price, 15.2}, {...}]
|
||||
return items.reduce((sum, obj) => {
|
||||
return sum + Number(obj.stock) * Number(obj.price);
|
||||
}, 0);
|
||||
}, [items]);
|
||||
|
||||
// useCallback weiter Einsatzbereich in Kombination mit ref- Attribut
|
||||
const theadRef = useCallback((el) => {
|
||||
if (el) console.log(el);
|
||||
}, []);
|
||||
|
||||
// const getTotalPrice = () => {
|
||||
// // [0, {stock: 2, price, 15.2}, {...}]
|
||||
// return items.reduce((sum, obj) => {
|
||||
// return sum + Number(obj.stock) * Number(obj.price);
|
||||
// }, 0);
|
||||
// };
|
||||
|
||||
return (
|
||||
<div className="m-table-products table-products">
|
||||
<div className="container py-2">
|
||||
<table className="table table-striped">
|
||||
<thead className="table-dark">
|
||||
<thead className="table-dark" ref={theadRef}>
|
||||
<tr>
|
||||
<th>SKU</th>
|
||||
<th>Stock</th>
|
||||
@@ -26,12 +112,20 @@ const TableProducts = (props) => {
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{items.length > 0 && items.map((product, idx) => <RowProduct key={`row-product-${idx}`} {...product} />)}
|
||||
{items.length > 0 &&
|
||||
items.map((product, idx) => (
|
||||
<RowProduct
|
||||
key={`row-product-${idx}`}
|
||||
{...product}
|
||||
onHandleAmount={handleAmount}
|
||||
onHandlePrice={handlePrice}
|
||||
/>
|
||||
))}
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td colSpan={4}>Total:</td>
|
||||
<td></td>
|
||||
<td>{totalPrice.toFixed(2)}</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
|
||||
@@ -1,21 +1,23 @@
|
||||
import { useState } from 'react';
|
||||
// import { useState } from 'react';
|
||||
import InputAmount from '../../inputs/InputAmount';
|
||||
import InputPrice from '../../inputs/InputPrice';
|
||||
|
||||
const RowProduct = (props) => {
|
||||
// const { sku = '', stock: amount = 0, price = 0, title = '' } = props;
|
||||
const { sku = '', title = '' } = props;
|
||||
const { _id, sku = '', stock: amount = 0, price = 0, title = '' } = props;
|
||||
//const { sku = '', title = '' } = props;
|
||||
|
||||
const [amount, setAmount] = useState(props.stock || 0);
|
||||
const [price, setPrice] = useState(props.price || 0);
|
||||
// const [amount, setAmount] = useState(props.stock || 0);
|
||||
// const [price, setPrice] = useState(props.price || 0);
|
||||
|
||||
// Eventhandler
|
||||
const handleAmount = (val) => {
|
||||
setAmount(val);
|
||||
// setAmount(val);
|
||||
props.onHandleAmount(val, _id);
|
||||
};
|
||||
|
||||
const handlePrice = (val) => {
|
||||
setPrice(val);
|
||||
// setPrice(val);
|
||||
props.onHandlePrice(val, _id);
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
@@ -7,6 +7,19 @@
|
||||
.input-group {
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
&:last-child {
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
}
|
||||
tfoot {
|
||||
tr {
|
||||
td {
|
||||
&:last-child {
|
||||
border-top: 2px solid #222;
|
||||
font-weight: 700;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user