From b3024116268f73486f1a4f4137d77ad04019116c Mon Sep 17 00:00:00 2001 From: Bastian Masanek Date: Mon, 3 Nov 2025 16:24:00 +0100 Subject: [PATCH] Implement checkout and payment flow with new components - Added Checkout and Payment pages to handle user authentication and order processing. - Introduced MockPayPalButton for simulating payment during development. - Updated CartSheet and CartSidebar components to navigate to the new checkout page. - Enhanced Cart UI with responsive design for mobile and desktop views. - Implemented order confirmation and success pages to provide feedback after payment completion. These changes complete the checkout and payment functionality, improving the overall user experience and ensuring a seamless transition from cart to order confirmation. --- app/app.vue | 8 ++ app/components/Cart/CartSheet.vue | 2 +- app/components/Cart/CartSidebar.vue | 2 +- app/components/MockPayPalButton.vue | 106 ++++++++++++++++++ app/pages/{kasse.vue => checkout.vue} | 48 ++++---- .../confirm}/[orderId].vue | 8 +- .../erfolg => order/success}/[orderId].vue | 10 +- app/pages/{zahlung.vue => payment.vue} | 10 +- app/pages/products/[id].vue | 52 +++------ server/utils/cart-helpers.ts | 3 +- 10 files changed, 169 insertions(+), 80 deletions(-) create mode 100644 app/components/MockPayPalButton.vue rename app/pages/{kasse.vue => checkout.vue} (87%) rename app/pages/{bestellung/bestaetigen => order/confirm}/[orderId].vue (96%) rename app/pages/{bestellung/erfolg => order/success}/[orderId].vue (96%) rename app/pages/{zahlung.vue => payment.vue} (95%) diff --git a/app/app.vue b/app/app.vue index 1032046..e29ccb5 100644 --- a/app/app.vue +++ b/app/app.vue @@ -9,12 +9,20 @@ // 15px, which shifted the entire page content 15px to the left. This prop prevents // that unwanted padding injection and layout shift. import { ConfigProvider } from 'reka-ui' + +// Import cart UI components +const { isMobile } = useCartUI() diff --git a/app/components/Cart/CartSheet.vue b/app/components/Cart/CartSheet.vue index 7a2ae7e..4951f2e 100644 --- a/app/components/Cart/CartSheet.vue +++ b/app/components/Cart/CartSheet.vue @@ -27,7 +27,7 @@ async function handleRemoveItem(itemId: string) { // Navigate to checkout function handleCheckout() { close() - navigateTo('/kasse') + navigateTo('/checkout') } diff --git a/app/components/Cart/CartSidebar.vue b/app/components/Cart/CartSidebar.vue index 04ffe42..2d28fea 100644 --- a/app/components/Cart/CartSidebar.vue +++ b/app/components/Cart/CartSidebar.vue @@ -27,7 +27,7 @@ async function handleRemoveItem(itemId: string) { // Navigate to checkout function handleCheckout() { close() - navigateTo('/kasse') + navigateTo('/checkout') } diff --git a/app/components/MockPayPalButton.vue b/app/components/MockPayPalButton.vue new file mode 100644 index 0000000..57dc415 --- /dev/null +++ b/app/components/MockPayPalButton.vue @@ -0,0 +1,106 @@ + + + diff --git a/app/pages/kasse.vue b/app/pages/checkout.vue similarity index 87% rename from app/pages/kasse.vue rename to app/pages/checkout.vue index b4d2af1..5d7677b 100644 --- a/app/pages/kasse.vue +++ b/app/pages/checkout.vue @@ -1,14 +1,15 @@ @@ -176,7 +176,7 @@ function handlePaymentSuccess() {
- + ← Zurück zur Kasse
diff --git a/app/pages/products/[id].vue b/app/pages/products/[id].vue index 85accfe..f12bf01 100644 --- a/app/pages/products/[id].vue +++ b/app/pages/products/[id].vue @@ -100,10 +100,8 @@ const handleAddToCart = async () => {
- + Zurück zur Übersicht @@ -142,15 +140,9 @@ const handleAddToCart = async () => {
- + -
+
@@ -178,12 +170,10 @@ const handleAddToCart = async () => {
Verfügbarkeit -
+
{{ product.stockQuantity > 0 ? 'Sofort' : 'Nicht verfügbar' }}
@@ -217,19 +207,13 @@ const handleAddToCart = async () => {
- - - Weitere Produkte ansehen -
-
+
Dieses Produkt befindet sich bereits in deinem Warenkorb.
diff --git a/server/utils/cart-helpers.ts b/server/utils/cart-helpers.ts index 19f043f..c6ad0b4 100644 --- a/server/utils/cart-helpers.ts +++ b/server/utils/cart-helpers.ts @@ -1,5 +1,5 @@ import type { H3Event } from 'h3' -import { and, eq, inArray } from 'drizzle-orm' +import { and, eq, inArray, asc } from 'drizzle-orm' import { carts, cartItems, products } from '../database/schema' // Re-export shared types @@ -89,6 +89,7 @@ export async function getCartWithItems(cartId: string): Promise { with: { product: true, }, + orderBy: asc(cartItems.addedAt), // Sort by addedAt to maintain stable order }) // Separate available and unavailable items