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.
 
 
 

6.2 KiB

Phase 6: Products (Display & List)

Status: Done Progress: 10/10 tasks (100%) Started: 2025-11-04 Completed: 2025-11-04 Assigned to: -


Overview

Implement product display functionality: API endpoints for fetching products, product list/detail pages, and UI components for displaying Makerspace annual passes.

Goal: Users can browse and view Makerspace-Jahreskarten products.


Dependencies

  • Phase 1: Foundation must be completed
  • Phase 2: Database must be completed (products table needed)
  • ⚠️ Optional: Phase 3: Authentication (for future protected features)

Tasks

API Endpoints

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

    • Query products from DB (Drizzle)
    • Filter by: active=true, category (optional)
    • Sort by: name, price
    • Return: Array of products
    • Example:
      export default defineEventHandler(async (event) => {
        const { category } = getQuery(event)
        const products = await db.query.products.findMany({
          where: and(
            eq(products.active, true),
            category ? eq(products.category, category) : undefined
          ),
          orderBy: products.name,
        })
        return products
      })
      
  • Create /api/products/[id].get.ts endpoint

UI Components

  • Create ProductCard component

    • File: components/Product/ProductCard.vue
    • Props: product (object)
    • Display: Image, name, price, short description
    • Button: "In den Warenkorb" (Add to Cart)
    • Styling: shadcn-nuxt Card component + Tailwind
    • Mobile-first design
  • Create ProductList component

    • File: components/Product/ProductList.vue
    • Props: products (array)
    • Grid layout: 1 col (mobile), 2 cols (tablet), 3 cols (desktop)
    • Uses: ProductCard for each product
    • Empty state: "Keine Produkte verfügbar"
  • Create ProductDetail component

    • File: components/Product/ProductDetail.vue
    • Props: product (object)
    • Display: Large image, full description, price, stock status
    • Button: "In den Warenkorb"
    • Breadcrumb: Home > Produkte > [Product Name]

Pages

  • Create products index page

    • File: pages/produkte/index.vue (German route)
    • Fetches products from API
    • Uses: ProductList component
    • Title: "Makerspace-Jahreskarten"
    • SEO meta tags
  • Create ProductDetail page

    • File: pages/produkte/[id].vue
    • Fetches product by ID from API
    • Uses: ProductDetail component
    • 404 page if product not found
    • SEO meta tags with product data

Asset Handling

  • Add product images handling
    • Create /public/images/products/ folder
    • Add placeholder image for products without image
    • Document image requirements (size, format)
    • Optimize images (use Nuxt Image module if needed)

Testing

  • Test product display

    • Seed database with sample products (manual or seed script)
    • Visit /produkte page
    • Verify products display correctly
    • Verify responsive design (mobile, tablet, desktop)
    • Click product to view detail page
    • Verify product detail displays correctly
  • Optimize product queries

    • Add indexes to products table if needed (active, category)
    • Test query performance with 100+ products
    • Add pagination if needed (future enhancement)
  • Document product schema

    • Document product data structure in code comments
    • Document how images are stored/referenced
    • Document category values (e.g., "makerspace-jahreskarte")

Acceptance Criteria

  • /api/products endpoint returns all active products
  • /api/products/[id] endpoint returns product by ID
  • ProductCard component displays product correctly
  • ProductList component shows products in grid layout
  • ProductDetail component shows full product info
  • /produkte page lists all products
  • /produkte/[id] page shows product detail
  • Images display correctly (or placeholder if missing)
  • Responsive design works on mobile/tablet/desktop
  • Product data structure is documented

Notes

Implementation Summary (Completed 2025-11-04)

Files Created (7):

  1. server/api/products/index.get.ts - Product list API with role-based filtering
  2. server/api/products/[id].get.ts - Product detail API with UUID validation
  3. app/components/Product/ProductCard.vue - Product card component (109 lines)
  4. app/components/Product/ProductGrid.vue - Product grid layout (67 lines)
  5. app/pages/products/index.vue - Product list page (137 lines)
  6. app/pages/products/[id].vue - Product detail page with cart integration (236 lines)
  7. Demo pages: /internal/products-demo.vue, /internal/product-detail-demo.vue

Key Features Implemented:

  • Role-based Visibility: Products filtered by user's approved roles (per CLAUDE.md)
  • Cart Integration: Functional "Add to Cart" on detail page with toast notifications
  • Responsive Design: Mobile-first with glassmorphism effects
  • Advanced UI: Badges, discount percentages, hover effects (image zoom, scale)
  • Database Optimization: Indexes on active, category, nav_product_id
  • English URLs: /products instead of /produkte (CLAUDE.md requirement)

Technical Highlights:

  • Unauthenticated users see NO products (security by default)
  • Category filtering via query parameter (comma-separated)
  • Stock validation on add-to-cart
  • Toast notifications using vue-sonner
  • Cart sidebar auto-open on item add
  • Proper error handling (404, 500) with user-friendly messages

Notes:

  • MVP Scope: Only Makerspace-Jahreskarten products for now
  • Images: Using placeholder /img/makerspace-jk-2025.jpg (DB supports unique images via imageUrl field)
  • Pagination: Not needed for MVP (< 10 products expected)
  • Filters: Category filter implemented in API, can be extended in UI if needed

Blockers

  • None currently (can use mock products if NAV ERP sync not ready)