From a8a8b57440831afdce5a4b4838b7df37b388dae3 Mon Sep 17 00:00:00 2001 From: parva3105 Date: Fri, 20 Mar 2026 17:29:38 -0400 Subject: [PATCH 1/2] chore: archive M1+M2 code, start revamp/phase-1 branch Move app/, components/, lib/, prisma/, jobs/, emails/, proxy.ts, and .env.example into _archive/ to clear the way for the frontend-first revamp. Old code preserved for reference. memory.md updated to reflect new active branch and approach. Co-Authored-By: Claude Sonnet 4.6 --- .claude/memory/memory.md | 12 +++++++++--- .env.example => _archive/.env.example | 0 {app => _archive/app}/(agency)/brands/[id]/page.tsx | 0 {app => _archive/app}/(agency)/brands/page.tsx | 0 {app => _archive/app}/(agency)/dashboard/page.tsx | 0 {app => _archive/app}/(agency)/deals/[id]/page.tsx | 0 {app => _archive/app}/(agency)/deals/new/page.tsx | 0 {app => _archive/app}/(agency)/deals/page.tsx | 0 {app => _archive/app}/(agency)/layout.tsx | 0 {app => _archive/app}/(agency)/roster/page.tsx | 0 {app => _archive/app}/(brand)/briefs/new/page.tsx | 0 {app => _archive/app}/(brand)/layout.tsx | 0 .../app}/(creator)/creator/deals/page.tsx | 0 {app => _archive/app}/(creator)/layout.tsx | 0 .../app}/(public)/login/[[...rest]]/page.tsx | 0 .../(public)/signup/agency/[[...rest]]/page.tsx | 0 .../app}/(public)/signup/brand/[[...rest]]/page.tsx | 0 .../app}/(public)/signup/complete/page.tsx | 0 .../(public)/signup/creator/[[...rest]]/page.tsx | 0 {app => _archive/app}/(public)/signup/page.tsx | 0 {app => _archive/app}/api/v1/auth/complete/route.ts | 0 {app => _archive/app}/api/v1/auth/set-role/route.ts | 0 {app => _archive/app}/api/v1/brands/[id]/route.ts | 0 {app => _archive/app}/api/v1/brands/route.ts | 0 .../app}/api/v1/deals/[id]/reopen/route.ts | 0 {app => _archive/app}/api/v1/deals/[id]/route.ts | 0 .../app}/api/v1/deals/[id]/stage/route.ts | 0 {app => _archive/app}/api/v1/deals/route.ts | 0 {app => _archive/app}/api/v1/roster/route.ts | 0 {app => _archive/app}/favicon.ico | Bin {app => _archive/app}/globals.css | 0 {app => _archive/app}/layout.tsx | 0 {app => _archive/app}/page.test.tsx | 0 {app => _archive/app}/page.tsx | 0 .../components}/__tests__/auth-layout.test.tsx | 0 .../components}/__tests__/brands.test.tsx | 0 .../components}/__tests__/deal-card.test.tsx | 0 .../components}/__tests__/deal-form.test.tsx | 0 .../__tests__/signup-role-picker.test.tsx | 0 .../components}/auth/auth-layout.tsx | 0 .../components}/auth/signup-role-picker.tsx | 0 .../components}/brands/add-brand-dialog.tsx | 0 .../components}/brands/brands-table.tsx | 0 .../components}/creator/.gitkeep | 0 {components => _archive/components}/deals/.gitkeep | 0 .../components}/deals/DealCard.tsx | 0 .../components}/deals/deal-detail.tsx | 0 .../components}/deals/stage-control-panel.tsx | 0 {components => _archive/components}/forms/.gitkeep | 0 .../components}/forms/deal-new-form.tsx | 0 .../components}/forms/inline-brand-form.tsx | 0 {components => _archive/components}/kanban/.gitkeep | 0 .../components}/kanban/DealDraggable.tsx | 0 .../components}/kanban/KanbanBoard.tsx | 0 .../components}/kanban/KanbanColumn.tsx | 0 .../components}/kanban/KanbanFilters.tsx | 0 .../components}/roster/add-creator-form.tsx | 0 .../components}/roster/add-creator-sheet.tsx | 0 .../components}/roster/roster-table.tsx | 0 {components => _archive/components}/ui/badge.tsx | 0 {components => _archive/components}/ui/button.tsx | 0 {components => _archive/components}/ui/card.tsx | 0 {components => _archive/components}/ui/checkbox.tsx | 0 {components => _archive/components}/ui/dialog.tsx | 0 {components => _archive/components}/ui/input.tsx | 0 {components => _archive/components}/ui/label.tsx | 0 {components => _archive/components}/ui/select.tsx | 0 {components => _archive/components}/ui/sheet.tsx | 0 {components => _archive/components}/ui/sonner.tsx | 0 {components => _archive/components}/ui/table.tsx | 0 {components => _archive/components}/ui/textarea.tsx | 0 {components => _archive/components}/ui/tooltip.tsx | 0 {emails => _archive/emails}/.gitkeep | 0 {jobs => _archive/jobs}/.gitkeep | 0 .../lib}/__tests__/deal-validation.test.ts | 0 {lib => _archive/lib}/__tests__/overdue.test.ts | 0 .../__tests__/stage-advance-business-logic.test.ts | 0 .../lib}/__tests__/stage-transitions.test.ts | 0 {lib => _archive/lib}/api-response.ts | 0 {lib => _archive/lib}/auth.ts | 0 {lib => _archive/lib}/button-variants.ts | 0 {lib => _archive/lib}/db.ts | 0 {lib => _archive/lib}/overdue.client.ts | 0 {lib => _archive/lib}/overdue.ts | 0 {lib => _archive/lib}/stage-transitions.client.ts | 0 {lib => _archive/lib}/stage-transitions.ts | 0 {lib => _archive/lib}/utils.ts | 0 {lib => _archive/lib}/validations/.gitkeep | 0 {lib => _archive/lib}/validations/brand.ts | 0 {lib => _archive/lib}/validations/deal.ts | 0 {lib => _archive/lib}/validations/roster.ts | 0 .../migrations/20260319025118_init/migration.sql | 0 .../20260319025143_add_search_indexes/migration.sql | 0 .../prisma}/migrations/migration_lock.toml | 0 {prisma => _archive/prisma}/schema.prisma | 0 proxy.ts => _archive/proxy.ts | 0 96 files changed, 9 insertions(+), 3 deletions(-) rename .env.example => _archive/.env.example (100%) rename {app => _archive/app}/(agency)/brands/[id]/page.tsx (100%) rename {app => _archive/app}/(agency)/brands/page.tsx (100%) rename {app => _archive/app}/(agency)/dashboard/page.tsx (100%) rename {app => _archive/app}/(agency)/deals/[id]/page.tsx (100%) rename {app => _archive/app}/(agency)/deals/new/page.tsx (100%) rename {app => _archive/app}/(agency)/deals/page.tsx (100%) rename {app => _archive/app}/(agency)/layout.tsx (100%) rename {app => _archive/app}/(agency)/roster/page.tsx (100%) rename {app => _archive/app}/(brand)/briefs/new/page.tsx (100%) rename {app => _archive/app}/(brand)/layout.tsx (100%) rename {app => _archive/app}/(creator)/creator/deals/page.tsx (100%) rename {app => _archive/app}/(creator)/layout.tsx (100%) rename {app => _archive/app}/(public)/login/[[...rest]]/page.tsx (100%) rename {app => _archive/app}/(public)/signup/agency/[[...rest]]/page.tsx (100%) rename {app => _archive/app}/(public)/signup/brand/[[...rest]]/page.tsx (100%) rename {app => _archive/app}/(public)/signup/complete/page.tsx (100%) rename {app => _archive/app}/(public)/signup/creator/[[...rest]]/page.tsx (100%) rename {app => _archive/app}/(public)/signup/page.tsx (100%) rename {app => _archive/app}/api/v1/auth/complete/route.ts (100%) rename {app => _archive/app}/api/v1/auth/set-role/route.ts (100%) rename {app => _archive/app}/api/v1/brands/[id]/route.ts (100%) rename {app => _archive/app}/api/v1/brands/route.ts (100%) rename {app => _archive/app}/api/v1/deals/[id]/reopen/route.ts (100%) rename {app => _archive/app}/api/v1/deals/[id]/route.ts (100%) rename {app => _archive/app}/api/v1/deals/[id]/stage/route.ts (100%) rename {app => _archive/app}/api/v1/deals/route.ts (100%) rename {app => _archive/app}/api/v1/roster/route.ts (100%) rename {app => _archive/app}/favicon.ico (100%) rename {app => _archive/app}/globals.css (100%) rename {app => _archive/app}/layout.tsx (100%) rename {app => _archive/app}/page.test.tsx (100%) rename {app => _archive/app}/page.tsx (100%) rename {components => _archive/components}/__tests__/auth-layout.test.tsx (100%) rename {components => _archive/components}/__tests__/brands.test.tsx (100%) rename {components => _archive/components}/__tests__/deal-card.test.tsx (100%) rename {components => _archive/components}/__tests__/deal-form.test.tsx (100%) rename {components => _archive/components}/__tests__/signup-role-picker.test.tsx (100%) rename {components => _archive/components}/auth/auth-layout.tsx (100%) rename {components => _archive/components}/auth/signup-role-picker.tsx (100%) rename {components => _archive/components}/brands/add-brand-dialog.tsx (100%) rename {components => _archive/components}/brands/brands-table.tsx (100%) rename {components => _archive/components}/creator/.gitkeep (100%) rename {components => _archive/components}/deals/.gitkeep (100%) rename {components => _archive/components}/deals/DealCard.tsx (100%) rename {components => _archive/components}/deals/deal-detail.tsx (100%) rename {components => _archive/components}/deals/stage-control-panel.tsx (100%) rename {components => _archive/components}/forms/.gitkeep (100%) rename {components => _archive/components}/forms/deal-new-form.tsx (100%) rename {components => _archive/components}/forms/inline-brand-form.tsx (100%) rename {components => _archive/components}/kanban/.gitkeep (100%) rename {components => _archive/components}/kanban/DealDraggable.tsx (100%) rename {components => _archive/components}/kanban/KanbanBoard.tsx (100%) rename {components => _archive/components}/kanban/KanbanColumn.tsx (100%) rename {components => _archive/components}/kanban/KanbanFilters.tsx (100%) rename {components => _archive/components}/roster/add-creator-form.tsx (100%) rename {components => _archive/components}/roster/add-creator-sheet.tsx (100%) rename {components => _archive/components}/roster/roster-table.tsx (100%) rename {components => _archive/components}/ui/badge.tsx (100%) rename {components => _archive/components}/ui/button.tsx (100%) rename {components => _archive/components}/ui/card.tsx (100%) rename {components => _archive/components}/ui/checkbox.tsx (100%) rename {components => _archive/components}/ui/dialog.tsx (100%) rename {components => _archive/components}/ui/input.tsx (100%) rename {components => _archive/components}/ui/label.tsx (100%) rename {components => _archive/components}/ui/select.tsx (100%) rename {components => _archive/components}/ui/sheet.tsx (100%) rename {components => _archive/components}/ui/sonner.tsx (100%) rename {components => _archive/components}/ui/table.tsx (100%) rename {components => _archive/components}/ui/textarea.tsx (100%) rename {components => _archive/components}/ui/tooltip.tsx (100%) rename {emails => _archive/emails}/.gitkeep (100%) rename {jobs => _archive/jobs}/.gitkeep (100%) rename {lib => _archive/lib}/__tests__/deal-validation.test.ts (100%) rename {lib => _archive/lib}/__tests__/overdue.test.ts (100%) rename {lib => _archive/lib}/__tests__/stage-advance-business-logic.test.ts (100%) rename {lib => _archive/lib}/__tests__/stage-transitions.test.ts (100%) rename {lib => _archive/lib}/api-response.ts (100%) rename {lib => _archive/lib}/auth.ts (100%) rename {lib => _archive/lib}/button-variants.ts (100%) rename {lib => _archive/lib}/db.ts (100%) rename {lib => _archive/lib}/overdue.client.ts (100%) rename {lib => _archive/lib}/overdue.ts (100%) rename {lib => _archive/lib}/stage-transitions.client.ts (100%) rename {lib => _archive/lib}/stage-transitions.ts (100%) rename {lib => _archive/lib}/utils.ts (100%) rename {lib => _archive/lib}/validations/.gitkeep (100%) rename {lib => _archive/lib}/validations/brand.ts (100%) rename {lib => _archive/lib}/validations/deal.ts (100%) rename {lib => _archive/lib}/validations/roster.ts (100%) rename {prisma => _archive/prisma}/migrations/20260319025118_init/migration.sql (100%) rename {prisma => _archive/prisma}/migrations/20260319025143_add_search_indexes/migration.sql (100%) rename {prisma => _archive/prisma}/migrations/migration_lock.toml (100%) rename {prisma => _archive/prisma}/schema.prisma (100%) rename proxy.ts => _archive/proxy.ts (100%) diff --git a/.claude/memory/memory.md b/.claude/memory/memory.md index e6bdc4a..6d1ebdc 100644 --- a/.claude/memory/memory.md +++ b/.claude/memory/memory.md @@ -1,9 +1,15 @@ # Project memory — Brand Deal Manager -_Last updated: 2026-03-19_ +_Last updated: 2026-03-20_ + +## Revamp (active) +- Branch: revamp/phase-1 +- Approach: Frontend-first — UI shell with mock data → real API → auth +- Spec: /revamp/ directory (README, PRODUCT, ARCHITECTURE, ROADMAP, FRONTEND, BACKEND, MOCKDATA) +- Old M1+M2 code archived in _archive/ ## Current state -- Status: **M2 COMPLETE** ✅ — Pre-M3 fixes in progress (2 PRs open) -- Active milestone: Pre-M3 fixes → then M3 — Creator Portal + Content Approval +- Status: **Revamp started** — Phase 1 UI Shell in progress +- Active milestone: Phase 1 — UI Shell (all pages with mock data, no DB, no Clerk) ## Pre-M3 fixes in progress — 2 PRs open - **PR #8** `fix/pre-m3-proxy-loop` — proxy.ts redirect loop guard (stale JWT) diff --git a/.env.example b/_archive/.env.example similarity index 100% rename from .env.example rename to _archive/.env.example diff --git a/app/(agency)/brands/[id]/page.tsx b/_archive/app/(agency)/brands/[id]/page.tsx similarity index 100% rename from app/(agency)/brands/[id]/page.tsx rename to _archive/app/(agency)/brands/[id]/page.tsx diff --git a/app/(agency)/brands/page.tsx b/_archive/app/(agency)/brands/page.tsx similarity index 100% rename from app/(agency)/brands/page.tsx rename to _archive/app/(agency)/brands/page.tsx diff --git a/app/(agency)/dashboard/page.tsx b/_archive/app/(agency)/dashboard/page.tsx similarity index 100% rename from app/(agency)/dashboard/page.tsx rename to _archive/app/(agency)/dashboard/page.tsx diff --git a/app/(agency)/deals/[id]/page.tsx b/_archive/app/(agency)/deals/[id]/page.tsx similarity index 100% rename from app/(agency)/deals/[id]/page.tsx rename to _archive/app/(agency)/deals/[id]/page.tsx diff --git a/app/(agency)/deals/new/page.tsx b/_archive/app/(agency)/deals/new/page.tsx similarity index 100% rename from app/(agency)/deals/new/page.tsx rename to _archive/app/(agency)/deals/new/page.tsx diff --git a/app/(agency)/deals/page.tsx b/_archive/app/(agency)/deals/page.tsx similarity index 100% rename from app/(agency)/deals/page.tsx rename to _archive/app/(agency)/deals/page.tsx diff --git a/app/(agency)/layout.tsx b/_archive/app/(agency)/layout.tsx similarity index 100% rename from app/(agency)/layout.tsx rename to _archive/app/(agency)/layout.tsx diff --git a/app/(agency)/roster/page.tsx b/_archive/app/(agency)/roster/page.tsx similarity index 100% rename from app/(agency)/roster/page.tsx rename to _archive/app/(agency)/roster/page.tsx diff --git a/app/(brand)/briefs/new/page.tsx b/_archive/app/(brand)/briefs/new/page.tsx similarity index 100% rename from app/(brand)/briefs/new/page.tsx rename to _archive/app/(brand)/briefs/new/page.tsx diff --git a/app/(brand)/layout.tsx b/_archive/app/(brand)/layout.tsx similarity index 100% rename from app/(brand)/layout.tsx rename to _archive/app/(brand)/layout.tsx diff --git a/app/(creator)/creator/deals/page.tsx b/_archive/app/(creator)/creator/deals/page.tsx similarity index 100% rename from app/(creator)/creator/deals/page.tsx rename to _archive/app/(creator)/creator/deals/page.tsx diff --git a/app/(creator)/layout.tsx b/_archive/app/(creator)/layout.tsx similarity index 100% rename from app/(creator)/layout.tsx rename to _archive/app/(creator)/layout.tsx diff --git a/app/(public)/login/[[...rest]]/page.tsx b/_archive/app/(public)/login/[[...rest]]/page.tsx similarity index 100% rename from app/(public)/login/[[...rest]]/page.tsx rename to _archive/app/(public)/login/[[...rest]]/page.tsx diff --git a/app/(public)/signup/agency/[[...rest]]/page.tsx b/_archive/app/(public)/signup/agency/[[...rest]]/page.tsx similarity index 100% rename from app/(public)/signup/agency/[[...rest]]/page.tsx rename to _archive/app/(public)/signup/agency/[[...rest]]/page.tsx diff --git a/app/(public)/signup/brand/[[...rest]]/page.tsx b/_archive/app/(public)/signup/brand/[[...rest]]/page.tsx similarity index 100% rename from app/(public)/signup/brand/[[...rest]]/page.tsx rename to _archive/app/(public)/signup/brand/[[...rest]]/page.tsx diff --git a/app/(public)/signup/complete/page.tsx b/_archive/app/(public)/signup/complete/page.tsx similarity index 100% rename from app/(public)/signup/complete/page.tsx rename to _archive/app/(public)/signup/complete/page.tsx diff --git a/app/(public)/signup/creator/[[...rest]]/page.tsx b/_archive/app/(public)/signup/creator/[[...rest]]/page.tsx similarity index 100% rename from app/(public)/signup/creator/[[...rest]]/page.tsx rename to _archive/app/(public)/signup/creator/[[...rest]]/page.tsx diff --git a/app/(public)/signup/page.tsx b/_archive/app/(public)/signup/page.tsx similarity index 100% rename from app/(public)/signup/page.tsx rename to _archive/app/(public)/signup/page.tsx diff --git a/app/api/v1/auth/complete/route.ts b/_archive/app/api/v1/auth/complete/route.ts similarity index 100% rename from app/api/v1/auth/complete/route.ts rename to _archive/app/api/v1/auth/complete/route.ts diff --git a/app/api/v1/auth/set-role/route.ts b/_archive/app/api/v1/auth/set-role/route.ts similarity index 100% rename from app/api/v1/auth/set-role/route.ts rename to _archive/app/api/v1/auth/set-role/route.ts diff --git a/app/api/v1/brands/[id]/route.ts b/_archive/app/api/v1/brands/[id]/route.ts similarity index 100% rename from app/api/v1/brands/[id]/route.ts rename to _archive/app/api/v1/brands/[id]/route.ts diff --git a/app/api/v1/brands/route.ts b/_archive/app/api/v1/brands/route.ts similarity index 100% rename from app/api/v1/brands/route.ts rename to _archive/app/api/v1/brands/route.ts diff --git a/app/api/v1/deals/[id]/reopen/route.ts b/_archive/app/api/v1/deals/[id]/reopen/route.ts similarity index 100% rename from app/api/v1/deals/[id]/reopen/route.ts rename to _archive/app/api/v1/deals/[id]/reopen/route.ts diff --git a/app/api/v1/deals/[id]/route.ts b/_archive/app/api/v1/deals/[id]/route.ts similarity index 100% rename from app/api/v1/deals/[id]/route.ts rename to _archive/app/api/v1/deals/[id]/route.ts diff --git a/app/api/v1/deals/[id]/stage/route.ts b/_archive/app/api/v1/deals/[id]/stage/route.ts similarity index 100% rename from app/api/v1/deals/[id]/stage/route.ts rename to _archive/app/api/v1/deals/[id]/stage/route.ts diff --git a/app/api/v1/deals/route.ts b/_archive/app/api/v1/deals/route.ts similarity index 100% rename from app/api/v1/deals/route.ts rename to _archive/app/api/v1/deals/route.ts diff --git a/app/api/v1/roster/route.ts b/_archive/app/api/v1/roster/route.ts similarity index 100% rename from app/api/v1/roster/route.ts rename to _archive/app/api/v1/roster/route.ts diff --git a/app/favicon.ico b/_archive/app/favicon.ico similarity index 100% rename from app/favicon.ico rename to _archive/app/favicon.ico diff --git a/app/globals.css b/_archive/app/globals.css similarity index 100% rename from app/globals.css rename to _archive/app/globals.css diff --git a/app/layout.tsx b/_archive/app/layout.tsx similarity index 100% rename from app/layout.tsx rename to _archive/app/layout.tsx diff --git a/app/page.test.tsx b/_archive/app/page.test.tsx similarity index 100% rename from app/page.test.tsx rename to _archive/app/page.test.tsx diff --git a/app/page.tsx b/_archive/app/page.tsx similarity index 100% rename from app/page.tsx rename to _archive/app/page.tsx diff --git a/components/__tests__/auth-layout.test.tsx b/_archive/components/__tests__/auth-layout.test.tsx similarity index 100% rename from components/__tests__/auth-layout.test.tsx rename to _archive/components/__tests__/auth-layout.test.tsx diff --git a/components/__tests__/brands.test.tsx b/_archive/components/__tests__/brands.test.tsx similarity index 100% rename from components/__tests__/brands.test.tsx rename to _archive/components/__tests__/brands.test.tsx diff --git a/components/__tests__/deal-card.test.tsx b/_archive/components/__tests__/deal-card.test.tsx similarity index 100% rename from components/__tests__/deal-card.test.tsx rename to _archive/components/__tests__/deal-card.test.tsx diff --git a/components/__tests__/deal-form.test.tsx b/_archive/components/__tests__/deal-form.test.tsx similarity index 100% rename from components/__tests__/deal-form.test.tsx rename to _archive/components/__tests__/deal-form.test.tsx diff --git a/components/__tests__/signup-role-picker.test.tsx b/_archive/components/__tests__/signup-role-picker.test.tsx similarity index 100% rename from components/__tests__/signup-role-picker.test.tsx rename to _archive/components/__tests__/signup-role-picker.test.tsx diff --git a/components/auth/auth-layout.tsx b/_archive/components/auth/auth-layout.tsx similarity index 100% rename from components/auth/auth-layout.tsx rename to _archive/components/auth/auth-layout.tsx diff --git a/components/auth/signup-role-picker.tsx b/_archive/components/auth/signup-role-picker.tsx similarity index 100% rename from components/auth/signup-role-picker.tsx rename to _archive/components/auth/signup-role-picker.tsx diff --git a/components/brands/add-brand-dialog.tsx b/_archive/components/brands/add-brand-dialog.tsx similarity index 100% rename from components/brands/add-brand-dialog.tsx rename to _archive/components/brands/add-brand-dialog.tsx diff --git a/components/brands/brands-table.tsx b/_archive/components/brands/brands-table.tsx similarity index 100% rename from components/brands/brands-table.tsx rename to _archive/components/brands/brands-table.tsx diff --git a/components/creator/.gitkeep b/_archive/components/creator/.gitkeep similarity index 100% rename from components/creator/.gitkeep rename to _archive/components/creator/.gitkeep diff --git a/components/deals/.gitkeep b/_archive/components/deals/.gitkeep similarity index 100% rename from components/deals/.gitkeep rename to _archive/components/deals/.gitkeep diff --git a/components/deals/DealCard.tsx b/_archive/components/deals/DealCard.tsx similarity index 100% rename from components/deals/DealCard.tsx rename to _archive/components/deals/DealCard.tsx diff --git a/components/deals/deal-detail.tsx b/_archive/components/deals/deal-detail.tsx similarity index 100% rename from components/deals/deal-detail.tsx rename to _archive/components/deals/deal-detail.tsx diff --git a/components/deals/stage-control-panel.tsx b/_archive/components/deals/stage-control-panel.tsx similarity index 100% rename from components/deals/stage-control-panel.tsx rename to _archive/components/deals/stage-control-panel.tsx diff --git a/components/forms/.gitkeep b/_archive/components/forms/.gitkeep similarity index 100% rename from components/forms/.gitkeep rename to _archive/components/forms/.gitkeep diff --git a/components/forms/deal-new-form.tsx b/_archive/components/forms/deal-new-form.tsx similarity index 100% rename from components/forms/deal-new-form.tsx rename to _archive/components/forms/deal-new-form.tsx diff --git a/components/forms/inline-brand-form.tsx b/_archive/components/forms/inline-brand-form.tsx similarity index 100% rename from components/forms/inline-brand-form.tsx rename to _archive/components/forms/inline-brand-form.tsx diff --git a/components/kanban/.gitkeep b/_archive/components/kanban/.gitkeep similarity index 100% rename from components/kanban/.gitkeep rename to _archive/components/kanban/.gitkeep diff --git a/components/kanban/DealDraggable.tsx b/_archive/components/kanban/DealDraggable.tsx similarity index 100% rename from components/kanban/DealDraggable.tsx rename to _archive/components/kanban/DealDraggable.tsx diff --git a/components/kanban/KanbanBoard.tsx b/_archive/components/kanban/KanbanBoard.tsx similarity index 100% rename from components/kanban/KanbanBoard.tsx rename to _archive/components/kanban/KanbanBoard.tsx diff --git a/components/kanban/KanbanColumn.tsx b/_archive/components/kanban/KanbanColumn.tsx similarity index 100% rename from components/kanban/KanbanColumn.tsx rename to _archive/components/kanban/KanbanColumn.tsx diff --git a/components/kanban/KanbanFilters.tsx b/_archive/components/kanban/KanbanFilters.tsx similarity index 100% rename from components/kanban/KanbanFilters.tsx rename to _archive/components/kanban/KanbanFilters.tsx diff --git a/components/roster/add-creator-form.tsx b/_archive/components/roster/add-creator-form.tsx similarity index 100% rename from components/roster/add-creator-form.tsx rename to _archive/components/roster/add-creator-form.tsx diff --git a/components/roster/add-creator-sheet.tsx b/_archive/components/roster/add-creator-sheet.tsx similarity index 100% rename from components/roster/add-creator-sheet.tsx rename to _archive/components/roster/add-creator-sheet.tsx diff --git a/components/roster/roster-table.tsx b/_archive/components/roster/roster-table.tsx similarity index 100% rename from components/roster/roster-table.tsx rename to _archive/components/roster/roster-table.tsx diff --git a/components/ui/badge.tsx b/_archive/components/ui/badge.tsx similarity index 100% rename from components/ui/badge.tsx rename to _archive/components/ui/badge.tsx diff --git a/components/ui/button.tsx b/_archive/components/ui/button.tsx similarity index 100% rename from components/ui/button.tsx rename to _archive/components/ui/button.tsx diff --git a/components/ui/card.tsx b/_archive/components/ui/card.tsx similarity index 100% rename from components/ui/card.tsx rename to _archive/components/ui/card.tsx diff --git a/components/ui/checkbox.tsx b/_archive/components/ui/checkbox.tsx similarity index 100% rename from components/ui/checkbox.tsx rename to _archive/components/ui/checkbox.tsx diff --git a/components/ui/dialog.tsx b/_archive/components/ui/dialog.tsx similarity index 100% rename from components/ui/dialog.tsx rename to _archive/components/ui/dialog.tsx diff --git a/components/ui/input.tsx b/_archive/components/ui/input.tsx similarity index 100% rename from components/ui/input.tsx rename to _archive/components/ui/input.tsx diff --git a/components/ui/label.tsx b/_archive/components/ui/label.tsx similarity index 100% rename from components/ui/label.tsx rename to _archive/components/ui/label.tsx diff --git a/components/ui/select.tsx b/_archive/components/ui/select.tsx similarity index 100% rename from components/ui/select.tsx rename to _archive/components/ui/select.tsx diff --git a/components/ui/sheet.tsx b/_archive/components/ui/sheet.tsx similarity index 100% rename from components/ui/sheet.tsx rename to _archive/components/ui/sheet.tsx diff --git a/components/ui/sonner.tsx b/_archive/components/ui/sonner.tsx similarity index 100% rename from components/ui/sonner.tsx rename to _archive/components/ui/sonner.tsx diff --git a/components/ui/table.tsx b/_archive/components/ui/table.tsx similarity index 100% rename from components/ui/table.tsx rename to _archive/components/ui/table.tsx diff --git a/components/ui/textarea.tsx b/_archive/components/ui/textarea.tsx similarity index 100% rename from components/ui/textarea.tsx rename to _archive/components/ui/textarea.tsx diff --git a/components/ui/tooltip.tsx b/_archive/components/ui/tooltip.tsx similarity index 100% rename from components/ui/tooltip.tsx rename to _archive/components/ui/tooltip.tsx diff --git a/emails/.gitkeep b/_archive/emails/.gitkeep similarity index 100% rename from emails/.gitkeep rename to _archive/emails/.gitkeep diff --git a/jobs/.gitkeep b/_archive/jobs/.gitkeep similarity index 100% rename from jobs/.gitkeep rename to _archive/jobs/.gitkeep diff --git a/lib/__tests__/deal-validation.test.ts b/_archive/lib/__tests__/deal-validation.test.ts similarity index 100% rename from lib/__tests__/deal-validation.test.ts rename to _archive/lib/__tests__/deal-validation.test.ts diff --git a/lib/__tests__/overdue.test.ts b/_archive/lib/__tests__/overdue.test.ts similarity index 100% rename from lib/__tests__/overdue.test.ts rename to _archive/lib/__tests__/overdue.test.ts diff --git a/lib/__tests__/stage-advance-business-logic.test.ts b/_archive/lib/__tests__/stage-advance-business-logic.test.ts similarity index 100% rename from lib/__tests__/stage-advance-business-logic.test.ts rename to _archive/lib/__tests__/stage-advance-business-logic.test.ts diff --git a/lib/__tests__/stage-transitions.test.ts b/_archive/lib/__tests__/stage-transitions.test.ts similarity index 100% rename from lib/__tests__/stage-transitions.test.ts rename to _archive/lib/__tests__/stage-transitions.test.ts diff --git a/lib/api-response.ts b/_archive/lib/api-response.ts similarity index 100% rename from lib/api-response.ts rename to _archive/lib/api-response.ts diff --git a/lib/auth.ts b/_archive/lib/auth.ts similarity index 100% rename from lib/auth.ts rename to _archive/lib/auth.ts diff --git a/lib/button-variants.ts b/_archive/lib/button-variants.ts similarity index 100% rename from lib/button-variants.ts rename to _archive/lib/button-variants.ts diff --git a/lib/db.ts b/_archive/lib/db.ts similarity index 100% rename from lib/db.ts rename to _archive/lib/db.ts diff --git a/lib/overdue.client.ts b/_archive/lib/overdue.client.ts similarity index 100% rename from lib/overdue.client.ts rename to _archive/lib/overdue.client.ts diff --git a/lib/overdue.ts b/_archive/lib/overdue.ts similarity index 100% rename from lib/overdue.ts rename to _archive/lib/overdue.ts diff --git a/lib/stage-transitions.client.ts b/_archive/lib/stage-transitions.client.ts similarity index 100% rename from lib/stage-transitions.client.ts rename to _archive/lib/stage-transitions.client.ts diff --git a/lib/stage-transitions.ts b/_archive/lib/stage-transitions.ts similarity index 100% rename from lib/stage-transitions.ts rename to _archive/lib/stage-transitions.ts diff --git a/lib/utils.ts b/_archive/lib/utils.ts similarity index 100% rename from lib/utils.ts rename to _archive/lib/utils.ts diff --git a/lib/validations/.gitkeep b/_archive/lib/validations/.gitkeep similarity index 100% rename from lib/validations/.gitkeep rename to _archive/lib/validations/.gitkeep diff --git a/lib/validations/brand.ts b/_archive/lib/validations/brand.ts similarity index 100% rename from lib/validations/brand.ts rename to _archive/lib/validations/brand.ts diff --git a/lib/validations/deal.ts b/_archive/lib/validations/deal.ts similarity index 100% rename from lib/validations/deal.ts rename to _archive/lib/validations/deal.ts diff --git a/lib/validations/roster.ts b/_archive/lib/validations/roster.ts similarity index 100% rename from lib/validations/roster.ts rename to _archive/lib/validations/roster.ts diff --git a/prisma/migrations/20260319025118_init/migration.sql b/_archive/prisma/migrations/20260319025118_init/migration.sql similarity index 100% rename from prisma/migrations/20260319025118_init/migration.sql rename to _archive/prisma/migrations/20260319025118_init/migration.sql diff --git a/prisma/migrations/20260319025143_add_search_indexes/migration.sql b/_archive/prisma/migrations/20260319025143_add_search_indexes/migration.sql similarity index 100% rename from prisma/migrations/20260319025143_add_search_indexes/migration.sql rename to _archive/prisma/migrations/20260319025143_add_search_indexes/migration.sql diff --git a/prisma/migrations/migration_lock.toml b/_archive/prisma/migrations/migration_lock.toml similarity index 100% rename from prisma/migrations/migration_lock.toml rename to _archive/prisma/migrations/migration_lock.toml diff --git a/prisma/schema.prisma b/_archive/prisma/schema.prisma similarity index 100% rename from prisma/schema.prisma rename to _archive/prisma/schema.prisma diff --git a/proxy.ts b/_archive/proxy.ts similarity index 100% rename from proxy.ts rename to _archive/proxy.ts From 93bd81cd19d3c85df960bb3b11b1d2e8c07b5e09 Mon Sep 17 00:00:00 2001 From: parva3105 Date: Fri, 20 Mar 2026 20:08:21 -0400 Subject: [PATCH 2/2] =?UTF-8?q?feat(revamp/phase-1):=20Phase=201=20UI=20Sh?= =?UTF-8?q?ell=20=E2=80=94=2018=20routes=20with=20mock=20data?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Builds the complete Phase 1 UI shell with all pages using typed mock data from lib/mock/. No API calls, no Clerk, no database. Routes built: - Agency: /dashboard (Kanban + dnd-kit), /deals, /deals/new, /deals/[id] /roster, /brands, /brands/[id], /briefs, /briefs/[id] - Creator: /creator/deals, /creator/deals/[id], /creator/profile - Brand: /briefs/new - Public: / (landing), /discover, /creators/[handle], /agencies Key features: - Kanban board with drag-and-drop (system stages reject drops) - Stage control panel with advance/reopen logic - Deal detail: 4 sections (Brief, Contract, Content, Payment) - Creator portal hides commission %, deal value - RoleSwitcher dev tool (localStorage) in header - Dark mode zinc/slate design - All 5 lib/mock/ fixture files with exact Prisma model shapes - 101 passing tests Co-Authored-By: Claude Sonnet 4.6 --- .claude/memory/decisions.md | 40 ++ .claude/memory/iterations.md | 175 ++++++ .claude/memory/memory.md | 5 +- .claude/memory/requests.md | 23 + .gitignore | 4 + app/(agency)/brands/[id]/page.tsx | 129 +++++ app/(agency)/brands/page.tsx | 11 + app/(agency)/briefs/[id]/page.tsx | 18 + app/(agency)/briefs/page.tsx | 11 + app/(agency)/dashboard/page.tsx | 6 + app/(agency)/deals/[id]/page.tsx | 22 + app/(agency)/deals/new/page.tsx | 12 + app/(agency)/deals/page.tsx | 10 + app/(agency)/layout.tsx | 16 + app/(agency)/not-found.tsx | 3 + app/(agency)/roster/page.tsx | 11 + app/(brand)/briefs/new/page.tsx | 10 + app/(brand)/layout.tsx | 16 + app/(creator)/creator/deals/[id]/page.tsx | 22 + app/(creator)/creator/deals/page.tsx | 71 +++ app/(creator)/creator/profile/page.tsx | 12 + app/(creator)/layout.tsx | 16 + app/(public)/agencies/page.tsx | 41 ++ app/(public)/creators/[handle]/page.tsx | 74 +++ app/(public)/discover/page.tsx | 12 + app/(public)/layout.tsx | 3 + app/(public)/page.tsx | 140 +++++ app/globals.css | 129 +++++ app/layout.tsx | 24 + components/__tests__/foundation.test.tsx | 281 +++++++++ .../__tests__/p1-2-agency-core.test.tsx | 327 +++++++++++ components/__tests__/p1-3-to-p1-6.test.tsx | 275 +++++++++ components/brands/AddBrandDialog.tsx | 101 ++++ components/brands/BrandsTable.tsx | 96 +++ components/briefs/BriefDetail.tsx | 166 ++++++ components/briefs/BriefsTable.tsx | 133 +++++ components/briefs/SubmitBriefForm.tsx | 230 ++++++++ components/creator/ContentSubmissionForm.tsx | 74 +++ components/creator/CreatorCard.tsx | 55 ++ components/creator/CreatorDealDetail.tsx | 207 +++++++ components/creator/CreatorDirectory.tsx | 133 +++++ components/creator/CreatorProfileEditor.tsx | 210 +++++++ .../creator/PartnershipRequestDialog.tsx | 50 ++ components/deals/DealDetail.tsx | 418 +++++++++++++ components/deals/DealsTable.tsx | 200 +++++++ components/deals/StageControlPanel.tsx | 114 ++++ components/deals/SubmissionHistory.tsx | 89 +++ components/forms/DealNewForm.tsx | 291 ++++++++++ components/forms/InlineBrandForm.tsx | 97 ++++ components/kanban/DealCard.tsx | 71 +++ components/kanban/DealDraggable.tsx | 31 + components/kanban/KanbanBoard.tsx | 118 ++++ components/kanban/KanbanColumn.tsx | 55 ++ components/kanban/KanbanFilters.tsx | 122 ++++ components/layout/Header.tsx | 27 + components/layout/RoleSwitcher.tsx | 41 ++ components/layout/Sidebar.tsx | 77 +++ components/roster/AddCreatorSheet.tsx | 189 ++++++ components/roster/RosterTable.tsx | 124 ++++ components/ui/alert-dialog.tsx | 187 ++++++ components/ui/badge.tsx | 52 ++ components/ui/button.tsx | 60 ++ components/ui/card.tsx | 103 ++++ components/ui/checkbox.tsx | 29 + components/ui/dialog.tsx | 160 +++++ components/ui/dropdown-menu.tsx | 268 +++++++++ components/ui/input.tsx | 20 + components/ui/label.tsx | 20 + components/ui/select.tsx | 201 +++++++ components/ui/separator.tsx | 25 + components/ui/sheet.tsx | 138 +++++ components/ui/sonner.tsx | 49 ++ components/ui/switch.tsx | 32 + components/ui/table.tsx | 116 ++++ components/ui/textarea.tsx | 18 + components/ui/tooltip.tsx | 66 +++ lib/button-variants.ts | 43 ++ lib/mock/brands.ts | 38 ++ lib/mock/briefs.ts | 82 +++ lib/mock/creators.ts | 97 ++++ lib/mock/deals.ts | 192 ++++++ lib/mock/submissions.ts | 52 ++ lib/overdue.client.ts | 7 + lib/role-context.tsx | 40 ++ lib/stage-transitions.client.ts | 47 ++ lib/utils.ts | 6 + package-lock.json | 9 + package.json | 1 + revamp/ARCHITECTURE.md | 212 +++++++ revamp/BACKEND.md | 547 ++++++++++++++++++ revamp/FRONTEND.md | 436 ++++++++++++++ revamp/MOCKDATA.md | 514 ++++++++++++++++ revamp/PRODUCT.md | 150 +++++ revamp/README.md | 52 ++ revamp/ROADMAP.md | 214 +++++++ tsconfig.json | 2 +- 96 files changed, 9750 insertions(+), 3 deletions(-) create mode 100644 app/(agency)/brands/[id]/page.tsx create mode 100644 app/(agency)/brands/page.tsx create mode 100644 app/(agency)/briefs/[id]/page.tsx create mode 100644 app/(agency)/briefs/page.tsx create mode 100644 app/(agency)/dashboard/page.tsx create mode 100644 app/(agency)/deals/[id]/page.tsx create mode 100644 app/(agency)/deals/new/page.tsx create mode 100644 app/(agency)/deals/page.tsx create mode 100644 app/(agency)/layout.tsx create mode 100644 app/(agency)/not-found.tsx create mode 100644 app/(agency)/roster/page.tsx create mode 100644 app/(brand)/briefs/new/page.tsx create mode 100644 app/(brand)/layout.tsx create mode 100644 app/(creator)/creator/deals/[id]/page.tsx create mode 100644 app/(creator)/creator/deals/page.tsx create mode 100644 app/(creator)/creator/profile/page.tsx create mode 100644 app/(creator)/layout.tsx create mode 100644 app/(public)/agencies/page.tsx create mode 100644 app/(public)/creators/[handle]/page.tsx create mode 100644 app/(public)/discover/page.tsx create mode 100644 app/(public)/layout.tsx create mode 100644 app/(public)/page.tsx create mode 100644 app/globals.css create mode 100644 app/layout.tsx create mode 100644 components/__tests__/foundation.test.tsx create mode 100644 components/__tests__/p1-2-agency-core.test.tsx create mode 100644 components/__tests__/p1-3-to-p1-6.test.tsx create mode 100644 components/brands/AddBrandDialog.tsx create mode 100644 components/brands/BrandsTable.tsx create mode 100644 components/briefs/BriefDetail.tsx create mode 100644 components/briefs/BriefsTable.tsx create mode 100644 components/briefs/SubmitBriefForm.tsx create mode 100644 components/creator/ContentSubmissionForm.tsx create mode 100644 components/creator/CreatorCard.tsx create mode 100644 components/creator/CreatorDealDetail.tsx create mode 100644 components/creator/CreatorDirectory.tsx create mode 100644 components/creator/CreatorProfileEditor.tsx create mode 100644 components/creator/PartnershipRequestDialog.tsx create mode 100644 components/deals/DealDetail.tsx create mode 100644 components/deals/DealsTable.tsx create mode 100644 components/deals/StageControlPanel.tsx create mode 100644 components/deals/SubmissionHistory.tsx create mode 100644 components/forms/DealNewForm.tsx create mode 100644 components/forms/InlineBrandForm.tsx create mode 100644 components/kanban/DealCard.tsx create mode 100644 components/kanban/DealDraggable.tsx create mode 100644 components/kanban/KanbanBoard.tsx create mode 100644 components/kanban/KanbanColumn.tsx create mode 100644 components/kanban/KanbanFilters.tsx create mode 100644 components/layout/Header.tsx create mode 100644 components/layout/RoleSwitcher.tsx create mode 100644 components/layout/Sidebar.tsx create mode 100644 components/roster/AddCreatorSheet.tsx create mode 100644 components/roster/RosterTable.tsx create mode 100644 components/ui/alert-dialog.tsx create mode 100644 components/ui/badge.tsx create mode 100644 components/ui/button.tsx create mode 100644 components/ui/card.tsx create mode 100644 components/ui/checkbox.tsx create mode 100644 components/ui/dialog.tsx create mode 100644 components/ui/dropdown-menu.tsx create mode 100644 components/ui/input.tsx create mode 100644 components/ui/label.tsx create mode 100644 components/ui/select.tsx create mode 100644 components/ui/separator.tsx create mode 100644 components/ui/sheet.tsx create mode 100644 components/ui/sonner.tsx create mode 100644 components/ui/switch.tsx create mode 100644 components/ui/table.tsx create mode 100644 components/ui/textarea.tsx create mode 100644 components/ui/tooltip.tsx create mode 100644 lib/button-variants.ts create mode 100644 lib/mock/brands.ts create mode 100644 lib/mock/briefs.ts create mode 100644 lib/mock/creators.ts create mode 100644 lib/mock/deals.ts create mode 100644 lib/mock/submissions.ts create mode 100644 lib/overdue.client.ts create mode 100644 lib/role-context.tsx create mode 100644 lib/stage-transitions.client.ts create mode 100644 lib/utils.ts create mode 100644 revamp/ARCHITECTURE.md create mode 100644 revamp/BACKEND.md create mode 100644 revamp/FRONTEND.md create mode 100644 revamp/MOCKDATA.md create mode 100644 revamp/PRODUCT.md create mode 100644 revamp/README.md create mode 100644 revamp/ROADMAP.md diff --git a/.claude/memory/decisions.md b/.claude/memory/decisions.md index 8aa2b97..4aaa8ff 100644 --- a/.claude/memory/decisions.md +++ b/.claude/memory/decisions.md @@ -3,6 +3,20 @@ _Append only. Never delete entries._ --- +## 2026-03-20 — revamp/phase-1: Mock data over real API calls +**Decision**: Phase 1 uses static mock data in `lib/mock/` with no API calls, no Clerk, no Prisma. +**Reason**: Allows rapid UI iteration without backend service dependencies; all values use dollars (not cents) for Phase 1 display simplicity; Prisma enums replaced with string literals throughout client code. +**Alternatives considered**: Keeping live API calls (rejected — Phase 1 is a clean-slate revamp, not patching M2 code). + +--- + +## 2026-03-20 — revamp/phase-1: geist npm package over next/font/google +**Decision**: Import Geist fonts via `geist/font/sans` and `geist/font/mono` (npm package), not `next/font/google`. +**Reason**: The `geist` package self-hosts fonts (no external requests), ships correct variable declarations (`--font-geist-sans`, `--font-geist-mono`), and is the Vercel-recommended pattern per official docs. +**Alternatives considered**: `next/font/google` (archive pattern) — still valid but requires network during build; self-hosting preferred. + +--- + ## 2026-03-18 — Framework: Next.js 16 App Router **Decision**: Use Next.js 16 with App Router. **Reason**: Multi-page routing needed, SSR for SEO on public creator directory (/discover, /creators/:handle), Server Components reduce client bundle, streaming support. @@ -217,3 +231,29 @@ The following were evaluated and explicitly excluded from MVP. Do not reopen wit ## 2026-03-19 — Button asChild not available; use Link + buttonVariants() **Decision**: For anchor-styled buttons (links that look like buttons), use `Link` from `next/link` with `buttonVariants()` class applied directly — not ` + + + + + + ) +} diff --git a/components/brands/BrandsTable.tsx b/components/brands/BrandsTable.tsx new file mode 100644 index 0000000..b70d6c6 --- /dev/null +++ b/components/brands/BrandsTable.tsx @@ -0,0 +1,96 @@ +'use client' + +import { useState } from 'react' +import Link from 'next/link' +import { + Table, + TableBody, + TableCell, + TableHead, + TableHeader, + TableRow, +} from '@/components/ui/table' +import { AddBrandDialog } from '@/components/brands/AddBrandDialog' +import type { MockBrand } from '@/lib/mock/brands' +import type { MockDeal } from '@/lib/mock/deals' + +interface BrandsTableProps { + initialBrands: MockBrand[] + deals: MockDeal[] +} + +export function BrandsTable({ initialBrands, deals }: BrandsTableProps) { + const [brands, setBrands] = useState(initialBrands) + + function handleCreated(brand: MockBrand) { + setBrands(prev => [...prev, brand]) + } + + return ( +
+
+

Brands

+ +
+ + {brands.length === 0 ? ( +

No brands yet.

+ ) : ( +
+ + + + Name + Website + Open Deals + Total Value + + + + {brands.map(brand => { + const brandDeals = deals.filter(d => d.brandId === brand.id) + const openDeals = brandDeals.filter(d => d.stage !== 'CLOSED').length + const totalValue = brandDeals.reduce((sum, d) => sum + d.dealValue, 0) + + return ( + + + + {brand.name} + + + + {brand.website ? ( + + {brand.website} + + ) : ( + + )} + + + {openDeals} + + + + ${totalValue.toLocaleString()} + + + + ) + })} + +
+
+ )} +
+ ) +} diff --git a/components/briefs/BriefDetail.tsx b/components/briefs/BriefDetail.tsx new file mode 100644 index 0000000..3c3a3e5 --- /dev/null +++ b/components/briefs/BriefDetail.tsx @@ -0,0 +1,166 @@ +'use client' + +import { useState } from 'react' +import { useRouter } from 'next/navigation' +import { toast } from 'sonner' +import { Badge } from '@/components/ui/badge' +import { Button } from '@/components/ui/button' +import { + AlertDialog, + AlertDialogAction, + AlertDialogCancel, + AlertDialogContent, + AlertDialogDescription, + AlertDialogFooter, + AlertDialogHeader, + AlertDialogTitle, + AlertDialogTrigger, +} from '@/components/ui/alert-dialog' +import type { MockBrief } from '@/lib/mock/briefs' + +function statusBadge(status: string) { + switch (status) { + case 'NEW': + return NEW + case 'REVIEWED': + return REVIEWED + case 'CONVERTED': + return CONVERTED + case 'DECLINED': + return DECLINED + default: + return {status} + } +} + +interface BriefDetailProps { + initialBrief: MockBrief +} + +export function BriefDetail({ initialBrief }: BriefDetailProps) { + const [brief, setBrief] = useState(initialBrief) + const router = useRouter() + + function handleMarkReviewed() { + setBrief(prev => ({ ...prev, status: 'REVIEWED' })) + toast.success('Brief marked as reviewed') + } + + function handleDecline() { + setBrief(prev => ({ ...prev, status: 'DECLINED' })) + toast.success('Brief declined') + } + + const isTerminal = brief.status === 'CONVERTED' || brief.status === 'DECLINED' + + return ( +
+ {/* Header */} +
+
+

{brief.title}

+
+ {statusBadge(brief.status)} + {brief.platform} +
+
+
+ + {/* Brief Info */} +
+
+

Description

+

{brief.description}

+
+ +
+
+

Platform

+

{brief.platform}

+
+
+

Niche

+

{brief.niche}

+
+
+

Budget

+

${brief.budget.toLocaleString()}

+
+
+
+ + {/* Submitted By */} +
+

Submitted By

+
+
+

Name

+

{brief.brandManagerName}

+
+
+

Company

+

{brief.brandManagerCompany}

+
+
+

Date

+

+ {new Date(brief.createdAt).toLocaleDateString('en-US', { + month: 'short', + day: 'numeric', + year: 'numeric', + })} +

+
+
+
+ + {/* Requested Creator */} + {brief.creatorId && ( +
+

Requested Creator

+

{brief.creatorId}

+
+ )} + + {/* Action Bar */} +
+ {isTerminal ? ( + <>{statusBadge(brief.status)} + ) : ( + <> + + + {brief.status === 'NEW' && ( + + )} + + + }> + Decline + + + + Decline this brief? + + This will mark the brief as declined. The brand manager will not be + notified in Phase 1. + + + + Cancel + + Decline Brief + + + + + + )} +
+
+ ) +} diff --git a/components/briefs/BriefsTable.tsx b/components/briefs/BriefsTable.tsx new file mode 100644 index 0000000..ec31c4f --- /dev/null +++ b/components/briefs/BriefsTable.tsx @@ -0,0 +1,133 @@ +'use client' + +import { useState } from 'react' +import Link from 'next/link' +import { Badge } from '@/components/ui/badge' +import { + Table, + TableBody, + TableCell, + TableHead, + TableHeader, + TableRow, +} from '@/components/ui/table' +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from '@/components/ui/select' +import type { MockBrief } from '@/lib/mock/briefs' + +const STATUS_OPTIONS = ['ALL', 'NEW', 'REVIEWED', 'CONVERTED', 'DECLINED'] as const + +function statusBadge(status: string) { + switch (status) { + case 'NEW': + return NEW + case 'REVIEWED': + return REVIEWED + case 'CONVERTED': + return CONVERTED + case 'DECLINED': + return DECLINED + default: + return {status} + } +} + +interface BriefsTableProps { + initialBriefs: MockBrief[] +} + +export function BriefsTable({ initialBriefs }: BriefsTableProps) { + const [briefs] = useState(initialBriefs) + const [statusFilter, setStatusFilter] = useState('ALL') + + const filtered = + statusFilter === 'ALL' + ? briefs + : briefs.filter(b => b.status === statusFilter) + + return ( +
+
+ +
+ + {filtered.length === 0 ? ( +

No briefs yet.

+ ) : ( +
+ + + + Title + Submitted By + Company + Platform + Budget + Niche + Status + Date + + + + {filtered.map(brief => ( + + + + {brief.title} + + + + {brief.brandManagerName} + + + {brief.brandManagerCompany} + + + {brief.platform} + + + + ${brief.budget.toLocaleString()} + + + + {brief.niche} + + {statusBadge(brief.status)} + + + {new Date(brief.createdAt).toLocaleDateString('en-US', { + month: 'short', + day: 'numeric', + year: 'numeric', + })} + + + + ))} + +
+
+ )} +
+ ) +} diff --git a/components/briefs/SubmitBriefForm.tsx b/components/briefs/SubmitBriefForm.tsx new file mode 100644 index 0000000..efa1469 --- /dev/null +++ b/components/briefs/SubmitBriefForm.tsx @@ -0,0 +1,230 @@ +'use client' + +import { useState } from 'react' +import { useForm } from 'react-hook-form' +import { CheckCircle } from 'lucide-react' +import { Button } from '@/components/ui/button' +import { Input } from '@/components/ui/input' +import { Label } from '@/components/ui/label' +import { Textarea } from '@/components/ui/textarea' +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from '@/components/ui/select' +import { Card } from '@/components/ui/card' + +const MOCK_AGENCIES = [ + { id: 'agency_001', name: 'Apex Talent Group' }, + { id: 'agency_002', name: 'Nova Creator Agency' }, + { id: 'agency_003', name: 'Spark Media Management' }, +] + +const PLATFORMS = [ + 'Instagram', + 'TikTok', + 'YouTube', + 'Twitter', + 'LinkedIn', + 'Pinterest', + 'Other', +] as const + +type BriefFormValues = { + title: string + description: string + platform: string + niche: string + budget: string + agencyId: string + creatorHandle: string +} + +export function SubmitBriefForm() { + const [submitted, setSubmitted] = useState(false) + + const { + register, + handleSubmit, + setValue, + watch, + reset, + formState: { errors }, + } = useForm({ + defaultValues: { + title: '', + description: '', + platform: '', + niche: '', + budget: '', + agencyId: '', + creatorHandle: '', + }, + }) + + const platform = watch('platform') + const agencyId = watch('agencyId') + + function validate(data: BriefFormValues): Record { + const errs: Record = {} + if (!data.title.trim()) errs.title = 'Title is required' + if (!data.description.trim()) errs.description = 'Description is required' + if (!data.platform) errs.platform = 'Platform is required' + if (!data.niche.trim()) errs.niche = 'Niche is required' + if (!data.budget || isNaN(Number(data.budget)) || Number(data.budget) < 0) + errs.budget = 'Budget must be a non-negative number' + if (!data.agencyId) errs.agencyId = 'Agency is required' + return errs + } + + function onSubmit(data: BriefFormValues) { + const errs = validate(data) + if (Object.keys(errs).length > 0) return + setSubmitted(true) + } + + if (submitted) { + return ( + + +

Brief Submitted!

+

+ The agency will review it and be in touch soon. +

+ +
+ ) + } + + return ( +
+
+ + + {errors.title && ( +

{errors.title.message}

+ )} +
+ +
+ +