Compare commits
No commits in common. "a19c082d9a347a8121a0158c0c1465597a21c859" and "e7fda0497e8a38a91c4c6e5c93b0206862c34488" have entirely different histories.
a19c082d9a
...
e7fda0497e
@ -10,17 +10,13 @@ type ProductDetailsProps = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const ProductDetails: React.FC<ProductDetailsProps> = ({ product, category }) => {
|
const ProductDetails: React.FC<ProductDetailsProps> = ({ product, category }) => {
|
||||||
const [selectedOption, setSelectedOption] = useState<ProductOption>(
|
const [selectedOption, setSelectedOption] = useState<ProductOption>(product.options[0]);
|
||||||
product.options?.[0] || { name: product.name, price: 0 }
|
|
||||||
);
|
|
||||||
const [quantity, setQuantity] = useState(1);
|
const [quantity, setQuantity] = useState(1);
|
||||||
const { addToCart } = useCart();
|
const { addToCart } = useCart();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
// Use a safer approach for options
|
// Check if all options have the same price
|
||||||
const options = product.options || [];
|
const hasSamePrice = product.options.every(option => option.price === product.options[0].price);
|
||||||
const hasSamePrice = options.length > 0 &&
|
|
||||||
options.every(option => option.price === options[0].price);
|
|
||||||
|
|
||||||
const handleAddToCart = () => {
|
const handleAddToCart = () => {
|
||||||
addToCart({
|
addToCart({
|
||||||
@ -34,29 +30,29 @@ const ProductDetails: React.FC<ProductDetailsProps> = ({ product, category }) =>
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="product-details">
|
<div
|
||||||
|
className="product-details"
|
||||||
|
>
|
||||||
<h2>{product.name}</h2>
|
<h2>{product.name}</h2>
|
||||||
|
|
||||||
{options.length > 0 && (
|
<div className="options-list">
|
||||||
<div className="options-list">
|
<h3>Optionen:</h3>
|
||||||
<h3>Optionen:</h3>
|
{product.options.map(option => (
|
||||||
{options.map(option => (
|
<div
|
||||||
<div
|
key={option.name}
|
||||||
key={option.name}
|
className={`option-item ${selectedOption.name === option.name ? 'selected' : ''}`}
|
||||||
className={`option-item ${selectedOption.name === option.name ? 'selected' : ''}`}
|
onClick={() => setSelectedOption(option)}
|
||||||
onClick={() => setSelectedOption(option)}
|
style={(option.color || product.color) ?
|
||||||
style={(option.color || product.color) ?
|
{ backgroundColor: `${option.color || product.color}60` } : {}}
|
||||||
{ backgroundColor: `${option.color || product.color}60` } : {}}
|
>
|
||||||
>
|
<span>{option.name}</span>
|
||||||
<span>{option.name}</span>
|
{!hasSamePrice && <span className="option-price">{option.price.toFixed(2)} €</span>}
|
||||||
{!hasSamePrice && <span className="option-price">{option.price.toFixed(2)} €</span>}
|
</div>
|
||||||
</div>
|
))}
|
||||||
))}
|
{hasSamePrice && (
|
||||||
{hasSamePrice && (
|
<div className="uniform-price">Preis: {product.options[0].price.toFixed(2)} €</div>
|
||||||
<div className="uniform-price">Preis: {options[0].price.toFixed(2)} €</div>
|
)}
|
||||||
)}
|
</div>
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<div className="quantity-controls">
|
<div className="quantity-controls">
|
||||||
<h3>Menge:</h3>
|
<h3>Menge:</h3>
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Product } from '../types/types';
|
import { Product } from '../types/types';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
import { useCart } from '../contexts/CartContext';
|
|
||||||
import './ProductList.css';
|
import './ProductList.css';
|
||||||
|
|
||||||
type ProductListProps = {
|
type ProductListProps = {
|
||||||
@ -10,55 +9,26 @@ type ProductListProps = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const ProductList: React.FC<ProductListProps> = ({ products, category }) => {
|
const ProductList: React.FC<ProductListProps> = ({ products, category }) => {
|
||||||
const { addToCart } = useCart();
|
// Sort products by name alphabetically
|
||||||
const sortedProducts = [...products].sort((a, b) =>
|
const sortedProducts = [...products].sort((a, b) =>
|
||||||
a.name.localeCompare(b.name)
|
a.name.localeCompare(b.name)
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleDirectAddToCart = (product: Product) => {
|
|
||||||
addToCart({
|
|
||||||
productId: product.id,
|
|
||||||
productName: product.name,
|
|
||||||
selectedOption: { name: product.name, price: product.basePrice },
|
|
||||||
quantity: 1,
|
|
||||||
category
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="product-list">
|
<div className="product-list">
|
||||||
{sortedProducts.map(product => {
|
{sortedProducts.map(product => (
|
||||||
const hasOptions = product.options && product.options.length > 0;
|
<Link
|
||||||
const style = product.color ? { backgroundColor: `${product.color}80` } : {};
|
to={`/product/${category}/${product.id}`}
|
||||||
if (hasOptions) {
|
key={product.id}
|
||||||
return (
|
className="product-item"
|
||||||
<Link
|
style={product.color ? { backgroundColor: `${product.color}80` } : {}}
|
||||||
to={`/product/${category}/${product.id}`}
|
>
|
||||||
key={product.id}
|
<div className="product-name">{product.name}</div>
|
||||||
className="product-item"
|
<div className="product-price">{product.basePrice.toFixed(2)} €</div>
|
||||||
style={style}
|
</Link>
|
||||||
>
|
))}
|
||||||
<div className="product-name">{product.name}</div>
|
|
||||||
<div className="product-price">{product.basePrice.toFixed(2)} €</div>
|
|
||||||
</Link>
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
key={product.id}
|
|
||||||
className="product-item"
|
|
||||||
style={style}
|
|
||||||
onClick={() => handleDirectAddToCart(product)}
|
|
||||||
>
|
|
||||||
<div className="product-name">{product.name}</div>
|
|
||||||
<div className="product-price">{product.basePrice.toFixed(2)} €</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
})}
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
export default ProductList;
|
export default ProductList;
|
||||||
|
|||||||
@ -15,7 +15,12 @@
|
|||||||
"id": "f2",
|
"id": "f2",
|
||||||
"name": "Schnitzelsemmel",
|
"name": "Schnitzelsemmel",
|
||||||
"basePrice": 5.80,
|
"basePrice": 5.80,
|
||||||
"color": "#FFEFC1"
|
"color": "#FFEFC1",
|
||||||
|
"options": [
|
||||||
|
{"name": "Klassisch", "price": 5.80},
|
||||||
|
{"name": "Mit Salat", "price": 6.50, "color": "#E8F5E9"},
|
||||||
|
{"name": "Mit Käse", "price": 6.80, "color": "#FFF9C4"}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "f3",
|
"id": "f3",
|
||||||
@ -90,7 +95,13 @@
|
|||||||
"id": "d3",
|
"id": "d3",
|
||||||
"name": "Softdrinks",
|
"name": "Softdrinks",
|
||||||
"basePrice": 3.50,
|
"basePrice": 3.50,
|
||||||
"color": "#FFDAB9"
|
"color": "#FFDAB9",
|
||||||
|
"options": [
|
||||||
|
{"name": "Fanta (0,5L)", "price": 3.50},
|
||||||
|
{"name": "Sprite (0,5L)", "price": 3.50},
|
||||||
|
{"name": "Almdudler (0,5L)", "price": 3.50},
|
||||||
|
{"name": "Eistee (0,5L)", "price": 3.50}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "d4",
|
"id": "d4",
|
||||||
|
|||||||
@ -8,7 +8,7 @@ export type Product = {
|
|||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
basePrice: number;
|
basePrice: number;
|
||||||
options?: ProductOption[];
|
options: ProductOption[];
|
||||||
color?: string; // Optional color code for background highlight
|
color?: string; // Optional color code for background highlight
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user