create-z3 0.0.48 → 0.0.49

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1730,26 +1730,28 @@ function getAdditionalProviders() {
1730
1730
 
1731
1731
  // src/installers/string-utils.ts
1732
1732
  import fs3 from "fs-extra";
1733
- var DEFAULT_THEME = `--background: 100% 0.000 0;
1734
- --foreground: 3.9% 0.006 240;
1735
- --card: 100% 0.000 0;
1736
- --card-foreground: 3.9% 0.006 240;
1737
- --popover: 100% 0.000 0;
1738
- --popover-foreground: 3.9% 0.006 240;
1739
- --primary: 10% 0.003 240;
1740
- --primary-foreground: 98% 0.000 0;
1741
- --secondary: 95.9% 0.002 240;
1742
- --secondary-foreground: 10% 0.003 240;
1743
- --muted: 95.9% 0.002 240;
1744
- --muted-foreground: 46.1% 0.002 240;
1745
- --accent: 95.9% 0.002 240;
1746
- --accent-foreground: 10% 0.003 240;
1747
- --destructive: 60.2% 0.168 0;
1748
- --destructive-foreground: 98% 0.000 0;
1749
- --border: 90% 0.003 240;
1750
- --input: 90% 0.003 240;
1751
- --ring: 10% 0.003 240;
1752
- --radius: 0.5rem;`;
1733
+ var DEFAULT_THEME = `:root {
1734
+ --background: 100% 0.000 0;
1735
+ --foreground: 3.9% 0.006 240;
1736
+ --card: 100% 0.000 0;
1737
+ --card-foreground: 3.9% 0.006 240;
1738
+ --popover: 100% 0.000 0;
1739
+ --popover-foreground: 3.9% 0.006 240;
1740
+ --primary: 10% 0.003 240;
1741
+ --primary-foreground: 98% 0.000 0;
1742
+ --secondary: 95.9% 0.002 240;
1743
+ --secondary-foreground: 10% 0.003 240;
1744
+ --muted: 95.9% 0.002 240;
1745
+ --muted-foreground: 46.1% 0.002 240;
1746
+ --accent: 95.9% 0.002 240;
1747
+ --accent-foreground: 10% 0.003 240;
1748
+ --destructive: 60.2% 0.168 0;
1749
+ --destructive-foreground: 98% 0.000 0;
1750
+ --border: 90% 0.003 240;
1751
+ --input: 90% 0.003 240;
1752
+ --ring: 10% 0.003 240;
1753
+ --radius: 0.5rem;
1754
+ }`;
1753
1755
  function detectIndentation(line) {
1754
1756
  const match = line.match(/^(\s*)/);
1755
1757
  return match ? match[1] : "";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-z3",
3
- "version": "0.0.48",
3
+ "version": "0.0.49",
4
4
  "type": "module",
5
5
  "description": "CLI for scaffolding Z3 Stack applications (TanStack/Next.js + Convex + Better Auth)",
6
6
  "bin": {
@@ -1,46 +1,40 @@
1
- import type { Metadata } from "next";
2
- import { Geist, Geist_Mono, Inter } from "next/font/google";
3
- import "./globals.css";
4
- import ServerProviders from "~/components/providers/server";
5
- import ClientProviders from "~/components/providers/client";
6
- import Head from "next/head";
1
+ import type { Metadata } from "next"
7
2
 
8
- const inter = Inter({ subsets: ['latin'], variable: '--font-sans' });
3
+ import { Geist, Geist_Mono, Inter } from "next/font/google"
4
+
5
+ import "./globals.css"
6
+
7
+ import ClientProviders from "~/components/providers/client"
8
+ import ServerProviders from "~/components/providers/server"
9
+
10
+ const inter = Inter({ subsets: ["latin"], variable: "--font-sans" })
9
11
 
10
12
  const geistSans = Geist({
11
- variable: "--font-geist-sans",
12
13
  subsets: ["latin"],
13
- });
14
+ variable: "--font-geist-sans",
15
+ })
14
16
 
15
17
  const geistMono = Geist_Mono({
16
- variable: "--font-geist-mono",
17
18
  subsets: ["latin"],
18
- });
19
+ variable: "--font-geist-mono",
20
+ })
19
21
 
20
22
  export const metadata: Metadata = {
21
- title: "Create Next App",
22
23
  description: "Generated by create next app",
23
- };
24
+ icons: { icon: "/favicons/favicon.ico" },
25
+ title: "Create Next App",
26
+ }
24
27
 
25
28
  export default function RootLayout({
26
29
  auth,
27
30
  children,
28
31
  }: Readonly<{
29
- auth: React.ReactNode;
30
- children: React.ReactNode;
32
+ auth: React.ReactNode
33
+ children: React.ReactNode
31
34
  }>) {
32
35
  return (
33
- <html lang="en" className={inter.variable}>
34
- <Head>
35
- <link
36
- href="/favicons/favicon.ico"
37
- rel="shortcut icon"
38
- type="image/x-icon"
39
- />
40
- </Head>
41
- <body
42
- className={`${geistSans.variable} ${geistMono.variable} antialiased`}
43
- >
36
+ <html className={inter.variable} lang="en" suppressHydrationWarning>
37
+ <body className={`${geistSans.variable} ${geistMono.variable} antialiased`}>
44
38
  <ServerProviders>
45
39
  <ClientProviders>
46
40
  {children}
@@ -49,5 +43,5 @@ export default function RootLayout({
49
43
  </ServerProviders>
50
44
  </body>
51
45
  </html>
52
- );
46
+ )
53
47
  }
@@ -1,503 +1,55 @@
1
1
  "use client"
2
2
 
3
- import * as React from "react"
3
+ import { TerminalIcon, UserIcon } from "lucide-react"
4
+ import Link from "next/link"
4
5
 
5
- import {
6
- Example,
7
- ExampleWrapper,
8
- } from "~/components/example"
9
- import {
10
- AlertDialog,
11
- AlertDialogAction,
12
- AlertDialogCancel,
13
- AlertDialogContent,
14
- AlertDialogDescription,
15
- AlertDialogFooter,
16
- AlertDialogHeader,
17
- AlertDialogMedia,
18
- AlertDialogTitle,
19
- AlertDialogTrigger,
20
- } from "~/components/ui/alert-dialog"
21
- import { Badge } from "~/components/ui/badge"
6
+ import { signOut, useSession } from "~/auth/client"
22
7
  import { Button } from "~/components/ui/button"
23
- import {
24
- Card,
25
- CardAction,
26
- CardContent,
27
- CardDescription,
28
- CardFooter,
29
- CardHeader,
30
- CardTitle,
31
- } from "~/components/ui/card"
32
- import {
33
- Combobox,
34
- ComboboxContent,
35
- ComboboxEmpty,
36
- ComboboxInput,
37
- ComboboxItem,
38
- ComboboxList,
39
- } from "~/components/ui/combobox"
40
- import {
41
- DropdownMenu,
42
- DropdownMenuCheckboxItem,
43
- DropdownMenuContent,
44
- DropdownMenuGroup,
45
- DropdownMenuItem,
46
- DropdownMenuLabel,
47
- DropdownMenuPortal,
48
- DropdownMenuRadioGroup,
49
- DropdownMenuRadioItem,
50
- DropdownMenuSeparator,
51
- DropdownMenuShortcut,
52
- DropdownMenuSub,
53
- DropdownMenuSubContent,
54
- DropdownMenuSubTrigger,
55
- DropdownMenuTrigger,
56
- } from "~/components/ui/dropdown-menu"
57
- import { Field, FieldGroup, FieldLabel } from "~/components/ui/field"
58
- import { Input } from "~/components/ui/input"
59
- import {
60
- Select,
61
- SelectContent,
62
- SelectGroup,
63
- SelectItem,
64
- SelectTrigger,
65
- SelectValue,
66
- } from "~/components/ui/select"
67
- import { Textarea } from "~/components/ui/textarea"
68
- import { PlusIcon, BluetoothIcon, MoreVerticalIcon, FileIcon, FolderIcon, FolderOpenIcon, FileCodeIcon, MoreHorizontalIcon, FolderSearchIcon, SaveIcon, DownloadIcon, EyeIcon, LayoutIcon, PaletteIcon, SunIcon, MoonIcon, MonitorIcon, UserIcon, CreditCardIcon, SettingsIcon, KeyboardIcon, LanguagesIcon, BellIcon, MailIcon, ShieldIcon, HelpCircleIcon, FileTextIcon, LogOutIcon } from "lucide-react"
69
8
  import { ThemeToggle } from "~/components/ui/theme-toggle"
70
9
 
71
10
  export function ComponentExample() {
72
- return (
73
- <ExampleWrapper>
74
- <ThemeToggle className="absolute w-md:top-10 right-10 top-2" />
75
- <CardExample />
76
- <FormExample />
77
- </ExampleWrapper>
78
- )
79
- }
80
-
81
- function CardExample() {
82
- return (
83
- <Example title="Card" className="items-center justify-center">
84
- <Card className="relative w-full max-w-sm overflow-hidden pt-0">
85
- <div className="bg-primary absolute inset-0 z-30 aspect-video opacity-50 mix-blend-color" />
86
- <img
87
- src="https://images.unsplash.com/photo-1604076850742-4c7221f3101b?q=80&w=1887&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"
88
- alt="Photo by mymind on Unsplash"
89
- title="Photo by mymind on Unsplash"
90
- className="relative z-20 aspect-video w-full object-cover brightness-60 grayscale"
91
- />
92
- <CardHeader>
93
- <CardTitle>Observability Plus is replacing Monitoring</CardTitle>
94
- <CardDescription>
95
- Switch to the improved way to explore your data, with natural
96
- language. Monitoring will no longer be available on the Pro plan in
97
- November, 2025
98
- </CardDescription>
99
- </CardHeader>
100
- <CardFooter>
101
- <AlertDialog>
102
- <AlertDialogTrigger render={<Button />}>
103
- <PlusIcon data-icon="inline-start" />
104
- Show Dialog
105
- </AlertDialogTrigger>
106
- <AlertDialogContent size="sm">
107
- <AlertDialogHeader>
108
- <AlertDialogMedia>
109
- <BluetoothIcon
110
- />
111
- </AlertDialogMedia>
112
- <AlertDialogTitle>Allow accessory to connect?</AlertDialogTitle>
113
- <AlertDialogDescription>
114
- Do you want to allow the USB accessory to connect to this
115
- device?
116
- </AlertDialogDescription>
117
- </AlertDialogHeader>
118
- <AlertDialogFooter>
119
- <AlertDialogCancel>Don&apos;t allow</AlertDialogCancel>
120
- <AlertDialogAction>Allow</AlertDialogAction>
121
- </AlertDialogFooter>
122
- </AlertDialogContent>
123
- </AlertDialog>
124
- <Badge variant="secondary" className="ml-auto">
125
- Warning
126
- </Badge>
127
- </CardFooter>
128
- </Card>
129
- </Example>
130
- )
131
- }
132
-
133
- const frameworks = [
134
- "Next.js",
135
- "SvelteKit",
136
- "Nuxt.js",
137
- "Remix",
138
- "Astro",
139
- ] as const
140
-
141
- const roleItems = [
142
- { label: "Developer", value: "developer" },
143
- { label: "Designer", value: "designer" },
144
- { label: "Manager", value: "manager" },
145
- { label: "Other", value: "other" },
146
- ]
147
-
148
- function FormExample() {
149
- const [notifications, setNotifications] = React.useState({
150
- email: true,
151
- sms: false,
152
- push: true,
153
- })
154
- const [theme, setTheme] = React.useState("light")
11
+ const { data: session } = useSession()
155
12
 
156
13
  return (
157
- <Example title="Form">
158
- <Card className="w-full max-w-md">
159
- <CardHeader>
160
- <CardTitle>User Information</CardTitle>
161
- <CardDescription>Please fill in your details below</CardDescription>
162
- <CardAction>
163
- <DropdownMenu>
164
- <DropdownMenuTrigger
165
- render={<Button variant="ghost" size="icon" />}
166
- >
167
- <MoreVerticalIcon
168
- />
169
- <span className="sr-only">More options</span>
170
- </DropdownMenuTrigger>
171
- <DropdownMenuContent align="end" className="w-56">
172
- <DropdownMenuGroup>
173
- <DropdownMenuLabel>File</DropdownMenuLabel>
174
- <DropdownMenuItem>
175
- <FileIcon
176
- />
177
- New File
178
- <DropdownMenuShortcut>⌘N</DropdownMenuShortcut>
179
- </DropdownMenuItem>
180
- <DropdownMenuItem>
181
- <FolderIcon
182
- />
183
- New Folder
184
- <DropdownMenuShortcut>⇧⌘N</DropdownMenuShortcut>
185
- </DropdownMenuItem>
186
- <DropdownMenuSub>
187
- <DropdownMenuSubTrigger>
188
- <FolderOpenIcon
189
- />
190
- Open Recent
191
- </DropdownMenuSubTrigger>
192
- <DropdownMenuPortal>
193
- <DropdownMenuSubContent>
194
- <DropdownMenuGroup>
195
- <DropdownMenuLabel>Recent Projects</DropdownMenuLabel>
196
- <DropdownMenuItem>
197
- <FileCodeIcon
198
- />
199
- Project Alpha
200
- </DropdownMenuItem>
201
- <DropdownMenuItem>
202
- <FileCodeIcon
203
- />
204
- Project Beta
205
- </DropdownMenuItem>
206
- <DropdownMenuSub>
207
- <DropdownMenuSubTrigger>
208
- <MoreHorizontalIcon
209
- />
210
- More Projects
211
- </DropdownMenuSubTrigger>
212
- <DropdownMenuPortal>
213
- <DropdownMenuSubContent>
214
- <DropdownMenuItem>
215
- <FileCodeIcon
216
- />
217
- Project Gamma
218
- </DropdownMenuItem>
219
- <DropdownMenuItem>
220
- <FileCodeIcon
221
- />
222
- Project Delta
223
- </DropdownMenuItem>
224
- </DropdownMenuSubContent>
225
- </DropdownMenuPortal>
226
- </DropdownMenuSub>
227
- </DropdownMenuGroup>
228
- <DropdownMenuSeparator />
229
- <DropdownMenuGroup>
230
- <DropdownMenuItem>
231
- <FolderSearchIcon
232
- />
233
- Browse...
234
- </DropdownMenuItem>
235
- </DropdownMenuGroup>
236
- </DropdownMenuSubContent>
237
- </DropdownMenuPortal>
238
- </DropdownMenuSub>
239
- <DropdownMenuSeparator />
240
- <DropdownMenuItem>
241
- <SaveIcon
242
- />
243
- Save
244
- <DropdownMenuShortcut>⌘S</DropdownMenuShortcut>
245
- </DropdownMenuItem>
246
- <DropdownMenuItem>
247
- <DownloadIcon
248
- />
249
- Export
250
- <DropdownMenuShortcut>⇧⌘E</DropdownMenuShortcut>
251
- </DropdownMenuItem>
252
- </DropdownMenuGroup>
253
- <DropdownMenuSeparator />
254
- <DropdownMenuGroup>
255
- <DropdownMenuLabel>View</DropdownMenuLabel>
256
- <DropdownMenuCheckboxItem
257
- checked={notifications.email}
258
- onCheckedChange={(checked) =>
259
- setNotifications({
260
- ...notifications,
261
- email: checked === true,
262
- })
263
- }
264
- >
265
- <EyeIcon
266
- />
267
- Show Sidebar
268
- </DropdownMenuCheckboxItem>
269
- <DropdownMenuCheckboxItem
270
- checked={notifications.sms}
271
- onCheckedChange={(checked) =>
272
- setNotifications({
273
- ...notifications,
274
- sms: checked === true,
275
- })
276
- }
277
- >
278
- <LayoutIcon
279
- />
280
- Show Status Bar
281
- </DropdownMenuCheckboxItem>
282
- <DropdownMenuSub>
283
- <DropdownMenuSubTrigger>
284
- <PaletteIcon
285
- />
286
- Theme
287
- </DropdownMenuSubTrigger>
288
- <DropdownMenuPortal>
289
- <DropdownMenuSubContent>
290
- <DropdownMenuGroup>
291
- <DropdownMenuLabel>Appearance</DropdownMenuLabel>
292
- <DropdownMenuRadioGroup
293
- value={theme}
294
- onValueChange={setTheme}
295
- >
296
- <DropdownMenuRadioItem value="light">
297
- <SunIcon
298
- />
299
- Light
300
- </DropdownMenuRadioItem>
301
- <DropdownMenuRadioItem value="dark">
302
- <MoonIcon
303
- />
304
- Dark
305
- </DropdownMenuRadioItem>
306
- <DropdownMenuRadioItem value="system">
307
- <MonitorIcon
308
- />
309
- System
310
- </DropdownMenuRadioItem>
311
- </DropdownMenuRadioGroup>
312
- </DropdownMenuGroup>
313
- </DropdownMenuSubContent>
314
- </DropdownMenuPortal>
315
- </DropdownMenuSub>
316
- </DropdownMenuGroup>
317
- <DropdownMenuSeparator />
318
- <DropdownMenuGroup>
319
- <DropdownMenuLabel>Account</DropdownMenuLabel>
320
- <DropdownMenuItem>
321
- <UserIcon
322
- />
323
- Profile
324
- <DropdownMenuShortcut>⇧⌘P</DropdownMenuShortcut>
325
- </DropdownMenuItem>
326
- <DropdownMenuItem>
327
- <CreditCardIcon
328
- />
329
- Billing
330
- </DropdownMenuItem>
331
- <DropdownMenuSub>
332
- <DropdownMenuSubTrigger>
333
- <SettingsIcon
334
- />
335
- Settings
336
- </DropdownMenuSubTrigger>
337
- <DropdownMenuPortal>
338
- <DropdownMenuSubContent>
339
- <DropdownMenuGroup>
340
- <DropdownMenuLabel>Preferences</DropdownMenuLabel>
341
- <DropdownMenuItem>
342
- <KeyboardIcon
343
- />
344
- Keyboard Shortcuts
345
- </DropdownMenuItem>
346
- <DropdownMenuItem>
347
- <LanguagesIcon
348
- />
349
- Language
350
- </DropdownMenuItem>
351
- <DropdownMenuSub>
352
- <DropdownMenuSubTrigger>
353
- <BellIcon
354
- />
355
- Notifications
356
- </DropdownMenuSubTrigger>
357
- <DropdownMenuPortal>
358
- <DropdownMenuSubContent>
359
- <DropdownMenuGroup>
360
- <DropdownMenuLabel>
361
- Notification Types
362
- </DropdownMenuLabel>
363
- <DropdownMenuCheckboxItem
364
- checked={notifications.push}
365
- onCheckedChange={(checked) =>
366
- setNotifications({
367
- ...notifications,
368
- push: checked === true,
369
- })
370
- }
371
- >
372
- <BellIcon
373
- />
374
- Push Notifications
375
- </DropdownMenuCheckboxItem>
376
- <DropdownMenuCheckboxItem
377
- checked={notifications.email}
378
- onCheckedChange={(checked) =>
379
- setNotifications({
380
- ...notifications,
381
- email: checked === true,
382
- })
383
- }
384
- >
385
- <MailIcon
386
- />
387
- Email Notifications
388
- </DropdownMenuCheckboxItem>
389
- </DropdownMenuGroup>
390
- </DropdownMenuSubContent>
391
- </DropdownMenuPortal>
392
- </DropdownMenuSub>
393
- </DropdownMenuGroup>
394
- <DropdownMenuSeparator />
395
- <DropdownMenuGroup>
396
- <DropdownMenuItem>
397
- <ShieldIcon
398
- />
399
- Privacy & Security
400
- </DropdownMenuItem>
401
- </DropdownMenuGroup>
402
- </DropdownMenuSubContent>
403
- </DropdownMenuPortal>
404
- </DropdownMenuSub>
405
- </DropdownMenuGroup>
406
- <DropdownMenuSeparator />
407
- <DropdownMenuGroup>
408
- <DropdownMenuItem>
409
- <HelpCircleIcon
410
- />
411
- Help & Support
412
- </DropdownMenuItem>
413
- <DropdownMenuItem>
414
- <FileTextIcon
415
- />
416
- Documentation
417
- </DropdownMenuItem>
418
- </DropdownMenuGroup>
419
- <DropdownMenuSeparator />
420
- <DropdownMenuGroup>
421
- <DropdownMenuItem variant="destructive">
422
- <LogOutIcon
423
- />
424
- Sign Out
425
- <DropdownMenuShortcut>⇧⌘Q</DropdownMenuShortcut>
426
- </DropdownMenuItem>
427
- </DropdownMenuGroup>
428
- </DropdownMenuContent>
429
- </DropdownMenu>
430
- </CardAction>
431
- </CardHeader>
432
- <CardContent>
433
- <form>
434
- <FieldGroup>
435
- <div className="grid grid-cols-2 gap-4">
436
- <Field>
437
- <FieldLabel htmlFor="small-form-name">Name</FieldLabel>
438
- <Input
439
- id="small-form-name"
440
- placeholder="Enter your name"
441
- required
442
- />
443
- </Field>
444
- <Field>
445
- <FieldLabel htmlFor="small-form-role">Role</FieldLabel>
446
- <Select items={roleItems} defaultValue={null}>
447
- <SelectTrigger id="small-form-role">
448
- <SelectValue />
449
- </SelectTrigger>
450
- <SelectContent>
451
- <SelectGroup>
452
- {roleItems.map((item) => (
453
- <SelectItem key={item.value} value={item.value}>
454
- {item.label}
455
- </SelectItem>
456
- ))}
457
- </SelectGroup>
458
- </SelectContent>
459
- </Select>
460
- </Field>
461
- </div>
462
- <Field>
463
- <FieldLabel htmlFor="small-form-framework">
464
- Framework
465
- </FieldLabel>
466
- <Combobox items={frameworks}>
467
- <ComboboxInput
468
- id="small-form-framework"
469
- placeholder="Select a framework"
470
- required
471
- />
472
- <ComboboxContent>
473
- <ComboboxEmpty>No frameworks found.</ComboboxEmpty>
474
- <ComboboxList>
475
- {(item) => (
476
- <ComboboxItem key={item} value={item}>
477
- {item}
478
- </ComboboxItem>
479
- )}
480
- </ComboboxList>
481
- </ComboboxContent>
482
- </Combobox>
483
- </Field>
484
- <Field>
485
- <FieldLabel htmlFor="small-form-comments">Comments</FieldLabel>
486
- <Textarea
487
- id="small-form-comments"
488
- placeholder="Add any additional comments"
489
- />
490
- </Field>
491
- <Field orientation="horizontal">
492
- <Button type="submit">Submit</Button>
493
- <Button variant="outline" type="button">
494
- Cancel
495
- </Button>
496
- </Field>
497
- </FieldGroup>
498
- </form>
499
- </CardContent>
500
- </Card>
501
- </Example>
14
+ <div className="bg-background flex min-h-screen flex-col items-center justify-center gap-8 p-6 text-center">
15
+ <div className="absolute top-4 right-4 flex items-center gap-2">
16
+ {session?.user && (
17
+ <>
18
+ <div className="bg-muted flex size-8 items-center justify-center rounded-full">
19
+ <UserIcon className="text-muted-foreground size-4" />
20
+ </div>
21
+ <span className="text-sm font-medium">{session.user.name}</span>
22
+ </>
23
+ )}
24
+ <ThemeToggle />
25
+ </div>
26
+
27
+ <div className="flex flex-col items-center gap-4">
28
+ <div className="bg-foreground text-background flex size-14 items-center justify-center rounded-2xl">
29
+ <TerminalIcon className="size-7" />
30
+ </div>
31
+ <div className="flex flex-col gap-1">
32
+ <h1 className="text-3xl font-bold tracking-tight">create-z3-app</h1>
33
+ <p className="text-muted-foreground max-w-sm text-base">
34
+ A full-stack starter with Next.js, Convex, and Better Auth — ready to ship.
35
+ </p>
36
+ </div>
37
+ </div>
38
+
39
+ <div className="flex gap-3">
40
+ {session?.user ? (
41
+ <Button variant="outline" onClick={() => signOut()}>Sign out</Button>
42
+ ) : (
43
+ <>
44
+ <Button nativeButton={false} render={<Link href="/auth/sign-up" />}>Sign up</Button>
45
+ <Button nativeButton={false} variant="outline" render={<Link href="/auth/sign-in" />}>Sign in</Button>
46
+ </>
47
+ )}
48
+ </div>
49
+
50
+ <code className="bg-muted text-muted-foreground rounded-lg px-4 py-2 text-sm font-mono">
51
+ npm create z3-app@latest
52
+ </code>
53
+ </div>
502
54
  )
503
55
  }
@@ -3,20 +3,24 @@ import { TerminalIcon, UserIcon } from 'lucide-react'
3
3
 
4
4
  import { signOut, useSession } from '~/lib/auth/client'
5
5
  import { Button } from '~/components/ui/button'
6
+ import { ThemeToggle } from '~/components/ui/theme-toggle'
6
7
 
7
8
  export function ComponentExample() {
8
9
  const { data: session } = useSession()
9
10
 
10
11
  return (
11
12
  <div className="bg-background flex min-h-screen flex-col items-center justify-center gap-8 p-6 text-center">
12
- {session?.user && (
13
- <div className="absolute top-4 right-4 flex items-center gap-2">
14
- <div className="bg-muted flex size-8 items-center justify-center rounded-full">
15
- <UserIcon className="text-muted-foreground size-4" />
16
- </div>
17
- <span className="text-sm font-medium">{session.user.name}</span>
18
- </div>
19
- )}
13
+ <div className="absolute top-4 right-4 flex items-center gap-2">
14
+ {session?.user && (
15
+ <>
16
+ <div className="bg-muted flex size-8 items-center justify-center rounded-full">
17
+ <UserIcon className="text-muted-foreground size-4" />
18
+ </div>
19
+ <span className="text-sm font-medium">{session.user.name}</span>
20
+ </>
21
+ )}
22
+ <ThemeToggle />
23
+ </div>
20
24
 
21
25
  <div className="flex flex-col items-center gap-4">
22
26
  <div className="bg-foreground text-background flex size-14 items-center justify-center rounded-2xl">
@@ -35,12 +39,8 @@ export function ComponentExample() {
35
39
  <Button variant="outline" onClick={() => signOut()}>Sign out</Button>
36
40
  ) : (
37
41
  <>
38
- <Button asChild>
39
- <Link to="/auth/$authView" params={{ authView: 'sign-up' }}>Sign up</Link>
40
- </Button>
41
- <Button variant="outline" asChild>
42
- <Link to="/auth/$authView" params={{ authView: 'sign-in' }}>Sign in</Link>
43
- </Button>
42
+ <Button nativeButton={false} render={<Link to="/auth/$authView" params={{ authView: 'sign-up' }} />}>Sign up</Button>
43
+ <Button nativeButton={false} variant="outline" render={<Link to="/auth/$authView" params={{ authView: 'sign-in' }} />}>Sign in</Button>
44
44
  </>
45
45
  )}
46
46
  </div>