create-z3 0.0.48 → 0.0.50
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 +22 -20
- package/package.json +1 -1
- package/templates/nextjs/src/app/(frontend)/layout.tsx +21 -27
- package/templates/nextjs/src/components/component-example.tsx +44 -492
- package/templates/tanstack-start/package.json +1 -0
- package/templates/tanstack-start/pnpm-workspace.yaml +2 -0
- package/templates/tanstack-start/src/components/component-example.tsx +14 -14
- package/templates/tanstack-start/src/routes/__root.tsx +1 -1
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 =
|
|
1734
|
-
--
|
|
1735
|
-
--
|
|
1736
|
-
--card
|
|
1737
|
-
--
|
|
1738
|
-
--popover
|
|
1739
|
-
--
|
|
1740
|
-
--primary
|
|
1741
|
-
--
|
|
1742
|
-
--secondary
|
|
1743
|
-
--
|
|
1744
|
-
--muted
|
|
1745
|
-
--
|
|
1746
|
-
--accent
|
|
1747
|
-
--
|
|
1748
|
-
--destructive
|
|
1749
|
-
--
|
|
1750
|
-
--
|
|
1751
|
-
--
|
|
1752
|
-
--
|
|
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,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
|
-
|
|
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
|
|
34
|
-
<
|
|
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
|
|
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
|
-
|
|
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'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
|
-
<
|
|
158
|
-
<
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
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
|
}
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
"format": "prettier --write . --cache",
|
|
14
14
|
"format:check": "prettier --check . --cache",
|
|
15
15
|
"validate": "pnpm run typecheck && pnpm run lint && pnpm run format:check",
|
|
16
|
+
"convex": "convex",
|
|
16
17
|
"secret:create": "openssl rand -hex 32 | tr -d '\\n' | pbcopy && echo '✅ Secret generated and copied to clipboard!'"
|
|
17
18
|
},
|
|
18
19
|
"dependencies": {
|
|
@@ -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
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
<
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
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
|
|
39
|
-
|
|
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>
|