From 92ca0e870bdfe8a2e41fc3493b638381c196929f Mon Sep 17 00:00:00 2001 From: klara Date: Sun, 24 Nov 2024 21:17:12 +0100 Subject: [PATCH 1/2] Ui erstellt --- ui | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 ui diff --git a/ui b/ui new file mode 100644 index 0000000..e69de29 -- 2.43.0 From d9d2b2c9172eff412fdf4348ebd5359f3e84dd0f Mon Sep 17 00:00:00 2001 From: klara Date: Sun, 24 Nov 2024 21:49:15 +0100 Subject: [PATCH 2/2] ui --- public/app.js | 94 ++++++++++++++++++++++++++++++++++++++++++++ public/index.html | 28 +++++++++++++ public/style.css | 90 ++++++++++++++++++++++++++++++++++++++++++ static/styles.css | 14 +++++++ templates/index.html | 41 +++++++++++++++++++ 5 files changed, 267 insertions(+) create mode 100644 public/app.js create mode 100644 public/index.html create mode 100644 public/style.css create mode 100644 static/styles.css create mode 100644 templates/index.html diff --git a/public/app.js b/public/app.js new file mode 100644 index 0000000..2f8ec93 --- /dev/null +++ b/public/app.js @@ -0,0 +1,94 @@ +// State management +let products = []; +let cart = []; + +// DOM Elements +const productsContainer = document.getElementById('products-container'); +const cartItems = document.getElementById('cart-items'); +const cartTotal = document.getElementById('cart-total'); +const cartCount = document.getElementById('cart-count'); + +// Fetch products from API +async function fetchProducts() { + const response = await fetch('/api/products'); + products = await response.json(); + renderProducts(); +} + +// Render products +function renderProducts() { + productsContainer.innerHTML = products.map(product => ` +
+ ${product.name} +

${product.name}

+

${product.description}

+

€${product.price.toFixed(2)}

+ +
+ `).join(''); +} + +// Add to cart +async function addToCart(productId) { + const response = await fetch('/api/cart', { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ productId }) + }); + cart = await response.json(); + updateCart(); +} + +// Remove from cart +async function removeFromCart(productId) { + const response = await fetch(`/api/cart/${productId}`, { + method: 'DELETE' + }); + cart = await response.json(); + updateCart(); +} + +// Update quantity +async function updateQuantity(productId, quantity) { + if (quantity < 1) return; + + const response = await fetch(`/api/cart/${productId}`, { + method: 'PUT', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ quantity }) + }); + cart = await response.json(); + updateCart(); +} + +// Update cart display +function updateCart() { + cartItems.innerHTML = cart.map(item => ` +
+
+

${item.product.name}

+
+ + ${item.quantity} + +
+
+
+

€${(item.product.price * item.quantity).toFixed(2)}

+ +
+
+ `).join(''); + + const total = cart.reduce((sum, item) => sum + (item.product.price * item.quantity), 0); + cartTotal.innerHTML = `Gesamt: €${total.toFixed(2)}`; + cartCount.innerHTML = cart.reduce((sum, item) => sum + item.quantity, 0); +} + +// Initialize +fetchProducts(); +updateCart(); \ No newline at end of file diff --git a/public/index.html b/public/index.html new file mode 100644 index 0000000..a140e49 --- /dev/null +++ b/public/index.html @@ -0,0 +1,28 @@ + + + + + + Online Shop + + + +
+

Online Shop

+
+ 🛒 0 +
+
+ +
+
+
+

Warenkorb

+
+
+
+
+ + + + \ No newline at end of file diff --git a/public/style.css b/public/style.css new file mode 100644 index 0000000..6da0e9b --- /dev/null +++ b/public/style.css @@ -0,0 +1,90 @@ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: Arial, sans-serif; + line-height: 1.6; + background-color: #f4f4f4; +} + +header { + background-color: #333; + color: white; + padding: 1rem; + display: flex; + justify-content: space-between; + align-items: center; +} + +#cart-icon { + cursor: pointer; + font-size: 1.2rem; +} + +main { + max-width: 1200px; + margin: 2rem auto; + padding: 0 1rem; + display: grid; + grid-template-columns: 3fr 1fr; + gap: 2rem; +} + +#products-container { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); + gap: 1rem; +} + +.product-card { + background: white; + padding: 1rem; + border-radius: 8px; + box-shadow: 0 2px 5px rgba(0,0,0,0.1); +} + +.product-card img { + width: 100%; + height: 200px; + object-fit: cover; + border-radius: 4px; +} + +.product-card button { + width: 100%; + padding: 0.5rem; + background-color: #007bff; + color: white; + border: none; + border-radius: 4px; + cursor: pointer; + margin-top: 1rem; +} + +.product-card button:hover { + background-color: #0056b3; +} + +#cart-container { + background: white; + padding: 1rem; + border-radius: 8px; + box-shadow: 0 2px 5px rgba(0,0,0,0.1); +} + +.cart-item { + display: flex; + justify-content: space-between; + align-items: center; + padding: 0.5rem 0; + border-bottom: 1px solid #eee; +} + +#cart-total { + margin-top: 1rem; + font-weight: bold; + text-align: right; +} \ No newline at end of file diff --git a/static/styles.css b/static/styles.css new file mode 100644 index 0000000..9c9e259 --- /dev/null +++ b/static/styles.css @@ -0,0 +1,14 @@ +/* Add basic styles */ +.product-grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); + gap: 2rem; + padding: 2rem; +} + +.product-card { + background: white; + border-radius: 8px; + padding: 1rem; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); +} \ No newline at end of file diff --git a/templates/index.html b/templates/index.html new file mode 100644 index 0000000..95ca8b2 --- /dev/null +++ b/templates/index.html @@ -0,0 +1,41 @@ + + + + + + Einfacher Online-Shop + + + + +
+
+

Unser Shop

+
+
+ +
+
+ {% for product in products %} +
+ {{ product.name }} +
+

{{ product.name }}

+

€{{ "%.2f"|format(product.price) }}

+ +
+
+ {% endfor %} +
+
+ + \ No newline at end of file -- 2.43.0