You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

4.5 KiB

Phase 4: Cart (Shopping Cart) PRIORITY

Status: Todo Progress: 0/12 tasks (0%) Started: - Completed: - Assigned to: -


Overview

Implement shopping cart functionality: API endpoints for cart operations, cart composable, and UI components for cart display and management.

Goal: Users can add products to cart, update quantities, and remove items.


Dependencies

  • Phase 2: Database must be completed (carts, cart_items tables needed)
  • Phase 3: Authentication should be completed (for user-specific carts)
  • ⚠️ Note: Products can be seeded manually for testing (Phase 6 can be done after Cart)

Tasks

API Endpoints

  • Create /api/cart/index.get.ts endpoint

    • Get current user's cart (or session cart for guests)
    • Include cart items with product details (join)
    • Calculate total price
    • Return: { cart, items: [{product, quantity, subtotal}], total }
  • Create /api/cart/items.post.ts endpoint

    • Add item to cart (body: {productId, quantity})
    • Validate product exists and has stock
    • Create cart if doesn't exist
    • Upsert cart_item (update quantity if already exists)
    • Return: Updated cart
  • Create /api/cart/items/[id].patch.ts endpoint

    • Update cart item quantity (body: {quantity})
    • Validate quantity > 0
    • Validate stock availability
    • Return: Updated cart item
  • Create /api/cart/items/[id].delete.ts endpoint

    • Remove item from cart
    • Delete cart_item record
    • Return: 204 No Content

Composables

  • Create useCart composable
    • File: composables/useCart.ts
    • State: cart (ref), items (computed), total (computed), itemCount (computed)
    • Functions:
      • fetchCart() - Load cart from API
      • addItem(productId, quantity) - Add to cart
      • updateItem(itemId, quantity) - Update quantity
      • removeItem(itemId) - Remove from cart
      • clearCart() - Empty cart
    • Auto-fetch on mount
    • See similar pattern: CLAUDE.md: useAuth

UI Components

  • Create CartItem component

    • File: components/Cart/CartItem.vue
    • Props: item (object with product, quantity, subtotal)
    • Display: Product image, name, price, quantity input, subtotal
    • Actions: Update quantity, Remove button
    • Emits: @update, @remove
  • Create CartSummary component

    • File: components/Cart/CartSummary.vue
    • Props: items (array), total (number)
    • Display: Items count, subtotal, VAT, total
    • Button: "Zur Kasse" (to checkout)
    • Styling: shadcn-nuxt Card

Pages

  • Create cart page
    • File: pages/warenkorb.vue (German route)
    • Uses: useCart composable
    • Shows: List of CartItem components + CartSummary
    • Empty state: "Ihr Warenkorb ist leer" with link to /produkte
    • Loading state while fetching

Testing

  • Test cart operations

    • Add product to cart from product page
    • Verify cart count updates (header badge)
    • Visit /warenkorb page
    • Update quantity via input
    • Remove item via button
    • Verify total updates correctly
  • Add cart persistence

    • For logged-in users: cart stored in DB (user_id)
    • For guests: cart stored in DB (session_id)
    • Test cart persists across page reloads
    • Test cart merges when guest logs in (optional, can defer)
  • Optimize cart queries

    • Ensure product details are fetched efficiently (join, not N+1)
    • Test with 10+ items in cart
    • Add indexes if needed
  • Document cart logic

    • Document cart/session relationship
    • Document cart item uniqueness (cart_id + product_id)
    • Document cart cleanup strategy (old carts)

Acceptance Criteria

  • All 4 cart API endpoints work correctly
  • useCart composable manages cart state
  • CartItem component displays and allows editing
  • CartSummary component shows total correctly
  • /warenkorb page shows cart with all items
  • Can add products to cart from product pages
  • Can update item quantities in cart
  • Can remove items from cart
  • Cart total calculates correctly
  • Cart persists across page reloads
  • Empty cart shows helpful message

Notes

  • Guest Carts: Use session_id for guest carts (cookie-based)
  • Cart Merge: When guest logs in, merge guest cart with user cart (optional for MVP)
  • Stock Validation: Ensure quantity doesn't exceed stock when adding/updating
  • VAT: 7% VAT for annual passes (hardcoded for MVP)

Blockers

  • None currently