page.tsx173 lines · main
1import Link from 'next/link';
2
3export const metadata = {
4 title: 'new project',
5};
6
7interface SourceCard {
8 slug: string;
9 name: string;
10 blurb: string;
11 status: 'auto' | 'concierge';
12}
13
14// Picker for the new-project wizard. The "blank" tile is the today-flow
15// (a fresh empty postgres schema). Every other tile is a migration
16// intake — clicking opens /migrate/<source>, which collects credentials/
17// notes and creates a migration_request row. During beta everything is
18// concierge-handled; the `status` field flips per-source as adapter
19// pipelines ship.
20const SOURCES: readonly SourceCard[] = [
21 {
22 slug: 'convex',
23 name: 'convex',
24 blurb: 'TS schema + query/mutation/action handlers. document-ish with refs.',
25 status: 'concierge',
26 },
27 {
28 slug: 'supabase',
29 name: 'supabase',
30 blurb: 'postgres under the hood. edge functions + auth + RLS to port.',
31 status: 'concierge',
32 },
33 {
34 slug: 'firebase',
35 name: 'firebase / firestore',
36 blurb: 'document store → relational. the hardest path; we walk you through it.',
37 status: 'concierge',
38 },
39 {
40 slug: 'mongodb',
41 name: 'mongodb',
42 blurb: 'document store. collection shape decisions per table.',
43 status: 'concierge',
44 },
45 {
46 slug: 'drizzle',
47 name: 'drizzle',
48 blurb: 'already postgres + already TS. fastest port.',
49 status: 'concierge',
50 },
51 {
52 slug: 'prisma',
53 name: 'prisma',
54 blurb: 'schema.prisma → briven schema DSL. PrismaClient calls become ctx.db.',
55 status: 'concierge',
56 },
57 {
58 slug: 'postgres',
59 name: 'raw postgres',
60 blurb: 'pg_dump | pg_restore + write your functions in briven.',
61 status: 'concierge',
62 },
63 {
64 slug: 'hasura',
65 name: 'hasura',
66 blurb: 'postgres half ports for free. permission rules become function guards.',
67 status: 'concierge',
68 },
69 {
70 slug: 'nextauth',
71 name: 'nextauth / auth.js',
72 blurb: 'user + session tables map to Better Auth. provider port is trivial.',
73 status: 'concierge',
74 },
75];
76
77// Starter templates (non-coder hero path). ids MUST match apps/api's
78// template registry (src/templates/index.ts).
79const TEMPLATE_CARDS = [
80 { id: 'contacts-crm', icon: '👥', name: 'contacts / crm', blurb: 'people, companies and deals.' },
81 { id: 'inventory', icon: '📦', name: 'inventory / stock', blurb: 'products, stock and suppliers.' },
82 { id: 'bookings', icon: '📅', name: 'bookings', blurb: 'clients, services and appointments.' },
83 { id: 'tasks', icon: '✅', name: 'tasks', blurb: 'projects, tasks and due dates.' },
84] as const;
85
86export default function NewProjectPickerPage() {
87 return (
88 <section className="max-w-4xl">
89 <header className="mb-8">
90 <h1 className="font-mono text-xl tracking-tight">new project</h1>
91 <p className="mt-1 font-mono text-sm text-[var(--color-text-muted)]">
92 start fresh, or bring your existing project from somewhere else. your source data
93 stays untouched until you say cut over.
94 </p>
95 </header>
96
97 <h2 className="mb-3 font-mono text-xs uppercase tracking-wider text-[var(--color-text-subtle)]">
98 start fresh
99 </h2>
100 <Link
101 href="/dashboard/projects/new/blank"
102 className="mb-10 flex items-start gap-4 rounded-md border border-[var(--color-border-primary)] bg-[var(--color-primary-subtle)] p-4 transition hover:border-[var(--color-primary)]"
103 >
104 <div className="flex h-10 w-10 shrink-0 items-center justify-center rounded-md bg-[var(--color-primary)] font-mono text-base text-[var(--color-text-inverse)]">
105 +
106 </div>
107 <div className="flex-1">
108 <p className="font-mono text-sm text-[var(--color-text)]">blank project</p>
109 <p className="mt-1 font-mono text-xs text-[var(--color-text-muted)]">
110 empty postgres schema + function runtime. one click, ready in seconds. pick this
111 if you&apos;re trying briven for the first time or building from scratch.
112 </p>
113 </div>
114 </Link>
115
116 <h2 className="mb-3 font-mono text-xs uppercase tracking-wider text-[var(--color-text-subtle)]">
117 start from a template
118 </h2>
119 <p className="mb-4 font-mono text-xs text-[var(--color-text-subtle)]">
120 no coding needed — briven builds the tables and example rows for you, ready to use in
121 seconds.
122 </p>
123 <ul className="mb-10 grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-4">
124 {TEMPLATE_CARDS.map((t) => (
125 <li key={t.id}>
126 <Link
127 href={`/dashboard/projects/new/template?t=${t.id}`}
128 className="flex h-full flex-col gap-2 rounded-md border border-[var(--color-border-subtle)] bg-[var(--color-surface)] p-4 transition hover:border-[var(--color-primary)]"
129 >
130 <span className="font-mono text-sm text-[var(--color-text)]">
131 <span aria-hidden>{t.icon}</span> {t.name}
132 </span>
133 <span className="font-mono text-xs text-[var(--color-text-muted)]">{t.blurb}</span>
134 </Link>
135 </li>
136 ))}
137 </ul>
138
139 <h2 className="mb-1 font-mono text-xs uppercase tracking-wider text-[var(--color-text-subtle)]">
140 bring your project
141 </h2>
142 <p className="mb-4 font-mono text-xs text-[var(--color-text-subtle)]">
143 every migration is free during beta — we handle the move for you and you keep
144 running on your source until you&apos;re ready to cut over.
145 </p>
146 <ul className="grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-3">
147 {SOURCES.map((s) => (
148 <li key={s.slug}>
149 <Link
150 href={`/dashboard/projects/new/migrate/${s.slug}`}
151 className="flex h-full flex-col gap-2 rounded-md border border-[var(--color-border-subtle)] bg-[var(--color-surface)] p-4 transition hover:border-[var(--color-border-strong)]"
152 >
153 <div className="flex items-center justify-between">
154 <p className="font-mono text-sm text-[var(--color-text)]">{s.name}</p>
155 <span className="rounded-full border border-[var(--color-border-subtle)] px-1.5 py-0.5 font-mono text-[9px] uppercase tracking-wider text-[var(--color-text-subtle)]">
156 {s.status === 'auto' ? 'auto' : 'concierge'}
157 </span>
158 </div>
159 <p className="font-mono text-xs text-[var(--color-text-muted)]">{s.blurb}</p>
160 </Link>
161 </li>
162 ))}
163 </ul>
164
165 <p className="mt-10 rounded-md border border-[var(--color-border-subtle)] bg-[var(--color-surface)] p-4 font-mono text-xs text-[var(--color-text-muted)]">
166 <strong className="text-[var(--color-text)]">your source stays safe.</strong> nothing
167 we do touches the system you&apos;re coming from. we read your data, write a copy into
168 briven, and let you parallel-run for as long as you need before you flip writes. you
169 can roll back to your source at any point in the first 7 days after cutover.
170 </p>
171 </section>
172 );
173}