# Frontend-Entwicklung - Payload CMS Multi-Tenant > **Server:** sv-frontend (LXC 704) - 10.10.181.104 > **Backend API:** https://pl.c2sgmbh.de/api ## Übersicht Das Frontend wird als separates Next.js-Projekt entwickelt und nutzt Payload CMS als Headless CMS über die REST-API. --- ## API-Dokumentation | Ressource | URL | |-----------|-----| | **Swagger UI** | https://pl.c2sgmbh.de/api/docs | | **OpenAPI JSON** | https://pl.c2sgmbh.de/api/openapi.json | | **REST API Base** | https://pl.c2sgmbh.de/api | --- ## Offene Frontend-Tasks ### Hohe Priorität - [ ] **Block-Komponenten entwickeln** - [ ] Hero Block - [ ] Text Block - [ ] Image Text Block - [ ] Card Grid Block - [ ] Quote Block - [ ] CTA Block - [ ] Contact Form Block - [ ] Video Block - [ ] Divider Block - [ ] Timeline Block - [ ] Posts List Block - [ ] Testimonials Block - [ ] Newsletter Block - [ ] Process Steps Block - [ ] **Newsletter-Anmelde-Formular** - API: `POST /api/newsletter/subscribe` - Double Opt-In Flow bereits im Backend implementiert - Felder: email, firstName (optional), tenantId, source - [ ] **Cookie-Banner implementieren** - Cookie Configurations aus API laden - Consent-Logs an Backend senden - DSGVO-konform mit Opt-In ### Mittlere Priorität - [ ] **Multi-Tenant Routing** - Domain-basierte Tenant-Erkennung - Locale-Routing (`/[locale]/...`) - Unterstützte Locales: `de` (default), `en` - [ ] **SEO-Integration** - Meta-Tags aus Pages/Posts - Structured Data (JSON-LD) - Sitemap: https://pl.c2sgmbh.de/sitemap.xml - [ ] **Suche implementieren** - API: `GET /api/search?q=...&locale=de` - Auto-Complete: `GET /api/search/suggestions?q=...` - Rate-Limit: 30 Requests/Minute ### Tenant-spezifische Features #### porwoll.de - [ ] Immobilien-Listing - [ ] Objektsuche mit Filtern - [ ] Kontaktformular mit Objekt-Referenz #### complexcaresolutions.de (C2S) - [ ] Team-Übersicht - [ ] Leistungs-Seiten - [ ] Karriere-Seite mit Stellenangeboten #### gunshin.de (Fotografin-Portfolio) - [ ] Portfolio-Galerie - API: `GET /api/portfolios?where[tenant][equals]=5` - Kategorien: `GET /api/portfolio-categories` - [ ] Projekt-Detailseiten mit Lightbox - [ ] Referenzen-Slider #### zweitmein.ng - [ ] Produkt-Übersicht (falls E-Commerce) - [ ] FAQ-Sektion - [ ] Preistabellen --- ## API-Endpoints ### Collections | Collection | Endpoint | Beschreibung | |------------|----------|--------------| | Pages | `GET /api/pages` | Seiten mit Blocks | | Posts | `GET /api/posts` | Blog, News, Presse | | Categories | `GET /api/categories` | Post-Kategorien | | Testimonials | `GET /api/testimonials` | Kundenbewertungen | | Team | `GET /api/team` | Team-Mitglieder | | Services | `GET /api/services` | Leistungen | | FAQs | `GET /api/faqs` | FAQ-Einträge | | Portfolios | `GET /api/portfolios` | Portfolio-Projekte | | Media | `GET /api/media` | Medien/Bilder | ### Globals | Global | Endpoint | Beschreibung | |--------|----------|--------------| | Site Settings | `GET /api/globals/site-settings` | Logo, Name, SEO | | Navigation | `GET /api/globals/navigation` | Menü-Struktur | | SEO Settings | `GET /api/globals/seo-settings` | Default SEO | ### Spezielle Endpoints | Endpoint | Methode | Beschreibung | |----------|---------|--------------| | `/api/search` | GET | Volltextsuche | | `/api/search/suggestions` | GET | Auto-Complete | | `/api/newsletter/subscribe` | POST | Newsletter-Anmeldung | --- ## Tenant-Filterung Alle Collection-Anfragen sollten nach Tenant gefiltert werden: ```typescript // Beispiel: Posts für Tenant "c2s" (ID: 4) fetch('https://pl.c2sgmbh.de/api/posts?where[tenant][equals]=4&locale=de') // Beispiel: Pages für Tenant "gunshin" (ID: 5) fetch('https://pl.c2sgmbh.de/api/pages?where[tenant][equals]=5&locale=de') ``` ### Tenant-IDs | ID | Name | Slug | Domain | |----|------|------|--------| | 1 | porwoll.de | porwoll | porwoll.de | | 4 | Complex Care Solutions GmbH | c2s | complexcaresolutions.de | | 5 | Gunshin | gunshin | gunshin.de | --- ## Bild-Optimierung Media-Objekte enthalten mehrere Größen: ```typescript interface Media { url: string // Original sizes: { thumbnail: { url, width, height } // 150x150 small: { url, width, height } // 300x300 medium: { url, width, height } // 600x600 large: { url, width, height } // 1200x1200 xlarge: { url, width, height } // 1920x1920 '2k': { url, width, height } // 2560x2560 og: { url, width, height } // 1200x630 (Social) // + AVIF-Varianten thumbnail_avif: { url, width, height } small_avif: { url, width, height } // ... } focalX?: number // Fokuspunkt X (0-100) focalY?: number // Fokuspunkt Y (0-100) } ``` --- ## Lokalisierung Unterstützte Locales: `de` (default), `en` ```typescript // Deutsch (default) fetch('https://pl.c2sgmbh.de/api/posts?locale=de') // Englisch fetch('https://pl.c2sgmbh.de/api/posts?locale=en') // Fallback: Wenn EN nicht vorhanden, wird DE zurückgegeben ``` --- ## Newsletter-Integration ### Anmeldung ```typescript const response = await fetch('https://pl.c2sgmbh.de/api/newsletter/subscribe', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ email: 'user@example.com', firstName: 'Max', // optional tenantId: 4, // Pflicht source: 'footer' // optional: Herkunft }) }) // Response: { success: true, message: '...' } ``` ### Flow 1. User gibt E-Mail ein → `POST /api/newsletter/subscribe` 2. Backend sendet Double Opt-In E-Mail 3. User klickt Bestätigungs-Link 4. Backend sendet Willkommens-E-Mail 5. User kann sich über Link in E-Mails abmelden --- ## Cookie-Consent ### Konfiguration laden ```typescript const config = await fetch('https://pl.c2sgmbh.de/api/cookie-configurations?where[tenant][equals]=4') ``` ### Consent loggen ```typescript await fetch('https://pl.c2sgmbh.de/api/consent-logs', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ tenant: 4, consentGiven: true, categories: ['necessary', 'analytics'], ipAddress: '...', // Optional, für DSGVO userAgent: navigator.userAgent }) }) ``` --- ## Kontaktformular Formular-Submissions werden über die Forms-Collection verarbeitet: ```typescript await fetch('https://pl.c2sgmbh.de/api/form-submissions', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ form: 1, // Form-ID submissionData: [ { field: 'name', value: 'Max Mustermann' }, { field: 'email', value: 'max@example.com' }, { field: 'message', value: 'Ihre Nachricht...' } ] }) }) ``` --- ## Authentifizierung (optional) Falls User-Authentifizierung benötigt wird: ```typescript // Login const { token, user } = await fetch('https://pl.c2sgmbh.de/api/users/login', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ email, password }) }).then(r => r.json()) // Authentifizierte Requests fetch('https://pl.c2sgmbh.de/api/...', { headers: { 'Authorization': `JWT ${token}` } }) ``` --- ## Entwicklungshinweise ### TypeScript-Typen Die Payload-Typen können aus dem Backend exportiert werden: ```bash # Auf dem Payload-Server pnpm payload generate:types # Datei: src/payload-types.ts ``` Diese Datei kann ins Frontend-Projekt kopiert werden für typsichere API-Calls. ### Rate-Limits | Endpoint | Limit | |----------|-------| | Öffentliche API | 60/min | | Suche | 30/min | | Newsletter | 5/10min | | Formulare | 5/10min | ### Caching - API-Responses werden serverseitig gecacht (Redis) - TTL: 60 Sekunden für Suche - Cache wird bei Content-Änderungen invalidiert --- ## Ressourcen - **Payload CMS Docs:** https://payloadcms.com/docs - **API-Dokumentation:** https://pl.c2sgmbh.de/api/docs - **Backend-Repository:** https://github.com/c2s-admin/cms.c2sgmbh.git --- *Erstellt: 11.12.2025*