@greatapps/greatauth-ui 0.1.0 → 0.1.4

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
@@ -79,13 +79,1301 @@ function createUseAuth(config) {
79
79
  };
80
80
  }
81
81
 
82
+ // src/components/ui/tooltip.tsx
83
+ import { Tooltip as TooltipPrimitive } from "radix-ui";
84
+
82
85
  // src/lib/utils.ts
83
86
  import { clsx } from "clsx";
84
87
  import { twMerge } from "tailwind-merge";
85
88
  function cn(...inputs) {
86
89
  return twMerge(clsx(inputs));
87
90
  }
91
+
92
+ // src/components/ui/tooltip.tsx
93
+ import { jsx, jsxs } from "react/jsx-runtime";
94
+ function TooltipProvider({
95
+ delayDuration = 0,
96
+ ...props
97
+ }) {
98
+ return /* @__PURE__ */ jsx(
99
+ TooltipPrimitive.Provider,
100
+ {
101
+ "data-slot": "tooltip-provider",
102
+ delayDuration,
103
+ ...props
104
+ }
105
+ );
106
+ }
107
+ function Tooltip({
108
+ ...props
109
+ }) {
110
+ return /* @__PURE__ */ jsx(TooltipPrimitive.Root, { "data-slot": "tooltip", ...props });
111
+ }
112
+ function TooltipTrigger({
113
+ ...props
114
+ }) {
115
+ return /* @__PURE__ */ jsx(TooltipPrimitive.Trigger, { "data-slot": "tooltip-trigger", ...props });
116
+ }
117
+ function TooltipContent({
118
+ className,
119
+ sideOffset = 0,
120
+ children,
121
+ ...props
122
+ }) {
123
+ return /* @__PURE__ */ jsx(TooltipPrimitive.Portal, { children: /* @__PURE__ */ jsxs(
124
+ TooltipPrimitive.Content,
125
+ {
126
+ "data-slot": "tooltip-content",
127
+ sideOffset,
128
+ className: cn(
129
+ "data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-[state=delayed-open]:animate-in data-[state=delayed-open]:fade-in-0 data-[state=delayed-open]:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-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 rounded-md px-3 py-1.5 text-xs bg-foreground text-background z-50 w-fit max-w-xs origin-(--radix-tooltip-content-transform-origin)",
130
+ className
131
+ ),
132
+ ...props,
133
+ children: [
134
+ children,
135
+ /* @__PURE__ */ jsx(TooltipPrimitive.Arrow, { className: "size-2.5 rotate-45 rounded-[2px] bg-foreground fill-foreground z-50 translate-y-[calc(-50%_-_2px)]" })
136
+ ]
137
+ }
138
+ ) });
139
+ }
140
+
141
+ // src/components/ui/sidebar.tsx
142
+ import * as React from "react";
143
+ import { cva as cva2 } from "class-variance-authority";
144
+ import { Slot as Slot2 } from "radix-ui";
145
+ import { PanelLeft } from "lucide-react";
146
+
147
+ // src/hooks/use-mobile.ts
148
+ import { useEffect, useState } from "react";
149
+ var MOBILE_BREAKPOINT = 768;
150
+ function useIsMobile() {
151
+ const [isMobile, setIsMobile] = useState(void 0);
152
+ useEffect(() => {
153
+ const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`);
154
+ const onChange = () => setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
155
+ mql.addEventListener("change", onChange);
156
+ setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
157
+ return () => mql.removeEventListener("change", onChange);
158
+ }, []);
159
+ return !!isMobile;
160
+ }
161
+
162
+ // src/components/ui/button.tsx
163
+ import { cva } from "class-variance-authority";
164
+ import { Slot } from "radix-ui";
165
+ import { jsx as jsx2 } from "react/jsx-runtime";
166
+ var buttonVariants = cva(
167
+ "focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-md border border-transparent bg-clip-padding text-sm font-medium focus-visible:ring-3 aria-invalid:ring-3 [&_svg:not([class*='size-'])]:size-4 inline-flex items-center justify-center whitespace-nowrap transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none shrink-0 [&_svg]:shrink-0 outline-none group/button select-none",
168
+ {
169
+ variants: {
170
+ variant: {
171
+ default: "bg-primary text-primary-foreground hover:bg-primary/80",
172
+ outline: "border-border bg-background hover:bg-muted hover:text-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50 aria-expanded:bg-muted aria-expanded:text-foreground shadow-xs",
173
+ secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80 aria-expanded:bg-secondary aria-expanded:text-secondary-foreground",
174
+ ghost: "hover:bg-muted hover:text-foreground dark:hover:bg-muted/50 aria-expanded:bg-muted aria-expanded:text-foreground",
175
+ destructive: "bg-destructive/10 hover:bg-destructive/20 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/20 text-destructive focus-visible:border-destructive/40 dark:hover:bg-destructive/30",
176
+ link: "text-primary underline-offset-4 hover:underline"
177
+ },
178
+ size: {
179
+ default: "h-9 gap-1.5 px-2.5 in-data-[slot=button-group]:rounded-md has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2",
180
+ xs: "h-6 gap-1 rounded-[min(var(--radius-md),8px)] px-2 text-xs in-data-[slot=button-group]:rounded-md has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3",
181
+ sm: "h-8 gap-1 rounded-[min(var(--radius-md),10px)] px-2.5 in-data-[slot=button-group]:rounded-md has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5",
182
+ lg: "h-10 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-3 has-data-[icon=inline-start]:pl-3",
183
+ icon: "size-9",
184
+ "icon-xs": "size-6 rounded-[min(var(--radius-md),8px)] in-data-[slot=button-group]:rounded-md [&_svg:not([class*='size-'])]:size-3",
185
+ "icon-sm": "size-8 rounded-[min(var(--radius-md),10px)] in-data-[slot=button-group]:rounded-md",
186
+ "icon-lg": "size-10"
187
+ }
188
+ },
189
+ defaultVariants: {
190
+ variant: "default",
191
+ size: "default"
192
+ }
193
+ }
194
+ );
195
+ function Button({
196
+ className,
197
+ variant = "default",
198
+ size = "default",
199
+ asChild = false,
200
+ ...props
201
+ }) {
202
+ const Comp = asChild ? Slot.Root : "button";
203
+ return /* @__PURE__ */ jsx2(
204
+ Comp,
205
+ {
206
+ "data-slot": "button",
207
+ "data-variant": variant,
208
+ "data-size": size,
209
+ className: cn(buttonVariants({ variant, size, className })),
210
+ ...props
211
+ }
212
+ );
213
+ }
214
+
215
+ // src/components/ui/input.tsx
216
+ import { jsx as jsx3 } from "react/jsx-runtime";
217
+ function Input({ className, type, ...props }) {
218
+ return /* @__PURE__ */ jsx3(
219
+ "input",
220
+ {
221
+ type,
222
+ "data-slot": "input",
223
+ className: cn(
224
+ "dark:bg-input/30 border-input focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 h-9 rounded-md border bg-transparent px-2.5 py-1 text-base shadow-xs transition-[color,box-shadow] file:h-7 file:text-sm file:font-medium focus-visible:ring-3 aria-invalid:ring-3 md:text-sm file:text-foreground placeholder:text-muted-foreground w-full min-w-0 outline-none file:inline-flex file:border-0 file:bg-transparent disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50",
225
+ className
226
+ ),
227
+ ...props
228
+ }
229
+ );
230
+ }
231
+
232
+ // src/components/ui/separator.tsx
233
+ import { Separator as SeparatorPrimitive } from "radix-ui";
234
+ import { jsx as jsx4 } from "react/jsx-runtime";
235
+ function Separator({
236
+ className,
237
+ orientation = "horizontal",
238
+ decorative = true,
239
+ ...props
240
+ }) {
241
+ return /* @__PURE__ */ jsx4(
242
+ SeparatorPrimitive.Root,
243
+ {
244
+ "data-slot": "separator",
245
+ decorative,
246
+ orientation,
247
+ className: cn(
248
+ "bg-border shrink-0 data-horizontal:h-px data-horizontal:w-full data-vertical:w-px data-vertical:self-stretch",
249
+ className
250
+ ),
251
+ ...props
252
+ }
253
+ );
254
+ }
255
+
256
+ // src/components/ui/sheet.tsx
257
+ import { Dialog as SheetPrimitive } from "radix-ui";
258
+ import { X } from "lucide-react";
259
+ import { jsx as jsx5, jsxs as jsxs2 } from "react/jsx-runtime";
260
+ function Sheet({ ...props }) {
261
+ return /* @__PURE__ */ jsx5(SheetPrimitive.Root, { "data-slot": "sheet", ...props });
262
+ }
263
+ function SheetPortal({
264
+ ...props
265
+ }) {
266
+ return /* @__PURE__ */ jsx5(SheetPrimitive.Portal, { "data-slot": "sheet-portal", ...props });
267
+ }
268
+ function SheetOverlay({
269
+ className,
270
+ ...props
271
+ }) {
272
+ return /* @__PURE__ */ jsx5(
273
+ SheetPrimitive.Overlay,
274
+ {
275
+ "data-slot": "sheet-overlay",
276
+ className: cn("data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 bg-black/10 duration-100 data-ending-style:opacity-0 data-starting-style:opacity-0 supports-backdrop-filter:backdrop-blur-xs fixed inset-0 z-50", className),
277
+ ...props
278
+ }
279
+ );
280
+ }
281
+ function SheetContent({
282
+ className,
283
+ children,
284
+ side = "right",
285
+ showCloseButton = true,
286
+ ...props
287
+ }) {
288
+ return /* @__PURE__ */ jsxs2(SheetPortal, { children: [
289
+ /* @__PURE__ */ jsx5(SheetOverlay, {}),
290
+ /* @__PURE__ */ jsxs2(
291
+ SheetPrimitive.Content,
292
+ {
293
+ "data-slot": "sheet-content",
294
+ "data-side": side,
295
+ className: cn("bg-background data-open:animate-in data-closed:animate-out data-[side=right]:data-closed:slide-out-to-right-10 data-[side=right]:data-open:slide-in-from-right-10 data-[side=left]:data-closed:slide-out-to-left-10 data-[side=left]:data-open:slide-in-from-left-10 data-[side=top]:data-closed:slide-out-to-top-10 data-[side=top]:data-open:slide-in-from-top-10 data-closed:fade-out-0 data-open:fade-in-0 data-[side=bottom]:data-closed:slide-out-to-bottom-10 data-[side=bottom]:data-open:slide-in-from-bottom-10 fixed z-50 flex flex-col gap-4 bg-clip-padding text-sm shadow-lg transition duration-200 ease-in-out data-[side=bottom]:inset-x-0 data-[side=bottom]:bottom-0 data-[side=bottom]:h-auto data-[side=bottom]:border-t data-[side=left]:inset-y-0 data-[side=left]:left-0 data-[side=left]:h-full data-[side=left]:w-3/4 data-[side=left]:border-r data-[side=right]:inset-y-0 data-[side=right]:right-0 data-[side=right]:h-full data-[side=right]:w-3/4 data-[side=right]:border-l data-[side=top]:inset-x-0 data-[side=top]:top-0 data-[side=top]:h-auto data-[side=top]:border-b data-[side=left]:sm:max-w-sm data-[side=right]:sm:max-w-sm", className),
296
+ ...props,
297
+ children: [
298
+ children,
299
+ showCloseButton && /* @__PURE__ */ jsx5(SheetPrimitive.Close, { "data-slot": "sheet-close", asChild: true, children: /* @__PURE__ */ jsxs2(Button, { variant: "ghost", className: "absolute top-4 right-4", size: "icon-sm", children: [
300
+ /* @__PURE__ */ jsx5(X, {}),
301
+ /* @__PURE__ */ jsx5("span", { className: "sr-only", children: "Close" })
302
+ ] }) })
303
+ ]
304
+ }
305
+ )
306
+ ] });
307
+ }
308
+ function SheetHeader({ className, ...props }) {
309
+ return /* @__PURE__ */ jsx5(
310
+ "div",
311
+ {
312
+ "data-slot": "sheet-header",
313
+ className: cn("gap-1.5 p-4 flex flex-col", className),
314
+ ...props
315
+ }
316
+ );
317
+ }
318
+ function SheetTitle({
319
+ className,
320
+ ...props
321
+ }) {
322
+ return /* @__PURE__ */ jsx5(
323
+ SheetPrimitive.Title,
324
+ {
325
+ "data-slot": "sheet-title",
326
+ className: cn("text-foreground font-medium", className),
327
+ ...props
328
+ }
329
+ );
330
+ }
331
+ function SheetDescription({
332
+ className,
333
+ ...props
334
+ }) {
335
+ return /* @__PURE__ */ jsx5(
336
+ SheetPrimitive.Description,
337
+ {
338
+ "data-slot": "sheet-description",
339
+ className: cn("text-muted-foreground text-sm", className),
340
+ ...props
341
+ }
342
+ );
343
+ }
344
+
345
+ // src/components/ui/skeleton.tsx
346
+ import { jsx as jsx6 } from "react/jsx-runtime";
347
+
348
+ // src/components/ui/sidebar.tsx
349
+ import { jsx as jsx7, jsxs as jsxs3 } from "react/jsx-runtime";
350
+ var SIDEBAR_COOKIE_NAME = "sidebar_state";
351
+ var SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7;
352
+ var SIDEBAR_WIDTH = "16rem";
353
+ var SIDEBAR_WIDTH_MOBILE = "18rem";
354
+ var SIDEBAR_WIDTH_ICON = "3rem";
355
+ var SIDEBAR_KEYBOARD_SHORTCUT = "b";
356
+ var SidebarContext = React.createContext(null);
357
+ function useSidebar() {
358
+ const context = React.useContext(SidebarContext);
359
+ if (!context) {
360
+ throw new Error("useSidebar must be used within a SidebarProvider.");
361
+ }
362
+ return context;
363
+ }
364
+ function SidebarProvider({
365
+ defaultOpen = true,
366
+ open: openProp,
367
+ onOpenChange: setOpenProp,
368
+ className,
369
+ style,
370
+ children,
371
+ ...props
372
+ }) {
373
+ const isMobile = useIsMobile();
374
+ const [openMobile, setOpenMobile] = React.useState(false);
375
+ const [_open, _setOpen] = React.useState(defaultOpen);
376
+ const open = openProp ?? _open;
377
+ const setOpen = React.useCallback(
378
+ (value) => {
379
+ const openState = typeof value === "function" ? value(open) : value;
380
+ if (setOpenProp) {
381
+ setOpenProp(openState);
382
+ } else {
383
+ _setOpen(openState);
384
+ }
385
+ document.cookie = `${SIDEBAR_COOKIE_NAME}=${openState}; path=/; max-age=${SIDEBAR_COOKIE_MAX_AGE}`;
386
+ },
387
+ [setOpenProp, open]
388
+ );
389
+ const toggleSidebar = React.useCallback(() => {
390
+ return isMobile ? setOpenMobile((open2) => !open2) : setOpen((open2) => !open2);
391
+ }, [isMobile, setOpen, setOpenMobile]);
392
+ React.useEffect(() => {
393
+ const handleKeyDown = (event) => {
394
+ if (event.key === SIDEBAR_KEYBOARD_SHORTCUT && (event.metaKey || event.ctrlKey)) {
395
+ event.preventDefault();
396
+ toggleSidebar();
397
+ }
398
+ };
399
+ window.addEventListener("keydown", handleKeyDown);
400
+ return () => window.removeEventListener("keydown", handleKeyDown);
401
+ }, [toggleSidebar]);
402
+ const state = open ? "expanded" : "collapsed";
403
+ const contextValue = React.useMemo(
404
+ () => ({
405
+ state,
406
+ open,
407
+ setOpen,
408
+ isMobile,
409
+ openMobile,
410
+ setOpenMobile,
411
+ toggleSidebar
412
+ }),
413
+ [state, open, setOpen, isMobile, openMobile, setOpenMobile, toggleSidebar]
414
+ );
415
+ return /* @__PURE__ */ jsx7(SidebarContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx7(
416
+ "div",
417
+ {
418
+ "data-slot": "sidebar-wrapper",
419
+ style: {
420
+ "--sidebar-width": SIDEBAR_WIDTH,
421
+ "--sidebar-width-icon": SIDEBAR_WIDTH_ICON,
422
+ ...style
423
+ },
424
+ className: cn(
425
+ "group/sidebar-wrapper has-data-[variant=inset]:bg-sidebar flex min-h-svh w-full",
426
+ className
427
+ ),
428
+ ...props,
429
+ children
430
+ }
431
+ ) });
432
+ }
433
+ function Sidebar({
434
+ side = "left",
435
+ variant = "sidebar",
436
+ collapsible = "offcanvas",
437
+ className,
438
+ children,
439
+ dir,
440
+ ...props
441
+ }) {
442
+ const { isMobile, state, openMobile, setOpenMobile } = useSidebar();
443
+ if (collapsible === "none") {
444
+ return /* @__PURE__ */ jsx7(
445
+ "div",
446
+ {
447
+ "data-slot": "sidebar",
448
+ className: cn(
449
+ "bg-sidebar text-sidebar-foreground flex h-full w-(--sidebar-width) flex-col",
450
+ className
451
+ ),
452
+ ...props,
453
+ children
454
+ }
455
+ );
456
+ }
457
+ if (isMobile) {
458
+ return /* @__PURE__ */ jsx7(Sheet, { open: openMobile, onOpenChange: setOpenMobile, ...props, children: /* @__PURE__ */ jsxs3(
459
+ SheetContent,
460
+ {
461
+ dir,
462
+ "data-sidebar": "sidebar",
463
+ "data-slot": "sidebar",
464
+ "data-mobile": "true",
465
+ className: "bg-sidebar text-sidebar-foreground w-(--sidebar-width) p-0 [&>button]:hidden",
466
+ style: {
467
+ "--sidebar-width": SIDEBAR_WIDTH_MOBILE
468
+ },
469
+ side,
470
+ children: [
471
+ /* @__PURE__ */ jsxs3(SheetHeader, { className: "sr-only", children: [
472
+ /* @__PURE__ */ jsx7(SheetTitle, { children: "Sidebar" }),
473
+ /* @__PURE__ */ jsx7(SheetDescription, { children: "Displays the mobile sidebar." })
474
+ ] }),
475
+ /* @__PURE__ */ jsx7("div", { className: "flex h-full w-full flex-col", children })
476
+ ]
477
+ }
478
+ ) });
479
+ }
480
+ return /* @__PURE__ */ jsxs3(
481
+ "div",
482
+ {
483
+ className: "group peer text-sidebar-foreground hidden md:block",
484
+ "data-state": state,
485
+ "data-collapsible": state === "collapsed" ? collapsible : "",
486
+ "data-variant": variant,
487
+ "data-side": side,
488
+ "data-slot": "sidebar",
489
+ children: [
490
+ /* @__PURE__ */ jsx7(
491
+ "div",
492
+ {
493
+ "data-slot": "sidebar-gap",
494
+ className: cn(
495
+ "transition-[width] duration-200 ease-linear relative w-(--sidebar-width) bg-transparent",
496
+ "group-data-[collapsible=offcanvas]:w-0",
497
+ "group-data-[side=right]:rotate-180",
498
+ variant === "floating" || variant === "inset" ? "group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4)))]" : "group-data-[collapsible=icon]:w-(--sidebar-width-icon)"
499
+ )
500
+ }
501
+ ),
502
+ /* @__PURE__ */ jsx7(
503
+ "div",
504
+ {
505
+ "data-slot": "sidebar-container",
506
+ "data-side": side,
507
+ className: cn(
508
+ "fixed inset-y-0 z-10 hidden h-svh w-(--sidebar-width) transition-[left,right,width] duration-200 ease-linear data-[side=left]:left-0 data-[side=left]:group-data-[collapsible=offcanvas]:left-[calc(var(--sidebar-width)*-1)] data-[side=right]:right-0 data-[side=right]:group-data-[collapsible=offcanvas]:right-[calc(var(--sidebar-width)*-1)] md:flex",
509
+ // Adjust the padding for floating and inset variants.
510
+ variant === "floating" || variant === "inset" ? "p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4))+2px)]" : "group-data-[collapsible=icon]:w-(--sidebar-width-icon) group-data-[side=left]:border-r group-data-[side=right]:border-l",
511
+ className
512
+ ),
513
+ ...props,
514
+ children: /* @__PURE__ */ jsx7(
515
+ "div",
516
+ {
517
+ "data-sidebar": "sidebar",
518
+ "data-slot": "sidebar-inner",
519
+ className: "bg-sidebar group-data-[variant=floating]:ring-sidebar-border group-data-[variant=floating]:rounded-lg group-data-[variant=floating]:shadow-sm group-data-[variant=floating]:ring-1 flex size-full flex-col",
520
+ children
521
+ }
522
+ )
523
+ }
524
+ )
525
+ ]
526
+ }
527
+ );
528
+ }
529
+ function SidebarTrigger({
530
+ className,
531
+ onClick,
532
+ ...props
533
+ }) {
534
+ const { toggleSidebar } = useSidebar();
535
+ return /* @__PURE__ */ jsxs3(
536
+ Button,
537
+ {
538
+ "data-sidebar": "trigger",
539
+ "data-slot": "sidebar-trigger",
540
+ variant: "ghost",
541
+ size: "icon-sm",
542
+ className: cn(className),
543
+ onClick: (event) => {
544
+ onClick?.(event);
545
+ toggleSidebar();
546
+ },
547
+ ...props,
548
+ children: [
549
+ /* @__PURE__ */ jsx7(PanelLeft, {}),
550
+ /* @__PURE__ */ jsx7("span", { className: "sr-only", children: "Toggle Sidebar" })
551
+ ]
552
+ }
553
+ );
554
+ }
555
+ function SidebarInset({ className, ...props }) {
556
+ return /* @__PURE__ */ jsx7(
557
+ "main",
558
+ {
559
+ "data-slot": "sidebar-inset",
560
+ className: cn(
561
+ "bg-background md:peer-data-[variant=inset]:m-2 md:peer-data-[variant=inset]:ml-0 md:peer-data-[variant=inset]:rounded-xl md:peer-data-[variant=inset]:shadow-sm md:peer-data-[variant=inset]:peer-data-[state=collapsed]:ml-2 relative flex w-full flex-1 flex-col",
562
+ className
563
+ ),
564
+ ...props
565
+ }
566
+ );
567
+ }
568
+ function SidebarHeader({ className, ...props }) {
569
+ return /* @__PURE__ */ jsx7(
570
+ "div",
571
+ {
572
+ "data-slot": "sidebar-header",
573
+ "data-sidebar": "header",
574
+ className: cn("gap-2 p-2 flex flex-col", className),
575
+ ...props
576
+ }
577
+ );
578
+ }
579
+ function SidebarFooter({ className, ...props }) {
580
+ return /* @__PURE__ */ jsx7(
581
+ "div",
582
+ {
583
+ "data-slot": "sidebar-footer",
584
+ "data-sidebar": "footer",
585
+ className: cn("gap-2 p-2 flex flex-col", className),
586
+ ...props
587
+ }
588
+ );
589
+ }
590
+ function SidebarContent({ className, ...props }) {
591
+ return /* @__PURE__ */ jsx7(
592
+ "div",
593
+ {
594
+ "data-slot": "sidebar-content",
595
+ "data-sidebar": "content",
596
+ className: cn(
597
+ "no-scrollbar gap-2 flex min-h-0 flex-1 flex-col overflow-auto group-data-[collapsible=icon]:overflow-hidden",
598
+ className
599
+ ),
600
+ ...props
601
+ }
602
+ );
603
+ }
604
+ function SidebarGroup({ className, ...props }) {
605
+ return /* @__PURE__ */ jsx7(
606
+ "div",
607
+ {
608
+ "data-slot": "sidebar-group",
609
+ "data-sidebar": "group",
610
+ className: cn(
611
+ "p-2 relative flex w-full min-w-0 flex-col",
612
+ className
613
+ ),
614
+ ...props
615
+ }
616
+ );
617
+ }
618
+ function SidebarGroupLabel({
619
+ className,
620
+ asChild = false,
621
+ ...props
622
+ }) {
623
+ const Comp = asChild ? Slot2.Root : "div";
624
+ return /* @__PURE__ */ jsx7(
625
+ Comp,
626
+ {
627
+ "data-slot": "sidebar-group-label",
628
+ "data-sidebar": "group-label",
629
+ className: cn(
630
+ "text-sidebar-foreground/70 ring-sidebar-ring h-8 rounded-md px-2 text-xs font-medium transition-[margin,opacity] duration-200 ease-linear group-data-[collapsible=icon]:-mt-8 group-data-[collapsible=icon]:opacity-0 focus-visible:ring-2 [&>svg]:size-4 flex shrink-0 items-center outline-hidden [&>svg]:shrink-0",
631
+ className
632
+ ),
633
+ ...props
634
+ }
635
+ );
636
+ }
637
+ function SidebarGroupContent({
638
+ className,
639
+ ...props
640
+ }) {
641
+ return /* @__PURE__ */ jsx7(
642
+ "div",
643
+ {
644
+ "data-slot": "sidebar-group-content",
645
+ "data-sidebar": "group-content",
646
+ className: cn("text-sm w-full", className),
647
+ ...props
648
+ }
649
+ );
650
+ }
651
+ function SidebarMenu({ className, ...props }) {
652
+ return /* @__PURE__ */ jsx7(
653
+ "ul",
654
+ {
655
+ "data-slot": "sidebar-menu",
656
+ "data-sidebar": "menu",
657
+ className: cn("gap-1 flex w-full min-w-0 flex-col", className),
658
+ ...props
659
+ }
660
+ );
661
+ }
662
+ function SidebarMenuItem({ className, ...props }) {
663
+ return /* @__PURE__ */ jsx7(
664
+ "li",
665
+ {
666
+ "data-slot": "sidebar-menu-item",
667
+ "data-sidebar": "menu-item",
668
+ className: cn("group/menu-item relative", className),
669
+ ...props
670
+ }
671
+ );
672
+ }
673
+ var sidebarMenuButtonVariants = cva2(
674
+ "ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground active:bg-sidebar-accent active:text-sidebar-accent-foreground data-active:bg-sidebar-accent data-active:text-sidebar-accent-foreground data-open:hover:bg-sidebar-accent data-open:hover:text-sidebar-accent-foreground gap-2 rounded-md p-2 text-left text-sm transition-[width,height,padding] group-has-data-[sidebar=menu-action]/menu-item:pr-8 group-data-[collapsible=icon]:size-8! group-data-[collapsible=icon]:p-2! focus-visible:ring-2 data-active:font-medium peer/menu-button flex w-full items-center overflow-hidden outline-hidden group/menu-button disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&>span:last-child]:truncate [&_svg]:size-4 [&_svg]:shrink-0",
675
+ {
676
+ variants: {
677
+ variant: {
678
+ default: "hover:bg-sidebar-accent hover:text-sidebar-accent-foreground",
679
+ outline: "bg-background hover:bg-sidebar-accent hover:text-sidebar-accent-foreground shadow-[0_0_0_1px_hsl(var(--sidebar-border))] hover:shadow-[0_0_0_1px_hsl(var(--sidebar-accent))]"
680
+ },
681
+ size: {
682
+ default: "h-8 text-sm",
683
+ sm: "h-7 text-xs",
684
+ lg: "h-12 text-sm group-data-[collapsible=icon]:p-0!"
685
+ }
686
+ },
687
+ defaultVariants: {
688
+ variant: "default",
689
+ size: "default"
690
+ }
691
+ }
692
+ );
693
+ function SidebarMenuButton({
694
+ asChild = false,
695
+ isActive = false,
696
+ variant = "default",
697
+ size = "default",
698
+ tooltip,
699
+ className,
700
+ ...props
701
+ }) {
702
+ const Comp = asChild ? Slot2.Root : "button";
703
+ const { isMobile, state } = useSidebar();
704
+ const button = /* @__PURE__ */ jsx7(
705
+ Comp,
706
+ {
707
+ "data-slot": "sidebar-menu-button",
708
+ "data-sidebar": "menu-button",
709
+ "data-size": size,
710
+ "data-active": isActive,
711
+ className: cn(sidebarMenuButtonVariants({ variant, size }), className),
712
+ ...props
713
+ }
714
+ );
715
+ if (!tooltip) {
716
+ return button;
717
+ }
718
+ if (typeof tooltip === "string") {
719
+ tooltip = {
720
+ children: tooltip
721
+ };
722
+ }
723
+ return /* @__PURE__ */ jsxs3(Tooltip, { children: [
724
+ /* @__PURE__ */ jsx7(TooltipTrigger, { asChild: true, children: button }),
725
+ /* @__PURE__ */ jsx7(
726
+ TooltipContent,
727
+ {
728
+ side: "right",
729
+ align: "center",
730
+ hidden: state !== "collapsed" || isMobile,
731
+ ...tooltip
732
+ }
733
+ )
734
+ ] });
735
+ }
736
+
737
+ // src/components/app-sidebar.tsx
738
+ import { usePathname, useRouter } from "next/navigation";
739
+ import Link from "next/link";
740
+ import { ChevronUp, ChevronRight as ChevronRight2, LogOut } from "lucide-react";
741
+
742
+ // src/components/ui/collapsible.tsx
743
+ import { Collapsible as CollapsiblePrimitive } from "radix-ui";
744
+ import { jsx as jsx8 } from "react/jsx-runtime";
745
+ function Collapsible({
746
+ ...props
747
+ }) {
748
+ return /* @__PURE__ */ jsx8(CollapsiblePrimitive.Root, { "data-slot": "collapsible", ...props });
749
+ }
750
+ function CollapsibleTrigger({
751
+ ...props
752
+ }) {
753
+ return /* @__PURE__ */ jsx8(
754
+ CollapsiblePrimitive.CollapsibleTrigger,
755
+ {
756
+ "data-slot": "collapsible-trigger",
757
+ ...props
758
+ }
759
+ );
760
+ }
761
+ function CollapsibleContent({
762
+ ...props
763
+ }) {
764
+ return /* @__PURE__ */ jsx8(
765
+ CollapsiblePrimitive.CollapsibleContent,
766
+ {
767
+ "data-slot": "collapsible-content",
768
+ ...props
769
+ }
770
+ );
771
+ }
772
+
773
+ // src/components/ui/dropdown-menu.tsx
774
+ import { DropdownMenu as DropdownMenuPrimitive } from "radix-ui";
775
+ import { Check, ChevronRight } from "lucide-react";
776
+ import { jsx as jsx9, jsxs as jsxs4 } from "react/jsx-runtime";
777
+ function DropdownMenu({
778
+ ...props
779
+ }) {
780
+ return /* @__PURE__ */ jsx9(DropdownMenuPrimitive.Root, { "data-slot": "dropdown-menu", ...props });
781
+ }
782
+ function DropdownMenuTrigger({
783
+ ...props
784
+ }) {
785
+ return /* @__PURE__ */ jsx9(
786
+ DropdownMenuPrimitive.Trigger,
787
+ {
788
+ "data-slot": "dropdown-menu-trigger",
789
+ ...props
790
+ }
791
+ );
792
+ }
793
+ function DropdownMenuContent({
794
+ className,
795
+ align = "start",
796
+ sideOffset = 4,
797
+ ...props
798
+ }) {
799
+ return /* @__PURE__ */ jsx9(DropdownMenuPrimitive.Portal, { children: /* @__PURE__ */ jsx9(
800
+ DropdownMenuPrimitive.Content,
801
+ {
802
+ "data-slot": "dropdown-menu-content",
803
+ sideOffset,
804
+ align,
805
+ className: cn("data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-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 ring-foreground/10 bg-popover text-popover-foreground min-w-32 rounded-md p-1 shadow-md ring-1 duration-100 z-50 max-h-(--radix-dropdown-menu-content-available-height) w-(--radix-dropdown-menu-trigger-width) origin-(--radix-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto data-[state=closed]:overflow-hidden", className),
806
+ ...props
807
+ }
808
+ ) });
809
+ }
810
+ function DropdownMenuItem({
811
+ className,
812
+ inset,
813
+ variant = "default",
814
+ ...props
815
+ }) {
816
+ return /* @__PURE__ */ jsx9(
817
+ DropdownMenuPrimitive.Item,
818
+ {
819
+ "data-slot": "dropdown-menu-item",
820
+ "data-inset": inset,
821
+ "data-variant": variant,
822
+ className: cn(
823
+ "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 not-data-[variant=destructive]:focus:**:text-accent-foreground gap-2 rounded-sm px-2 py-1.5 text-sm data-inset:pl-8 [&_svg:not([class*='size-'])]:size-4 group/dropdown-menu-item relative flex cursor-default items-center outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0",
824
+ className
825
+ ),
826
+ ...props
827
+ }
828
+ );
829
+ }
830
+ function DropdownMenuLabel({
831
+ className,
832
+ inset,
833
+ ...props
834
+ }) {
835
+ return /* @__PURE__ */ jsx9(
836
+ DropdownMenuPrimitive.Label,
837
+ {
838
+ "data-slot": "dropdown-menu-label",
839
+ "data-inset": inset,
840
+ className: cn("text-muted-foreground px-2 py-1.5 text-xs font-medium data-inset:pl-8", className),
841
+ ...props
842
+ }
843
+ );
844
+ }
845
+ function DropdownMenuSeparator({
846
+ className,
847
+ ...props
848
+ }) {
849
+ return /* @__PURE__ */ jsx9(
850
+ DropdownMenuPrimitive.Separator,
851
+ {
852
+ "data-slot": "dropdown-menu-separator",
853
+ className: cn("bg-border -mx-1 my-1 h-px", className),
854
+ ...props
855
+ }
856
+ );
857
+ }
858
+
859
+ // src/components/ui/avatar.tsx
860
+ import { Avatar as AvatarPrimitive } from "radix-ui";
861
+ import { jsx as jsx10 } from "react/jsx-runtime";
862
+ function Avatar({
863
+ className,
864
+ size = "default",
865
+ ...props
866
+ }) {
867
+ return /* @__PURE__ */ jsx10(
868
+ AvatarPrimitive.Root,
869
+ {
870
+ "data-slot": "avatar",
871
+ "data-size": size,
872
+ className: cn(
873
+ "size-8 rounded-full after:rounded-full data-[size=lg]:size-10 data-[size=sm]:size-6 after:border-border group/avatar relative flex shrink-0 select-none after:absolute after:inset-0 after:border after:mix-blend-darken dark:after:mix-blend-lighten",
874
+ className
875
+ ),
876
+ ...props
877
+ }
878
+ );
879
+ }
880
+ function AvatarFallback({
881
+ className,
882
+ ...props
883
+ }) {
884
+ return /* @__PURE__ */ jsx10(
885
+ AvatarPrimitive.Fallback,
886
+ {
887
+ "data-slot": "avatar-fallback",
888
+ className: cn(
889
+ "bg-muted text-muted-foreground rounded-full flex size-full items-center justify-center text-sm group-data-[size=sm]/avatar:text-xs",
890
+ className
891
+ ),
892
+ ...props
893
+ }
894
+ );
895
+ }
896
+
897
+ // src/components/ui/badge.tsx
898
+ import { cva as cva3 } from "class-variance-authority";
899
+ import { Slot as Slot3 } from "radix-ui";
900
+ import { jsx as jsx11 } from "react/jsx-runtime";
901
+ var badgeVariants = cva3(
902
+ "h-5 gap-1 rounded-4xl border border-transparent px-2 py-0.5 text-xs font-medium transition-all has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&>svg]:size-3! inline-flex items-center justify-center w-fit whitespace-nowrap shrink-0 [&>svg]:pointer-events-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 overflow-hidden group/badge",
903
+ {
904
+ variants: {
905
+ variant: {
906
+ default: "bg-primary text-primary-foreground [a]:hover:bg-primary/80",
907
+ secondary: "bg-secondary text-secondary-foreground [a]:hover:bg-secondary/80",
908
+ destructive: "bg-destructive/10 [a]:hover:bg-destructive/20 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 text-destructive dark:bg-destructive/20",
909
+ outline: "border-border text-foreground [a]:hover:bg-muted [a]:hover:text-muted-foreground",
910
+ ghost: "hover:bg-muted hover:text-muted-foreground dark:hover:bg-muted/50",
911
+ link: "text-primary underline-offset-4 hover:underline"
912
+ }
913
+ },
914
+ defaultVariants: {
915
+ variant: "default"
916
+ }
917
+ }
918
+ );
919
+ function Badge({
920
+ className,
921
+ variant = "default",
922
+ asChild = false,
923
+ ...props
924
+ }) {
925
+ const Comp = asChild ? Slot3.Root : "span";
926
+ return /* @__PURE__ */ jsx11(
927
+ Comp,
928
+ {
929
+ "data-slot": "badge",
930
+ "data-variant": variant,
931
+ className: cn(badgeVariants({ variant }), className),
932
+ ...props
933
+ }
934
+ );
935
+ }
936
+
937
+ // src/components/app-sidebar.tsx
938
+ import { jsx as jsx12, jsxs as jsxs5 } from "react/jsx-runtime";
939
+ function getUserInitials(name, email, showLastName) {
940
+ if (!name) return email?.[0]?.toUpperCase() || "?";
941
+ const parts = name.trim().split(/\s+/);
942
+ if (showLastName && parts.length > 1) {
943
+ return (parts[0][0] + parts[parts.length - 1][0]).toUpperCase();
944
+ }
945
+ return (parts[0][0] + (email?.[0] || "")).toUpperCase();
946
+ }
947
+ function SimpleMenuItem({ item, pathname }) {
948
+ const isActive = pathname.startsWith(item.href);
949
+ const Icon = item.icon;
950
+ return /* @__PURE__ */ jsx12(SidebarMenuItem, { children: /* @__PURE__ */ jsx12(SidebarMenuButton, { asChild: true, isActive, tooltip: item.label, children: /* @__PURE__ */ jsxs5(Link, { href: item.href, onClick: item.onClick, children: [
951
+ /* @__PURE__ */ jsx12(Icon, { className: "size-4" }),
952
+ /* @__PURE__ */ jsx12("span", { children: item.label })
953
+ ] }) }) });
954
+ }
955
+ function CollapsibleMenuItem({ item, pathname }) {
956
+ const Icon = item.icon;
957
+ const isChildActive = item.children?.some((child) => pathname.startsWith(child.href)) ?? false;
958
+ return /* @__PURE__ */ jsx12(Collapsible, { defaultOpen: isChildActive, className: "group/collapsible", children: /* @__PURE__ */ jsxs5(SidebarMenuItem, { children: [
959
+ /* @__PURE__ */ jsx12(CollapsibleTrigger, { asChild: true, children: /* @__PURE__ */ jsxs5(SidebarMenuButton, { tooltip: item.label, children: [
960
+ /* @__PURE__ */ jsx12(Icon, { className: "size-4" }),
961
+ /* @__PURE__ */ jsx12("span", { children: item.label }),
962
+ /* @__PURE__ */ jsx12(ChevronRight2, { className: "ml-auto transition-transform duration-200 group-data-[state=open]/collapsible:rotate-90" })
963
+ ] }) }),
964
+ /* @__PURE__ */ jsx12(CollapsibleContent, { children: /* @__PURE__ */ jsx12(SidebarMenu, { className: "ml-4 border-l pl-2", children: item.children?.map((child) => /* @__PURE__ */ jsx12(SimpleMenuItem, { item: child, pathname }, child.href)) }) })
965
+ ] }) });
966
+ }
967
+ function AppSidebar({ config }) {
968
+ const pathname = usePathname();
969
+ const router = useRouter();
970
+ const { data: session } = useSession();
971
+ const handleLogout = async () => {
972
+ config.onLogout?.();
973
+ await signOut({ fetchOptions: { onSuccess: () => router.push("/login") } });
974
+ };
975
+ const userName = session?.user?.name || "";
976
+ const userEmail = session?.user?.email || "";
977
+ const initials = getUserInitials(userName, userEmail, config.userDisplayFields?.showLastName);
978
+ return /* @__PURE__ */ jsxs5(Sidebar, { children: [
979
+ /* @__PURE__ */ jsx12(SidebarHeader, { children: /* @__PURE__ */ jsx12(SidebarMenu, { children: /* @__PURE__ */ jsx12(SidebarMenuItem, { children: /* @__PURE__ */ jsx12(SidebarMenuButton, { size: "lg", asChild: true, children: /* @__PURE__ */ jsxs5("div", { className: "flex items-center gap-2", children: [
980
+ config.appIcon,
981
+ /* @__PURE__ */ jsx12("span", { className: "font-semibold", children: config.appName }),
982
+ config.appBadge && /* @__PURE__ */ jsx12(Badge, { variant: "destructive", children: config.appBadge })
983
+ ] }) }) }) }) }),
984
+ /* @__PURE__ */ jsx12(SidebarContent, { children: config.menuGroups.map((group) => /* @__PURE__ */ jsxs5(SidebarGroup, { children: [
985
+ /* @__PURE__ */ jsx12(SidebarGroupLabel, { children: group.label }),
986
+ /* @__PURE__ */ jsx12(SidebarGroupContent, { children: /* @__PURE__ */ jsx12(SidebarMenu, { children: group.items.map(
987
+ (item) => item.children && item.children.length > 0 ? /* @__PURE__ */ jsx12(CollapsibleMenuItem, { item, pathname }, item.href) : /* @__PURE__ */ jsx12(SimpleMenuItem, { item, pathname }, item.href)
988
+ ) }) })
989
+ ] }, group.label)) }),
990
+ /* @__PURE__ */ jsx12(SidebarFooter, { children: /* @__PURE__ */ jsx12(SidebarMenu, { children: /* @__PURE__ */ jsx12(SidebarMenuItem, { children: /* @__PURE__ */ jsxs5(DropdownMenu, { children: [
991
+ /* @__PURE__ */ jsx12(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxs5(SidebarMenuButton, { size: "lg", children: [
992
+ /* @__PURE__ */ jsx12(Avatar, { className: "size-8", children: /* @__PURE__ */ jsx12(AvatarFallback, { children: initials }) }),
993
+ /* @__PURE__ */ jsxs5("div", { className: "grid flex-1 text-left text-sm leading-tight", children: [
994
+ /* @__PURE__ */ jsx12("span", { className: "truncate font-semibold", children: userName }),
995
+ /* @__PURE__ */ jsx12("span", { className: "truncate text-xs text-muted-foreground", children: userEmail })
996
+ ] }),
997
+ /* @__PURE__ */ jsx12(ChevronUp, { className: "ml-auto size-4" })
998
+ ] }) }),
999
+ /* @__PURE__ */ jsxs5(
1000
+ DropdownMenuContent,
1001
+ {
1002
+ className: "w-(--radix-dropdown-menu-trigger-width) min-w-56",
1003
+ side: "top",
1004
+ align: "end",
1005
+ sideOffset: 4,
1006
+ children: [
1007
+ /* @__PURE__ */ jsx12(DropdownMenuLabel, { className: "font-normal", children: /* @__PURE__ */ jsxs5("div", { className: "flex flex-col space-y-1", children: [
1008
+ /* @__PURE__ */ jsx12("p", { className: "text-sm font-medium leading-none", children: userName }),
1009
+ /* @__PURE__ */ jsx12("p", { className: "text-xs leading-none text-muted-foreground", children: userEmail })
1010
+ ] }) }),
1011
+ /* @__PURE__ */ jsx12(DropdownMenuSeparator, {}),
1012
+ config.footerExtra,
1013
+ /* @__PURE__ */ jsxs5(DropdownMenuItem, { onClick: handleLogout, children: [
1014
+ /* @__PURE__ */ jsx12(LogOut, { className: "size-4" }),
1015
+ "Sair"
1016
+ ] })
1017
+ ]
1018
+ }
1019
+ )
1020
+ ] }) }) }) })
1021
+ ] });
1022
+ }
1023
+
1024
+ // src/components/app-header.tsx
1025
+ import { Fragment } from "react";
1026
+ import { usePathname as usePathname2 } from "next/navigation";
1027
+
1028
+ // src/components/ui/breadcrumb.tsx
1029
+ import { Slot as Slot4 } from "radix-ui";
1030
+ import { ChevronRight as ChevronRight3, MoreHorizontal } from "lucide-react";
1031
+ import { jsx as jsx13, jsxs as jsxs6 } from "react/jsx-runtime";
1032
+ function Breadcrumb({ className, ...props }) {
1033
+ return /* @__PURE__ */ jsx13(
1034
+ "nav",
1035
+ {
1036
+ "aria-label": "breadcrumb",
1037
+ "data-slot": "breadcrumb",
1038
+ className: cn(className),
1039
+ ...props
1040
+ }
1041
+ );
1042
+ }
1043
+ function BreadcrumbList({ className, ...props }) {
1044
+ return /* @__PURE__ */ jsx13(
1045
+ "ol",
1046
+ {
1047
+ "data-slot": "breadcrumb-list",
1048
+ className: cn(
1049
+ "text-muted-foreground gap-1.5 text-sm sm:gap-2.5 flex flex-wrap items-center wrap-break-word",
1050
+ className
1051
+ ),
1052
+ ...props
1053
+ }
1054
+ );
1055
+ }
1056
+ function BreadcrumbItem({ className, ...props }) {
1057
+ return /* @__PURE__ */ jsx13(
1058
+ "li",
1059
+ {
1060
+ "data-slot": "breadcrumb-item",
1061
+ className: cn("gap-1.5 inline-flex items-center", className),
1062
+ ...props
1063
+ }
1064
+ );
1065
+ }
1066
+ function BreadcrumbPage({ className, ...props }) {
1067
+ return /* @__PURE__ */ jsx13(
1068
+ "span",
1069
+ {
1070
+ "data-slot": "breadcrumb-page",
1071
+ role: "link",
1072
+ "aria-disabled": "true",
1073
+ "aria-current": "page",
1074
+ className: cn("text-foreground font-normal", className),
1075
+ ...props
1076
+ }
1077
+ );
1078
+ }
1079
+ function BreadcrumbSeparator({
1080
+ children,
1081
+ className,
1082
+ ...props
1083
+ }) {
1084
+ return /* @__PURE__ */ jsx13(
1085
+ "li",
1086
+ {
1087
+ "data-slot": "breadcrumb-separator",
1088
+ role: "presentation",
1089
+ "aria-hidden": "true",
1090
+ className: cn("[&>svg]:size-3.5", className),
1091
+ ...props,
1092
+ children: children ?? /* @__PURE__ */ jsx13(ChevronRight3, {})
1093
+ }
1094
+ );
1095
+ }
1096
+
1097
+ // src/components/theme-toggle.tsx
1098
+ import { useTheme } from "next-themes";
1099
+ import { Sun, Moon } from "lucide-react";
1100
+ import { jsx as jsx14, jsxs as jsxs7 } from "react/jsx-runtime";
1101
+ function ThemeToggle() {
1102
+ const { theme, setTheme } = useTheme();
1103
+ return /* @__PURE__ */ jsxs7(
1104
+ Button,
1105
+ {
1106
+ variant: "ghost",
1107
+ size: "icon",
1108
+ onClick: () => setTheme(theme === "dark" ? "light" : "dark"),
1109
+ children: [
1110
+ /* @__PURE__ */ jsx14(Sun, { className: "h-5 w-5 rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0" }),
1111
+ /* @__PURE__ */ jsx14(Moon, { className: "absolute h-5 w-5 rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100" }),
1112
+ /* @__PURE__ */ jsx14("span", { className: "sr-only", children: "Alternar tema" })
1113
+ ]
1114
+ }
1115
+ );
1116
+ }
1117
+
1118
+ // src/components/app-header.tsx
1119
+ import { jsx as jsx15, jsxs as jsxs8 } from "react/jsx-runtime";
1120
+ function AppHeader({ config }) {
1121
+ const pathname = usePathname2();
1122
+ const segments = pathname.split("/").filter(Boolean);
1123
+ const breadcrumbs = segments.map((seg) => config.routeLabels[seg]).filter(Boolean);
1124
+ return /* @__PURE__ */ jsxs8("header", { className: "flex h-14 shrink-0 items-center gap-2 border-b px-4", children: [
1125
+ /* @__PURE__ */ jsx15(SidebarTrigger, { className: "-ml-1" }),
1126
+ /* @__PURE__ */ jsx15(Separator, { orientation: "vertical", className: "mr-2 !h-4" }),
1127
+ /* @__PURE__ */ jsx15(Breadcrumb, { className: "flex-1", children: /* @__PURE__ */ jsx15(BreadcrumbList, { children: breadcrumbs.length > 0 ? breadcrumbs.map((label, i) => /* @__PURE__ */ jsxs8(Fragment, { children: [
1128
+ i > 0 && /* @__PURE__ */ jsx15(BreadcrumbSeparator, {}),
1129
+ /* @__PURE__ */ jsx15(BreadcrumbItem, { children: /* @__PURE__ */ jsx15(BreadcrumbPage, { children: label }) })
1130
+ ] }, i)) : config.defaultBreadcrumb ? /* @__PURE__ */ jsx15(BreadcrumbItem, { children: /* @__PURE__ */ jsx15(BreadcrumbPage, { children: config.defaultBreadcrumb }) }) : null }) }),
1131
+ /* @__PURE__ */ jsx15(ThemeToggle, {})
1132
+ ] });
1133
+ }
1134
+
1135
+ // src/components/app-shell.tsx
1136
+ import { Fragment as Fragment2, jsx as jsx16, jsxs as jsxs9 } from "react/jsx-runtime";
1137
+ function AppShell({ config, children, renderAbove }) {
1138
+ return /* @__PURE__ */ jsxs9(Fragment2, { children: [
1139
+ renderAbove,
1140
+ /* @__PURE__ */ jsx16(TooltipProvider, { children: /* @__PURE__ */ jsxs9(SidebarProvider, { className: "!h-svh !overflow-hidden", children: [
1141
+ /* @__PURE__ */ jsx16(AppSidebar, { config }),
1142
+ /* @__PURE__ */ jsxs9(SidebarInset, { className: "flex flex-col min-w-0 overflow-hidden", children: [
1143
+ /* @__PURE__ */ jsx16(AppHeader, { config }),
1144
+ /* @__PURE__ */ jsx16("main", { className: "flex-1 overflow-auto", children })
1145
+ ] })
1146
+ ] }) })
1147
+ ] });
1148
+ }
1149
+
1150
+ // src/components/login-form.tsx
1151
+ import { useState as useState3 } from "react";
1152
+ import { useRouter as useRouter2, useSearchParams } from "next/navigation";
1153
+ import { Loader2 } from "lucide-react";
1154
+
1155
+ // src/components/ui/label.tsx
1156
+ import { Label as LabelPrimitive } from "radix-ui";
1157
+ import { jsx as jsx17 } from "react/jsx-runtime";
1158
+ function Label({
1159
+ className,
1160
+ ...props
1161
+ }) {
1162
+ return /* @__PURE__ */ jsx17(
1163
+ LabelPrimitive.Root,
1164
+ {
1165
+ "data-slot": "label",
1166
+ className: cn(
1167
+ "gap-2 text-sm leading-none font-medium group-data-[disabled=true]:opacity-50 peer-disabled:opacity-50 flex items-center select-none group-data-[disabled=true]:pointer-events-none peer-disabled:cursor-not-allowed",
1168
+ className
1169
+ ),
1170
+ ...props
1171
+ }
1172
+ );
1173
+ }
1174
+
1175
+ // src/components/ui/card.tsx
1176
+ import { jsx as jsx18 } from "react/jsx-runtime";
1177
+ function Card({
1178
+ className,
1179
+ size = "default",
1180
+ ...props
1181
+ }) {
1182
+ return /* @__PURE__ */ jsx18(
1183
+ "div",
1184
+ {
1185
+ "data-slot": "card",
1186
+ "data-size": size,
1187
+ className: cn("ring-foreground/10 bg-card text-card-foreground gap-6 overflow-hidden rounded-xl py-6 text-sm shadow-xs ring-1 has-[>img:first-child]:pt-0 data-[size=sm]:gap-4 data-[size=sm]:py-4 *:[img:first-child]:rounded-t-xl *:[img:last-child]:rounded-b-xl group/card flex flex-col", className),
1188
+ ...props
1189
+ }
1190
+ );
1191
+ }
1192
+ function CardHeader({ className, ...props }) {
1193
+ return /* @__PURE__ */ jsx18(
1194
+ "div",
1195
+ {
1196
+ "data-slot": "card-header",
1197
+ className: cn(
1198
+ "gap-1 rounded-t-xl px-6 group-data-[size=sm]/card:px-4 [.border-b]:pb-6 group-data-[size=sm]/card:[.border-b]:pb-4 group/card-header @container/card-header grid auto-rows-min items-start has-data-[slot=card-action]:grid-cols-[1fr_auto] has-data-[slot=card-description]:grid-rows-[auto_auto]",
1199
+ className
1200
+ ),
1201
+ ...props
1202
+ }
1203
+ );
1204
+ }
1205
+ function CardTitle({ className, ...props }) {
1206
+ return /* @__PURE__ */ jsx18(
1207
+ "div",
1208
+ {
1209
+ "data-slot": "card-title",
1210
+ className: cn("text-base leading-normal font-medium group-data-[size=sm]/card:text-sm", className),
1211
+ ...props
1212
+ }
1213
+ );
1214
+ }
1215
+ function CardDescription({ className, ...props }) {
1216
+ return /* @__PURE__ */ jsx18(
1217
+ "div",
1218
+ {
1219
+ "data-slot": "card-description",
1220
+ className: cn("text-muted-foreground text-sm", className),
1221
+ ...props
1222
+ }
1223
+ );
1224
+ }
1225
+ function CardContent({ className, ...props }) {
1226
+ return /* @__PURE__ */ jsx18(
1227
+ "div",
1228
+ {
1229
+ "data-slot": "card-content",
1230
+ className: cn("px-6 group-data-[size=sm]/card:px-4", className),
1231
+ ...props
1232
+ }
1233
+ );
1234
+ }
1235
+
1236
+ // src/components/ui/alert.tsx
1237
+ import { cva as cva4 } from "class-variance-authority";
1238
+ import { jsx as jsx19 } from "react/jsx-runtime";
1239
+ var alertVariants = cva4("grid gap-0.5 rounded-lg border px-4 py-3 text-left text-sm has-data-[slot=alert-action]:relative has-data-[slot=alert-action]:pr-18 has-[>svg]:grid-cols-[auto_1fr] has-[>svg]:gap-x-2.5 *:[svg]:row-span-2 *:[svg]:translate-y-0.5 *:[svg]:text-current *:[svg:not([class*='size-'])]:size-4 w-full relative group/alert", {
1240
+ variants: {
1241
+ variant: {
1242
+ default: "bg-card text-card-foreground",
1243
+ destructive: "text-destructive bg-card *:data-[slot=alert-description]:text-destructive/90 *:[svg]:text-current"
1244
+ }
1245
+ },
1246
+ defaultVariants: {
1247
+ variant: "default"
1248
+ }
1249
+ });
1250
+ function Alert({
1251
+ className,
1252
+ variant,
1253
+ ...props
1254
+ }) {
1255
+ return /* @__PURE__ */ jsx19(
1256
+ "div",
1257
+ {
1258
+ "data-slot": "alert",
1259
+ role: "alert",
1260
+ className: cn(alertVariants({ variant }), className),
1261
+ ...props
1262
+ }
1263
+ );
1264
+ }
1265
+ function AlertDescription({
1266
+ className,
1267
+ ...props
1268
+ }) {
1269
+ return /* @__PURE__ */ jsx19(
1270
+ "div",
1271
+ {
1272
+ "data-slot": "alert-description",
1273
+ className: cn(
1274
+ "text-muted-foreground text-sm text-balance md:text-pretty [&_p:not(:last-child)]:mb-4 [&_a]:hover:text-foreground [&_a]:underline [&_a]:underline-offset-3",
1275
+ className
1276
+ ),
1277
+ ...props
1278
+ }
1279
+ );
1280
+ }
1281
+
1282
+ // src/components/login-form.tsx
1283
+ import { jsx as jsx20, jsxs as jsxs10 } from "react/jsx-runtime";
1284
+ function LoginForm({ config }) {
1285
+ const router = useRouter2();
1286
+ const searchParams = useSearchParams();
1287
+ const callbackUrl = searchParams.get("callbackUrl") || config.callbackUrlDefault;
1288
+ const [email, setEmail] = useState3("");
1289
+ const [password, setPassword] = useState3("");
1290
+ const [loading, setLoading] = useState3(false);
1291
+ const [error, setError] = useState3("");
1292
+ const handleSubmit = async (e) => {
1293
+ e.preventDefault();
1294
+ if (loading) return;
1295
+ setLoading(true);
1296
+ setError("");
1297
+ try {
1298
+ const { data, error: signInError } = await authClient.signIn.email({
1299
+ email,
1300
+ password,
1301
+ callbackURL: callbackUrl
1302
+ });
1303
+ if (signInError) {
1304
+ setError(signInError.message || "Erro ao entrar");
1305
+ setLoading(false);
1306
+ return;
1307
+ }
1308
+ if (config.onPostLoginSuccess) {
1309
+ const gauthToken = data?.user?.gauthToken;
1310
+ const redirectUrl = await config.onPostLoginSuccess(data?.user, gauthToken);
1311
+ if (redirectUrl) {
1312
+ router.push(redirectUrl);
1313
+ return;
1314
+ }
1315
+ }
1316
+ router.push(callbackUrl);
1317
+ } catch {
1318
+ setError("Erro ao entrar");
1319
+ setLoading(false);
1320
+ }
1321
+ };
1322
+ return /* @__PURE__ */ jsx20("div", { className: "flex min-h-svh flex-col items-center justify-center p-6 md:p-10", children: /* @__PURE__ */ jsx20("div", { className: "w-full max-w-sm", children: /* @__PURE__ */ jsxs10(Card, { children: [
1323
+ /* @__PURE__ */ jsxs10(CardHeader, { className: "text-center", children: [
1324
+ /* @__PURE__ */ jsxs10("div", { className: "flex items-center justify-center gap-2 mb-2", children: [
1325
+ config.icon,
1326
+ /* @__PURE__ */ jsx20(CardTitle, { className: "text-xl", children: config.appName }),
1327
+ config.appBadge && /* @__PURE__ */ jsx20(Badge, { variant: config.appBadge.variant, children: config.appBadge.text })
1328
+ ] }),
1329
+ /* @__PURE__ */ jsx20(CardDescription, { children: config.description })
1330
+ ] }),
1331
+ /* @__PURE__ */ jsx20(CardContent, { children: /* @__PURE__ */ jsx20("form", { onSubmit: handleSubmit, children: /* @__PURE__ */ jsxs10("div", { className: "grid gap-4", children: [
1332
+ error && /* @__PURE__ */ jsx20(Alert, { variant: "destructive", children: /* @__PURE__ */ jsx20(AlertDescription, { children: error }) }),
1333
+ /* @__PURE__ */ jsxs10("div", { className: "grid gap-2", children: [
1334
+ /* @__PURE__ */ jsx20(Label, { htmlFor: "email", children: "Email" }),
1335
+ /* @__PURE__ */ jsx20(
1336
+ Input,
1337
+ {
1338
+ id: "email",
1339
+ type: "email",
1340
+ placeholder: "email@exemplo.com",
1341
+ value: email,
1342
+ onChange: (e) => setEmail(e.target.value),
1343
+ required: true
1344
+ }
1345
+ )
1346
+ ] }),
1347
+ /* @__PURE__ */ jsxs10("div", { className: "grid gap-2", children: [
1348
+ /* @__PURE__ */ jsx20(Label, { htmlFor: "password", children: "Senha" }),
1349
+ /* @__PURE__ */ jsx20(
1350
+ Input,
1351
+ {
1352
+ id: "password",
1353
+ type: "password",
1354
+ value: password,
1355
+ onChange: (e) => setPassword(e.target.value),
1356
+ required: true
1357
+ }
1358
+ )
1359
+ ] }),
1360
+ /* @__PURE__ */ jsxs10(Button, { type: "submit", className: "w-full", disabled: loading, children: [
1361
+ loading && /* @__PURE__ */ jsx20(Loader2, { className: "animate-spin" }),
1362
+ "Entrar"
1363
+ ] })
1364
+ ] }) }) })
1365
+ ] }) }) });
1366
+ }
88
1367
  export {
1368
+ AppHeader,
1369
+ AppShell,
1370
+ AppSidebar,
1371
+ LoginForm,
1372
+ SidebarInset,
1373
+ SidebarProvider,
1374
+ SidebarTrigger,
1375
+ ThemeToggle,
1376
+ TooltipProvider,
89
1377
  authClient,
90
1378
  authMiddlewareConfig,
91
1379
  cn,
@@ -94,6 +1382,7 @@ export {
94
1382
  signIn,
95
1383
  signOut,
96
1384
  signUp,
97
- useSession
1385
+ useSession,
1386
+ useSidebar
98
1387
  };
99
1388
  //# sourceMappingURL=index.js.map