This commit is contained in:
Philippe Torrel
2026-08-28 13:40:03 +02:00
parent 0d15f066d1
commit bc4d5a41fd
320 changed files with 32001 additions and 95 deletions

Binary file not shown.

View File

@@ -1,3 +1,4 @@
import { useLocation } from 'react-router-dom';
import FooterMain from './components/footers/FooterMain';
import HeaderMain from './components/headers/HeaderMain';
import NavMain from './components/navs/NavMain';
@@ -5,10 +6,12 @@ import Router from './routes/Router';
function App(props) {
// const { } = props;
const { pathname: path } = useLocation();
console.log(path);
return (
<>
<HeaderMain />
{path === '/' && <HeaderMain />}
<NavMain />
<main id="main">
<Router />

View File

@@ -1,82 +1,21 @@
import { useCallback, useMemo, useReducer, useState } from 'react';
import { useCallback, useMemo } from 'react';
import RowProduct from './content/RowProduct';
import { ProductsProvider, useProductsState } from '../../stores/products';
// Reducer (bei größerer Applikaitonsstuktur ausgelagert)
const initialState = (props) => {
// Validierung und Error Checks
return { items: props.items || [] };
};
const TableProductsView = (props) => {
const { items } = useProductsState();
// const dispatch = useProductsDispatch()
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 }, dispatch] = useReducer(reducer, initialState(props));
// const [items, setItems] = useState(
// props.items || [
// {
// _id: '1',
// title: 'Example Product 1',
// sku: 'ABC1234',
// stock: 2,
// price: 15.2,
// },
// ],
// );
//const [{ items }, dispatch] = useReducer(reducer, initialState(props));
// EventHandler ============
const handleAmount = useCallback((amount, id) => {
dispatch({ type: 'UPDATE_AMOUNT', payload: { amount, id } });
// const handleAmount = useCallback((amount, id) => {
// dispatch({ type: PRODUCTS_ACTIONS.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));
// });
}, []);
// const handlePrice = useCallback((price, id) => {
// dispatch({ type: PRODUCTS_ACTIONS.UPDATE_PRICE, payload: { price, id } });
// }, []);
// Functions ===============
const totalPrice = useMemo(() => {
@@ -91,13 +30,6 @@ const TableProducts = (props) => {
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">
@@ -117,8 +49,8 @@ const TableProducts = (props) => {
<RowProduct
key={`row-product-${idx}`}
{...product}
onHandleAmount={handleAmount}
onHandlePrice={handlePrice}
// onHandleAmount={handleAmount}
// onHandlePrice={handlePrice}
/>
))}
</tbody>
@@ -133,4 +65,14 @@ const TableProducts = (props) => {
</div>
);
};
const TableProducts = (props) => {
// const { } = props;
return (
<ProductsProvider items={props.items}>
<TableProductsView />
</ProductsProvider>
);
};
export default TableProducts;

View File

@@ -1,4 +1,8 @@
// import { useState } from 'react';
import { memo, useCallback } from 'react';
import { useProductsActions } from '../../../stores/products'; // /index.js muss nicht angegeben werden (wg. Bundler)
// import { useProductsDispatch } from '../../../stores/products';
// import { PRODUCTS_ACTIONS } from '../../../stores/products';
import InputAmount from '../../inputs/InputAmount';
import InputPrice from '../../inputs/InputPrice';
@@ -6,19 +10,35 @@ const RowProduct = (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 { updateAmount, updatePrice } = useProductsActions();
// const dispatch = useProductsDispatch();
// Eventhandler
const handleAmount = (val) => {
// setAmount(val);
props.onHandleAmount(val, _id);
};
// const handleAmount = useCallback((val) => {
// // setAmount(val);
// // props.onHandleAmount(val, _id);
// dispatch({ type: PRODUCTS_ACTIONS.UPDATE_AMOUNT, payload: { amount: val, id: _id } });
// }, []);
const handlePrice = (val) => {
// setPrice(val);
props.onHandlePrice(val, _id);
};
const handleAmount = useCallback(
(val) => {
updateAmount(val, _id);
},
[updateAmount, _id],
);
// const handlePrice = (val) => {
// // setPrice(val);
// // props.onHandlePrice(val, _id);
// dispatch({ type: PRODUCTS_ACTIONS.UPDATE_PRICE, payload: { price: val, id: _id } });
// };
const handlePrice = useCallback(
(val) => {
updatePrice(val, _id);
},
[updatePrice, _id],
);
return (
<tr className="row-product">
@@ -34,4 +54,4 @@ const RowProduct = (props) => {
</tr>
);
};
export default RowProduct;
export default memo(RowProduct);

View File

@@ -0,0 +1,68 @@
import { createContext, useCallback, useContext, useReducer } from 'react';
import { PRODUCTS_ACTIONS, productsReducer } from './reducer';
import { createInitialState } from './initialState';
const ProductsStateContext = createContext(null);
const ProductsDispatchContext = createContext(null);
// const ProductsContext = createContext(null);
export const ProductsProvider = (props) => {
const { children, items = [] } = props;
const [state, dispatch] = useReducer(productsReducer, items, createInitialState);
return (
// <ProductsContext.Provider value={{state, dispatch}}>
// {children}
// </ProductsContext.Provider>
<ProductsStateContext.Provider value={state}>
<ProductsDispatchContext.Provider value={dispatch}>{children}</ProductsDispatchContext.Provider>
</ProductsStateContext.Provider>
);
};
// eigene Hooks mit ErrorHandler
export const useProductsState = () => {
const state = useContext(ProductsStateContext);
if (state == null) {
throw Error('useProductsState muss innerhalb von ProductsProvider verwendet werden.');
}
return state;
};
export const useProductsDispatch = () => {
const dispatch = useContext(ProductsDispatchContext);
if (dispatch == null) {
throw Error('useProductsDispatch muss innerhalb von ProductsProvider verwendet werden.');
}
return dispatch;
};
export const useProductsActions = () => {
const dispatch = useProductsDispatch();
const updateAmount = useCallback(
(amount, id) => {
dispatch({ type: PRODUCTS_ACTIONS.UPDATE_AMOUNT, payload: { id, amount } });
},
[dispatch],
);
const updatePrice = useCallback(
(price, id) => {
dispatch({ type: PRODUCTS_ACTIONS.UPDATE_PRICE, payload: { id, price } });
},
[dispatch],
);
return {
updateAmount,
updatePrice,
};
};

View File

@@ -0,0 +1,3 @@
export { createInitialState } from './initialState';
export { PRODUCTS_ACTIONS, productsReducer } from './reducer';
export { ProductsProvider, useProductsActions, useProductsDispatch, useProductsState } from './ProductsStore';

View File

@@ -0,0 +1,7 @@
// import mit {}
export const createInitialState = (items) => {
// validation and sanitizing
return { items: items || [] };
};
export default createInitialState; // import mit eigener Benennung möglich

View File

@@ -0,0 +1,36 @@
// in ts enum
export const PRODUCTS_ACTIONS = {
UPDATE_AMOUNT: 'UPDATE_AMOUNT',
UPDATE_PRICE: 'UPDATE_PRICE',
};
export const productsReducer = (state, action) => {
const { type, payload } = action;
console.log(state);
switch (type) {
case PRODUCTS_ACTIONS.UPDATE_AMOUNT:
return {
...state,
items: state.items.map((item) =>
item._id === payload.id //
? { ...item, stock: payload.amount }
: item,
),
};
case PRODUCTS_ACTIONS.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;
}
};