From d925ab75cf8adb10eb0a0b096a0e7e567adcdcd3 Mon Sep 17 00:00:00 2001 From: Nicholai Date: Wed, 17 Sep 2025 00:30:49 -0600 Subject: [PATCH] feat(mobile): add services carousel, persistent booking bar, and improved navigation while preserving desktop layouts --- .clinerules/authrules.md | 24 +++++ .clinerules/cicdrules.md | 17 ++++ .clinerules/dockerrules.md | 6 ++ .clinerules/infrarules.md | 20 ++++ .clinerules/nextjsrules.md | 36 +++++++ .clinerules/observabilityrules.md | 4 + .clinerules/testing.md | 7 ++ .clinerules/ui-rules.md | 16 +++ app/page.tsx | 2 + components/artists-grid.tsx | 48 ++++----- components/contact-section.tsx | 6 +- components/hero-section.tsx | 2 +- components/mobile-booking-bar.tsx | 19 ++++ components/navigation.tsx | 12 +-- components/services-mobile-carousel.tsx | 125 ++++++++++++++++++++++++ components/services-section.tsx | 51 +--------- et -e | 72 ++++++++++++++ implementation_plan.md | 125 ++++++++++++++++++++++++ 18 files changed, 509 insertions(+), 83 deletions(-) create mode 100644 .clinerules/authrules.md create mode 100644 .clinerules/cicdrules.md create mode 100644 .clinerules/dockerrules.md create mode 100644 .clinerules/infrarules.md create mode 100644 .clinerules/nextjsrules.md create mode 100644 .clinerules/observabilityrules.md create mode 100644 .clinerules/testing.md create mode 100644 .clinerules/ui-rules.md create mode 100644 components/mobile-booking-bar.tsx create mode 100644 components/services-mobile-carousel.tsx create mode 100644 et -e create mode 100644 implementation_plan.md diff --git a/.clinerules/authrules.md b/.clinerules/authrules.md new file mode 100644 index 000000000..c93a25a6e --- /dev/null +++ b/.clinerules/authrules.md @@ -0,0 +1,24 @@ +# Security, Auth, Headers, Validation, Rate‑Limiting, Secrets + +## Authentication & RBAC +- **NextAuth (Auth.js)** mandatory +- Sessions: pick JWT or DB, document choice +- Route/Server Action guards via middleware; role model documented + +## Security Headers +- CSP (nonce/hash) + `Referrer-Policy: strict-origin-when-cross-origin` +- `X-Frame-Options: DENY`; `Permissions-Policy` scoped +- COOP/COEP where SharedArrayBuffer needed +- Cookies: HttpOnly, Secure, SameSite=Strict + +## Validation +- **Zod everywhere** (server actions, routes, forms) +- `react-hook-form` + zod resolver + +## Rate Limiting +- Redis (Upstash/self-hosted) +- Enforce on auth, forms, APIs (middleware/handlers) + +## Secrets Policy +- `.env.example` is canonical list; validate at boot (`lib/env.ts` with Zod) +- Use SOPS/Age, 1Password, or Docker secrets; never commit secrets \ No newline at end of file diff --git a/.clinerules/cicdrules.md b/.clinerules/cicdrules.md new file mode 100644 index 000000000..620268983 --- /dev/null +++ b/.clinerules/cicdrules.md @@ -0,0 +1,17 @@ +# CI/CD, Budgets, Required Workflow + +## Pipeline (Gitea) +1) Lint, Typecheck, Biome/Prettier +2) Unit tests (Vitest) + Component (RTL) +3) Build +4) Migration dry‑run +5) E2E (Playwright) on preview env +6) Bundle size budgets enforced (fail on overage) +7) Release tagging (semver) + notes + +## Required Workflow +- Run Context7 checks for new deps, upgrades, DS changes +- Check shadcn registry before custom components +- Use Supabase MCP for all DB ops (incl. migrations) +- Plan & Act for complex features; reference existing patterns +- Clarify ambiguous requirements early; provide confidence rating \ No newline at end of file diff --git a/.clinerules/dockerrules.md b/.clinerules/dockerrules.md new file mode 100644 index 000000000..f641de9fc --- /dev/null +++ b/.clinerules/dockerrules.md @@ -0,0 +1,6 @@ +# Docker & Deployment +- Multi‑stage builds; `next build` with `output: standalone` +- Non‑root user; healthcheck endpoint (`/health`) +- Volumes for persistence (DB/cache) +- Pin base images to minor; scan for vulns +- Node vs Edge runtime documented per route; default Node \ No newline at end of file diff --git a/.clinerules/infrarules.md b/.clinerules/infrarules.md new file mode 100644 index 000000000..ed7ee4858 --- /dev/null +++ b/.clinerules/infrarules.md @@ -0,0 +1,20 @@ +# Data, MCP, Codegen, Migrations, File Uploads + +## MCP Requirements +- All DB access (dev/prod/migrations/scripts) via **Supabase MCP** +- Context7 MCP required for: new deps, framework upgrades, DS changes +- Cache/pin Context7 outputs; PRs require justification to override + +## Data Layer & Codegen (choose one) +- **Prisma**: schema as SSoT; generated client/types committed +- **or Kysely**: typed SQL builder; generate DB types; commit outputs +- PRs fail on type/codegen drift + +## Migrations +- Source of truth in `sql/` +- Executed via MCP; CI does migration dry‑run on ephemeral DB + +## File Uploads +- S3‑compatible storage with signed URLs (no direct multipart to app) +- MCP writes file metadata (size/mime/checksum) to DB +- Resumable uploads (TUS) allowed when needed \ No newline at end of file diff --git a/.clinerules/nextjsrules.md b/.clinerules/nextjsrules.md new file mode 100644 index 000000000..6462e9e7e --- /dev/null +++ b/.clinerules/nextjsrules.md @@ -0,0 +1,36 @@ +# Cline Next.js Development Rules + +## Core Technology Stack +- Next.js 14+ App Router (no Pages Router) +- Tailwind + shadcn/ui (mandatory) +- TypeScript only (.ts/.tsx) +- State: Zustand (local UI) + React Query (server state) +- DB: Postgres (Docker) **via Supabase MCP only** +- VCS: Gitea +- MCP: Supabase MCP (DB), Context7 MCP (patterns/updates) + +## Project Structure (no `src/`) +app/ | components/ (ui/, custom/) | lib/ | hooks/ | types/ | constants/ | docker/ | sql/ + +## Next.js Rules +- App Router only; organize with `(group)` +- Implement `loading.tsx` and `error.tsx` in segments +- **Server Actions** for authenticated same‑origin mutations +- **Route Handlers** for webhooks, cross‑origin, streaming, public APIs +- Image component required; dynamic import heavy modules +- Tag‑based caching + `revalidateTag` policy + +## Cross‑refs +- UI & shadcn → `UI_RULES.md` +- Security, Auth, Headers, Rate‑limit, Secrets → `SECURITY_AUTH.md` +- Data, Migrations, File Uploads, MCP usage → `DATA_INFRA.md` +- CI/CD, Budgets, Workflow → `CI_CD.md` +- Testing → `TESTING.md` +- Observability → `OBSERVABILITY.md` +- Docker & Deployment → `DOCKER_DEPLOY.md` + +## Forbidden +- Direct DB access (MCP only) +- Bypass Context7 for upgrades/pattern changes +- Override shadcn internals or use inline styles +- Custom tokens outside DS; committing secrets \ No newline at end of file diff --git a/.clinerules/observabilityrules.md b/.clinerules/observabilityrules.md new file mode 100644 index 000000000..642ef8be3 --- /dev/null +++ b/.clinerules/observabilityrules.md @@ -0,0 +1,4 @@ +# Observability +- **OpenTelemetry**: traces/metrics/logs for Next.js, server actions, MCP DB calls +- **Sentry**: exceptions + release tracking +- Log redaction: PII/secrets never leave process \ No newline at end of file diff --git a/.clinerules/testing.md b/.clinerules/testing.md new file mode 100644 index 000000000..f15608cc1 --- /dev/null +++ b/.clinerules/testing.md @@ -0,0 +1,7 @@ +# Testing Strategy +- **Vitest + RTL** for unit/component +- **Playwright** for e2e +- **Testcontainers** for DB integration +- Contract tests for MCP responses (shape/status) +- a11y checks (eslint-plugin-jsx-a11y + automated tooling) +- Responsive checks across breakpoints \ No newline at end of file diff --git a/.clinerules/ui-rules.md b/.clinerules/ui-rules.md new file mode 100644 index 000000000..00458c15b --- /dev/null +++ b/.clinerules/ui-rules.md @@ -0,0 +1,16 @@ +# UI & shadcn/ui Rules + +## Usage Order +1) Check shadcn registry (verify via Context7) +2) Compose/extend with variants +3) Custom only if primitives can’t express it + +## Constraints +- Do not hack internal classes or override CSS +- Use `cva()` and `cn()` utilities +- Follow shadcn prop/naming conventions + +## Variants & Composition +```tsx + +Title \ No newline at end of file diff --git a/app/page.tsx b/app/page.tsx index dc7b9be2e..09b9d3835 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -6,6 +6,7 @@ import { ArtistsSection } from "@/components/artists-section" import { ServicesSection } from "@/components/services-section" import { ContactSection } from "@/components/contact-section" import { Footer } from "@/components/footer" +import { MobileBookingBar } from "@/components/mobile-booking-bar" export default function HomePage() { return ( @@ -26,6 +27,7 @@ export default function HomePage() {