diff --git a/src/components/CartOverview.css b/src/components/CartOverview.css index 557bf2e..025effd 100644 --- a/src/components/CartOverview.css +++ b/src/components/CartOverview.css @@ -1,64 +1,64 @@ .cart-overview { - padding: 15px; + padding: 8px 4px; } .cart-summary { - background-color: #f5f5f5; - border-radius: 8px; - padding: 15px; - margin-bottom: 20px; - box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); + background-color: #f7f9fc; + border-radius: 6px; + padding: 12px; + margin-bottom: 16px; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.06); } .count-info { display: flex; justify-content: space-between; - margin-bottom: 10px; + margin-bottom: 8px; } .food-count, .drink-count { font-weight: 500; + font-size: 0.9rem; } .total-price { font-weight: bold; - font-size: 1.2rem; + font-size: 1.1rem; text-align: center; - margin-top: 10px; + margin-top: 8px; color: #2c7be5; } -.clear-cart-button { - width: 100%; - padding: 12px; - margin-bottom: 15px; - background-color: #ff5252; - color: white; - border: none; - border-radius: 8px; - font-weight: bold; - cursor: pointer; - transition: background-color 0.2s; -} -.calculate-change-button { - width: 100%; - padding: 12px; - background-color: #2c7be5; - color: white; - border: none; - border-radius: 8px; - font-weight: bold; - cursor: pointer; - transition: background-color 0.2s; -} .cart-actions { display: flex; flex-direction: column; - gap: 12px; - margin-bottom: 20px; + gap: 10px; + margin-bottom: 16px; } + +.calculate-change-button, .clear-cart-button { + width: 100%; + padding: 10px; + border: none; + border-radius: 6px; + font-weight: 600; + font-size: 0.95rem; + cursor: pointer; + transition: background-color 0.2s; +} + +.calculate-change-button { + background-color: #2c7be5; + color: white; +} + +.clear-cart-button { + background-color: #ff5252; + color: white; +} + .calculate-change-button:active { - background-color: #1b5eb5; + background-color: #1b5eb5; } .clear-cart-button:active { @@ -68,49 +68,51 @@ .cart-items { display: flex; flex-direction: column; - gap: 15px; + gap: 8px; } .cart-item { display: flex; justify-content: space-between; align-items: center; - background-color: white; - padding: 15px; - border-radius: 8px; - box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); + background-color: #f7f9fc; + padding: 12px; + border-radius: 6px; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.06); } .item-info { display: flex; flex-direction: column; - gap: 5px; + gap: 3px; flex: 1; } .item-name { font-weight: 500; + font-size: 0.95rem; } .item-option { - font-size: 0.9rem; + font-size: 0.85rem; color: #666; } .item-price { font-weight: bold; color: #2c7be5; + font-size: 0.9rem; } .item-quantity { display: flex; align-items: center; - gap: 10px; + gap: 8px; } .item-quantity button { - width: 30px; - height: 30px; + width: 26px; + height: 26px; border: none; border-radius: 50%; background-color: #2c7be5; @@ -126,7 +128,8 @@ .empty-cart { text-align: center; - padding: 30px; - color: #666; + padding: 20px; + color: #888; font-style: italic; + font-size: 0.9rem; } diff --git a/src/components/ProductDetails.tsx b/src/components/ProductDetails.tsx index 27e5235..d534553 100644 --- a/src/components/ProductDetails.tsx +++ b/src/components/ProductDetails.tsx @@ -15,6 +15,9 @@ const ProductDetails: React.FC = ({ product, category }) => const { addToCart } = useCart(); const navigate = useNavigate(); + // Check if all options have the same price + const hasSamePrice = product.options.every(option => option.price === product.options[0].price); + const handleAddToCart = () => { addToCart({ productId: product.id, @@ -26,14 +29,10 @@ const ProductDetails: React.FC = ({ product, category }) => navigate('/'); }; - const incrementQuantity = () => setQuantity(prev => prev + 1); - const decrementQuantity = () => setQuantity(prev => Math.max(1, prev - 1)); - - // Check if all options have the same price - const hasSamePrice = product.options.every(option => option.price === product.options[0].price); - return ( -
+

{product.name}

@@ -43,24 +42,24 @@ const ProductDetails: React.FC = ({ product, category }) => key={option.name} className={`option-item ${selectedOption.name === option.name ? 'selected' : ''}`} onClick={() => setSelectedOption(option)} + style={(option.color || product.color) ? + { backgroundColor: `${option.color || product.color}60` } : {}} > {option.name} {!hasSamePrice && {option.price.toFixed(2)} €}
))} {hasSamePrice && ( -
- Preis: {product.options[0].price.toFixed(2)} € -
+
Preis: {product.options[0].price.toFixed(2)} €
)}

Menge:

- + {quantity} - +
diff --git a/src/components/ProductList.css b/src/components/ProductList.css index f728ba8..3891b23 100644 --- a/src/components/ProductList.css +++ b/src/components/ProductList.css @@ -1,34 +1,35 @@ .product-list { display: flex; flex-direction: column; - gap: 10px; - padding: 10px; + gap: 8px; + padding: 6px; } .product-item { display: flex; justify-content: space-between; align-items: center; - padding: 15px; + padding: 14px; background-color: #fff; - border-radius: 8px; - box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); + border-radius: 6px; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08); text-decoration: none; color: #333; transition: transform 0.2s, box-shadow 0.2s; } .product-item:active { - transform: scale(0.98); + transform: scale(0.99); + box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); } .product-name { font-weight: 500; - font-size: 1.1rem; + font-size: 1rem; } .product-price { - font-weight: bold; + font-weight: 600; color: #2c7be5; - font-size: 1.1rem; + font-size: 0.95rem; } diff --git a/src/components/ProductList.tsx b/src/components/ProductList.tsx index 3d442cd..af8ccb0 100644 --- a/src/components/ProductList.tsx +++ b/src/components/ProductList.tsx @@ -21,6 +21,7 @@ const ProductList: React.FC = ({ products, category }) => { to={`/product/${category}/${product.id}`} key={product.id} className="product-item" + style={product.color ? { backgroundColor: `${product.color}80` } : {}} >
{product.name}
{product.basePrice.toFixed(2)} €
diff --git a/src/data/products.json b/src/data/products.json index 81ce6f1..a92ed23 100644 --- a/src/data/products.json +++ b/src/data/products.json @@ -4,9 +4,10 @@ "id": "f1", "name": "Hendl", "basePrice": 9.50, + "color": "#FFEBCD", "options": [ {"name": "Halbes Hendl", "price": 9.50}, - {"name": "Ganzes Hendl", "price": 16.00}, + {"name": "Ganzes Hendl", "price": 16.00, "color": "#FFDAB9"}, {"name": "Hendl mit Semmel", "price": 11.00} ] }, @@ -14,16 +15,18 @@ "id": "f2", "name": "Schnitzelsemmel", "basePrice": 5.80, + "color": "#FFEFC1", "options": [ {"name": "Klassisch", "price": 5.80}, - {"name": "Mit Salat", "price": 6.50}, - {"name": "Mit Käse", "price": 6.80} + {"name": "Mit Salat", "price": 6.50, "color": "#E8F5E9"}, + {"name": "Mit Käse", "price": 6.80, "color": "#FFF9C4"} ] }, { "id": "f3", "name": "Pommes", "basePrice": 3.50, + "color": "#FFD700", "options": [ {"name": "Klein", "price": 3.50}, {"name": "Groß", "price": 4.50}, @@ -34,6 +37,7 @@ "id": "f4", "name": "Grillwurst", "basePrice": 4.20, + "color": "#FFCCCB", "options": [ {"name": "Bratwurst", "price": 4.20}, {"name": "Käsekrainer", "price": 4.50}, @@ -44,6 +48,7 @@ "id": "f5", "name": "Leberkässemmel", "basePrice": 4.00, + "color": "#FFE4E1", "options": [ {"name": "Klassisch", "price": 4.00}, {"name": "Mit Gurkerl", "price": 4.30}, @@ -54,6 +59,7 @@ "id": "f6", "name": "Langos", "basePrice": 4.80, + "color": "#DEB887", "options": [ {"name": "Mit Knoblauch", "price": 4.80}, {"name": "Mit Käse", "price": 5.50}, @@ -66,16 +72,18 @@ "id": "d1", "name": "Bier", "basePrice": 4.20, + "color": "#F0E68C", "options": [ - {"name": "Krügerl (0,5L)", "price": 4.20}, + {"name": "Krügerl (0,5L)", "price": 4.20, "color": "#F5DEB3"}, {"name": "Seidl (0,3L)", "price": 3.50}, - {"name": "Radler (0,5L)", "price": 4.20} + {"name": "Radler (0,5L)", "price": 4.20, "color": "#FAFAD2"} ] }, { "id": "d2", "name": "Cola", "basePrice": 3.50, + "color": "#D2B48C", "options": [ {"name": "Cola Rot (0,5L)", "price": 3.50}, {"name": "Cola Weiß (0,5L)", "price": 3.50}, @@ -87,6 +95,7 @@ "id": "d3", "name": "Softdrinks", "basePrice": 3.50, + "color": "#FFDAB9", "options": [ {"name": "Fanta (0,5L)", "price": 3.50}, {"name": "Sprite (0,5L)", "price": 3.50}, @@ -98,6 +107,7 @@ "id": "d4", "name": "Mineral", "basePrice": 2.80, + "color": "#E0FFFF", "options": [ {"name": "Prickelnd (0,5L)", "price": 2.80}, {"name": "Still (0,5L)", "price": 2.80}, @@ -109,6 +119,7 @@ "id": "d5", "name": "Gespritzt", "basePrice": 3.00, + "color": "#FFDAB9", "options": [ {"name": "Apfelsaft g'spritzt", "price": 3.00}, {"name": "Johannisbeer g'spritzt", "price": 3.20}, @@ -120,6 +131,7 @@ "id": "d6", "name": "Spritzer", "basePrice": 3.80, + "color": "#FFE4E1", "options": [ {"name": "Weißer Spritzer", "price": 3.80}, {"name": "Aperol Spritzer", "price": 4.50}, @@ -131,6 +143,7 @@ "id": "d7", "name": "Schnaps", "basePrice": 3.00, + "color": "#E6E6FA", "options": [ {"name": "Marille (2cl)", "price": 3.00}, {"name": "Williams (2cl)", "price": 3.00}, diff --git a/src/pages/HomePage.css b/src/pages/HomePage.css index 4205d4d..22e52f1 100644 --- a/src/pages/HomePage.css +++ b/src/pages/HomePage.css @@ -1,37 +1,61 @@ .home-page { - padding-bottom: 20px; + display: flex; + flex-direction: column; + min-height: 100vh; + background-color: #f9fafb; } .app-header { background-color: #2c7be5; color: white; text-align: center; - padding: 15px; + padding: 12px; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); } .app-header h1 { margin: 0; - font-size: 1.5rem; + font-size: 1.4rem; + font-weight: 600; +} + +.main-container { + flex: 1; + display: flex; + flex-direction: column; + gap: 16px; + padding: 16px; + max-width: 600px; + margin: 0 auto; + width: 100%; +} + +.section-title { + margin: 8px 0; + font-size: 1.2rem; + color: #333; + font-weight: 500; + padding-left: 8px; + border-left: 3px solid #2c7be5; } .category-tabs { display: flex; - margin: 10px; border-radius: 8px; overflow: hidden; - box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); + margin-bottom: 4px; } .category-tabs button { flex: 1; - padding: 15px; + padding: 12px; background-color: #f5f5f5; border: none; - font-size: 1.1rem; + font-size: 1rem; font-weight: 500; cursor: pointer; - transition: background-color 0.2s; + transition: all 0.2s ease; } .category-tabs button.active { @@ -39,14 +63,22 @@ color: white; } -.products-section, .cart-section { - margin: 20px 0; +.products-container { + background-color: white; + border-radius: 10px; + padding: 12px; + box-shadow: 0 2px 6px rgba(0, 0, 0, 0.05); } -.products-section h2, .cart-section h2 { - margin: 0 10px 10px 10px; - font-size: 1.3rem; - color: #333; - padding-left: 10px; - border-left: 4px solid #2c7be5; +.cart-container { + background-color: white; + border-radius: 10px; + padding: 12px; + box-shadow: 0 2px 6px rgba(0, 0, 0, 0.05); +} + +@media (min-width: 768px) { + .main-container { + max-width: 800px; + } } diff --git a/src/pages/HomePage.tsx b/src/pages/HomePage.tsx index 32c37ce..8a6b9fa 100644 --- a/src/pages/HomePage.tsx +++ b/src/pages/HomePage.tsx @@ -9,23 +9,11 @@ const HomePage: React.FC = () => { const [activeTab, setActiveTab] = useState<'food' | 'drinks'>('drinks'); useEffect(() => { - const loadProducts = async () => { - try { - const data = await import('../data/products.json'); - - // Sort both food and drinks by name - const sortedData = { - food: [...data.food].sort((a, b) => a.name.localeCompare(b.name)), - drinks: [...data.drinks].sort((a, b) => a.name.localeCompare(b.name)) - }; - - setProductsData(sortedData); - } catch (error) { - console.error('Failed to load products:', error); - } - }; - - loadProducts(); + import('../data/products.json') + .then(data => { + setProductsData(data); + }) + .catch(error => console.error('Failed to load products:', error)); }, []); return ( @@ -34,31 +22,34 @@ const HomePage: React.FC = () => {

Preis Rechner

-
- - - -
- -
-

{activeTab === 'food' ? 'Essen' : 'Getränke'}

- {activeTab === 'food' && } - {activeTab === 'drinks' && } -
- -
-

Warenkorb

- +
+
+
+ + +
+ +

{activeTab === 'food' ? 'Essen' : 'Getränke'}

+ +
+ +
+

Warenkorb

+ +
); diff --git a/src/types/types.ts b/src/types/types.ts index 144fa68..bc543ab 100644 --- a/src/types/types.ts +++ b/src/types/types.ts @@ -1,6 +1,7 @@ export type ProductOption = { name: string; price: number; + color?: string; // Optional color for this specific option }; export type Product = { @@ -8,6 +9,7 @@ export type Product = { name: string; basePrice: number; options: ProductOption[]; + color?: string; // Optional color code for background highlight }; export type ProductsData = {