# 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

- [x] 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:
    ```typescript
    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
    })
    ```

- [x] Create /api/products/[id].get.ts endpoint
  - Validate ID (Zod: UUID)
  - Query product by ID
  - Return 404 if not found
  - Return: Product object
  - See: [CLAUDE.md: API Route Example](../CLAUDE.md#api-route-example)

### UI Components

- [x] 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

- [x] 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"

- [x] 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

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

- [x] 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

- [x] 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

- [x] 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

- [x] Optimize product queries
  - Add indexes to products table if needed (active, category)
  - Test query performance with 100+ products
  - Add pagination if needed (future enhancement)

- [x] 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

- [x] /api/products endpoint returns all active products
- [x] /api/products/[id] endpoint returns product by ID
- [x] ProductCard component displays product correctly
- [x] ProductList component shows products in grid layout
- [x] ProductDetail component shows full product info
- [x] /produkte page lists all products
- [x] /produkte/[id] page shows product detail
- [x] Images display correctly (or placeholder if missing)
- [x] Responsive design works on mobile/tablet/desktop
- [x] 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)

---

## Related Documentation

- [docs/PRD.md: F-004](../docs/PRD.md#f-004-produktanzeige)
- [docs/ARCHITECTURE.md: Products Table](../docs/ARCHITECTURE.md#products)
- [CLAUDE.md: API Route Example](../CLAUDE.md#api-route-example)
