# GitHub Copilot Instructions - BMC Webshop (Frontend) ## Project Overview BMC Webshop er en kunde-styret webshop løsning, hvor **BMC Hub** ejer indholdet, **API Gateway** (`apigateway.bmcnetworks.dk`) styrer logikken, og **Webshoppen** (dette projekt) kun viser og indsamler input. **Tech Stack**: React/Next.js/Vue.js (vælg én), TypeScript, Tailwind CSS eller Bootstrap 5 --- ## 3-Lags Arkitektur ``` ┌─────────────────────────────────────────────────────────┐ │ TIER 1: BMC HUB (Admin System) │ │ - Administrerer webshop-opsætning │ │ - Pusher data til Gateway │ │ - Poller Gateway for nye ordrer │ │ https://hub.bmcnetworks.dk │ └─────────────────────────────────────────────────────────┘ ▼ (Push config) ┌─────────────────────────────────────────────────────────┐ │ TIER 2: API GATEWAY (Forretningslogik + Database) │ │ - Modtager og gemmer webshop-config fra Hub │ │ - Ejer PostgreSQL database med produkter, priser, ordrer│ │ - Håndterer email/OTP login │ │ - Beregner priser og filtrerer varer │ │ - Leverer sikre API'er til Webshoppen │ │ https://apigateway.bmcnetworks.dk │ └─────────────────────────────────────────────────────────┘ ▲ (API calls) ┌─────────────────────────────────────────────────────────┐ │ TIER 3: WEBSHOP (Dette projekt - Kun Frontend) │ │ - Viser logo, tekster, produkter, priser │ │ - Shopping cart (kun i frontend state) │ │ - Sender ordre som payload til Gateway │ │ - INGEN forretningslogik eller datapersistering │ └─────────────────────────────────────────────────────────┘ ``` --- ## Webshoppens Ansvar ### ✅ Hvad Webshoppen GØR - Viser kundens logo, header-tekst, intro-tekst (fra Gateway) - Viser produktkatalog med navn, beskrivelse, pris (fra Gateway) - Samler kurv i browser state (localStorage/React state) - Sender ordre til Gateway ved checkout - Email/OTP login flow (kalder Gateway's auth-endpoint) ### ❌ Hvad Webshoppen IKKE GØR - Gemmer INGEN data (hverken kurv, produkter, eller ordrer) - Beregner INGEN priser eller avance - Håndterer INGEN produkt-filtrering (Gateway leverer klar liste) - Snakker IKKE direkte med Hub eller e-conomic - Håndterer IKKE betalingsgateway (Gateway's ansvar) --- ## API Gateway Kontrakt Base URL: `https://apigateway.bmcnetworks.dk` ### 1. Login med Email + Engangskode **Step 1: Anmod om engangskode** ```http POST /webshop/auth/request-code Content-Type: application/json { "email": "kunde@firma.dk" } Response 200: { "success": true, "message": "Engangskode sendt til kunde@firma.dk" } ``` **Step 2: Verificer kode og få JWT token** ```http POST /webshop/auth/verify-code Content-Type: application/json { "email": "kunde@firma.dk", "code": "123456" } Response 200: { "success": true, "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", "customer_id": 42, "expires_at": "2026-01-13T15:00:00Z" } ``` ### 2. Hent Webshop Context (Komplet Webshop-Data) ```http GET /webshop/{customer_id}/context Authorization: Bearer {jwt_token} Response 200: { "customer_id": 42, "company_name": "Advokatfirma A/S", "config_version": "2026-01-13T12:00:00Z", "branding": { "logo_url": "https://apigateway.bmcnetworks.dk/assets/logos/42.png", "header_text": "Velkommen til vores webshop", "intro_text": "Bestil nemt og hurtigt direkte her.", "primary_color": "#0f4c75", "accent_color": "#3282b8" }, "products": [ { "id": 101, "ean": "5711045071324", "product_number": "FIRE-001", "name": "Cisco Firewall ASA 5506-X", "description": "Next-generation firewall med 8 porte", "unit": "stk", "base_price": 8500.00, "calculated_price": 9350.00, "margin_percent": 10.0, "currency": "DKK", "stock_available": true, "category": "Network Security" }, { "id": 102, "ean": "5704174801740", "product_number": "SW-024", "name": "TP-Link 24-Port Gigabit Switch", "description": "Managed switch med VLAN support", "unit": "stk", "base_price": 2100.00, "calculated_price": 2310.00, "margin_percent": 10.0, "currency": "DKK", "stock_available": true, "category": "Switches" } ], "allowed_payment_methods": ["invoice", "card"], "min_order_amount": 500.00, "shipping_cost": 0.00 } ``` ### 3. Opret Ordre ```http POST /webshop/orders Authorization: Bearer {jwt_token} Content-Type: application/json { "customer_id": 42, "order_items": [ { "product_id": 101, "quantity": 2, "unit_price": 9350.00 }, { "product_id": 102, "quantity": 5, "unit_price": 2310.00 } ], "shipping_address": { "company_name": "Advokatfirma A/S", "street": "Hovedgaden 1", "postal_code": "1000", "city": "København K", "country": "DK" }, "delivery_note": "Levering til bagsiden, ring på døren", "total_amount": 30250.00 } Response 201: { "success": true, "order_id": "ORD-2026-00123", "status": "pending", "total_amount": 30250.00, "created_at": "2026-01-13T14:30:00Z", "message": "Ordre modtaget. Du vil modtage en bekræftelse på email." } ``` ### 4. Hent Mine Ordrer (Optional) ```http GET /webshop/orders?customer_id=42 Authorization: Bearer {jwt_token} Response 200: { "orders": [ { "order_id": "ORD-2026-00123", "created_at": "2026-01-13T14:30:00Z", "status": "pending", "total_amount": 30250.00, "item_count": 7 } ] } ``` --- ## Frontend Krav ### Mandatory Features 1. **Responsive Design** - Mobile-first approach - Breakpoints: 576px (mobile), 768px (tablet), 992px (desktop) - Brug CSS Grid/Flexbox eller framework grid system 2. **Dark Mode Support** - Toggle mellem light/dark theme - Gem præference i localStorage - CSS Variables for farver 3. **Shopping Cart** - Gem kurv i localStorage (persist ved page reload) - Vis antal varer i header badge - Real-time opdatering af total pris - Slet/rediger varer i kurv 4. **Login Flow** - Email input → Send kode - Vis countdown timer (5 minutter) - Verificer kode → Få JWT token - Gem token i localStorage - Auto-logout ved token expiry 5. **Product Catalog** - Vis produkter i grid layout (3-4 kolonner på desktop) - Filtrer produkter efter kategori (hvis Gateway leverer kategorier) - Søgning i produktnavn/beskrivelse - "Tilføj til kurv" knap med antal-vælger 6. **Checkout Flow** - Vis kurv-oversigt - Leveringsadresse (kan være pre-udfyldt fra Gateway) - Leveringsnotat (textarea) - "Bekræft ordre" knap - Loading state under ordre-oprettelse - Success/error feedback ### Design Guidelines **Stil**: Minimalistisk, clean, "Nordic" æstetik (inspireret af BMC Hub's Nordic Top design) **Farver** (kan overskrives af Gateway's branding config): - Primary: `#0f4c75` (Deep Blue) - Accent: `#3282b8` (Bright Blue) - Success: `#27ae60` - Warning: `#f39c12` - Danger: `#e74c3c` **Typografi**: - Font: System font stack (`-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, ...`) - Headings: 500-600 weight - Body: 400 weight **Components**: - Cards med subtil shadow/border - Buttons med hover states - Input fields med focus outline - Loading spinners (ikke lange tekst-beskeder) --- ## State Management ### Local Storage Keys ```javascript // Authentication webshop_jwt_token // JWT token fra Gateway webshop_customer_id // Customer ID webshop_token_expires_at // ISO timestamp // Shopping Cart webshop_cart // JSON array af cart items webshop_theme // "light" eller "dark" // Cache (optional) webshop_context // Cached webshop context (TTL: 5 minutter) ``` ### Cart Item Format ```javascript { product_id: 101, ean: "5711045071324", name: "Cisco Firewall ASA 5506-X", unit_price: 9350.00, quantity: 2, total: 18700.00 } ``` --- ## Error Handling ### Gateway API Errors ```javascript // Eksempel på error response fra Gateway { "success": false, "error": "invalid_code", "message": "Ugyldig engangskode. Prøv igen." } ``` **Error Codes** (forventet fra Gateway): - `invalid_email` - Email ikke fundet eller ikke whitelisted - `invalid_code` - Forkert engangskode - `code_expired` - Engangskode udløbet (>5 min) - `token_expired` - JWT token udløbet - `unauthorized` - Manglende/ugyldig Authorization header - `product_not_found` - Produkt ID findes ikke - `min_order_not_met` - Ordre under minimum beløb - `out_of_stock` - Produkt ikke på lager **Handling**: - Vis brugervenlig fejlbesked i UI (ikke tekniske detaljer) - Log tekniske fejl til console (kun i development) - Redirect til login ved `token_expired` eller `unauthorized` --- ## Security 1. **HTTPS Only** - Al kommunikation med Gateway over HTTPS - Ingen hardcoded credentials 2. **JWT Token** - Gem i localStorage (ikke cookie) - Send i `Authorization: Bearer {token}` header - Check expiry før hver API call - Auto-logout ved expiry 3. **Input Validation** - Validér email format (client-side) - Validér antal > 0 ved "Tilføj til kurv" - Validér leveringsadresse udfyldt ved checkout - Sanitize input (brug library som DOMPurify hvis nødvendigt) 4. **CORS** - Gateway skal have `Access-Control-Allow-Origin` header - Webshoppen kalder altid Gateway (ikke Hub direkte) --- ## Deployment ### Environment Variables ```bash # .env.production NEXT_PUBLIC_API_GATEWAY_URL=https://apigateway.bmcnetworks.dk NEXT_PUBLIC_WEBSHOP_NAME="BMC Networks Webshop" ``` ### Build Process ```bash # Development npm run dev # Production build npm run build npm run start # Docker (optional) docker build -t bmc-webshop . docker run -p 3000:3000 bmc-webshop ``` ### Static Hosting (Anbefalet) - Vercel, Netlify, eller Cloudflare Pages - Deploy fra Git repository - Automatisk HTTPS og CDN - Environment variables i hosting provider UI --- ## Testing ### Manual Testing Checklist - [ ] Login med email/OTP virker - [ ] Token gemmes og bruges i efterfølgende API calls - [ ] Webshop context hentes og vises korrekt - [ ] Produkter vises i grid - [ ] "Tilføj til kurv" opdaterer cart badge - [ ] Cart viser korrekte varer og total pris - [ ] Checkout sender korrekt payload til Gateway - [ ] Success message vises ved succesfuld ordre - [ ] Error handling virker (test med ugyldig kode, udløbet token) - [ ] Dark mode toggle virker - [ ] Responsive design på mobil/tablet/desktop --- ## Common Pitfalls to Avoid 1. **Gem IKKE data i Webshoppen** - alt kommer fra Gateway 2. **Beregn IKKE priser selv** - Gateway leverer `calculated_price` 3. **Snakker IKKE direkte med Hub** - kun via Gateway 4. **Gem IKKE kurv i database** - kun localStorage 5. **Hardcode IKKE customer_id** - hent fra JWT token 6. **Valider IKKE produkter selv** - Gateway filtrerer allerede 7. **Implementer IKKE betalingsgateway** - Gateway's ansvar --- ## Quick Reference ### API Endpoints ``` POST /webshop/auth/request-code # Anmod engangskode POST /webshop/auth/verify-code # Verificer kode → JWT GET /webshop/{customer_id}/context # Hent webshop data POST /webshop/orders # Opret ordre GET /webshop/orders?customer_id={id} # Hent mine ordrer ``` ### Typical Flow ``` 1. User indtaster email → POST /auth/request-code 2. User indtaster kode → POST /auth/verify-code → Gem JWT token 3. App henter webshop context → GET /context (med JWT header) 4. User browser produkter, tilføjer til kurv (localStorage) 5. User går til checkout → POST /orders (med cart data) 6. Gateway behandler ordre → Success message vises ``` --- ## Support & Documentation **Hub Repository**: `/Users/christianthomas/DEV/bmc_hub_dev` **Hub API Docs**: `https://hub.bmcnetworks.dk/api/docs` **Gateway API Docs**: `https://apigateway.bmcnetworks.dk/docs` (når implementeret) **Kontakt**: ct@bmcnetworks.dk