# CLAUDE.md This file provides guidance to Claude Code when working with this repository. ## Project Overview porwoll.de frontend — a Next.js 16 application for professional portrait and business photography by Caroline Porwoll. Consumes Payload CMS as a headless backend. **Tenant:** porwoll (ID: 1, Slug: porwoll) **Tech Stack:** Next.js 16, React 19, TypeScript, Tailwind CSS 4 **Backend API:** https://cms.c2sgmbh.de/api **Package Manager:** pnpm ## Commands ```bash pnpm dev # Development server pnpm build # Production build pnpm start # Start production server pnpm lint # ESLint ``` ## Environment Variables Create `.env.local`: ```env NEXT_PUBLIC_PAYLOAD_URL=https://cms.c2sgmbh.de NEXT_PUBLIC_TENANT_ID=1 NEXT_PUBLIC_TENANT_SLUG=porwoll NEXT_PUBLIC_SITE_URL=https://porwoll.de NODE_ENV=production ``` ## Shared Contracts Package This project uses `@c2s/payload-contracts` for the API client and types. **Architecture:** - `src/lib/cms.ts` — Shared PayloadClient instance (tenant: porwoll, ID: 1) - `src/lib/api.ts` — API functions powered by contracts client (types re-exported from contracts) **Contracts Repo:** `github:complexcaresolutions/payload-contracts` ```typescript // CMS client (src/lib/cms.ts) import { createPayloadClient } from "@c2s/payload-contracts/api-client" export const cms = createPayloadClient({ baseUrl: process.env.NEXT_PUBLIC_PAYLOAD_URL!, tenantId: process.env.NEXT_PUBLIC_TENANT_ID!, }) // Usage — tenant isolation is automatic const page = await cms.pages.getPage("home") const posts = await cms.posts.getPosts({ type: "blog" }) ``` **Types:** Imported directly from `@c2s/payload-contracts/types`. No local type overrides. **Block Catalog:** See `node_modules/@c2s/payload-contracts/docs/BLOCK_CATALOG.md` **Updating Contracts:** ```bash pnpm update @c2s/payload-contracts pnpm build # Verify types still compile ``` ## Architecture ### Directory Structure ``` src/ ├── app/ │ ├── layout.tsx # Root layout │ ├── page.tsx # Homepage (CMS page: "home") │ └── [slug]/page.tsx # Dynamic CMS pages ├── components/ │ └── blocks/ │ └── index.tsx # Block renderer (placeholder components) └── lib/ ├── cms.ts # PayloadClient instance └── api.ts # API functions ``` ### Block System Pages from Payload contain a `layout` array of blocks. The block renderer uses `createBlockRenderer()` from contracts. **Registered Blocks (~15):** | Block Type | Status | |------------|--------| | `hero-block` | Placeholder | | `text-block` | Placeholder | | `image-text-block` | Placeholder | | `card-grid-block` | Placeholder | | `cta-block` | Placeholder | | `divider-block` | Placeholder | | `testimonials-block` | Placeholder | | `faq-block` | Placeholder | | `contact-form-block` | Placeholder | | `image-slider-block` | Placeholder | | `services-block` | Placeholder | | `team-block` | Placeholder | | `locations-block` | Placeholder | | `stats-block` | Placeholder | | `quote-block` | Placeholder | **Implementing a block:** Replace the Placeholder in `src/components/blocks/index.tsx` with a real component. Use `BlockByType<"hero-block">` from contracts for type-safe props: ```typescript import type { BlockByType } from "@c2s/payload-contracts/types" type Props = Omit, "blockType"> export function HeroBlock({ headline, subline, backgroundImage }: Props) { // Render block } ``` ### API Endpoints | Endpoint | Purpose | |----------|---------| | `GET /api/pages?where[tenant][equals]=1` | Pages | | `GET /api/posts?where[tenant][equals]=1` | Blog posts | | `GET /api/navigations?where[tenant][equals]=1` | Navigation menus | | `GET /api/site-settings?where[tenant][equals]=1` | Site configuration | | `GET /api/testimonials?where[tenant][equals]=1` | Customer testimonials | | `GET /api/bookings?where[tenant][equals]=1` | Photography bookings | | `POST /api/newsletter/subscribe` | Newsletter signup | | `POST /api/form-submissions` | Contact form | **API Documentation:** https://cms.c2sgmbh.de/api/docs ## Design Guidelines **Philosophy:** Professional, clean, hero-driven. Photography-focused — let the images speak. **Tone:** Serioes, warm but professional. German language (de). **Key Principles:** - Large hero images that showcase photography work - Clean whitespace, minimal visual clutter - Professional typography (no playful fonts) - Before/After comparisons for retouching work - Portfolio galleries with lightbox - Mobile-first responsive design **Photography Specialties:** - Business portraits / Headshots - Personal branding - Team photography - Event photography ## porwoll-Specific Collections - **bookings** — Photography session bookings - **services** — Photography packages offered - **locations** — Studio/shooting locations ## Git Workflow | Branch | Purpose | Deployment | |--------|---------|------------| | `develop` | Active development | Staging | | `main` | Production-ready | Plesk auto-deploy | **Commit conventions:** `feat:`, `fix:`, `docs:`, `refactor:`, `test:`, `chore:` ## Import Alias `@/*` maps to `./src/*` (configured in tsconfig.json)