MotirBuilding in public
MOTIR · moooon
onMotir
You’re viewing a public project. Anyone can view it — no account needed. Sign in to submit, upvote, or comment on requests.View-only — you can’t edit work items
MOTIR-40

1.3.4 Project UI: create modal + empty state + project switcher + Server Actions

Done
Description

Estimate: 28m · Depends on: 1.3.2, 1.3.3

The production React for projects, following the 1.2.6 mockups-to-code pattern. Adds the project switcher to the existing (authed) TopNav (beside the workspace switcher), the create-project modal, the "create your first project" empty state, and the archive flow — all wired through Server Actions (not client fetches), DB access through projectsService.

What you'll do: Add app/(authed)/_components/ProjectSwitcher.tsx (client; Popover listing the active workspace's projects with a check on active + "Create project"; selecting calls a setActiveProjectAction Server Action + router.refresh()). Compose it into TopNav.tsx beside WorkspaceSwitcher. Add the create-project Modal (name + overridable identifier with live key-preview → createProjectAction). Add a project empty-state surface (when the active workspace has zero projects). Add app/(authed)/_actions or a project-scoped actions file with createProjectAction, setActiveProjectAction, archiveProjectAction (archive opens the typed-identifier double-confirmation modal). The active-project context comes from 1.3.2's getActiveProject(). Honor the brand-mark-deferral principle (no wordmark).

Acceptance criteria

  • TopNav renders the project switcher beside the workspace switcher on every authed route; selecting a project sets activeProjectId via a Server Action + router.refresh().
  • Create-project modal: name + auto-derived identifier (overridable) with a live {IDENTIFIER}-1 key preview; Create calls createProjectAction; new project becomes active; success toast via the existing Toast primitive.
  • Empty state ("Create your first project") shows when the active workspace has zero projects, with a CTA opening the create modal.
  • Archive: typed-identifier double-confirmation modal (matching 1.3.3's mockup); confirm calls archiveProjectAction (sets archivedAt, NOT a hard delete); active project falls back to a remaining project or the empty state.
  • All form posts go through Server Actions; zero db.* in pages/actions/components. Modal width is correct (uses the fixed Modal primitive — finding #10). All quality gates green.

Context refs

  • /design/projects/*.png from 1.3.3
  • app/(authed)/_components/{TopNav,WorkspaceSwitcher,UserMenu}.tsx + app/(authed)/_actions.ts + app/(authed)/settings/workspace/* from 1.2.6 — the exact switcher / Server-Action / modal patterns to mirror
  • lib/services/projectsService.ts + getActiveProject() from 1.3.1/1.3.2
  • components/ui/{Modal,Popover,Toast}.tsx — note Modal's fixed width variants (finding #10)
Status
Done
Type
Sub-task