@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.d.ts +60 -11
- package/dist/index.js +1290 -1
- package/dist/index.js.map +1 -1
- package/dist/middleware.d.ts +12 -0
- package/dist/middleware.js +27 -0
- package/dist/middleware.js.map +1 -0
- package/package.json +15 -4
- package/src/components/app-header.tsx +55 -0
- package/src/components/app-shell.tsx +33 -0
- package/src/components/app-sidebar.tsx +185 -0
- package/src/components/index.ts +5 -0
- package/src/components/login-form.tsx +122 -0
- package/src/components/theme-toggle.tsx +21 -0
- package/src/components/ui/alert.tsx +72 -0
- package/src/components/ui/avatar.tsx +109 -0
- package/src/components/ui/badge.tsx +45 -0
- package/src/components/ui/breadcrumb.tsx +121 -0
- package/src/components/ui/button.tsx +60 -0
- package/src/components/ui/card.tsx +94 -0
- package/src/components/ui/collapsible.tsx +34 -0
- package/src/components/ui/dropdown-menu.tsx +261 -0
- package/src/components/ui/input.tsx +19 -0
- package/src/components/ui/label.tsx +24 -0
- package/src/components/ui/separator.tsx +28 -0
- package/src/components/ui/sheet.tsx +133 -0
- package/src/components/ui/sidebar.tsx +701 -0
- package/src/components/ui/skeleton.tsx +15 -0
- package/src/components/ui/tooltip.tsx +57 -0
- package/src/hooks/use-mobile.ts +19 -0
- package/src/index.ts +11 -0
- package/src/middleware.ts +2 -0
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
|