@victusvinceere/saas-core 0.1.0

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.
Files changed (64) hide show
  1. package/dist/auth/index.d.mts +40 -0
  2. package/dist/auth/index.d.ts +40 -0
  3. package/dist/auth/index.js +147 -0
  4. package/dist/auth/index.js.map +1 -0
  5. package/dist/auth/index.mjs +111 -0
  6. package/dist/auth/index.mjs.map +1 -0
  7. package/dist/authorization/index.d.mts +78 -0
  8. package/dist/authorization/index.d.ts +78 -0
  9. package/dist/authorization/index.js +137 -0
  10. package/dist/authorization/index.js.map +1 -0
  11. package/dist/authorization/index.mjs +104 -0
  12. package/dist/authorization/index.mjs.map +1 -0
  13. package/dist/components/auth/index.d.mts +26 -0
  14. package/dist/components/auth/index.d.ts +26 -0
  15. package/dist/components/auth/index.js +733 -0
  16. package/dist/components/auth/index.js.map +1 -0
  17. package/dist/components/auth/index.mjs +696 -0
  18. package/dist/components/auth/index.mjs.map +1 -0
  19. package/dist/components/dashboard/index.d.mts +32 -0
  20. package/dist/components/dashboard/index.d.ts +32 -0
  21. package/dist/components/dashboard/index.js +440 -0
  22. package/dist/components/dashboard/index.js.map +1 -0
  23. package/dist/components/dashboard/index.mjs +401 -0
  24. package/dist/components/dashboard/index.mjs.map +1 -0
  25. package/dist/components/ui/index.d.mts +351 -0
  26. package/dist/components/ui/index.d.ts +351 -0
  27. package/dist/components/ui/index.js +14342 -0
  28. package/dist/components/ui/index.js.map +1 -0
  29. package/dist/components/ui/index.mjs +14173 -0
  30. package/dist/components/ui/index.mjs.map +1 -0
  31. package/dist/config/index.d.mts +45 -0
  32. package/dist/config/index.d.ts +45 -0
  33. package/dist/config/index.js +71 -0
  34. package/dist/config/index.js.map +1 -0
  35. package/dist/config/index.mjs +44 -0
  36. package/dist/config/index.mjs.map +1 -0
  37. package/dist/hooks/index.d.mts +20 -0
  38. package/dist/hooks/index.d.ts +20 -0
  39. package/dist/hooks/index.js +103 -0
  40. package/dist/hooks/index.js.map +1 -0
  41. package/dist/hooks/index.mjs +65 -0
  42. package/dist/hooks/index.mjs.map +1 -0
  43. package/dist/index.d.mts +21 -0
  44. package/dist/index.d.ts +21 -0
  45. package/dist/index.js +459 -0
  46. package/dist/index.js.map +1 -0
  47. package/dist/index.mjs +401 -0
  48. package/dist/index.mjs.map +1 -0
  49. package/dist/prisma/index.d.mts +11 -0
  50. package/dist/prisma/index.d.ts +11 -0
  51. package/dist/prisma/index.js +46 -0
  52. package/dist/prisma/index.js.map +1 -0
  53. package/dist/prisma/index.mjs +20 -0
  54. package/dist/prisma/index.mjs.map +1 -0
  55. package/dist/providers/index.d.mts +37 -0
  56. package/dist/providers/index.d.ts +37 -0
  57. package/dist/providers/index.js +97 -0
  58. package/dist/providers/index.js.map +1 -0
  59. package/dist/providers/index.mjs +69 -0
  60. package/dist/providers/index.mjs.map +1 -0
  61. package/dist/sidebar-ttX_iZ40.d.mts +22 -0
  62. package/dist/sidebar-ttX_iZ40.d.ts +22 -0
  63. package/package.json +122 -0
  64. package/prisma/schema.prisma +106 -0
@@ -0,0 +1,733 @@
1
+ "use client";
2
+ "use strict";
3
+ var __create = Object.create;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __export = (target, all) => {
10
+ for (var name in all)
11
+ __defProp(target, name, { get: all[name], enumerable: true });
12
+ };
13
+ var __copyProps = (to, from, except, desc) => {
14
+ if (from && typeof from === "object" || typeof from === "function") {
15
+ for (let key of __getOwnPropNames(from))
16
+ if (!__hasOwnProp.call(to, key) && key !== except)
17
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
18
+ }
19
+ return to;
20
+ };
21
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
22
+ // If the importer is in node compatibility mode or this is not an ESM
23
+ // file that has been converted to a CommonJS file using a Babel-
24
+ // compatible transform (i.e. "__esModule" has not been set), then set
25
+ // "default" to the CommonJS "module.exports" for node compatibility.
26
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
27
+ mod
28
+ ));
29
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
30
+
31
+ // src/components/auth/index.ts
32
+ var auth_exports = {};
33
+ __export(auth_exports, {
34
+ AuthForm: () => AuthForm,
35
+ UserButton: () => UserButton
36
+ });
37
+ module.exports = __toCommonJS(auth_exports);
38
+
39
+ // src/components/ui/avatar.tsx
40
+ var AvatarPrimitive = __toESM(require("@radix-ui/react-avatar"));
41
+
42
+ // src/lib/utils.ts
43
+ var import_clsx = require("clsx");
44
+ var import_tailwind_merge = require("tailwind-merge");
45
+ function cn(...inputs) {
46
+ return (0, import_tailwind_merge.twMerge)((0, import_clsx.clsx)(inputs));
47
+ }
48
+
49
+ // src/components/ui/avatar.tsx
50
+ var import_jsx_runtime = require("react/jsx-runtime");
51
+ function Avatar({
52
+ className,
53
+ ...props
54
+ }) {
55
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
56
+ AvatarPrimitive.Root,
57
+ {
58
+ "data-slot": "avatar",
59
+ className: cn(
60
+ "relative flex size-8 shrink-0 overflow-hidden rounded-full",
61
+ className
62
+ ),
63
+ ...props
64
+ }
65
+ );
66
+ }
67
+ function AvatarImage({
68
+ className,
69
+ ...props
70
+ }) {
71
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
72
+ AvatarPrimitive.Image,
73
+ {
74
+ "data-slot": "avatar-image",
75
+ className: cn("aspect-square size-full", className),
76
+ ...props
77
+ }
78
+ );
79
+ }
80
+ function AvatarFallback({
81
+ className,
82
+ ...props
83
+ }) {
84
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
85
+ AvatarPrimitive.Fallback,
86
+ {
87
+ "data-slot": "avatar-fallback",
88
+ className: cn(
89
+ "bg-muted flex size-full items-center justify-center rounded-full",
90
+ className
91
+ ),
92
+ ...props
93
+ }
94
+ );
95
+ }
96
+
97
+ // src/components/ui/button.tsx
98
+ var import_react_slot = require("@radix-ui/react-slot");
99
+ var import_class_variance_authority = require("class-variance-authority");
100
+ var import_jsx_runtime2 = require("react/jsx-runtime");
101
+ var buttonVariants = (0, import_class_variance_authority.cva)(
102
+ "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
103
+ {
104
+ variants: {
105
+ variant: {
106
+ default: "bg-primary text-primary-foreground hover:bg-primary/90",
107
+ destructive: "bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
108
+ outline: "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50",
109
+ secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
110
+ ghost: "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
111
+ link: "text-primary underline-offset-4 hover:underline"
112
+ },
113
+ size: {
114
+ default: "h-9 px-4 py-2 has-[>svg]:px-3",
115
+ sm: "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5",
116
+ lg: "h-10 rounded-md px-6 has-[>svg]:px-4",
117
+ icon: "size-9",
118
+ "icon-sm": "size-8",
119
+ "icon-lg": "size-10"
120
+ }
121
+ },
122
+ defaultVariants: {
123
+ variant: "default",
124
+ size: "default"
125
+ }
126
+ }
127
+ );
128
+ function Button({
129
+ className,
130
+ variant = "default",
131
+ size = "default",
132
+ asChild = false,
133
+ ...props
134
+ }) {
135
+ const Comp = asChild ? import_react_slot.Slot : "button";
136
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
137
+ Comp,
138
+ {
139
+ "data-slot": "button",
140
+ "data-variant": variant,
141
+ "data-size": size,
142
+ className: cn(buttonVariants({ variant, size, className })),
143
+ ...props
144
+ }
145
+ );
146
+ }
147
+
148
+ // src/components/ui/dropdown-menu.tsx
149
+ var DropdownMenuPrimitive = __toESM(require("@radix-ui/react-dropdown-menu"));
150
+ var import_lucide_react = require("lucide-react");
151
+ var import_jsx_runtime3 = require("react/jsx-runtime");
152
+ function DropdownMenu({
153
+ ...props
154
+ }) {
155
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(DropdownMenuPrimitive.Root, { "data-slot": "dropdown-menu", ...props });
156
+ }
157
+ function DropdownMenuTrigger({
158
+ ...props
159
+ }) {
160
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
161
+ DropdownMenuPrimitive.Trigger,
162
+ {
163
+ "data-slot": "dropdown-menu-trigger",
164
+ ...props
165
+ }
166
+ );
167
+ }
168
+ function DropdownMenuContent({
169
+ className,
170
+ sideOffset = 4,
171
+ ...props
172
+ }) {
173
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(DropdownMenuPrimitive.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
174
+ DropdownMenuPrimitive.Content,
175
+ {
176
+ "data-slot": "dropdown-menu-content",
177
+ sideOffset,
178
+ className: cn(
179
+ "bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 max-h-(--radix-dropdown-menu-content-available-height) min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border p-1 shadow-md",
180
+ className
181
+ ),
182
+ ...props
183
+ }
184
+ ) });
185
+ }
186
+ function DropdownMenuItem({
187
+ className,
188
+ inset,
189
+ variant = "default",
190
+ ...props
191
+ }) {
192
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
193
+ DropdownMenuPrimitive.Item,
194
+ {
195
+ "data-slot": "dropdown-menu-item",
196
+ "data-inset": inset,
197
+ "data-variant": variant,
198
+ className: cn(
199
+ "focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:!text-destructive [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
200
+ className
201
+ ),
202
+ ...props
203
+ }
204
+ );
205
+ }
206
+ function DropdownMenuLabel({
207
+ className,
208
+ inset,
209
+ ...props
210
+ }) {
211
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
212
+ DropdownMenuPrimitive.Label,
213
+ {
214
+ "data-slot": "dropdown-menu-label",
215
+ "data-inset": inset,
216
+ className: cn(
217
+ "px-2 py-1.5 text-sm font-medium data-[inset]:pl-8",
218
+ className
219
+ ),
220
+ ...props
221
+ }
222
+ );
223
+ }
224
+ function DropdownMenuSeparator({
225
+ className,
226
+ ...props
227
+ }) {
228
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
229
+ DropdownMenuPrimitive.Separator,
230
+ {
231
+ "data-slot": "dropdown-menu-separator",
232
+ className: cn("bg-border -mx-1 my-1 h-px", className),
233
+ ...props
234
+ }
235
+ );
236
+ }
237
+
238
+ // src/components/ui/drawer.tsx
239
+ var import_vaul = require("vaul");
240
+ var import_jsx_runtime4 = require("react/jsx-runtime");
241
+ function Drawer({
242
+ ...props
243
+ }) {
244
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_vaul.Drawer.Root, { "data-slot": "drawer", ...props });
245
+ }
246
+ function DrawerTrigger({
247
+ ...props
248
+ }) {
249
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_vaul.Drawer.Trigger, { "data-slot": "drawer-trigger", ...props });
250
+ }
251
+ function DrawerPortal({
252
+ ...props
253
+ }) {
254
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_vaul.Drawer.Portal, { "data-slot": "drawer-portal", ...props });
255
+ }
256
+ function DrawerOverlay({
257
+ className,
258
+ ...props
259
+ }) {
260
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
261
+ import_vaul.Drawer.Overlay,
262
+ {
263
+ "data-slot": "drawer-overlay",
264
+ className: cn(
265
+ "data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50",
266
+ className
267
+ ),
268
+ ...props
269
+ }
270
+ );
271
+ }
272
+ function DrawerContent({
273
+ className,
274
+ children,
275
+ ...props
276
+ }) {
277
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(DrawerPortal, { "data-slot": "drawer-portal", children: [
278
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(DrawerOverlay, {}),
279
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
280
+ import_vaul.Drawer.Content,
281
+ {
282
+ "data-slot": "drawer-content",
283
+ className: cn(
284
+ "group/drawer-content bg-background fixed z-50 flex h-auto flex-col",
285
+ "data-[vaul-drawer-direction=top]:inset-x-0 data-[vaul-drawer-direction=top]:top-0 data-[vaul-drawer-direction=top]:mb-24 data-[vaul-drawer-direction=top]:max-h-[80vh] data-[vaul-drawer-direction=top]:rounded-b-lg data-[vaul-drawer-direction=top]:border-b",
286
+ "data-[vaul-drawer-direction=bottom]:inset-x-0 data-[vaul-drawer-direction=bottom]:bottom-0 data-[vaul-drawer-direction=bottom]:mt-24 data-[vaul-drawer-direction=bottom]:max-h-[80vh] data-[vaul-drawer-direction=bottom]:rounded-t-lg data-[vaul-drawer-direction=bottom]:border-t",
287
+ "data-[vaul-drawer-direction=right]:inset-y-0 data-[vaul-drawer-direction=right]:right-0 data-[vaul-drawer-direction=right]:w-3/4 data-[vaul-drawer-direction=right]:border-l data-[vaul-drawer-direction=right]:sm:max-w-sm",
288
+ "data-[vaul-drawer-direction=left]:inset-y-0 data-[vaul-drawer-direction=left]:left-0 data-[vaul-drawer-direction=left]:w-3/4 data-[vaul-drawer-direction=left]:border-r data-[vaul-drawer-direction=left]:sm:max-w-sm",
289
+ className
290
+ ),
291
+ ...props,
292
+ children: [
293
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "bg-muted mx-auto mt-4 hidden h-2 w-[100px] shrink-0 rounded-full group-data-[vaul-drawer-direction=bottom]/drawer-content:block" }),
294
+ children
295
+ ]
296
+ }
297
+ )
298
+ ] });
299
+ }
300
+ function DrawerHeader({ className, ...props }) {
301
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
302
+ "div",
303
+ {
304
+ "data-slot": "drawer-header",
305
+ className: cn(
306
+ "flex flex-col gap-0.5 p-4 group-data-[vaul-drawer-direction=bottom]/drawer-content:text-center group-data-[vaul-drawer-direction=top]/drawer-content:text-center md:gap-1.5 md:text-left",
307
+ className
308
+ ),
309
+ ...props
310
+ }
311
+ );
312
+ }
313
+ function DrawerTitle({
314
+ className,
315
+ ...props
316
+ }) {
317
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
318
+ import_vaul.Drawer.Title,
319
+ {
320
+ "data-slot": "drawer-title",
321
+ className: cn("text-foreground font-semibold", className),
322
+ ...props
323
+ }
324
+ );
325
+ }
326
+
327
+ // src/components/auth/user-button.tsx
328
+ var import_react = require("next-auth/react");
329
+ var import_lucide_react2 = require("lucide-react");
330
+ var import_link = __toESM(require("next/link"));
331
+
332
+ // src/hooks/use-mobile.ts
333
+ var React = __toESM(require("react"));
334
+ var MOBILE_BREAKPOINT = 768;
335
+ function useIsMobile() {
336
+ const [isMobile, setIsMobile] = React.useState(void 0);
337
+ React.useEffect(() => {
338
+ const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`);
339
+ const onChange = () => {
340
+ setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
341
+ };
342
+ mql.addEventListener("change", onChange);
343
+ setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
344
+ return () => mql.removeEventListener("change", onChange);
345
+ }, []);
346
+ return !!isMobile;
347
+ }
348
+
349
+ // src/components/auth/user-button.tsx
350
+ var import_next_themes = require("next-themes");
351
+ var import_jsx_runtime5 = require("react/jsx-runtime");
352
+ var defaultMenuItems = [
353
+ {
354
+ icon: import_lucide_react2.User,
355
+ label: "Profile",
356
+ href: "/dashboard/settings/profile"
357
+ },
358
+ {
359
+ icon: import_lucide_react2.CreditCard,
360
+ label: "Billing",
361
+ href: "/dashboard/settings/billing"
362
+ },
363
+ {
364
+ icon: import_lucide_react2.Settings,
365
+ label: "Settings",
366
+ href: "/dashboard/settings"
367
+ }
368
+ ];
369
+ function UserButton({
370
+ menuItems = defaultMenuItems,
371
+ signInHref = "/login",
372
+ showThemeToggle = true
373
+ }) {
374
+ const { data: session } = (0, import_react.useSession)();
375
+ const isMobile = useIsMobile();
376
+ const { theme, setTheme } = (0, import_next_themes.useTheme)();
377
+ if (!session?.user) {
378
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Button, { asChild: true, variant: "ghost", size: "sm", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_link.default, { href: signInHref, children: "Sign in" }) });
379
+ }
380
+ const initials = session.user.name?.split(" ").map((n) => n[0]).join("").toUpperCase() || session.user.email?.[0]?.toUpperCase() || "U";
381
+ const toggleTheme = () => {
382
+ setTheme(theme === "dark" ? "light" : "dark");
383
+ };
384
+ const handleSignOut = () => {
385
+ (0, import_react.signOut)({ callbackUrl: "/" });
386
+ };
387
+ const AvatarButton = /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Button, { variant: "ghost", className: "relative h-8 w-8 rounded-full", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Avatar, { className: "h-8 w-8", children: [
388
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
389
+ AvatarImage,
390
+ {
391
+ src: session.user.image || void 0,
392
+ alt: session.user.name || "User"
393
+ }
394
+ ),
395
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(AvatarFallback, { className: "bg-primary/10 text-primary", children: initials })
396
+ ] }) });
397
+ if (isMobile) {
398
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Drawer, { children: [
399
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(DrawerTrigger, { asChild: true, children: AvatarButton }),
400
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(DrawerContent, { children: [
401
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(DrawerHeader, { className: "text-left", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(DrawerTitle, { children: "Account" }) }),
402
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "px-4 pb-8", children: [
403
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "mb-6 flex items-center gap-3", children: [
404
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Avatar, { className: "h-12 w-12", children: [
405
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
406
+ AvatarImage,
407
+ {
408
+ src: session.user.image || void 0,
409
+ alt: session.user.name || "User"
410
+ }
411
+ ),
412
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(AvatarFallback, { className: "bg-primary/10 text-primary text-lg", children: initials })
413
+ ] }),
414
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { children: [
415
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "font-medium", children: session.user.name || "User" }),
416
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "text-sm text-muted-foreground", children: session.user.email })
417
+ ] })
418
+ ] }),
419
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "space-y-1", children: [
420
+ menuItems.map((item) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
421
+ Button,
422
+ {
423
+ variant: "ghost",
424
+ className: "w-full justify-start",
425
+ asChild: true,
426
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_link.default, { href: item.href, children: [
427
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(item.icon, { className: "mr-3 h-4 w-4" }),
428
+ item.label
429
+ ] })
430
+ },
431
+ item.label
432
+ )),
433
+ showThemeToggle && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
434
+ Button,
435
+ {
436
+ variant: "ghost",
437
+ className: "w-full justify-start",
438
+ onClick: toggleTheme,
439
+ children: [
440
+ theme === "dark" ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react2.Sun, { className: "mr-3 h-4 w-4" }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react2.Moon, { className: "mr-3 h-4 w-4" }),
441
+ theme === "dark" ? "Light mode" : "Dark mode"
442
+ ]
443
+ }
444
+ ),
445
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "my-2 border-t" }),
446
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
447
+ Button,
448
+ {
449
+ variant: "ghost",
450
+ className: "w-full justify-start text-destructive hover:text-destructive",
451
+ onClick: handleSignOut,
452
+ children: [
453
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react2.LogOut, { className: "mr-3 h-4 w-4" }),
454
+ "Sign out"
455
+ ]
456
+ }
457
+ )
458
+ ] })
459
+ ] })
460
+ ] })
461
+ ] });
462
+ }
463
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(DropdownMenu, { children: [
464
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(DropdownMenuTrigger, { asChild: true, children: AvatarButton }),
465
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(DropdownMenuContent, { className: "w-56", align: "end", forceMount: true, children: [
466
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(DropdownMenuLabel, { className: "font-normal", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "flex flex-col space-y-1", children: [
467
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "text-sm font-medium leading-none", children: session.user.name || "User" }),
468
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "text-xs leading-none text-muted-foreground", children: session.user.email })
469
+ ] }) }),
470
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(DropdownMenuSeparator, {}),
471
+ menuItems.map((item) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(DropdownMenuItem, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_link.default, { href: item.href, children: [
472
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(item.icon, { className: "mr-2 h-4 w-4" }),
473
+ item.label
474
+ ] }) }, item.label)),
475
+ showThemeToggle && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(DropdownMenuItem, { onClick: toggleTheme, children: [
476
+ theme === "dark" ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react2.Sun, { className: "mr-2 h-4 w-4" }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react2.Moon, { className: "mr-2 h-4 w-4" }),
477
+ theme === "dark" ? "Light mode" : "Dark mode"
478
+ ] }),
479
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(DropdownMenuSeparator, {}),
480
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
481
+ DropdownMenuItem,
482
+ {
483
+ onClick: handleSignOut,
484
+ className: "text-destructive focus:text-destructive",
485
+ children: [
486
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react2.LogOut, { className: "mr-2 h-4 w-4" }),
487
+ "Sign out"
488
+ ]
489
+ }
490
+ )
491
+ ] })
492
+ ] });
493
+ }
494
+
495
+ // src/components/ui/input.tsx
496
+ var import_jsx_runtime6 = require("react/jsx-runtime");
497
+ function Input({ className, type, ...props }) {
498
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
499
+ "input",
500
+ {
501
+ type,
502
+ "data-slot": "input",
503
+ className: cn(
504
+ "file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
505
+ "focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
506
+ "aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
507
+ className
508
+ ),
509
+ ...props
510
+ }
511
+ );
512
+ }
513
+
514
+ // src/components/ui/label.tsx
515
+ var LabelPrimitive = __toESM(require("@radix-ui/react-label"));
516
+ var import_jsx_runtime7 = require("react/jsx-runtime");
517
+ function Label2({
518
+ className,
519
+ ...props
520
+ }) {
521
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
522
+ LabelPrimitive.Root,
523
+ {
524
+ "data-slot": "label",
525
+ className: cn(
526
+ "flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50",
527
+ className
528
+ ),
529
+ ...props
530
+ }
531
+ );
532
+ }
533
+
534
+ // src/components/ui/separator.tsx
535
+ var SeparatorPrimitive = __toESM(require("@radix-ui/react-separator"));
536
+ var import_jsx_runtime8 = require("react/jsx-runtime");
537
+ function Separator2({
538
+ className,
539
+ orientation = "horizontal",
540
+ decorative = true,
541
+ ...props
542
+ }) {
543
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
544
+ SeparatorPrimitive.Root,
545
+ {
546
+ "data-slot": "separator",
547
+ decorative,
548
+ orientation,
549
+ className: cn(
550
+ "bg-border shrink-0 data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px",
551
+ className
552
+ ),
553
+ ...props
554
+ }
555
+ );
556
+ }
557
+
558
+ // src/components/auth/auth-form.tsx
559
+ var import_react2 = require("next-auth/react");
560
+ var import_react3 = require("react");
561
+ var import_lucide_react3 = require("lucide-react");
562
+ var import_link2 = __toESM(require("next/link"));
563
+ var import_navigation = require("next/navigation");
564
+ var import_jsx_runtime9 = require("react/jsx-runtime");
565
+ function AuthForm({
566
+ mode,
567
+ providers = ["google", "email"],
568
+ signupHref = "/signup",
569
+ loginHref = "/login",
570
+ verifyRequestHref = "/verify-request",
571
+ defaultCallbackUrl = "/dashboard"
572
+ }) {
573
+ const [email, setEmail] = (0, import_react3.useState)("");
574
+ const [isLoading, setIsLoading] = (0, import_react3.useState)(false);
575
+ const [isGoogleLoading, setIsGoogleLoading] = (0, import_react3.useState)(false);
576
+ const [isGithubLoading, setIsGithubLoading] = (0, import_react3.useState)(false);
577
+ const [error, setError] = (0, import_react3.useState)("");
578
+ const searchParams = (0, import_navigation.useSearchParams)();
579
+ const callbackUrl = searchParams.get("callbackUrl") || defaultCallbackUrl;
580
+ const isLogin = mode === "login";
581
+ const showGoogle = providers.includes("google");
582
+ const showGithub = providers.includes("github");
583
+ const showEmail = providers.includes("email");
584
+ const handleEmailSubmit = async (e) => {
585
+ e.preventDefault();
586
+ setIsLoading(true);
587
+ setError("");
588
+ try {
589
+ const result = await (0, import_react2.signIn)("resend", {
590
+ email,
591
+ callbackUrl,
592
+ redirect: false
593
+ });
594
+ if (result?.error) {
595
+ setError("Failed to send magic link. Please try again.");
596
+ } else {
597
+ window.location.href = verifyRequestHref;
598
+ }
599
+ } catch {
600
+ setError("Something went wrong");
601
+ } finally {
602
+ setIsLoading(false);
603
+ }
604
+ };
605
+ const handleGoogleSignIn = async () => {
606
+ setIsGoogleLoading(true);
607
+ try {
608
+ await (0, import_react2.signIn)("google", {
609
+ callbackUrl
610
+ });
611
+ } catch (error2) {
612
+ console.error("Google sign in error:", error2);
613
+ } finally {
614
+ setIsGoogleLoading(false);
615
+ }
616
+ };
617
+ const handleGithubSignIn = async () => {
618
+ setIsGithubLoading(true);
619
+ try {
620
+ await (0, import_react2.signIn)("github", {
621
+ callbackUrl
622
+ });
623
+ } catch (error2) {
624
+ console.error("GitHub sign in error:", error2);
625
+ } finally {
626
+ setIsGithubLoading(false);
627
+ }
628
+ };
629
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "space-y-6", children: [
630
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "space-y-2 text-center", children: [
631
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("h1", { className: "text-2xl font-semibold tracking-tight", children: isLogin ? "Welcome back" : "Create an account" }),
632
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("p", { className: "text-sm text-muted-foreground", children: isLogin ? "Sign in to your account to continue" : "Enter your email to get started" })
633
+ ] }),
634
+ error && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "p-3 text-sm text-destructive bg-destructive/10 rounded-md", children: error }),
635
+ showGoogle && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
636
+ Button,
637
+ {
638
+ type: "button",
639
+ variant: "outline",
640
+ className: "w-full",
641
+ onClick: handleGoogleSignIn,
642
+ disabled: isGoogleLoading,
643
+ children: [
644
+ isGoogleLoading ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react3.Loader2, { className: "mr-2 h-4 w-4 animate-spin" }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("svg", { className: "mr-2 h-4 w-4", viewBox: "0 0 24 24", children: [
645
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
646
+ "path",
647
+ {
648
+ d: "M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z",
649
+ fill: "#4285F4"
650
+ }
651
+ ),
652
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
653
+ "path",
654
+ {
655
+ d: "M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z",
656
+ fill: "#34A853"
657
+ }
658
+ ),
659
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
660
+ "path",
661
+ {
662
+ d: "M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z",
663
+ fill: "#FBBC05"
664
+ }
665
+ ),
666
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
667
+ "path",
668
+ {
669
+ d: "M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z",
670
+ fill: "#EA4335"
671
+ }
672
+ )
673
+ ] }),
674
+ "Continue with Google"
675
+ ]
676
+ }
677
+ ),
678
+ showGithub && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
679
+ Button,
680
+ {
681
+ type: "button",
682
+ variant: "outline",
683
+ className: "w-full",
684
+ onClick: handleGithubSignIn,
685
+ disabled: isGithubLoading,
686
+ children: [
687
+ isGithubLoading ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react3.Loader2, { className: "mr-2 h-4 w-4 animate-spin" }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("svg", { className: "mr-2 h-4 w-4", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("path", { d: "M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z" }) }),
688
+ "Continue with GitHub"
689
+ ]
690
+ }
691
+ ),
692
+ showEmail && (showGoogle || showGithub) && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "relative", children: [
693
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "absolute inset-0 flex items-center", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Separator2, { className: "w-full" }) }),
694
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "relative flex justify-center text-xs uppercase", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "bg-background px-2 text-muted-foreground", children: "Or continue with email" }) })
695
+ ] }),
696
+ showEmail && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("form", { onSubmit: handleEmailSubmit, className: "space-y-4", children: [
697
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "space-y-2", children: [
698
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Label2, { htmlFor: "email", children: "Email" }),
699
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
700
+ Input,
701
+ {
702
+ id: "email",
703
+ type: "email",
704
+ placeholder: "name@example.com",
705
+ value: email,
706
+ onChange: (e) => setEmail(e.target.value),
707
+ required: true,
708
+ disabled: isLoading
709
+ }
710
+ )
711
+ ] }),
712
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Button, { type: "submit", className: "w-full", disabled: isLoading, children: isLoading ? /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
713
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react3.Loader2, { className: "mr-2 h-4 w-4 animate-spin" }),
714
+ "Sending magic link..."
715
+ ] }) : "Send magic link" })
716
+ ] }),
717
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("p", { className: "text-center text-sm text-muted-foreground", children: isLogin ? /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
718
+ "Don't have an account?",
719
+ " ",
720
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_link2.default, { href: signupHref, className: "text-primary hover:underline", children: "Sign up" })
721
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
722
+ "Already have an account?",
723
+ " ",
724
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_link2.default, { href: loginHref, className: "text-primary hover:underline", children: "Sign in" })
725
+ ] }) })
726
+ ] });
727
+ }
728
+ // Annotate the CommonJS export names for ESM import in node:
729
+ 0 && (module.exports = {
730
+ AuthForm,
731
+ UserButton
732
+ });
733
+ //# sourceMappingURL=index.js.map