@greatapps/greatauth-ui 0.3.18 → 0.3.19
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/chunk-5XZPBJRT.js +28 -0
- package/dist/chunk-5XZPBJRT.js.map +1 -0
- package/dist/chunk-OS2C4IWR.js +1790 -0
- package/dist/chunk-OS2C4IWR.js.map +1 -0
- package/dist/index.js +390 -1849
- package/dist/index.js.map +1 -1
- package/dist/middleware.js +4 -22
- package/dist/middleware.js.map +1 -1
- package/dist/ui.js +493 -2055
- package/dist/ui.js.map +1 -1
- package/package.json +1 -1
- package/src/components/app-header.tsx +2 -1
- package/src/components/app-sidebar.tsx +7 -7
- package/src/components/users/users-page.tsx +8 -5
- package/src/hooks/use-auth.ts +38 -33
- package/src/hooks/use-mobile.ts +5 -3
- package/src/hooks/use-users.ts +1 -1
package/dist/index.js
CHANGED
|
@@ -1,32 +1,87 @@
|
|
|
1
|
+
import {
|
|
2
|
+
authMiddlewareConfig,
|
|
3
|
+
createAuthMiddleware
|
|
4
|
+
} from "./chunk-5XZPBJRT.js";
|
|
5
|
+
import {
|
|
6
|
+
AlertDialog,
|
|
7
|
+
AlertDialogAction,
|
|
8
|
+
AlertDialogCancel,
|
|
9
|
+
AlertDialogContent,
|
|
10
|
+
AlertDialogDescription,
|
|
11
|
+
AlertDialogFooter,
|
|
12
|
+
AlertDialogHeader,
|
|
13
|
+
AlertDialogTitle,
|
|
14
|
+
Avatar,
|
|
15
|
+
AvatarFallback,
|
|
16
|
+
AvatarImage,
|
|
17
|
+
Badge,
|
|
18
|
+
Breadcrumb,
|
|
19
|
+
BreadcrumbEllipsis,
|
|
20
|
+
BreadcrumbItem,
|
|
21
|
+
BreadcrumbLink,
|
|
22
|
+
BreadcrumbList,
|
|
23
|
+
BreadcrumbPage,
|
|
24
|
+
BreadcrumbSeparator,
|
|
25
|
+
Button,
|
|
26
|
+
Collapsible,
|
|
27
|
+
CollapsibleContent,
|
|
28
|
+
CollapsibleTrigger,
|
|
29
|
+
Dialog,
|
|
30
|
+
DialogContent,
|
|
31
|
+
DialogFooter,
|
|
32
|
+
DialogHeader,
|
|
33
|
+
DialogTitle,
|
|
34
|
+
DropdownMenu,
|
|
35
|
+
DropdownMenuContent,
|
|
36
|
+
DropdownMenuItem,
|
|
37
|
+
DropdownMenuLabel,
|
|
38
|
+
DropdownMenuSeparator,
|
|
39
|
+
DropdownMenuTrigger,
|
|
40
|
+
Input,
|
|
41
|
+
Label,
|
|
42
|
+
Select,
|
|
43
|
+
SelectContent,
|
|
44
|
+
SelectItem,
|
|
45
|
+
SelectTrigger,
|
|
46
|
+
SelectValue,
|
|
47
|
+
Separator,
|
|
48
|
+
Sidebar,
|
|
49
|
+
SidebarContent,
|
|
50
|
+
SidebarFooter,
|
|
51
|
+
SidebarGroup,
|
|
52
|
+
SidebarGroupContent,
|
|
53
|
+
SidebarGroupLabel,
|
|
54
|
+
SidebarHeader,
|
|
55
|
+
SidebarInset,
|
|
56
|
+
SidebarMenu,
|
|
57
|
+
SidebarMenuButton,
|
|
58
|
+
SidebarMenuItem,
|
|
59
|
+
SidebarProvider,
|
|
60
|
+
SidebarRail,
|
|
61
|
+
SidebarTrigger,
|
|
62
|
+
Skeleton,
|
|
63
|
+
Slider,
|
|
64
|
+
Table,
|
|
65
|
+
TableBody,
|
|
66
|
+
TableCell,
|
|
67
|
+
TableHead,
|
|
68
|
+
TableHeader,
|
|
69
|
+
TableRow,
|
|
70
|
+
Tooltip,
|
|
71
|
+
TooltipContent,
|
|
72
|
+
TooltipProvider,
|
|
73
|
+
TooltipTrigger,
|
|
74
|
+
cn,
|
|
75
|
+
useSidebar
|
|
76
|
+
} from "./chunk-OS2C4IWR.js";
|
|
77
|
+
|
|
1
78
|
// src/auth/auth-client.ts
|
|
2
79
|
import { createAuthClient } from "better-auth/react";
|
|
3
80
|
var authClient = createAuthClient();
|
|
4
81
|
var { useSession, signIn, signUp, signOut } = authClient;
|
|
5
82
|
|
|
6
|
-
// src/auth/middleware.ts
|
|
7
|
-
import { NextResponse } from "next/server";
|
|
8
|
-
function createAuthMiddleware(config) {
|
|
9
|
-
const { publicPaths, preserveSearchParams = false } = config;
|
|
10
|
-
return function middleware(request2) {
|
|
11
|
-
const { pathname, search } = request2.nextUrl;
|
|
12
|
-
if (publicPaths.some((path) => pathname.startsWith(path))) {
|
|
13
|
-
return NextResponse.next();
|
|
14
|
-
}
|
|
15
|
-
const sessionToken = request2.cookies.get("better-auth.session_token")?.value || request2.cookies.get("__Secure-better-auth.session_token")?.value;
|
|
16
|
-
if (!sessionToken) {
|
|
17
|
-
const callbackUrl = preserveSearchParams ? pathname + search : pathname;
|
|
18
|
-
const loginUrl = new URL("/login", request2.url);
|
|
19
|
-
loginUrl.searchParams.set("callbackUrl", callbackUrl);
|
|
20
|
-
return NextResponse.redirect(loginUrl);
|
|
21
|
-
}
|
|
22
|
-
return NextResponse.next();
|
|
23
|
-
};
|
|
24
|
-
}
|
|
25
|
-
var authMiddlewareConfig = {
|
|
26
|
-
matcher: ["/((?!_next/static|_next/image|favicon.ico|api/auth).*)"]
|
|
27
|
-
};
|
|
28
|
-
|
|
29
83
|
// src/hooks/use-auth.ts
|
|
84
|
+
import { useMemo } from "react";
|
|
30
85
|
function decodeJwtPayload(token) {
|
|
31
86
|
try {
|
|
32
87
|
const parts = token.split(".");
|
|
@@ -41,967 +96,55 @@ function decodeJwtPayload(token) {
|
|
|
41
96
|
function createUseAuth(config) {
|
|
42
97
|
return function useAuth() {
|
|
43
98
|
const { data: sessionData, isPending, error } = useSession();
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
99
|
+
const result = useMemo(() => {
|
|
100
|
+
const session = sessionData?.session ?? null;
|
|
101
|
+
const user = sessionData?.user ?? null;
|
|
102
|
+
const sessionObj = session;
|
|
103
|
+
const userObj = user;
|
|
104
|
+
const gauthToken = sessionObj?.gauthToken ?? userObj?.gauthToken ?? null;
|
|
105
|
+
const idAccount = sessionObj?.idAccount ?? userObj?.idAccount ?? null;
|
|
106
|
+
const gauthProfile = sessionObj?.gauthProfile ?? userObj?.gauthProfile ?? null;
|
|
107
|
+
const res = {
|
|
108
|
+
session,
|
|
109
|
+
user,
|
|
110
|
+
gauthToken,
|
|
111
|
+
idAccount,
|
|
112
|
+
gauthProfile,
|
|
113
|
+
isLoading: isPending,
|
|
114
|
+
isAuthenticated: !!session && !!user,
|
|
115
|
+
error: error ?? null
|
|
116
|
+
};
|
|
117
|
+
if (config?.jwtClaims && gauthToken) {
|
|
118
|
+
const payload = decodeJwtPayload(gauthToken);
|
|
119
|
+
if (payload) {
|
|
120
|
+
for (const [jwtKey, fieldName] of Object.entries(config.jwtClaims)) {
|
|
121
|
+
res[fieldName] = payload[jwtKey] ?? null;
|
|
122
|
+
}
|
|
66
123
|
}
|
|
67
124
|
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
125
|
+
if (config?.accountIdOverride) {
|
|
126
|
+
const overriddenId = config.accountIdOverride(user);
|
|
127
|
+
if (overriddenId !== null) {
|
|
128
|
+
res.idAccount = overriddenId;
|
|
129
|
+
}
|
|
73
130
|
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
131
|
+
if (config?.extraUserFields && user) {
|
|
132
|
+
for (const field of config.extraUserFields) {
|
|
133
|
+
res[field] = user[field] ?? null;
|
|
134
|
+
}
|
|
78
135
|
}
|
|
79
|
-
|
|
136
|
+
return res;
|
|
137
|
+
}, [sessionData, isPending, error]);
|
|
80
138
|
return result;
|
|
81
139
|
};
|
|
82
140
|
}
|
|
83
141
|
|
|
84
|
-
// src/components/ui/tooltip.tsx
|
|
85
|
-
import { Tooltip as TooltipPrimitive } from "radix-ui";
|
|
86
|
-
|
|
87
|
-
// src/lib/utils.ts
|
|
88
|
-
import { clsx } from "clsx";
|
|
89
|
-
import { twMerge } from "tailwind-merge";
|
|
90
|
-
function cn(...inputs) {
|
|
91
|
-
return twMerge(clsx(inputs));
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
// src/components/ui/tooltip.tsx
|
|
95
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
96
|
-
function TooltipProvider({
|
|
97
|
-
delayDuration = 0,
|
|
98
|
-
...props
|
|
99
|
-
}) {
|
|
100
|
-
return /* @__PURE__ */ jsx(
|
|
101
|
-
TooltipPrimitive.Provider,
|
|
102
|
-
{
|
|
103
|
-
"data-slot": "tooltip-provider",
|
|
104
|
-
delayDuration,
|
|
105
|
-
...props
|
|
106
|
-
}
|
|
107
|
-
);
|
|
108
|
-
}
|
|
109
|
-
function Tooltip({
|
|
110
|
-
...props
|
|
111
|
-
}) {
|
|
112
|
-
return /* @__PURE__ */ jsx(TooltipPrimitive.Root, { "data-slot": "tooltip", ...props });
|
|
113
|
-
}
|
|
114
|
-
function TooltipTrigger({
|
|
115
|
-
...props
|
|
116
|
-
}) {
|
|
117
|
-
return /* @__PURE__ */ jsx(TooltipPrimitive.Trigger, { "data-slot": "tooltip-trigger", ...props });
|
|
118
|
-
}
|
|
119
|
-
function TooltipContent({
|
|
120
|
-
className,
|
|
121
|
-
sideOffset = 0,
|
|
122
|
-
children,
|
|
123
|
-
...props
|
|
124
|
-
}) {
|
|
125
|
-
return /* @__PURE__ */ jsx(TooltipPrimitive.Portal, { children: /* @__PURE__ */ jsxs(
|
|
126
|
-
TooltipPrimitive.Content,
|
|
127
|
-
{
|
|
128
|
-
"data-slot": "tooltip-content",
|
|
129
|
-
sideOffset,
|
|
130
|
-
className: cn(
|
|
131
|
-
"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)",
|
|
132
|
-
className
|
|
133
|
-
),
|
|
134
|
-
...props,
|
|
135
|
-
children: [
|
|
136
|
-
children,
|
|
137
|
-
/* @__PURE__ */ jsx(TooltipPrimitive.Arrow, { className: "size-2.5 rotate-45 rounded-[2px] bg-foreground fill-foreground z-50 translate-y-[calc(-50%_-_2px)]" })
|
|
138
|
-
]
|
|
139
|
-
}
|
|
140
|
-
) });
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
// src/components/ui/sidebar.tsx
|
|
144
|
-
import * as React from "react";
|
|
145
|
-
import { cva as cva2 } from "class-variance-authority";
|
|
146
|
-
import { Slot as Slot2 } from "radix-ui";
|
|
147
|
-
import { PanelLeft } from "lucide-react";
|
|
148
|
-
|
|
149
|
-
// src/hooks/use-mobile.ts
|
|
150
|
-
import { useEffect, useState } from "react";
|
|
151
|
-
var MOBILE_BREAKPOINT = 768;
|
|
152
|
-
function useIsMobile() {
|
|
153
|
-
const [isMobile, setIsMobile] = useState(void 0);
|
|
154
|
-
useEffect(() => {
|
|
155
|
-
const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`);
|
|
156
|
-
const onChange = () => setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
|
|
157
|
-
mql.addEventListener("change", onChange);
|
|
158
|
-
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
|
|
159
|
-
return () => mql.removeEventListener("change", onChange);
|
|
160
|
-
}, []);
|
|
161
|
-
return !!isMobile;
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
// src/components/ui/button.tsx
|
|
165
|
-
import { cva } from "class-variance-authority";
|
|
166
|
-
import { Slot } from "radix-ui";
|
|
167
|
-
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
168
|
-
var buttonVariants = cva(
|
|
169
|
-
"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",
|
|
170
|
-
{
|
|
171
|
-
variants: {
|
|
172
|
-
variant: {
|
|
173
|
-
default: "bg-primary text-primary-foreground hover:bg-primary/80",
|
|
174
|
-
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",
|
|
175
|
-
secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80 aria-expanded:bg-secondary aria-expanded:text-secondary-foreground",
|
|
176
|
-
ghost: "hover:bg-muted hover:text-foreground dark:hover:bg-muted/50 aria-expanded:bg-muted aria-expanded:text-foreground",
|
|
177
|
-
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",
|
|
178
|
-
link: "text-primary underline-offset-4 hover:underline"
|
|
179
|
-
},
|
|
180
|
-
size: {
|
|
181
|
-
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",
|
|
182
|
-
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",
|
|
183
|
-
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",
|
|
184
|
-
lg: "h-10 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-3 has-data-[icon=inline-start]:pl-3",
|
|
185
|
-
icon: "size-9",
|
|
186
|
-
"icon-xs": "size-6 rounded-[min(var(--radius-md),8px)] in-data-[slot=button-group]:rounded-md [&_svg:not([class*='size-'])]:size-3",
|
|
187
|
-
"icon-sm": "size-8 rounded-[min(var(--radius-md),10px)] in-data-[slot=button-group]:rounded-md",
|
|
188
|
-
"icon-lg": "size-10"
|
|
189
|
-
}
|
|
190
|
-
},
|
|
191
|
-
defaultVariants: {
|
|
192
|
-
variant: "default",
|
|
193
|
-
size: "default"
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
);
|
|
197
|
-
function Button({
|
|
198
|
-
className,
|
|
199
|
-
variant = "default",
|
|
200
|
-
size = "default",
|
|
201
|
-
asChild = false,
|
|
202
|
-
...props
|
|
203
|
-
}) {
|
|
204
|
-
const Comp = asChild ? Slot.Root : "button";
|
|
205
|
-
return /* @__PURE__ */ jsx2(
|
|
206
|
-
Comp,
|
|
207
|
-
{
|
|
208
|
-
"data-slot": "button",
|
|
209
|
-
"data-variant": variant,
|
|
210
|
-
"data-size": size,
|
|
211
|
-
className: cn(buttonVariants({ variant, size, className })),
|
|
212
|
-
...props
|
|
213
|
-
}
|
|
214
|
-
);
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
// src/components/ui/input.tsx
|
|
218
|
-
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
219
|
-
function Input({ className, type, ...props }) {
|
|
220
|
-
return /* @__PURE__ */ jsx3(
|
|
221
|
-
"input",
|
|
222
|
-
{
|
|
223
|
-
type,
|
|
224
|
-
"data-slot": "input",
|
|
225
|
-
className: cn(
|
|
226
|
-
"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",
|
|
227
|
-
className
|
|
228
|
-
),
|
|
229
|
-
...props
|
|
230
|
-
}
|
|
231
|
-
);
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
// src/components/ui/separator.tsx
|
|
235
|
-
import { Separator as SeparatorPrimitive } from "radix-ui";
|
|
236
|
-
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
237
|
-
function Separator({
|
|
238
|
-
className,
|
|
239
|
-
orientation = "horizontal",
|
|
240
|
-
decorative = true,
|
|
241
|
-
...props
|
|
242
|
-
}) {
|
|
243
|
-
return /* @__PURE__ */ jsx4(
|
|
244
|
-
SeparatorPrimitive.Root,
|
|
245
|
-
{
|
|
246
|
-
"data-slot": "separator",
|
|
247
|
-
decorative,
|
|
248
|
-
orientation,
|
|
249
|
-
className: cn(
|
|
250
|
-
"bg-border shrink-0 data-horizontal:h-px data-horizontal:w-full data-vertical:w-px data-vertical:self-stretch",
|
|
251
|
-
className
|
|
252
|
-
),
|
|
253
|
-
...props
|
|
254
|
-
}
|
|
255
|
-
);
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
// src/components/ui/sheet.tsx
|
|
259
|
-
import { Dialog as SheetPrimitive } from "radix-ui";
|
|
260
|
-
import { X } from "lucide-react";
|
|
261
|
-
import { jsx as jsx5, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
262
|
-
function Sheet({ ...props }) {
|
|
263
|
-
return /* @__PURE__ */ jsx5(SheetPrimitive.Root, { "data-slot": "sheet", ...props });
|
|
264
|
-
}
|
|
265
|
-
function SheetPortal({
|
|
266
|
-
...props
|
|
267
|
-
}) {
|
|
268
|
-
return /* @__PURE__ */ jsx5(SheetPrimitive.Portal, { "data-slot": "sheet-portal", ...props });
|
|
269
|
-
}
|
|
270
|
-
function SheetOverlay({
|
|
271
|
-
className,
|
|
272
|
-
...props
|
|
273
|
-
}) {
|
|
274
|
-
return /* @__PURE__ */ jsx5(
|
|
275
|
-
SheetPrimitive.Overlay,
|
|
276
|
-
{
|
|
277
|
-
"data-slot": "sheet-overlay",
|
|
278
|
-
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),
|
|
279
|
-
...props
|
|
280
|
-
}
|
|
281
|
-
);
|
|
282
|
-
}
|
|
283
|
-
function SheetContent({
|
|
284
|
-
className,
|
|
285
|
-
children,
|
|
286
|
-
side = "right",
|
|
287
|
-
showCloseButton = true,
|
|
288
|
-
...props
|
|
289
|
-
}) {
|
|
290
|
-
return /* @__PURE__ */ jsxs2(SheetPortal, { children: [
|
|
291
|
-
/* @__PURE__ */ jsx5(SheetOverlay, {}),
|
|
292
|
-
/* @__PURE__ */ jsxs2(
|
|
293
|
-
SheetPrimitive.Content,
|
|
294
|
-
{
|
|
295
|
-
"data-slot": "sheet-content",
|
|
296
|
-
"data-side": side,
|
|
297
|
-
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),
|
|
298
|
-
...props,
|
|
299
|
-
children: [
|
|
300
|
-
children,
|
|
301
|
-
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: [
|
|
302
|
-
/* @__PURE__ */ jsx5(X, {}),
|
|
303
|
-
/* @__PURE__ */ jsx5("span", { className: "sr-only", children: "Close" })
|
|
304
|
-
] }) })
|
|
305
|
-
]
|
|
306
|
-
}
|
|
307
|
-
)
|
|
308
|
-
] });
|
|
309
|
-
}
|
|
310
|
-
function SheetHeader({ className, ...props }) {
|
|
311
|
-
return /* @__PURE__ */ jsx5(
|
|
312
|
-
"div",
|
|
313
|
-
{
|
|
314
|
-
"data-slot": "sheet-header",
|
|
315
|
-
className: cn("gap-1.5 p-4 flex flex-col", className),
|
|
316
|
-
...props
|
|
317
|
-
}
|
|
318
|
-
);
|
|
319
|
-
}
|
|
320
|
-
function SheetTitle({
|
|
321
|
-
className,
|
|
322
|
-
...props
|
|
323
|
-
}) {
|
|
324
|
-
return /* @__PURE__ */ jsx5(
|
|
325
|
-
SheetPrimitive.Title,
|
|
326
|
-
{
|
|
327
|
-
"data-slot": "sheet-title",
|
|
328
|
-
className: cn("text-foreground font-medium", className),
|
|
329
|
-
...props
|
|
330
|
-
}
|
|
331
|
-
);
|
|
332
|
-
}
|
|
333
|
-
function SheetDescription({
|
|
334
|
-
className,
|
|
335
|
-
...props
|
|
336
|
-
}) {
|
|
337
|
-
return /* @__PURE__ */ jsx5(
|
|
338
|
-
SheetPrimitive.Description,
|
|
339
|
-
{
|
|
340
|
-
"data-slot": "sheet-description",
|
|
341
|
-
className: cn("text-muted-foreground text-sm", className),
|
|
342
|
-
...props
|
|
343
|
-
}
|
|
344
|
-
);
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
// src/components/ui/skeleton.tsx
|
|
348
|
-
import { jsx as jsx6 } from "react/jsx-runtime";
|
|
349
|
-
function Skeleton({ className, ...props }) {
|
|
350
|
-
return /* @__PURE__ */ jsx6(
|
|
351
|
-
"div",
|
|
352
|
-
{
|
|
353
|
-
"data-slot": "skeleton",
|
|
354
|
-
className: cn("bg-muted rounded-md animate-pulse", className),
|
|
355
|
-
...props
|
|
356
|
-
}
|
|
357
|
-
);
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
// src/components/ui/sidebar.tsx
|
|
361
|
-
import { jsx as jsx7, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
362
|
-
var SIDEBAR_STORAGE_KEY = "sidebar_state";
|
|
363
|
-
var SIDEBAR_WIDTH = "16rem";
|
|
364
|
-
var SIDEBAR_WIDTH_MOBILE = "18rem";
|
|
365
|
-
var SIDEBAR_WIDTH_ICON = "3.5rem";
|
|
366
|
-
var SIDEBAR_KEYBOARD_SHORTCUT = "b";
|
|
367
|
-
var SidebarContext = React.createContext(null);
|
|
368
|
-
function useSidebar() {
|
|
369
|
-
const context = React.useContext(SidebarContext);
|
|
370
|
-
if (!context) {
|
|
371
|
-
throw new Error("useSidebar must be used within a SidebarProvider.");
|
|
372
|
-
}
|
|
373
|
-
return context;
|
|
374
|
-
}
|
|
375
|
-
function SidebarProvider({
|
|
376
|
-
defaultOpen = true,
|
|
377
|
-
open: openProp,
|
|
378
|
-
onOpenChange: setOpenProp,
|
|
379
|
-
className,
|
|
380
|
-
style,
|
|
381
|
-
children,
|
|
382
|
-
...props
|
|
383
|
-
}) {
|
|
384
|
-
const isMobile = useIsMobile();
|
|
385
|
-
const [openMobile, setOpenMobile] = React.useState(false);
|
|
386
|
-
const [_open, _setOpen] = React.useState(() => {
|
|
387
|
-
if (typeof window === "undefined") return defaultOpen;
|
|
388
|
-
const stored = localStorage.getItem(SIDEBAR_STORAGE_KEY);
|
|
389
|
-
if (stored === "true") return true;
|
|
390
|
-
if (stored === "false") return false;
|
|
391
|
-
return defaultOpen;
|
|
392
|
-
});
|
|
393
|
-
const open = openProp ?? _open;
|
|
394
|
-
const setOpen = React.useCallback(
|
|
395
|
-
(value) => {
|
|
396
|
-
const openState = typeof value === "function" ? value(open) : value;
|
|
397
|
-
if (setOpenProp) {
|
|
398
|
-
setOpenProp(openState);
|
|
399
|
-
} else {
|
|
400
|
-
_setOpen(openState);
|
|
401
|
-
}
|
|
402
|
-
try {
|
|
403
|
-
localStorage.setItem(SIDEBAR_STORAGE_KEY, String(openState));
|
|
404
|
-
} catch {
|
|
405
|
-
}
|
|
406
|
-
},
|
|
407
|
-
[setOpenProp, open]
|
|
408
|
-
);
|
|
409
|
-
const toggleSidebar = React.useCallback(() => {
|
|
410
|
-
return isMobile ? setOpenMobile((open2) => !open2) : setOpen((open2) => !open2);
|
|
411
|
-
}, [isMobile, setOpen, setOpenMobile]);
|
|
412
|
-
React.useEffect(() => {
|
|
413
|
-
const handleKeyDown = (event) => {
|
|
414
|
-
if (event.key === SIDEBAR_KEYBOARD_SHORTCUT && (event.metaKey || event.ctrlKey)) {
|
|
415
|
-
event.preventDefault();
|
|
416
|
-
toggleSidebar();
|
|
417
|
-
}
|
|
418
|
-
};
|
|
419
|
-
window.addEventListener("keydown", handleKeyDown);
|
|
420
|
-
return () => window.removeEventListener("keydown", handleKeyDown);
|
|
421
|
-
}, [toggleSidebar]);
|
|
422
|
-
const state = open ? "expanded" : "collapsed";
|
|
423
|
-
const contextValue = React.useMemo(
|
|
424
|
-
() => ({
|
|
425
|
-
state,
|
|
426
|
-
open,
|
|
427
|
-
setOpen,
|
|
428
|
-
isMobile,
|
|
429
|
-
openMobile,
|
|
430
|
-
setOpenMobile,
|
|
431
|
-
toggleSidebar
|
|
432
|
-
}),
|
|
433
|
-
[state, open, setOpen, isMobile, openMobile, setOpenMobile, toggleSidebar]
|
|
434
|
-
);
|
|
435
|
-
return /* @__PURE__ */ jsx7(SidebarContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx7(
|
|
436
|
-
"div",
|
|
437
|
-
{
|
|
438
|
-
"data-slot": "sidebar-wrapper",
|
|
439
|
-
style: {
|
|
440
|
-
"--sidebar-width": SIDEBAR_WIDTH,
|
|
441
|
-
"--sidebar-width-icon": SIDEBAR_WIDTH_ICON,
|
|
442
|
-
...style
|
|
443
|
-
},
|
|
444
|
-
className: cn(
|
|
445
|
-
"group/sidebar-wrapper has-data-[variant=inset]:bg-sidebar flex min-h-svh w-full",
|
|
446
|
-
className
|
|
447
|
-
),
|
|
448
|
-
...props,
|
|
449
|
-
children
|
|
450
|
-
}
|
|
451
|
-
) });
|
|
452
|
-
}
|
|
453
|
-
function Sidebar({
|
|
454
|
-
side = "left",
|
|
455
|
-
variant = "sidebar",
|
|
456
|
-
collapsible = "offcanvas",
|
|
457
|
-
className,
|
|
458
|
-
children,
|
|
459
|
-
dir,
|
|
460
|
-
...props
|
|
461
|
-
}) {
|
|
462
|
-
const { isMobile, state, openMobile, setOpenMobile } = useSidebar();
|
|
463
|
-
if (collapsible === "none") {
|
|
464
|
-
return /* @__PURE__ */ jsx7(
|
|
465
|
-
"div",
|
|
466
|
-
{
|
|
467
|
-
"data-slot": "sidebar",
|
|
468
|
-
className: cn(
|
|
469
|
-
"bg-sidebar text-sidebar-foreground flex h-full w-(--sidebar-width) flex-col",
|
|
470
|
-
className
|
|
471
|
-
),
|
|
472
|
-
...props,
|
|
473
|
-
children
|
|
474
|
-
}
|
|
475
|
-
);
|
|
476
|
-
}
|
|
477
|
-
if (isMobile) {
|
|
478
|
-
return /* @__PURE__ */ jsx7(Sheet, { open: openMobile, onOpenChange: setOpenMobile, ...props, children: /* @__PURE__ */ jsxs3(
|
|
479
|
-
SheetContent,
|
|
480
|
-
{
|
|
481
|
-
dir,
|
|
482
|
-
"data-sidebar": "sidebar",
|
|
483
|
-
"data-slot": "sidebar",
|
|
484
|
-
"data-mobile": "true",
|
|
485
|
-
className: "bg-sidebar text-sidebar-foreground w-(--sidebar-width) p-0 [&>button]:hidden",
|
|
486
|
-
style: {
|
|
487
|
-
"--sidebar-width": SIDEBAR_WIDTH_MOBILE
|
|
488
|
-
},
|
|
489
|
-
side,
|
|
490
|
-
children: [
|
|
491
|
-
/* @__PURE__ */ jsxs3(SheetHeader, { className: "sr-only", children: [
|
|
492
|
-
/* @__PURE__ */ jsx7(SheetTitle, { children: "Sidebar" }),
|
|
493
|
-
/* @__PURE__ */ jsx7(SheetDescription, { children: "Displays the mobile sidebar." })
|
|
494
|
-
] }),
|
|
495
|
-
/* @__PURE__ */ jsx7("div", { className: "flex h-full w-full flex-col", children })
|
|
496
|
-
]
|
|
497
|
-
}
|
|
498
|
-
) });
|
|
499
|
-
}
|
|
500
|
-
return /* @__PURE__ */ jsxs3(
|
|
501
|
-
"div",
|
|
502
|
-
{
|
|
503
|
-
className: "group peer text-sidebar-foreground hidden md:block",
|
|
504
|
-
"data-state": state,
|
|
505
|
-
"data-collapsible": state === "collapsed" ? collapsible : "",
|
|
506
|
-
"data-variant": variant,
|
|
507
|
-
"data-side": side,
|
|
508
|
-
"data-slot": "sidebar",
|
|
509
|
-
children: [
|
|
510
|
-
/* @__PURE__ */ jsx7(
|
|
511
|
-
"div",
|
|
512
|
-
{
|
|
513
|
-
"data-slot": "sidebar-gap",
|
|
514
|
-
className: cn(
|
|
515
|
-
"transition-[width] duration-200 ease-linear relative w-(--sidebar-width) bg-transparent",
|
|
516
|
-
"group-data-[collapsible=offcanvas]:w-0",
|
|
517
|
-
"group-data-[side=right]:rotate-180",
|
|
518
|
-
variant === "floating" || variant === "inset" ? "group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4)))]" : "group-data-[collapsible=icon]:w-(--sidebar-width-icon)"
|
|
519
|
-
)
|
|
520
|
-
}
|
|
521
|
-
),
|
|
522
|
-
/* @__PURE__ */ jsx7(
|
|
523
|
-
"div",
|
|
524
|
-
{
|
|
525
|
-
"data-slot": "sidebar-container",
|
|
526
|
-
"data-side": side,
|
|
527
|
-
className: cn(
|
|
528
|
-
"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",
|
|
529
|
-
// Adjust the padding for floating and inset variants.
|
|
530
|
-
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",
|
|
531
|
-
className
|
|
532
|
-
),
|
|
533
|
-
...props,
|
|
534
|
-
children: /* @__PURE__ */ jsx7(
|
|
535
|
-
"div",
|
|
536
|
-
{
|
|
537
|
-
"data-sidebar": "sidebar",
|
|
538
|
-
"data-slot": "sidebar-inner",
|
|
539
|
-
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",
|
|
540
|
-
children
|
|
541
|
-
}
|
|
542
|
-
)
|
|
543
|
-
}
|
|
544
|
-
)
|
|
545
|
-
]
|
|
546
|
-
}
|
|
547
|
-
);
|
|
548
|
-
}
|
|
549
|
-
function SidebarTrigger({
|
|
550
|
-
className,
|
|
551
|
-
onClick,
|
|
552
|
-
...props
|
|
553
|
-
}) {
|
|
554
|
-
const { toggleSidebar } = useSidebar();
|
|
555
|
-
return /* @__PURE__ */ jsxs3(
|
|
556
|
-
Button,
|
|
557
|
-
{
|
|
558
|
-
"data-sidebar": "trigger",
|
|
559
|
-
"data-slot": "sidebar-trigger",
|
|
560
|
-
variant: "ghost",
|
|
561
|
-
size: "icon-sm",
|
|
562
|
-
className: cn(className),
|
|
563
|
-
onClick: (event) => {
|
|
564
|
-
onClick?.(event);
|
|
565
|
-
toggleSidebar();
|
|
566
|
-
},
|
|
567
|
-
...props,
|
|
568
|
-
children: [
|
|
569
|
-
/* @__PURE__ */ jsx7(PanelLeft, {}),
|
|
570
|
-
/* @__PURE__ */ jsx7("span", { className: "sr-only", children: "Toggle Sidebar" })
|
|
571
|
-
]
|
|
572
|
-
}
|
|
573
|
-
);
|
|
574
|
-
}
|
|
575
|
-
function SidebarRail({ className, ...props }) {
|
|
576
|
-
const { toggleSidebar } = useSidebar();
|
|
577
|
-
return /* @__PURE__ */ jsx7(
|
|
578
|
-
"button",
|
|
579
|
-
{
|
|
580
|
-
"data-sidebar": "rail",
|
|
581
|
-
"data-slot": "sidebar-rail",
|
|
582
|
-
"aria-label": "Toggle Sidebar",
|
|
583
|
-
tabIndex: -1,
|
|
584
|
-
onClick: toggleSidebar,
|
|
585
|
-
title: "Toggle Sidebar",
|
|
586
|
-
className: cn(
|
|
587
|
-
"hover:after:bg-sidebar-border absolute inset-y-0 z-20 hidden w-4 transition-all ease-linear group-data-[side=left]:-right-4 group-data-[side=right]:left-0 after:absolute after:inset-y-0 after:start-1/2 after:w-[2px] sm:flex ltr:-translate-x-1/2 rtl:-translate-x-1/2",
|
|
588
|
-
"in-data-[side=left]:cursor-w-resize in-data-[side=right]:cursor-e-resize",
|
|
589
|
-
"[[data-side=left][data-state=collapsed]_&]:cursor-e-resize [[data-side=right][data-state=collapsed]_&]:cursor-w-resize",
|
|
590
|
-
"hover:group-data-[collapsible=offcanvas]:bg-sidebar group-data-[collapsible=offcanvas]:translate-x-0 group-data-[collapsible=offcanvas]:after:left-full",
|
|
591
|
-
"[[data-side=left][data-collapsible=offcanvas]_&]:-right-2",
|
|
592
|
-
"[[data-side=right][data-collapsible=offcanvas]_&]:-left-2",
|
|
593
|
-
className
|
|
594
|
-
),
|
|
595
|
-
...props
|
|
596
|
-
}
|
|
597
|
-
);
|
|
598
|
-
}
|
|
599
|
-
function SidebarInset({ className, ...props }) {
|
|
600
|
-
return /* @__PURE__ */ jsx7(
|
|
601
|
-
"main",
|
|
602
|
-
{
|
|
603
|
-
"data-slot": "sidebar-inset",
|
|
604
|
-
className: cn(
|
|
605
|
-
"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",
|
|
606
|
-
className
|
|
607
|
-
),
|
|
608
|
-
...props
|
|
609
|
-
}
|
|
610
|
-
);
|
|
611
|
-
}
|
|
612
|
-
function SidebarHeader({ className, ...props }) {
|
|
613
|
-
return /* @__PURE__ */ jsx7(
|
|
614
|
-
"div",
|
|
615
|
-
{
|
|
616
|
-
"data-slot": "sidebar-header",
|
|
617
|
-
"data-sidebar": "header",
|
|
618
|
-
className: cn("gap-2 p-2 flex flex-col", className),
|
|
619
|
-
...props
|
|
620
|
-
}
|
|
621
|
-
);
|
|
622
|
-
}
|
|
623
|
-
function SidebarFooter({ className, ...props }) {
|
|
624
|
-
return /* @__PURE__ */ jsx7(
|
|
625
|
-
"div",
|
|
626
|
-
{
|
|
627
|
-
"data-slot": "sidebar-footer",
|
|
628
|
-
"data-sidebar": "footer",
|
|
629
|
-
className: cn("gap-2 p-2 flex flex-col", className),
|
|
630
|
-
...props
|
|
631
|
-
}
|
|
632
|
-
);
|
|
633
|
-
}
|
|
634
|
-
function SidebarContent({ className, ...props }) {
|
|
635
|
-
return /* @__PURE__ */ jsx7(
|
|
636
|
-
"div",
|
|
637
|
-
{
|
|
638
|
-
"data-slot": "sidebar-content",
|
|
639
|
-
"data-sidebar": "content",
|
|
640
|
-
className: cn(
|
|
641
|
-
"no-scrollbar gap-2 flex min-h-0 flex-1 flex-col overflow-auto group-data-[collapsible=icon]:overflow-hidden",
|
|
642
|
-
className
|
|
643
|
-
),
|
|
644
|
-
...props
|
|
645
|
-
}
|
|
646
|
-
);
|
|
647
|
-
}
|
|
648
|
-
function SidebarGroup({ className, ...props }) {
|
|
649
|
-
return /* @__PURE__ */ jsx7(
|
|
650
|
-
"div",
|
|
651
|
-
{
|
|
652
|
-
"data-slot": "sidebar-group",
|
|
653
|
-
"data-sidebar": "group",
|
|
654
|
-
className: cn(
|
|
655
|
-
"p-2 relative flex w-full min-w-0 flex-col",
|
|
656
|
-
className
|
|
657
|
-
),
|
|
658
|
-
...props
|
|
659
|
-
}
|
|
660
|
-
);
|
|
661
|
-
}
|
|
662
|
-
function SidebarGroupLabel({
|
|
663
|
-
className,
|
|
664
|
-
asChild = false,
|
|
665
|
-
...props
|
|
666
|
-
}) {
|
|
667
|
-
const Comp = asChild ? Slot2.Root : "div";
|
|
668
|
-
return /* @__PURE__ */ jsx7(
|
|
669
|
-
Comp,
|
|
670
|
-
{
|
|
671
|
-
"data-slot": "sidebar-group-label",
|
|
672
|
-
"data-sidebar": "group-label",
|
|
673
|
-
className: cn(
|
|
674
|
-
"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",
|
|
675
|
-
className
|
|
676
|
-
),
|
|
677
|
-
...props
|
|
678
|
-
}
|
|
679
|
-
);
|
|
680
|
-
}
|
|
681
|
-
function SidebarGroupContent({
|
|
682
|
-
className,
|
|
683
|
-
...props
|
|
684
|
-
}) {
|
|
685
|
-
return /* @__PURE__ */ jsx7(
|
|
686
|
-
"div",
|
|
687
|
-
{
|
|
688
|
-
"data-slot": "sidebar-group-content",
|
|
689
|
-
"data-sidebar": "group-content",
|
|
690
|
-
className: cn("text-sm w-full", className),
|
|
691
|
-
...props
|
|
692
|
-
}
|
|
693
|
-
);
|
|
694
|
-
}
|
|
695
|
-
function SidebarMenu({ className, ...props }) {
|
|
696
|
-
return /* @__PURE__ */ jsx7(
|
|
697
|
-
"ul",
|
|
698
|
-
{
|
|
699
|
-
"data-slot": "sidebar-menu",
|
|
700
|
-
"data-sidebar": "menu",
|
|
701
|
-
className: cn("gap-1 flex w-full min-w-0 flex-col", className),
|
|
702
|
-
...props
|
|
703
|
-
}
|
|
704
|
-
);
|
|
705
|
-
}
|
|
706
|
-
function SidebarMenuItem({ className, ...props }) {
|
|
707
|
-
return /* @__PURE__ */ jsx7(
|
|
708
|
-
"li",
|
|
709
|
-
{
|
|
710
|
-
"data-slot": "sidebar-menu-item",
|
|
711
|
-
"data-sidebar": "menu-item",
|
|
712
|
-
className: cn("group/menu-item relative", className),
|
|
713
|
-
...props
|
|
714
|
-
}
|
|
715
|
-
);
|
|
716
|
-
}
|
|
717
|
-
var sidebarMenuButtonVariants = cva2(
|
|
718
|
-
"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",
|
|
719
|
-
{
|
|
720
|
-
variants: {
|
|
721
|
-
variant: {
|
|
722
|
-
default: "hover:bg-sidebar-accent hover:text-sidebar-accent-foreground",
|
|
723
|
-
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))]"
|
|
724
|
-
},
|
|
725
|
-
size: {
|
|
726
|
-
default: "h-8 text-sm",
|
|
727
|
-
sm: "h-7 text-xs",
|
|
728
|
-
lg: "h-12 text-sm group-data-[collapsible=icon]:p-0!"
|
|
729
|
-
}
|
|
730
|
-
},
|
|
731
|
-
defaultVariants: {
|
|
732
|
-
variant: "default",
|
|
733
|
-
size: "default"
|
|
734
|
-
}
|
|
735
|
-
}
|
|
736
|
-
);
|
|
737
|
-
function SidebarMenuButton({
|
|
738
|
-
asChild = false,
|
|
739
|
-
isActive = false,
|
|
740
|
-
variant = "default",
|
|
741
|
-
size = "default",
|
|
742
|
-
tooltip,
|
|
743
|
-
className,
|
|
744
|
-
...props
|
|
745
|
-
}) {
|
|
746
|
-
const Comp = asChild ? Slot2.Root : "button";
|
|
747
|
-
const { isMobile, state } = useSidebar();
|
|
748
|
-
const button = /* @__PURE__ */ jsx7(
|
|
749
|
-
Comp,
|
|
750
|
-
{
|
|
751
|
-
"data-slot": "sidebar-menu-button",
|
|
752
|
-
"data-sidebar": "menu-button",
|
|
753
|
-
"data-size": size,
|
|
754
|
-
"data-active": isActive,
|
|
755
|
-
className: cn(sidebarMenuButtonVariants({ variant, size }), className),
|
|
756
|
-
...props
|
|
757
|
-
}
|
|
758
|
-
);
|
|
759
|
-
if (!tooltip) {
|
|
760
|
-
return button;
|
|
761
|
-
}
|
|
762
|
-
if (typeof tooltip === "string") {
|
|
763
|
-
tooltip = {
|
|
764
|
-
children: tooltip
|
|
765
|
-
};
|
|
766
|
-
}
|
|
767
|
-
return /* @__PURE__ */ jsxs3(Tooltip, { children: [
|
|
768
|
-
/* @__PURE__ */ jsx7(TooltipTrigger, { asChild: true, children: button }),
|
|
769
|
-
/* @__PURE__ */ jsx7(
|
|
770
|
-
TooltipContent,
|
|
771
|
-
{
|
|
772
|
-
side: "right",
|
|
773
|
-
align: "center",
|
|
774
|
-
hidden: state !== "collapsed" || isMobile,
|
|
775
|
-
...tooltip
|
|
776
|
-
}
|
|
777
|
-
)
|
|
778
|
-
] });
|
|
779
|
-
}
|
|
780
|
-
|
|
781
142
|
// src/components/app-sidebar.tsx
|
|
782
|
-
import { useState
|
|
143
|
+
import { useState, useEffect, memo } from "react";
|
|
783
144
|
import { usePathname, useRouter } from "next/navigation";
|
|
784
145
|
import Link from "next/link";
|
|
785
|
-
import { ChevronsUpDown, ChevronRight
|
|
786
|
-
|
|
787
|
-
// src/components/ui/collapsible.tsx
|
|
788
|
-
import { Collapsible as CollapsiblePrimitive } from "radix-ui";
|
|
789
|
-
import { jsx as jsx8 } from "react/jsx-runtime";
|
|
790
|
-
function Collapsible({
|
|
791
|
-
...props
|
|
792
|
-
}) {
|
|
793
|
-
return /* @__PURE__ */ jsx8(CollapsiblePrimitive.Root, { "data-slot": "collapsible", ...props });
|
|
794
|
-
}
|
|
795
|
-
function CollapsibleTrigger({
|
|
796
|
-
...props
|
|
797
|
-
}) {
|
|
798
|
-
return /* @__PURE__ */ jsx8(
|
|
799
|
-
CollapsiblePrimitive.CollapsibleTrigger,
|
|
800
|
-
{
|
|
801
|
-
"data-slot": "collapsible-trigger",
|
|
802
|
-
...props
|
|
803
|
-
}
|
|
804
|
-
);
|
|
805
|
-
}
|
|
806
|
-
function CollapsibleContent({
|
|
807
|
-
className,
|
|
808
|
-
...props
|
|
809
|
-
}) {
|
|
810
|
-
return /* @__PURE__ */ jsx8(
|
|
811
|
-
CollapsiblePrimitive.CollapsibleContent,
|
|
812
|
-
{
|
|
813
|
-
"data-slot": "collapsible-content",
|
|
814
|
-
className: cn(
|
|
815
|
-
"overflow-hidden data-[state=closed]:animate-collapsible-up data-[state=open]:animate-collapsible-down",
|
|
816
|
-
className
|
|
817
|
-
),
|
|
818
|
-
...props
|
|
819
|
-
}
|
|
820
|
-
);
|
|
821
|
-
}
|
|
822
|
-
|
|
823
|
-
// src/components/ui/dropdown-menu.tsx
|
|
824
|
-
import { DropdownMenu as DropdownMenuPrimitive } from "radix-ui";
|
|
825
|
-
import { Check, ChevronRight } from "lucide-react";
|
|
826
|
-
import { jsx as jsx9, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
827
|
-
function DropdownMenu({
|
|
828
|
-
...props
|
|
829
|
-
}) {
|
|
830
|
-
return /* @__PURE__ */ jsx9(DropdownMenuPrimitive.Root, { "data-slot": "dropdown-menu", ...props });
|
|
831
|
-
}
|
|
832
|
-
function DropdownMenuTrigger({
|
|
833
|
-
...props
|
|
834
|
-
}) {
|
|
835
|
-
return /* @__PURE__ */ jsx9(
|
|
836
|
-
DropdownMenuPrimitive.Trigger,
|
|
837
|
-
{
|
|
838
|
-
"data-slot": "dropdown-menu-trigger",
|
|
839
|
-
...props
|
|
840
|
-
}
|
|
841
|
-
);
|
|
842
|
-
}
|
|
843
|
-
function DropdownMenuContent({
|
|
844
|
-
className,
|
|
845
|
-
align = "start",
|
|
846
|
-
sideOffset = 4,
|
|
847
|
-
...props
|
|
848
|
-
}) {
|
|
849
|
-
return /* @__PURE__ */ jsx9(DropdownMenuPrimitive.Portal, { children: /* @__PURE__ */ jsx9(
|
|
850
|
-
DropdownMenuPrimitive.Content,
|
|
851
|
-
{
|
|
852
|
-
"data-slot": "dropdown-menu-content",
|
|
853
|
-
sideOffset,
|
|
854
|
-
align,
|
|
855
|
-
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),
|
|
856
|
-
...props
|
|
857
|
-
}
|
|
858
|
-
) });
|
|
859
|
-
}
|
|
860
|
-
function DropdownMenuItem({
|
|
861
|
-
className,
|
|
862
|
-
inset,
|
|
863
|
-
variant = "default",
|
|
864
|
-
...props
|
|
865
|
-
}) {
|
|
866
|
-
return /* @__PURE__ */ jsx9(
|
|
867
|
-
DropdownMenuPrimitive.Item,
|
|
868
|
-
{
|
|
869
|
-
"data-slot": "dropdown-menu-item",
|
|
870
|
-
"data-inset": inset,
|
|
871
|
-
"data-variant": variant,
|
|
872
|
-
className: cn(
|
|
873
|
-
"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",
|
|
874
|
-
className
|
|
875
|
-
),
|
|
876
|
-
...props
|
|
877
|
-
}
|
|
878
|
-
);
|
|
879
|
-
}
|
|
880
|
-
function DropdownMenuLabel({
|
|
881
|
-
className,
|
|
882
|
-
inset,
|
|
883
|
-
...props
|
|
884
|
-
}) {
|
|
885
|
-
return /* @__PURE__ */ jsx9(
|
|
886
|
-
DropdownMenuPrimitive.Label,
|
|
887
|
-
{
|
|
888
|
-
"data-slot": "dropdown-menu-label",
|
|
889
|
-
"data-inset": inset,
|
|
890
|
-
className: cn("text-muted-foreground px-2 py-1.5 text-xs font-medium data-inset:pl-8", className),
|
|
891
|
-
...props
|
|
892
|
-
}
|
|
893
|
-
);
|
|
894
|
-
}
|
|
895
|
-
function DropdownMenuSeparator({
|
|
896
|
-
className,
|
|
897
|
-
...props
|
|
898
|
-
}) {
|
|
899
|
-
return /* @__PURE__ */ jsx9(
|
|
900
|
-
DropdownMenuPrimitive.Separator,
|
|
901
|
-
{
|
|
902
|
-
"data-slot": "dropdown-menu-separator",
|
|
903
|
-
className: cn("bg-border -mx-1 my-1 h-px", className),
|
|
904
|
-
...props
|
|
905
|
-
}
|
|
906
|
-
);
|
|
907
|
-
}
|
|
908
|
-
|
|
909
|
-
// src/components/ui/avatar.tsx
|
|
910
|
-
import { Avatar as AvatarPrimitive } from "radix-ui";
|
|
911
|
-
import { jsx as jsx10 } from "react/jsx-runtime";
|
|
912
|
-
function Avatar({
|
|
913
|
-
className,
|
|
914
|
-
size = "default",
|
|
915
|
-
...props
|
|
916
|
-
}) {
|
|
917
|
-
return /* @__PURE__ */ jsx10(
|
|
918
|
-
AvatarPrimitive.Root,
|
|
919
|
-
{
|
|
920
|
-
"data-slot": "avatar",
|
|
921
|
-
"data-size": size,
|
|
922
|
-
className: cn(
|
|
923
|
-
"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",
|
|
924
|
-
className
|
|
925
|
-
),
|
|
926
|
-
...props
|
|
927
|
-
}
|
|
928
|
-
);
|
|
929
|
-
}
|
|
930
|
-
function AvatarImage({
|
|
931
|
-
className,
|
|
932
|
-
...props
|
|
933
|
-
}) {
|
|
934
|
-
return /* @__PURE__ */ jsx10(
|
|
935
|
-
AvatarPrimitive.Image,
|
|
936
|
-
{
|
|
937
|
-
"data-slot": "avatar-image",
|
|
938
|
-
className: cn(
|
|
939
|
-
"rounded-full aspect-square size-full object-cover",
|
|
940
|
-
className
|
|
941
|
-
),
|
|
942
|
-
...props
|
|
943
|
-
}
|
|
944
|
-
);
|
|
945
|
-
}
|
|
946
|
-
function AvatarFallback({
|
|
947
|
-
className,
|
|
948
|
-
...props
|
|
949
|
-
}) {
|
|
950
|
-
return /* @__PURE__ */ jsx10(
|
|
951
|
-
AvatarPrimitive.Fallback,
|
|
952
|
-
{
|
|
953
|
-
"data-slot": "avatar-fallback",
|
|
954
|
-
className: cn(
|
|
955
|
-
"bg-muted text-muted-foreground rounded-full flex size-full items-center justify-center text-sm group-data-[size=sm]/avatar:text-xs",
|
|
956
|
-
className
|
|
957
|
-
),
|
|
958
|
-
...props
|
|
959
|
-
}
|
|
960
|
-
);
|
|
961
|
-
}
|
|
962
|
-
|
|
963
|
-
// src/components/ui/badge.tsx
|
|
964
|
-
import { cva as cva3 } from "class-variance-authority";
|
|
965
|
-
import { Slot as Slot3 } from "radix-ui";
|
|
966
|
-
import { jsx as jsx11 } from "react/jsx-runtime";
|
|
967
|
-
var badgeVariants = cva3(
|
|
968
|
-
"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",
|
|
969
|
-
{
|
|
970
|
-
variants: {
|
|
971
|
-
variant: {
|
|
972
|
-
default: "bg-primary text-primary-foreground [a]:hover:bg-primary/80",
|
|
973
|
-
secondary: "bg-secondary text-secondary-foreground [a]:hover:bg-secondary/80",
|
|
974
|
-
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",
|
|
975
|
-
outline: "border-border text-foreground [a]:hover:bg-muted [a]:hover:text-muted-foreground",
|
|
976
|
-
ghost: "hover:bg-muted hover:text-muted-foreground dark:hover:bg-muted/50",
|
|
977
|
-
link: "text-primary underline-offset-4 hover:underline"
|
|
978
|
-
}
|
|
979
|
-
},
|
|
980
|
-
defaultVariants: {
|
|
981
|
-
variant: "default"
|
|
982
|
-
}
|
|
983
|
-
}
|
|
984
|
-
);
|
|
985
|
-
function Badge({
|
|
986
|
-
className,
|
|
987
|
-
variant = "default",
|
|
988
|
-
asChild = false,
|
|
989
|
-
...props
|
|
990
|
-
}) {
|
|
991
|
-
const Comp = asChild ? Slot3.Root : "span";
|
|
992
|
-
return /* @__PURE__ */ jsx11(
|
|
993
|
-
Comp,
|
|
994
|
-
{
|
|
995
|
-
"data-slot": "badge",
|
|
996
|
-
"data-variant": variant,
|
|
997
|
-
className: cn(badgeVariants({ variant }), className),
|
|
998
|
-
...props
|
|
999
|
-
}
|
|
1000
|
-
);
|
|
1001
|
-
}
|
|
1002
|
-
|
|
1003
|
-
// src/components/app-sidebar.tsx
|
|
1004
|
-
import { jsx as jsx12, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
146
|
+
import { ChevronsUpDown, ChevronRight, LogOut } from "lucide-react";
|
|
147
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
1005
148
|
function getUserInitials(name, email) {
|
|
1006
149
|
if (!name) return email?.[0]?.toUpperCase() || "?";
|
|
1007
150
|
const parts = name.trim().split(/\s+/);
|
|
@@ -1010,43 +153,43 @@ function getUserInitials(name, email) {
|
|
|
1010
153
|
}
|
|
1011
154
|
return parts[0][0].toUpperCase();
|
|
1012
155
|
}
|
|
1013
|
-
|
|
156
|
+
var SimpleMenuItem = memo(function SimpleMenuItem2({ item, pathname }) {
|
|
1014
157
|
const isActive = item.isActive ?? pathname.startsWith(item.href);
|
|
1015
158
|
const Icon = item.icon;
|
|
1016
|
-
return /* @__PURE__ */
|
|
1017
|
-
/* @__PURE__ */
|
|
1018
|
-
/* @__PURE__ */
|
|
1019
|
-
item.badge != null && /* @__PURE__ */
|
|
159
|
+
return /* @__PURE__ */ jsx(SidebarMenuItem, { children: /* @__PURE__ */ jsx(SidebarMenuButton, { asChild: true, isActive, tooltip: item.label, children: /* @__PURE__ */ jsxs(Link, { href: item.href, onClick: item.onClick, "aria-current": isActive ? "page" : void 0, children: [
|
|
160
|
+
/* @__PURE__ */ jsx(Icon, { className: "size-4" }),
|
|
161
|
+
/* @__PURE__ */ jsx("span", { children: item.label }),
|
|
162
|
+
item.badge != null && /* @__PURE__ */ jsx("span", { className: "ml-auto flex h-5 min-w-5 items-center justify-center rounded-full bg-primary/10 px-1.5 text-[10px] font-semibold text-primary tabular-nums", children: item.badge })
|
|
1020
163
|
] }) }) });
|
|
1021
|
-
}
|
|
1022
|
-
|
|
164
|
+
});
|
|
165
|
+
var CollapsibleMenuItem = memo(function CollapsibleMenuItem2({ item, pathname }) {
|
|
1023
166
|
const Icon = item.icon;
|
|
1024
167
|
const isParentActive = pathname.startsWith(item.href);
|
|
1025
168
|
const isChildActive = item.children?.some(
|
|
1026
169
|
(child) => child.isActive !== void 0 ? child.isActive : pathname.startsWith(child.href)
|
|
1027
170
|
) ?? false;
|
|
1028
171
|
const isActive = isParentActive || isChildActive;
|
|
1029
|
-
const [open, setOpen] =
|
|
1030
|
-
|
|
1031
|
-
setOpen(isActive);
|
|
172
|
+
const [open, setOpen] = useState(isActive);
|
|
173
|
+
useEffect(() => {
|
|
174
|
+
if (open !== isActive) setOpen(isActive);
|
|
1032
175
|
}, [isActive]);
|
|
1033
|
-
return /* @__PURE__ */
|
|
1034
|
-
/* @__PURE__ */
|
|
1035
|
-
/* @__PURE__ */
|
|
1036
|
-
/* @__PURE__ */
|
|
176
|
+
return /* @__PURE__ */ jsx(Collapsible, { open, onOpenChange: setOpen, className: "group/collapsible", children: /* @__PURE__ */ jsxs(SidebarMenuItem, { children: [
|
|
177
|
+
/* @__PURE__ */ jsx(SidebarMenuButton, { asChild: true, isActive: isParentActive, tooltip: item.label, children: /* @__PURE__ */ jsxs(Link, { href: item.href, onClick: item.onClick, children: [
|
|
178
|
+
/* @__PURE__ */ jsx(Icon, { className: "size-4" }),
|
|
179
|
+
/* @__PURE__ */ jsx("span", { children: item.label })
|
|
1037
180
|
] }) }),
|
|
1038
|
-
/* @__PURE__ */
|
|
181
|
+
/* @__PURE__ */ jsx(CollapsibleTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
|
|
1039
182
|
"button",
|
|
1040
183
|
{
|
|
1041
184
|
"data-sidebar": "menu-action",
|
|
1042
185
|
className: "absolute right-1 top-1.5 flex h-5 w-5 items-center justify-center rounded-md text-sidebar-foreground hover:bg-sidebar-accent hover:text-sidebar-accent-foreground outline-hidden focus-visible:ring-2 ring-sidebar-ring transition-colors group-data-[collapsible=icon]:hidden after:absolute after:-inset-2 md:after:hidden",
|
|
1043
186
|
"aria-label": "Expandir submenu",
|
|
1044
|
-
children: /* @__PURE__ */
|
|
187
|
+
children: /* @__PURE__ */ jsx(ChevronRight, { className: "size-3.5 shrink-0 transition-transform duration-200 group-data-[state=open]/collapsible:rotate-90" })
|
|
1045
188
|
}
|
|
1046
189
|
) }),
|
|
1047
|
-
/* @__PURE__ */
|
|
190
|
+
/* @__PURE__ */ jsx(CollapsibleContent, { children: /* @__PURE__ */ jsx(SidebarMenu, { className: "ml-4 border-l pl-2", children: item.children?.map((child) => /* @__PURE__ */ jsx(SimpleMenuItem, { item: child, pathname }, child.href + child.label)) }) })
|
|
1048
191
|
] }) });
|
|
1049
|
-
}
|
|
192
|
+
});
|
|
1050
193
|
function AppSidebar({ config }) {
|
|
1051
194
|
const pathname = usePathname();
|
|
1052
195
|
const router = useRouter();
|
|
@@ -1059,31 +202,31 @@ function AppSidebar({ config }) {
|
|
|
1059
202
|
const userEmail = session?.user?.email || "";
|
|
1060
203
|
const userImage = session?.user?.image || "";
|
|
1061
204
|
const initials = getUserInitials(userName, userEmail);
|
|
1062
|
-
return /* @__PURE__ */
|
|
1063
|
-
/* @__PURE__ */
|
|
1064
|
-
/* @__PURE__ */
|
|
1065
|
-
/* @__PURE__ */
|
|
1066
|
-
config.appBadge && /* @__PURE__ */
|
|
205
|
+
return /* @__PURE__ */ jsxs(Sidebar, { collapsible: "icon", children: [
|
|
206
|
+
/* @__PURE__ */ jsx(SidebarHeader, { children: /* @__PURE__ */ jsx(SidebarMenu, { children: /* @__PURE__ */ jsx(SidebarMenuItem, { children: /* @__PURE__ */ jsx(SidebarMenuButton, { size: "lg", asChild: true, children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 group-data-[collapsible=icon]:justify-center group-data-[collapsible=icon]:gap-0", children: [
|
|
207
|
+
/* @__PURE__ */ jsx("div", { className: "shrink-0", children: config.appIcon }),
|
|
208
|
+
/* @__PURE__ */ jsx("span", { className: "font-semibold truncate group-data-[collapsible=icon]:hidden", children: config.appName }),
|
|
209
|
+
config.appBadge && /* @__PURE__ */ jsx(Badge, { variant: "destructive", className: "group-data-[collapsible=icon]:hidden", children: config.appBadge })
|
|
1067
210
|
] }) }) }) }) }),
|
|
1068
|
-
/* @__PURE__ */
|
|
1069
|
-
/* @__PURE__ */
|
|
1070
|
-
/* @__PURE__ */
|
|
1071
|
-
(item) => item.children && item.children.length > 0 ? /* @__PURE__ */
|
|
211
|
+
/* @__PURE__ */ jsx(SidebarContent, { children: config.menuGroups.map((group) => /* @__PURE__ */ jsxs(SidebarGroup, { children: [
|
|
212
|
+
/* @__PURE__ */ jsx(SidebarGroupLabel, { children: group.label }),
|
|
213
|
+
/* @__PURE__ */ jsx(SidebarGroupContent, { children: /* @__PURE__ */ jsx(SidebarMenu, { children: group.items.map(
|
|
214
|
+
(item) => item.children && item.children.length > 0 ? /* @__PURE__ */ jsx(CollapsibleMenuItem, { item, pathname }, item.href) : /* @__PURE__ */ jsx(SimpleMenuItem, { item, pathname }, item.href)
|
|
1072
215
|
) }) })
|
|
1073
216
|
] }, group.label)) }),
|
|
1074
|
-
/* @__PURE__ */
|
|
1075
|
-
/* @__PURE__ */
|
|
1076
|
-
/* @__PURE__ */
|
|
1077
|
-
userImage && /* @__PURE__ */
|
|
1078
|
-
/* @__PURE__ */
|
|
217
|
+
/* @__PURE__ */ jsx(SidebarFooter, { children: /* @__PURE__ */ jsx(SidebarMenu, { children: /* @__PURE__ */ jsx(SidebarMenuItem, { children: /* @__PURE__ */ jsxs(DropdownMenu, { children: [
|
|
218
|
+
/* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(SidebarMenuButton, { size: "lg", children: [
|
|
219
|
+
/* @__PURE__ */ jsxs(Avatar, { className: "size-8", children: [
|
|
220
|
+
userImage && /* @__PURE__ */ jsx(AvatarImage, { src: userImage, alt: userName }),
|
|
221
|
+
/* @__PURE__ */ jsx(AvatarFallback, { children: initials })
|
|
1079
222
|
] }),
|
|
1080
|
-
/* @__PURE__ */
|
|
1081
|
-
/* @__PURE__ */
|
|
1082
|
-
/* @__PURE__ */
|
|
223
|
+
/* @__PURE__ */ jsxs("div", { className: "grid flex-1 text-left text-sm leading-tight group-data-[collapsible=icon]:hidden", children: [
|
|
224
|
+
/* @__PURE__ */ jsx("span", { className: "truncate font-semibold", children: userName }),
|
|
225
|
+
/* @__PURE__ */ jsx("span", { className: "truncate text-xs text-muted-foreground", children: userEmail })
|
|
1083
226
|
] }),
|
|
1084
|
-
/* @__PURE__ */
|
|
227
|
+
/* @__PURE__ */ jsx(ChevronsUpDown, { "aria-hidden": "true", className: "ml-auto size-4 group-data-[collapsible=icon]:hidden" })
|
|
1085
228
|
] }) }),
|
|
1086
|
-
/* @__PURE__ */
|
|
229
|
+
/* @__PURE__ */ jsxs(
|
|
1087
230
|
DropdownMenuContent,
|
|
1088
231
|
{
|
|
1089
232
|
className: "w-(--radix-dropdown-menu-trigger-width) min-w-56",
|
|
@@ -1091,21 +234,21 @@ function AppSidebar({ config }) {
|
|
|
1091
234
|
align: "end",
|
|
1092
235
|
sideOffset: 4,
|
|
1093
236
|
children: [
|
|
1094
|
-
/* @__PURE__ */
|
|
1095
|
-
/* @__PURE__ */
|
|
1096
|
-
/* @__PURE__ */
|
|
237
|
+
/* @__PURE__ */ jsx(DropdownMenuLabel, { className: "font-normal", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col space-y-1", children: [
|
|
238
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm font-medium leading-none", children: userName }),
|
|
239
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs leading-none text-muted-foreground", children: userEmail })
|
|
1097
240
|
] }) }),
|
|
1098
|
-
/* @__PURE__ */
|
|
241
|
+
/* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
|
|
1099
242
|
config.footerExtra,
|
|
1100
|
-
/* @__PURE__ */
|
|
1101
|
-
/* @__PURE__ */
|
|
243
|
+
/* @__PURE__ */ jsxs(DropdownMenuItem, { onClick: handleLogout, children: [
|
|
244
|
+
/* @__PURE__ */ jsx(LogOut, { "aria-hidden": "true", className: "size-4" }),
|
|
1102
245
|
"Sair"
|
|
1103
246
|
] })
|
|
1104
247
|
]
|
|
1105
248
|
}
|
|
1106
249
|
)
|
|
1107
250
|
] }) }) }) }),
|
|
1108
|
-
/* @__PURE__ */
|
|
251
|
+
/* @__PURE__ */ jsx(SidebarRail, {})
|
|
1109
252
|
] });
|
|
1110
253
|
}
|
|
1111
254
|
|
|
@@ -1114,120 +257,14 @@ import { Fragment, useMemo as useMemo2 } from "react";
|
|
|
1114
257
|
import { usePathname as usePathname2 } from "next/navigation";
|
|
1115
258
|
import Link2 from "next/link";
|
|
1116
259
|
|
|
1117
|
-
// src/components/ui/breadcrumb.tsx
|
|
1118
|
-
import { Slot as Slot4 } from "radix-ui";
|
|
1119
|
-
import { ChevronRight as ChevronRight3, MoreHorizontal } from "lucide-react";
|
|
1120
|
-
import { jsx as jsx13, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1121
|
-
function Breadcrumb({ className, ...props }) {
|
|
1122
|
-
return /* @__PURE__ */ jsx13(
|
|
1123
|
-
"nav",
|
|
1124
|
-
{
|
|
1125
|
-
"aria-label": "breadcrumb",
|
|
1126
|
-
"data-slot": "breadcrumb",
|
|
1127
|
-
className: cn(className),
|
|
1128
|
-
...props
|
|
1129
|
-
}
|
|
1130
|
-
);
|
|
1131
|
-
}
|
|
1132
|
-
function BreadcrumbList({ className, ...props }) {
|
|
1133
|
-
return /* @__PURE__ */ jsx13(
|
|
1134
|
-
"ol",
|
|
1135
|
-
{
|
|
1136
|
-
"data-slot": "breadcrumb-list",
|
|
1137
|
-
className: cn(
|
|
1138
|
-
"text-muted-foreground gap-1.5 text-sm sm:gap-2.5 flex flex-wrap items-center wrap-break-word",
|
|
1139
|
-
className
|
|
1140
|
-
),
|
|
1141
|
-
...props
|
|
1142
|
-
}
|
|
1143
|
-
);
|
|
1144
|
-
}
|
|
1145
|
-
function BreadcrumbItem({ className, ...props }) {
|
|
1146
|
-
return /* @__PURE__ */ jsx13(
|
|
1147
|
-
"li",
|
|
1148
|
-
{
|
|
1149
|
-
"data-slot": "breadcrumb-item",
|
|
1150
|
-
className: cn("gap-1.5 inline-flex items-center", className),
|
|
1151
|
-
...props
|
|
1152
|
-
}
|
|
1153
|
-
);
|
|
1154
|
-
}
|
|
1155
|
-
function BreadcrumbLink({
|
|
1156
|
-
asChild,
|
|
1157
|
-
className,
|
|
1158
|
-
...props
|
|
1159
|
-
}) {
|
|
1160
|
-
const Comp = asChild ? Slot4.Root : "a";
|
|
1161
|
-
return /* @__PURE__ */ jsx13(
|
|
1162
|
-
Comp,
|
|
1163
|
-
{
|
|
1164
|
-
"data-slot": "breadcrumb-link",
|
|
1165
|
-
className: cn("hover:text-foreground transition-colors", className),
|
|
1166
|
-
...props
|
|
1167
|
-
}
|
|
1168
|
-
);
|
|
1169
|
-
}
|
|
1170
|
-
function BreadcrumbPage({ className, ...props }) {
|
|
1171
|
-
return /* @__PURE__ */ jsx13(
|
|
1172
|
-
"span",
|
|
1173
|
-
{
|
|
1174
|
-
"data-slot": "breadcrumb-page",
|
|
1175
|
-
role: "link",
|
|
1176
|
-
"aria-disabled": "true",
|
|
1177
|
-
"aria-current": "page",
|
|
1178
|
-
className: cn("text-foreground font-normal", className),
|
|
1179
|
-
...props
|
|
1180
|
-
}
|
|
1181
|
-
);
|
|
1182
|
-
}
|
|
1183
|
-
function BreadcrumbSeparator({
|
|
1184
|
-
children,
|
|
1185
|
-
className,
|
|
1186
|
-
...props
|
|
1187
|
-
}) {
|
|
1188
|
-
return /* @__PURE__ */ jsx13(
|
|
1189
|
-
"li",
|
|
1190
|
-
{
|
|
1191
|
-
"data-slot": "breadcrumb-separator",
|
|
1192
|
-
role: "presentation",
|
|
1193
|
-
"aria-hidden": "true",
|
|
1194
|
-
className: cn("[&>svg]:size-3.5", className),
|
|
1195
|
-
...props,
|
|
1196
|
-
children: children ?? /* @__PURE__ */ jsx13(ChevronRight3, {})
|
|
1197
|
-
}
|
|
1198
|
-
);
|
|
1199
|
-
}
|
|
1200
|
-
function BreadcrumbEllipsis({
|
|
1201
|
-
className,
|
|
1202
|
-
...props
|
|
1203
|
-
}) {
|
|
1204
|
-
return /* @__PURE__ */ jsxs6(
|
|
1205
|
-
"span",
|
|
1206
|
-
{
|
|
1207
|
-
"data-slot": "breadcrumb-ellipsis",
|
|
1208
|
-
role: "presentation",
|
|
1209
|
-
"aria-hidden": "true",
|
|
1210
|
-
className: cn(
|
|
1211
|
-
"size-5 [&>svg]:size-4 flex items-center justify-center",
|
|
1212
|
-
className
|
|
1213
|
-
),
|
|
1214
|
-
...props,
|
|
1215
|
-
children: [
|
|
1216
|
-
/* @__PURE__ */ jsx13(MoreHorizontal, {}),
|
|
1217
|
-
/* @__PURE__ */ jsx13("span", { className: "sr-only", children: "More" })
|
|
1218
|
-
]
|
|
1219
|
-
}
|
|
1220
|
-
);
|
|
1221
|
-
}
|
|
1222
|
-
|
|
1223
260
|
// src/components/theme-toggle.tsx
|
|
1224
261
|
import { useTheme } from "next-themes";
|
|
1225
262
|
import { Sun, Moon } from "lucide-react";
|
|
1226
|
-
import { useCallback
|
|
1227
|
-
import { jsx as
|
|
263
|
+
import { useCallback } from "react";
|
|
264
|
+
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
1228
265
|
function ThemeToggle() {
|
|
1229
266
|
const { theme, setTheme } = useTheme();
|
|
1230
|
-
const toggleTheme =
|
|
267
|
+
const toggleTheme = useCallback(
|
|
1231
268
|
(e) => {
|
|
1232
269
|
const nextTheme = theme === "dark" ? "light" : "dark";
|
|
1233
270
|
if (!document.startViewTransition) {
|
|
@@ -1244,18 +281,19 @@ function ThemeToggle() {
|
|
|
1244
281
|
},
|
|
1245
282
|
[theme, setTheme]
|
|
1246
283
|
);
|
|
1247
|
-
return /* @__PURE__ */
|
|
1248
|
-
/* @__PURE__ */
|
|
1249
|
-
/* @__PURE__ */
|
|
1250
|
-
/* @__PURE__ */
|
|
284
|
+
return /* @__PURE__ */ jsxs2(Button, { variant: "ghost", size: "icon", onClick: toggleTheme, children: [
|
|
285
|
+
/* @__PURE__ */ jsx2(Sun, { "aria-hidden": "true", className: "h-5 w-5 rotate-0 scale-100 transition-transform transition-opacity dark:-rotate-90 dark:scale-0" }),
|
|
286
|
+
/* @__PURE__ */ jsx2(Moon, { "aria-hidden": "true", className: "absolute h-5 w-5 rotate-90 scale-0 transition-transform transition-opacity dark:rotate-0 dark:scale-100" }),
|
|
287
|
+
/* @__PURE__ */ jsx2("span", { className: "sr-only", children: "Alternar tema" })
|
|
1251
288
|
] });
|
|
1252
289
|
}
|
|
1253
290
|
|
|
1254
291
|
// src/components/app-header.tsx
|
|
1255
|
-
import { jsx as
|
|
292
|
+
import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
1256
293
|
function AppHeader({ config }) {
|
|
1257
294
|
const pathname = usePathname2();
|
|
1258
295
|
const segments = pathname.split("/").filter(Boolean);
|
|
296
|
+
const routeLabelsJson = JSON.stringify(config.routeLabels);
|
|
1259
297
|
const breadcrumbs = useMemo2(() => {
|
|
1260
298
|
const items = [];
|
|
1261
299
|
for (let i = 0; i < segments.length; i++) {
|
|
@@ -1266,75 +304,53 @@ function AppHeader({ config }) {
|
|
|
1266
304
|
}
|
|
1267
305
|
}
|
|
1268
306
|
return items;
|
|
1269
|
-
}, [segments,
|
|
307
|
+
}, [segments, routeLabelsJson]);
|
|
1270
308
|
const isLast = (i) => i === breadcrumbs.length - 1;
|
|
1271
309
|
const showEllipsis = breadcrumbs.length > 2;
|
|
1272
|
-
return /* @__PURE__ */
|
|
1273
|
-
/* @__PURE__ */
|
|
1274
|
-
/* @__PURE__ */
|
|
1275
|
-
/* @__PURE__ */
|
|
310
|
+
return /* @__PURE__ */ jsxs3("header", { className: "flex h-14 shrink-0 items-center gap-2 border-b px-4", children: [
|
|
311
|
+
/* @__PURE__ */ jsx3(SidebarTrigger, { className: "-ml-1" }),
|
|
312
|
+
/* @__PURE__ */ jsx3(Separator, { orientation: "vertical", className: "mr-2 !h-4" }),
|
|
313
|
+
/* @__PURE__ */ jsx3(Breadcrumb, { className: "flex-1", children: /* @__PURE__ */ jsx3(BreadcrumbList, { children: breadcrumbs.length > 0 ? breadcrumbs.map((crumb, i) => {
|
|
1276
314
|
const hiddenOnMobile = showEllipsis && i < breadcrumbs.length - 2;
|
|
1277
|
-
return /* @__PURE__ */
|
|
1278
|
-
showEllipsis && i === breadcrumbs.length - 2 && /* @__PURE__ */
|
|
1279
|
-
i > 0 && /* @__PURE__ */
|
|
1280
|
-
/* @__PURE__ */
|
|
315
|
+
return /* @__PURE__ */ jsxs3(Fragment, { children: [
|
|
316
|
+
showEllipsis && i === breadcrumbs.length - 2 && /* @__PURE__ */ jsx3(BreadcrumbItem, { className: "sm:hidden", children: /* @__PURE__ */ jsx3(BreadcrumbEllipsis, {}) }),
|
|
317
|
+
i > 0 && /* @__PURE__ */ jsx3(BreadcrumbSeparator, { className: hiddenOnMobile ? "hidden sm:flex" : void 0 }),
|
|
318
|
+
/* @__PURE__ */ jsx3(BreadcrumbItem, { className: hiddenOnMobile ? "hidden sm:flex" : void 0, children: isLast(i) ? /* @__PURE__ */ jsx3(BreadcrumbPage, { children: crumb.label }) : /* @__PURE__ */ jsx3(BreadcrumbLink, { asChild: true, children: /* @__PURE__ */ jsx3(Link2, { href: crumb.href, children: crumb.label }) }) })
|
|
1281
319
|
] }, i);
|
|
1282
|
-
}) : config.defaultBreadcrumb ? /* @__PURE__ */
|
|
1283
|
-
/* @__PURE__ */
|
|
320
|
+
}) : config.defaultBreadcrumb ? /* @__PURE__ */ jsx3(BreadcrumbItem, { children: /* @__PURE__ */ jsx3(BreadcrumbPage, { children: config.defaultBreadcrumb }) }) : null }) }),
|
|
321
|
+
/* @__PURE__ */ jsx3(ThemeToggle, {})
|
|
1284
322
|
] });
|
|
1285
323
|
}
|
|
1286
324
|
|
|
1287
325
|
// src/components/app-shell.tsx
|
|
1288
|
-
import { Fragment as Fragment2, jsx as
|
|
326
|
+
import { Fragment as Fragment2, jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
1289
327
|
function AppShell({ config, children, renderAbove }) {
|
|
1290
|
-
return /* @__PURE__ */
|
|
328
|
+
return /* @__PURE__ */ jsxs4(Fragment2, { children: [
|
|
1291
329
|
renderAbove,
|
|
1292
|
-
/* @__PURE__ */
|
|
1293
|
-
/* @__PURE__ */
|
|
1294
|
-
/* @__PURE__ */
|
|
1295
|
-
/* @__PURE__ */
|
|
1296
|
-
/* @__PURE__ */
|
|
330
|
+
/* @__PURE__ */ jsx4(TooltipProvider, { children: /* @__PURE__ */ jsxs4(SidebarProvider, { className: "!h-svh !overflow-hidden", children: [
|
|
331
|
+
/* @__PURE__ */ jsx4(AppSidebar, { config }),
|
|
332
|
+
/* @__PURE__ */ jsxs4(SidebarInset, { className: "flex flex-col min-w-0 overflow-hidden", children: [
|
|
333
|
+
/* @__PURE__ */ jsx4(AppHeader, { config }),
|
|
334
|
+
/* @__PURE__ */ jsx4("main", { className: "flex-1 overflow-auto", children })
|
|
1297
335
|
] })
|
|
1298
336
|
] }) })
|
|
1299
337
|
] });
|
|
1300
338
|
}
|
|
1301
339
|
|
|
1302
340
|
// src/components/login-form.tsx
|
|
1303
|
-
import { useState as
|
|
341
|
+
import { useState as useState2 } from "react";
|
|
1304
342
|
import { useRouter as useRouter2, useSearchParams } from "next/navigation";
|
|
1305
343
|
import { Loader2, Mail, Lock, AlertCircle, Eye, EyeOff } from "lucide-react";
|
|
1306
|
-
|
|
1307
|
-
// src/components/ui/label.tsx
|
|
1308
|
-
import { Label as LabelPrimitive } from "radix-ui";
|
|
1309
|
-
import { jsx as jsx17 } from "react/jsx-runtime";
|
|
1310
|
-
function Label({
|
|
1311
|
-
className,
|
|
1312
|
-
...props
|
|
1313
|
-
}) {
|
|
1314
|
-
return /* @__PURE__ */ jsx17(
|
|
1315
|
-
LabelPrimitive.Root,
|
|
1316
|
-
{
|
|
1317
|
-
"data-slot": "label",
|
|
1318
|
-
className: cn(
|
|
1319
|
-
"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",
|
|
1320
|
-
className
|
|
1321
|
-
),
|
|
1322
|
-
...props
|
|
1323
|
-
}
|
|
1324
|
-
);
|
|
1325
|
-
}
|
|
1326
|
-
|
|
1327
|
-
// src/components/login-form.tsx
|
|
1328
|
-
import { Fragment as Fragment3, jsx as jsx18, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
344
|
+
import { Fragment as Fragment3, jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
1329
345
|
function LoginForm({ config }) {
|
|
1330
346
|
const router = useRouter2();
|
|
1331
347
|
const searchParams = useSearchParams();
|
|
1332
348
|
const callbackUrl = searchParams.get("callbackUrl") || config.callbackUrlDefault;
|
|
1333
|
-
const [email, setEmail] =
|
|
1334
|
-
const [password, setPassword] =
|
|
1335
|
-
const [loading, setLoading] =
|
|
1336
|
-
const [error, setError] =
|
|
1337
|
-
const [showPassword, setShowPassword] =
|
|
349
|
+
const [email, setEmail] = useState2("");
|
|
350
|
+
const [password, setPassword] = useState2("");
|
|
351
|
+
const [loading, setLoading] = useState2(false);
|
|
352
|
+
const [error, setError] = useState2("");
|
|
353
|
+
const [showPassword, setShowPassword] = useState2(false);
|
|
1338
354
|
const handleSubmit = async (e) => {
|
|
1339
355
|
e.preventDefault();
|
|
1340
356
|
if (loading) return;
|
|
@@ -1365,9 +381,9 @@ function LoginForm({ config }) {
|
|
|
1365
381
|
setLoading(false);
|
|
1366
382
|
}
|
|
1367
383
|
};
|
|
1368
|
-
return /* @__PURE__ */
|
|
1369
|
-
/* @__PURE__ */
|
|
1370
|
-
/* @__PURE__ */
|
|
384
|
+
return /* @__PURE__ */ jsxs5("div", { className: "relative flex min-h-svh", children: [
|
|
385
|
+
/* @__PURE__ */ jsx5("div", { className: "fixed top-4 right-4 z-50", children: /* @__PURE__ */ jsx5(ThemeToggle, {}) }),
|
|
386
|
+
/* @__PURE__ */ jsxs5(
|
|
1371
387
|
"div",
|
|
1372
388
|
{
|
|
1373
389
|
className: "relative hidden items-center justify-center overflow-hidden bg-primary md:flex md:w-1/2",
|
|
@@ -1376,34 +392,34 @@ function LoginForm({ config }) {
|
|
|
1376
392
|
backgroundSize: "24px 24px"
|
|
1377
393
|
},
|
|
1378
394
|
children: [
|
|
1379
|
-
/* @__PURE__ */
|
|
1380
|
-
/* @__PURE__ */
|
|
1381
|
-
/* @__PURE__ */
|
|
1382
|
-
/* @__PURE__ */
|
|
1383
|
-
/* @__PURE__ */
|
|
395
|
+
/* @__PURE__ */ jsx5("div", { className: "absolute inset-0 bg-gradient-to-br from-primary/80 via-primary to-primary/90" }),
|
|
396
|
+
/* @__PURE__ */ jsxs5("div", { className: "relative z-10 flex flex-col items-center gap-4 px-8 text-center text-primary-foreground", children: [
|
|
397
|
+
/* @__PURE__ */ jsx5("div", { className: "flex h-16 w-16 items-center justify-center rounded-2xl bg-primary-foreground/15 shadow-lg backdrop-blur-sm", children: config.icon }),
|
|
398
|
+
/* @__PURE__ */ jsx5("h2", { className: "text-3xl font-bold tracking-tight", children: config.appName }),
|
|
399
|
+
/* @__PURE__ */ jsx5("p", { className: "max-w-xs text-base text-primary-foreground/80", children: config.description })
|
|
1384
400
|
] })
|
|
1385
401
|
]
|
|
1386
402
|
}
|
|
1387
403
|
),
|
|
1388
|
-
/* @__PURE__ */
|
|
1389
|
-
/* @__PURE__ */
|
|
1390
|
-
/* @__PURE__ */
|
|
1391
|
-
/* @__PURE__ */
|
|
1392
|
-
/* @__PURE__ */
|
|
1393
|
-
config.appBadge && /* @__PURE__ */
|
|
404
|
+
/* @__PURE__ */ jsx5("div", { className: "flex w-full items-center justify-center bg-background p-4 md:w-1/2", children: /* @__PURE__ */ jsxs5("div", { className: "w-full max-w-sm", children: [
|
|
405
|
+
/* @__PURE__ */ jsxs5("div", { className: "mb-8 text-center", children: [
|
|
406
|
+
/* @__PURE__ */ jsx5("div", { className: "mx-auto mb-4 flex h-12 w-12 items-center justify-center rounded-xl bg-primary text-primary-foreground shadow-sm md:hidden", children: config.icon }),
|
|
407
|
+
/* @__PURE__ */ jsxs5("div", { className: "flex items-center justify-center gap-2", children: [
|
|
408
|
+
/* @__PURE__ */ jsx5("h1", { className: "text-3xl font-bold tracking-tight", children: config.appName }),
|
|
409
|
+
config.appBadge && /* @__PURE__ */ jsx5(Badge, { variant: config.appBadge.variant, className: "text-xs", children: config.appBadge.text })
|
|
1394
410
|
] }),
|
|
1395
|
-
/* @__PURE__ */
|
|
411
|
+
/* @__PURE__ */ jsx5("p", { className: "mt-1.5 text-base text-muted-foreground", children: config.description })
|
|
1396
412
|
] }),
|
|
1397
|
-
/* @__PURE__ */
|
|
1398
|
-
error && /* @__PURE__ */
|
|
1399
|
-
/* @__PURE__ */
|
|
413
|
+
/* @__PURE__ */ jsx5("div", { className: "rounded-xl border bg-card p-6 shadow-sm", children: /* @__PURE__ */ jsxs5("form", { onSubmit: handleSubmit, className: "space-y-4", children: [
|
|
414
|
+
error && /* @__PURE__ */ jsxs5("div", { className: "flex items-center gap-2 rounded-lg border border-destructive/30 bg-destructive/5 px-3 py-2.5 text-sm text-destructive", children: [
|
|
415
|
+
/* @__PURE__ */ jsx5(AlertCircle, { "aria-hidden": "true", className: "h-4 w-4 shrink-0" }),
|
|
1400
416
|
error
|
|
1401
417
|
] }),
|
|
1402
|
-
/* @__PURE__ */
|
|
1403
|
-
/* @__PURE__ */
|
|
1404
|
-
/* @__PURE__ */
|
|
1405
|
-
/* @__PURE__ */
|
|
1406
|
-
/* @__PURE__ */
|
|
418
|
+
/* @__PURE__ */ jsxs5("div", { className: "space-y-1.5", children: [
|
|
419
|
+
/* @__PURE__ */ jsx5(Label, { htmlFor: "login-email", className: "text-sm font-medium", children: "Email" }),
|
|
420
|
+
/* @__PURE__ */ jsxs5("div", { className: "relative", children: [
|
|
421
|
+
/* @__PURE__ */ jsx5(Mail, { "aria-hidden": "true", className: "pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" }),
|
|
422
|
+
/* @__PURE__ */ jsx5(
|
|
1407
423
|
Input,
|
|
1408
424
|
{
|
|
1409
425
|
id: "login-email",
|
|
@@ -1419,11 +435,11 @@ function LoginForm({ config }) {
|
|
|
1419
435
|
)
|
|
1420
436
|
] })
|
|
1421
437
|
] }),
|
|
1422
|
-
/* @__PURE__ */
|
|
1423
|
-
/* @__PURE__ */
|
|
1424
|
-
/* @__PURE__ */
|
|
1425
|
-
/* @__PURE__ */
|
|
1426
|
-
/* @__PURE__ */
|
|
438
|
+
/* @__PURE__ */ jsxs5("div", { className: "space-y-1.5", children: [
|
|
439
|
+
/* @__PURE__ */ jsx5(Label, { htmlFor: "login-password", className: "text-sm font-medium", children: "Senha" }),
|
|
440
|
+
/* @__PURE__ */ jsxs5("div", { className: "relative", children: [
|
|
441
|
+
/* @__PURE__ */ jsx5(Lock, { "aria-hidden": "true", className: "pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" }),
|
|
442
|
+
/* @__PURE__ */ jsx5(
|
|
1427
443
|
Input,
|
|
1428
444
|
{
|
|
1429
445
|
id: "login-password",
|
|
@@ -1437,33 +453,33 @@ function LoginForm({ config }) {
|
|
|
1437
453
|
required: true
|
|
1438
454
|
}
|
|
1439
455
|
),
|
|
1440
|
-
/* @__PURE__ */
|
|
456
|
+
/* @__PURE__ */ jsx5(
|
|
1441
457
|
"button",
|
|
1442
458
|
{
|
|
1443
459
|
type: "button",
|
|
1444
460
|
onClick: () => setShowPassword(!showPassword),
|
|
1445
461
|
className: "absolute right-3 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground transition-colors",
|
|
1446
462
|
"aria-label": showPassword ? "Ocultar senha" : "Mostrar senha",
|
|
1447
|
-
children: showPassword ? /* @__PURE__ */
|
|
463
|
+
children: showPassword ? /* @__PURE__ */ jsx5(EyeOff, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx5(Eye, { className: "h-4 w-4" })
|
|
1448
464
|
}
|
|
1449
465
|
)
|
|
1450
466
|
] })
|
|
1451
467
|
] }),
|
|
1452
|
-
/* @__PURE__ */
|
|
468
|
+
/* @__PURE__ */ jsx5(
|
|
1453
469
|
Button,
|
|
1454
470
|
{
|
|
1455
471
|
type: "submit",
|
|
1456
472
|
className: cn("w-full", loading && "cursor-wait"),
|
|
1457
473
|
disabled: loading,
|
|
1458
|
-
children: loading ? /* @__PURE__ */
|
|
1459
|
-
/* @__PURE__ */
|
|
474
|
+
children: loading ? /* @__PURE__ */ jsxs5(Fragment3, { children: [
|
|
475
|
+
/* @__PURE__ */ jsx5(Loader2, { "aria-hidden": "true", className: "h-4 w-4 animate-spin" }),
|
|
1460
476
|
"A entrar\u2026"
|
|
1461
477
|
] }) : "Entrar"
|
|
1462
478
|
}
|
|
1463
479
|
)
|
|
1464
480
|
] }) }),
|
|
1465
|
-
/* @__PURE__ */
|
|
1466
|
-
/* @__PURE__ */
|
|
481
|
+
/* @__PURE__ */ jsx5("p", { className: "mt-6 text-center text-xs text-muted-foreground", children: config.footerText || "Acesso restrito a utilizadores autorizados" }),
|
|
482
|
+
/* @__PURE__ */ jsxs5("p", { className: "mt-1 text-center text-xs text-muted-foreground", children: [
|
|
1467
483
|
"\xA9 ",
|
|
1468
484
|
(/* @__PURE__ */ new Date()).getFullYear(),
|
|
1469
485
|
" ",
|
|
@@ -1474,7 +490,7 @@ function LoginForm({ config }) {
|
|
|
1474
490
|
}
|
|
1475
491
|
|
|
1476
492
|
// src/components/entity-avatar.tsx
|
|
1477
|
-
import { jsx as
|
|
493
|
+
import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1478
494
|
var COLORS = [
|
|
1479
495
|
"bg-red-100 text-red-700 dark:bg-red-900 dark:text-red-300",
|
|
1480
496
|
"bg-orange-100 text-orange-700 dark:bg-orange-900 dark:text-orange-300",
|
|
@@ -1515,8 +531,8 @@ function EntityAvatar({
|
|
|
1515
531
|
const displayName = name || "?";
|
|
1516
532
|
const color = COLORS[hashCode(displayName) % COLORS.length];
|
|
1517
533
|
const initials = getInitials(displayName);
|
|
1518
|
-
return /* @__PURE__ */
|
|
1519
|
-
photo && /* @__PURE__ */
|
|
534
|
+
return /* @__PURE__ */ jsxs6(Avatar, { className: cn(SIZE_MAP[size], className), children: [
|
|
535
|
+
photo && /* @__PURE__ */ jsx6(
|
|
1520
536
|
AvatarImage,
|
|
1521
537
|
{
|
|
1522
538
|
src: photo,
|
|
@@ -1524,169 +540,13 @@ function EntityAvatar({
|
|
|
1524
540
|
className: "object-cover"
|
|
1525
541
|
}
|
|
1526
542
|
),
|
|
1527
|
-
/* @__PURE__ */
|
|
543
|
+
/* @__PURE__ */ jsx6(AvatarFallback, { className: cn("font-medium", color), children: initials })
|
|
1528
544
|
] });
|
|
1529
545
|
}
|
|
1530
546
|
|
|
1531
547
|
// src/components/image-crop-upload.tsx
|
|
1532
|
-
import { useCallback as
|
|
548
|
+
import { useCallback as useCallback2, useRef, useState as useState3 } from "react";
|
|
1533
549
|
import Cropper from "react-easy-crop";
|
|
1534
|
-
|
|
1535
|
-
// src/components/ui/dialog.tsx
|
|
1536
|
-
import { Dialog as DialogPrimitive } from "radix-ui";
|
|
1537
|
-
import { X as X2 } from "lucide-react";
|
|
1538
|
-
import { jsx as jsx20, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
1539
|
-
function Dialog({
|
|
1540
|
-
...props
|
|
1541
|
-
}) {
|
|
1542
|
-
return /* @__PURE__ */ jsx20(DialogPrimitive.Root, { "data-slot": "dialog", ...props });
|
|
1543
|
-
}
|
|
1544
|
-
function DialogPortal({
|
|
1545
|
-
...props
|
|
1546
|
-
}) {
|
|
1547
|
-
return /* @__PURE__ */ jsx20(DialogPrimitive.Portal, { "data-slot": "dialog-portal", ...props });
|
|
1548
|
-
}
|
|
1549
|
-
function DialogOverlay({
|
|
1550
|
-
className,
|
|
1551
|
-
...props
|
|
1552
|
-
}) {
|
|
1553
|
-
return /* @__PURE__ */ jsx20(
|
|
1554
|
-
DialogPrimitive.Overlay,
|
|
1555
|
-
{
|
|
1556
|
-
"data-slot": "dialog-overlay",
|
|
1557
|
-
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 supports-backdrop-filter:backdrop-blur-xs fixed inset-0 isolate z-50", className),
|
|
1558
|
-
...props
|
|
1559
|
-
}
|
|
1560
|
-
);
|
|
1561
|
-
}
|
|
1562
|
-
function DialogContent({
|
|
1563
|
-
className,
|
|
1564
|
-
children,
|
|
1565
|
-
showCloseButton = true,
|
|
1566
|
-
...props
|
|
1567
|
-
}) {
|
|
1568
|
-
return /* @__PURE__ */ jsxs12(DialogPortal, { children: [
|
|
1569
|
-
/* @__PURE__ */ jsx20(DialogOverlay, {}),
|
|
1570
|
-
/* @__PURE__ */ jsxs12(
|
|
1571
|
-
DialogPrimitive.Content,
|
|
1572
|
-
{
|
|
1573
|
-
"data-slot": "dialog-content",
|
|
1574
|
-
className: cn(
|
|
1575
|
-
"bg-background 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 ring-foreground/10 grid max-w-[calc(100%-2rem)] gap-6 rounded-xl p-6 text-sm ring-1 duration-100 sm:max-w-md fixed top-1/2 left-1/2 z-50 w-full -translate-x-1/2 -translate-y-1/2 outline-none",
|
|
1576
|
-
className
|
|
1577
|
-
),
|
|
1578
|
-
...props,
|
|
1579
|
-
children: [
|
|
1580
|
-
children,
|
|
1581
|
-
showCloseButton && /* @__PURE__ */ jsx20(DialogPrimitive.Close, { "data-slot": "dialog-close", asChild: true, children: /* @__PURE__ */ jsxs12(Button, { variant: "ghost", className: "absolute top-4 right-4", size: "icon-sm", children: [
|
|
1582
|
-
/* @__PURE__ */ jsx20(X2, {}),
|
|
1583
|
-
/* @__PURE__ */ jsx20("span", { className: "sr-only", children: "Close" })
|
|
1584
|
-
] }) })
|
|
1585
|
-
]
|
|
1586
|
-
}
|
|
1587
|
-
)
|
|
1588
|
-
] });
|
|
1589
|
-
}
|
|
1590
|
-
function DialogHeader({ className, ...props }) {
|
|
1591
|
-
return /* @__PURE__ */ jsx20(
|
|
1592
|
-
"div",
|
|
1593
|
-
{
|
|
1594
|
-
"data-slot": "dialog-header",
|
|
1595
|
-
className: cn("gap-2 flex flex-col", className),
|
|
1596
|
-
...props
|
|
1597
|
-
}
|
|
1598
|
-
);
|
|
1599
|
-
}
|
|
1600
|
-
function DialogFooter({
|
|
1601
|
-
className,
|
|
1602
|
-
children,
|
|
1603
|
-
...props
|
|
1604
|
-
}) {
|
|
1605
|
-
return /* @__PURE__ */ jsx20(
|
|
1606
|
-
"div",
|
|
1607
|
-
{
|
|
1608
|
-
"data-slot": "dialog-footer",
|
|
1609
|
-
className: cn(
|
|
1610
|
-
"flex flex-col-reverse gap-2 sm:flex-row sm:justify-end",
|
|
1611
|
-
className
|
|
1612
|
-
),
|
|
1613
|
-
...props,
|
|
1614
|
-
children
|
|
1615
|
-
}
|
|
1616
|
-
);
|
|
1617
|
-
}
|
|
1618
|
-
function DialogTitle({
|
|
1619
|
-
className,
|
|
1620
|
-
...props
|
|
1621
|
-
}) {
|
|
1622
|
-
return /* @__PURE__ */ jsx20(
|
|
1623
|
-
DialogPrimitive.Title,
|
|
1624
|
-
{
|
|
1625
|
-
"data-slot": "dialog-title",
|
|
1626
|
-
className: cn("leading-none font-medium", className),
|
|
1627
|
-
...props
|
|
1628
|
-
}
|
|
1629
|
-
);
|
|
1630
|
-
}
|
|
1631
|
-
|
|
1632
|
-
// src/components/ui/slider.tsx
|
|
1633
|
-
import * as React2 from "react";
|
|
1634
|
-
import { Slider as SliderPrimitive } from "radix-ui";
|
|
1635
|
-
import { jsx as jsx21, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
1636
|
-
function Slider({
|
|
1637
|
-
className,
|
|
1638
|
-
defaultValue,
|
|
1639
|
-
value,
|
|
1640
|
-
min = 0,
|
|
1641
|
-
max = 100,
|
|
1642
|
-
...props
|
|
1643
|
-
}) {
|
|
1644
|
-
const _values = React2.useMemo(
|
|
1645
|
-
() => Array.isArray(value) ? value : Array.isArray(defaultValue) ? defaultValue : [min, max],
|
|
1646
|
-
[value, defaultValue, min, max]
|
|
1647
|
-
);
|
|
1648
|
-
return /* @__PURE__ */ jsxs13(
|
|
1649
|
-
SliderPrimitive.Root,
|
|
1650
|
-
{
|
|
1651
|
-
"data-slot": "slider",
|
|
1652
|
-
defaultValue,
|
|
1653
|
-
value,
|
|
1654
|
-
min,
|
|
1655
|
-
max,
|
|
1656
|
-
className: cn(
|
|
1657
|
-
"data-vertical:min-h-40 relative flex w-full touch-none items-center select-none data-disabled:opacity-50 data-vertical:h-full data-vertical:w-auto data-vertical:flex-col",
|
|
1658
|
-
className
|
|
1659
|
-
),
|
|
1660
|
-
...props,
|
|
1661
|
-
children: [
|
|
1662
|
-
/* @__PURE__ */ jsx21(
|
|
1663
|
-
SliderPrimitive.Track,
|
|
1664
|
-
{
|
|
1665
|
-
"data-slot": "slider-track",
|
|
1666
|
-
className: "bg-muted rounded-full data-horizontal:h-1.5 data-vertical:w-1.5 relative grow overflow-hidden data-horizontal:w-full data-vertical:h-full",
|
|
1667
|
-
children: /* @__PURE__ */ jsx21(
|
|
1668
|
-
SliderPrimitive.Range,
|
|
1669
|
-
{
|
|
1670
|
-
"data-slot": "slider-range",
|
|
1671
|
-
className: "bg-primary absolute select-none data-horizontal:h-full data-vertical:w-full"
|
|
1672
|
-
}
|
|
1673
|
-
)
|
|
1674
|
-
}
|
|
1675
|
-
),
|
|
1676
|
-
Array.from({ length: _values.length }, (_, index) => /* @__PURE__ */ jsx21(
|
|
1677
|
-
SliderPrimitive.Thumb,
|
|
1678
|
-
{
|
|
1679
|
-
"data-slot": "slider-thumb",
|
|
1680
|
-
className: "border-primary ring-ring/50 size-4 rounded-full border bg-white shadow-sm transition-[color,box-shadow] hover:ring-4 focus-visible:ring-4 focus-visible:outline-hidden block shrink-0 select-none disabled:pointer-events-none disabled:opacity-50"
|
|
1681
|
-
},
|
|
1682
|
-
index
|
|
1683
|
-
))
|
|
1684
|
-
]
|
|
1685
|
-
}
|
|
1686
|
-
);
|
|
1687
|
-
}
|
|
1688
|
-
|
|
1689
|
-
// src/components/image-crop-upload.tsx
|
|
1690
550
|
import { toast } from "sonner";
|
|
1691
551
|
import { Camera, Trash2 } from "lucide-react";
|
|
1692
552
|
|
|
@@ -1759,7 +619,7 @@ function fileToDataUrl(file) {
|
|
|
1759
619
|
}
|
|
1760
620
|
|
|
1761
621
|
// src/components/image-crop-upload.tsx
|
|
1762
|
-
import { jsx as
|
|
622
|
+
import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1763
623
|
var STORAGE_URL_MAP = {
|
|
1764
624
|
users: "https://gauth-r2-storage.greatlabs.workers.dev",
|
|
1765
625
|
agents: "https://gagents-r2-storage.greatlabs.workers.dev",
|
|
@@ -1788,17 +648,17 @@ function ImageCropUpload({
|
|
|
1788
648
|
name,
|
|
1789
649
|
disabled = false
|
|
1790
650
|
}) {
|
|
1791
|
-
const [imageSrc, setImageSrc] =
|
|
1792
|
-
const [crop, setCrop] =
|
|
1793
|
-
const [zoom, setZoom] =
|
|
1794
|
-
const [croppedArea, setCroppedArea] =
|
|
1795
|
-
const [isOpen, setIsOpen] =
|
|
1796
|
-
const [isUploading, setIsUploading] =
|
|
651
|
+
const [imageSrc, setImageSrc] = useState3(null);
|
|
652
|
+
const [crop, setCrop] = useState3({ x: 0, y: 0 });
|
|
653
|
+
const [zoom, setZoom] = useState3(1);
|
|
654
|
+
const [croppedArea, setCroppedArea] = useState3(null);
|
|
655
|
+
const [isOpen, setIsOpen] = useState3(false);
|
|
656
|
+
const [isUploading, setIsUploading] = useState3(false);
|
|
1797
657
|
const inputRef = useRef(null);
|
|
1798
|
-
const onCropComplete =
|
|
658
|
+
const onCropComplete = useCallback2((_, croppedAreaPixels) => {
|
|
1799
659
|
setCroppedArea(croppedAreaPixels);
|
|
1800
660
|
}, []);
|
|
1801
|
-
const handleFileSelect =
|
|
661
|
+
const handleFileSelect = useCallback2(
|
|
1802
662
|
async (e) => {
|
|
1803
663
|
const file = e.target.files?.[0];
|
|
1804
664
|
if (!file) return;
|
|
@@ -1817,7 +677,7 @@ function ImageCropUpload({
|
|
|
1817
677
|
},
|
|
1818
678
|
[]
|
|
1819
679
|
);
|
|
1820
|
-
const handleConfirmCrop =
|
|
680
|
+
const handleConfirmCrop = useCallback2(async () => {
|
|
1821
681
|
if (!imageSrc || !croppedArea) return;
|
|
1822
682
|
setIsUploading(true);
|
|
1823
683
|
try {
|
|
@@ -1847,7 +707,7 @@ function ImageCropUpload({
|
|
|
1847
707
|
setImageSrc(null);
|
|
1848
708
|
}
|
|
1849
709
|
}, [imageSrc, croppedArea, entityType, entityId, idAccount, onChange]);
|
|
1850
|
-
const handleRemove =
|
|
710
|
+
const handleRemove = useCallback2(async () => {
|
|
1851
711
|
if (!value) return;
|
|
1852
712
|
try {
|
|
1853
713
|
const path = `${entityType}/${idAccount}/${entityId || "temp"}.webp`;
|
|
@@ -1864,21 +724,21 @@ function ImageCropUpload({
|
|
|
1864
724
|
toast.error("Erro ao remover imagem");
|
|
1865
725
|
}
|
|
1866
726
|
}, [value, entityType, entityId, idAccount, onRemove]);
|
|
1867
|
-
return /* @__PURE__ */
|
|
1868
|
-
/* @__PURE__ */
|
|
1869
|
-
/* @__PURE__ */
|
|
1870
|
-
!disabled && /* @__PURE__ */
|
|
727
|
+
return /* @__PURE__ */ jsxs7("div", { className: "flex flex-col items-center gap-2", children: [
|
|
728
|
+
/* @__PURE__ */ jsxs7("div", { className: "relative group", children: [
|
|
729
|
+
/* @__PURE__ */ jsx7(EntityAvatar, { photo: value, name: name ?? null, size: "xl" }),
|
|
730
|
+
!disabled && /* @__PURE__ */ jsx7(
|
|
1871
731
|
"button",
|
|
1872
732
|
{
|
|
1873
733
|
type: "button",
|
|
1874
734
|
onClick: () => inputRef.current?.click(),
|
|
1875
735
|
className: "absolute inset-0 flex items-center justify-center rounded-full bg-black/50 opacity-0 group-hover:opacity-100 transition-opacity cursor-pointer",
|
|
1876
736
|
"aria-label": "Alterar foto",
|
|
1877
|
-
children: /* @__PURE__ */
|
|
737
|
+
children: /* @__PURE__ */ jsx7(Camera, { "aria-hidden": "true", className: "h-5 w-5 text-white" })
|
|
1878
738
|
}
|
|
1879
739
|
)
|
|
1880
740
|
] }),
|
|
1881
|
-
/* @__PURE__ */
|
|
741
|
+
/* @__PURE__ */ jsx7(
|
|
1882
742
|
"input",
|
|
1883
743
|
{
|
|
1884
744
|
ref: inputRef,
|
|
@@ -1890,7 +750,7 @@ function ImageCropUpload({
|
|
|
1890
750
|
"aria-label": "Selecionar imagem"
|
|
1891
751
|
}
|
|
1892
752
|
),
|
|
1893
|
-
!disabled && value && /* @__PURE__ */
|
|
753
|
+
!disabled && value && /* @__PURE__ */ jsxs7(
|
|
1894
754
|
Button,
|
|
1895
755
|
{
|
|
1896
756
|
type: "button",
|
|
@@ -1899,14 +759,14 @@ function ImageCropUpload({
|
|
|
1899
759
|
onClick: handleRemove,
|
|
1900
760
|
className: "text-destructive hover:text-destructive",
|
|
1901
761
|
children: [
|
|
1902
|
-
/* @__PURE__ */
|
|
762
|
+
/* @__PURE__ */ jsx7(Trash2, { "aria-hidden": "true", className: "h-4 w-4 mr-1" }),
|
|
1903
763
|
"Remover"
|
|
1904
764
|
]
|
|
1905
765
|
}
|
|
1906
766
|
),
|
|
1907
|
-
/* @__PURE__ */
|
|
1908
|
-
/* @__PURE__ */
|
|
1909
|
-
/* @__PURE__ */
|
|
767
|
+
/* @__PURE__ */ jsx7(Dialog, { open: isOpen, onOpenChange: setIsOpen, children: /* @__PURE__ */ jsxs7(DialogContent, { className: "sm:max-w-md", children: [
|
|
768
|
+
/* @__PURE__ */ jsx7(DialogHeader, { children: /* @__PURE__ */ jsx7(DialogTitle, { children: "Recortar imagem" }) }),
|
|
769
|
+
/* @__PURE__ */ jsx7("div", { className: "relative w-full h-72 bg-muted rounded-md overflow-hidden", children: imageSrc && /* @__PURE__ */ jsx7(
|
|
1910
770
|
Cropper,
|
|
1911
771
|
{
|
|
1912
772
|
image: imageSrc,
|
|
@@ -1920,9 +780,9 @@ function ImageCropUpload({
|
|
|
1920
780
|
showGrid: false
|
|
1921
781
|
}
|
|
1922
782
|
) }),
|
|
1923
|
-
/* @__PURE__ */
|
|
1924
|
-
/* @__PURE__ */
|
|
1925
|
-
/* @__PURE__ */
|
|
783
|
+
/* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-3 px-1", children: [
|
|
784
|
+
/* @__PURE__ */ jsx7("span", { className: "text-sm text-muted-foreground whitespace-nowrap", children: "Zoom" }),
|
|
785
|
+
/* @__PURE__ */ jsx7(
|
|
1926
786
|
Slider,
|
|
1927
787
|
{
|
|
1928
788
|
value: [zoom],
|
|
@@ -1934,8 +794,8 @@ function ImageCropUpload({
|
|
|
1934
794
|
}
|
|
1935
795
|
)
|
|
1936
796
|
] }),
|
|
1937
|
-
/* @__PURE__ */
|
|
1938
|
-
/* @__PURE__ */
|
|
797
|
+
/* @__PURE__ */ jsxs7(DialogFooter, { children: [
|
|
798
|
+
/* @__PURE__ */ jsx7(
|
|
1939
799
|
Button,
|
|
1940
800
|
{
|
|
1941
801
|
variant: "outline",
|
|
@@ -1947,7 +807,7 @@ function ImageCropUpload({
|
|
|
1947
807
|
children: "Cancelar"
|
|
1948
808
|
}
|
|
1949
809
|
),
|
|
1950
|
-
/* @__PURE__ */
|
|
810
|
+
/* @__PURE__ */ jsx7(
|
|
1951
811
|
Button,
|
|
1952
812
|
{
|
|
1953
813
|
onClick: handleConfirmCrop,
|
|
@@ -1990,7 +850,7 @@ async function request(url, token, options) {
|
|
|
1990
850
|
}
|
|
1991
851
|
function useUsers(config, params) {
|
|
1992
852
|
return useQuery({
|
|
1993
|
-
queryKey: ["greatauth", "users", config.accountId, params],
|
|
853
|
+
queryKey: ["greatauth", "users", config.accountId, JSON.stringify(params)],
|
|
1994
854
|
queryFn: () => {
|
|
1995
855
|
const qs = params ? "?" + new URLSearchParams(params).toString() : "";
|
|
1996
856
|
return request(buildUrl(config, `users${qs}`), config.token);
|
|
@@ -2035,136 +895,13 @@ function useResetPassword(config) {
|
|
|
2035
895
|
}
|
|
2036
896
|
|
|
2037
897
|
// src/components/users/users-page.tsx
|
|
2038
|
-
import { useMemo as
|
|
2039
|
-
|
|
2040
|
-
// src/components/users/user-form-dialog.tsx
|
|
2041
|
-
import { useEffect as useEffect4, useState as useState6 } from "react";
|
|
2042
|
-
|
|
2043
|
-
// src/components/ui/select.tsx
|
|
2044
|
-
import { Select as SelectPrimitive } from "radix-ui";
|
|
2045
|
-
import { ChevronsUpDown as ChevronsUpDown2, Check as Check2, ChevronUp, ChevronDown } from "lucide-react";
|
|
2046
|
-
import { jsx as jsx23, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
2047
|
-
function Select({
|
|
2048
|
-
...props
|
|
2049
|
-
}) {
|
|
2050
|
-
return /* @__PURE__ */ jsx23(SelectPrimitive.Root, { "data-slot": "select", ...props });
|
|
2051
|
-
}
|
|
2052
|
-
function SelectValue({
|
|
2053
|
-
...props
|
|
2054
|
-
}) {
|
|
2055
|
-
return /* @__PURE__ */ jsx23(SelectPrimitive.Value, { "data-slot": "select-value", ...props });
|
|
2056
|
-
}
|
|
2057
|
-
function SelectTrigger({
|
|
2058
|
-
className,
|
|
2059
|
-
size = "default",
|
|
2060
|
-
children,
|
|
2061
|
-
...props
|
|
2062
|
-
}) {
|
|
2063
|
-
return /* @__PURE__ */ jsxs15(
|
|
2064
|
-
SelectPrimitive.Trigger,
|
|
2065
|
-
{
|
|
2066
|
-
"data-slot": "select-trigger",
|
|
2067
|
-
"data-size": size,
|
|
2068
|
-
className: cn(
|
|
2069
|
-
"border-input data-placeholder:text-muted-foreground dark:bg-input/30 dark:hover:bg-input/50 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 gap-1.5 rounded-md border bg-transparent py-2 pr-2 pl-2.5 text-sm shadow-xs transition-[color,box-shadow] focus-visible:ring-3 aria-invalid:ring-3 data-[size=default]:h-9 data-[size=sm]:h-8 *:data-[slot=select-value]:gap-1.5 [&_svg:not([class*='size-'])]:size-4 flex w-fit items-center justify-between whitespace-nowrap outline-none disabled:cursor-not-allowed disabled:opacity-50 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center [&_svg]:pointer-events-none [&_svg]:shrink-0",
|
|
2070
|
-
className
|
|
2071
|
-
),
|
|
2072
|
-
...props,
|
|
2073
|
-
children: [
|
|
2074
|
-
children,
|
|
2075
|
-
/* @__PURE__ */ jsx23(SelectPrimitive.Icon, { asChild: true, children: /* @__PURE__ */ jsx23(ChevronsUpDown2, { className: "text-muted-foreground size-4 pointer-events-none" }) })
|
|
2076
|
-
]
|
|
2077
|
-
}
|
|
2078
|
-
);
|
|
2079
|
-
}
|
|
2080
|
-
function SelectContent({
|
|
2081
|
-
className,
|
|
2082
|
-
children,
|
|
2083
|
-
position = "item-aligned",
|
|
2084
|
-
align = "center",
|
|
2085
|
-
...props
|
|
2086
|
-
}) {
|
|
2087
|
-
return /* @__PURE__ */ jsx23(SelectPrimitive.Portal, { children: /* @__PURE__ */ jsxs15(
|
|
2088
|
-
SelectPrimitive.Content,
|
|
2089
|
-
{
|
|
2090
|
-
"data-slot": "select-content",
|
|
2091
|
-
"data-align-trigger": position === "item-aligned",
|
|
2092
|
-
className: cn("bg-popover text-popover-foreground 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 min-w-36 rounded-md shadow-md ring-1 duration-100 relative z-50 max-h-(--radix-select-content-available-height) origin-(--radix-select-content-transform-origin) overflow-x-hidden overflow-y-auto data-[align-trigger=true]:animate-none", position === "popper" && "data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1", className),
|
|
2093
|
-
position,
|
|
2094
|
-
align,
|
|
2095
|
-
...props,
|
|
2096
|
-
children: [
|
|
2097
|
-
/* @__PURE__ */ jsx23(SelectScrollUpButton, {}),
|
|
2098
|
-
/* @__PURE__ */ jsx23(
|
|
2099
|
-
SelectPrimitive.Viewport,
|
|
2100
|
-
{
|
|
2101
|
-
"data-position": position,
|
|
2102
|
-
className: cn(
|
|
2103
|
-
"data-[position=popper]:h-(--radix-select-trigger-height) data-[position=popper]:w-full data-[position=popper]:min-w-(--radix-select-trigger-width)",
|
|
2104
|
-
position === "popper" && ""
|
|
2105
|
-
),
|
|
2106
|
-
children
|
|
2107
|
-
}
|
|
2108
|
-
),
|
|
2109
|
-
/* @__PURE__ */ jsx23(SelectScrollDownButton, {})
|
|
2110
|
-
]
|
|
2111
|
-
}
|
|
2112
|
-
) });
|
|
2113
|
-
}
|
|
2114
|
-
function SelectItem({
|
|
2115
|
-
className,
|
|
2116
|
-
children,
|
|
2117
|
-
...props
|
|
2118
|
-
}) {
|
|
2119
|
-
return /* @__PURE__ */ jsxs15(
|
|
2120
|
-
SelectPrimitive.Item,
|
|
2121
|
-
{
|
|
2122
|
-
"data-slot": "select-item",
|
|
2123
|
-
className: cn(
|
|
2124
|
-
"focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2 relative flex w-full cursor-default items-center outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0",
|
|
2125
|
-
className
|
|
2126
|
-
),
|
|
2127
|
-
...props,
|
|
2128
|
-
children: [
|
|
2129
|
-
/* @__PURE__ */ jsx23("span", { className: "pointer-events-none absolute right-2 flex size-4 items-center justify-center", children: /* @__PURE__ */ jsx23(SelectPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx23(Check2, { className: "pointer-events-none" }) }) }),
|
|
2130
|
-
/* @__PURE__ */ jsx23(SelectPrimitive.ItemText, { children })
|
|
2131
|
-
]
|
|
2132
|
-
}
|
|
2133
|
-
);
|
|
2134
|
-
}
|
|
2135
|
-
function SelectScrollUpButton({
|
|
2136
|
-
className,
|
|
2137
|
-
...props
|
|
2138
|
-
}) {
|
|
2139
|
-
return /* @__PURE__ */ jsx23(
|
|
2140
|
-
SelectPrimitive.ScrollUpButton,
|
|
2141
|
-
{
|
|
2142
|
-
"data-slot": "select-scroll-up-button",
|
|
2143
|
-
className: cn("bg-popover z-10 flex cursor-default items-center justify-center py-1 [&_svg:not([class*='size-'])]:size-4", className),
|
|
2144
|
-
...props,
|
|
2145
|
-
children: /* @__PURE__ */ jsx23(ChevronUp, {})
|
|
2146
|
-
}
|
|
2147
|
-
);
|
|
2148
|
-
}
|
|
2149
|
-
function SelectScrollDownButton({
|
|
2150
|
-
className,
|
|
2151
|
-
...props
|
|
2152
|
-
}) {
|
|
2153
|
-
return /* @__PURE__ */ jsx23(
|
|
2154
|
-
SelectPrimitive.ScrollDownButton,
|
|
2155
|
-
{
|
|
2156
|
-
"data-slot": "select-scroll-down-button",
|
|
2157
|
-
className: cn("bg-popover z-10 flex cursor-default items-center justify-center py-1 [&_svg:not([class*='size-'])]:size-4", className),
|
|
2158
|
-
...props,
|
|
2159
|
-
children: /* @__PURE__ */ jsx23(ChevronDown, {})
|
|
2160
|
-
}
|
|
2161
|
-
);
|
|
2162
|
-
}
|
|
898
|
+
import { useCallback as useCallback3, useMemo as useMemo3, useState as useState6 } from "react";
|
|
2163
899
|
|
|
2164
900
|
// src/components/users/user-form-dialog.tsx
|
|
901
|
+
import { useEffect as useEffect2, useState as useState4 } from "react";
|
|
2165
902
|
import { Loader2 as Loader22 } from "lucide-react";
|
|
2166
903
|
import { toast as toast2 } from "sonner";
|
|
2167
|
-
import { jsx as
|
|
904
|
+
import { jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
2168
905
|
var PROFILE_OPTIONS = [
|
|
2169
906
|
{ value: "owner", label: "Propriet\xE1rio" },
|
|
2170
907
|
{ value: "admin", label: "Administrador" },
|
|
@@ -2182,13 +919,13 @@ function UserFormDialog({
|
|
|
2182
919
|
const isEditing = !!user;
|
|
2183
920
|
const createUser = useCreateUser(config);
|
|
2184
921
|
const updateUser = useUpdateUser(config);
|
|
2185
|
-
const [name, setName] =
|
|
2186
|
-
const [lastName, setLastName] =
|
|
2187
|
-
const [email, setEmail] =
|
|
2188
|
-
const [profile, setProfile] =
|
|
2189
|
-
const [password, setPassword] =
|
|
2190
|
-
const [photo, setPhoto] =
|
|
2191
|
-
|
|
922
|
+
const [name, setName] = useState4("");
|
|
923
|
+
const [lastName, setLastName] = useState4("");
|
|
924
|
+
const [email, setEmail] = useState4("");
|
|
925
|
+
const [profile, setProfile] = useState4("collaborator");
|
|
926
|
+
const [password, setPassword] = useState4("");
|
|
927
|
+
const [photo, setPhoto] = useState4("");
|
|
928
|
+
useEffect2(() => {
|
|
2192
929
|
if (user) {
|
|
2193
930
|
setName(user.name || "");
|
|
2194
931
|
setLastName(user.last_name || "");
|
|
@@ -2237,10 +974,10 @@ function UserFormDialog({
|
|
|
2237
974
|
toast2.error(isEditing ? "Erro ao atualizar usu\xE1rio" : "Erro ao criar usu\xE1rio");
|
|
2238
975
|
}
|
|
2239
976
|
}
|
|
2240
|
-
return /* @__PURE__ */
|
|
2241
|
-
/* @__PURE__ */
|
|
2242
|
-
/* @__PURE__ */
|
|
2243
|
-
/* @__PURE__ */
|
|
977
|
+
return /* @__PURE__ */ jsx8(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxs8(DialogContent, { children: [
|
|
978
|
+
/* @__PURE__ */ jsx8(DialogHeader, { children: /* @__PURE__ */ jsx8(DialogTitle, { children: isEditing ? "Editar Usu\xE1rio" : "Novo Usu\xE1rio" }) }),
|
|
979
|
+
/* @__PURE__ */ jsxs8("form", { onSubmit: handleSubmit, className: "space-y-4", children: [
|
|
980
|
+
/* @__PURE__ */ jsx8("div", { className: "flex justify-center", children: /* @__PURE__ */ jsx8(
|
|
2244
981
|
ImageCropUpload,
|
|
2245
982
|
{
|
|
2246
983
|
value: photo || null,
|
|
@@ -2253,36 +990,36 @@ function UserFormDialog({
|
|
|
2253
990
|
disabled: isPending
|
|
2254
991
|
}
|
|
2255
992
|
) }),
|
|
2256
|
-
/* @__PURE__ */
|
|
2257
|
-
/* @__PURE__ */
|
|
2258
|
-
/* @__PURE__ */
|
|
2259
|
-
/* @__PURE__ */
|
|
993
|
+
/* @__PURE__ */ jsxs8("div", { className: "grid grid-cols-2 gap-4", children: [
|
|
994
|
+
/* @__PURE__ */ jsxs8("div", { className: "space-y-2", children: [
|
|
995
|
+
/* @__PURE__ */ jsx8(Label, { htmlFor: "user-name", children: "Nome *" }),
|
|
996
|
+
/* @__PURE__ */ jsx8(Input, { id: "user-name", name: "firstName", value: name, onChange: (e) => setName(e.target.value), placeholder: "Nome", required: true, disabled: isPending })
|
|
2260
997
|
] }),
|
|
2261
|
-
/* @__PURE__ */
|
|
2262
|
-
/* @__PURE__ */
|
|
2263
|
-
/* @__PURE__ */
|
|
998
|
+
/* @__PURE__ */ jsxs8("div", { className: "space-y-2", children: [
|
|
999
|
+
/* @__PURE__ */ jsx8(Label, { htmlFor: "user-lastname", children: "Sobrenome" }),
|
|
1000
|
+
/* @__PURE__ */ jsx8(Input, { id: "user-lastname", name: "lastName", value: lastName, onChange: (e) => setLastName(e.target.value), placeholder: "Sobrenome", disabled: isPending })
|
|
2264
1001
|
] })
|
|
2265
1002
|
] }),
|
|
2266
|
-
/* @__PURE__ */
|
|
2267
|
-
/* @__PURE__ */
|
|
2268
|
-
/* @__PURE__ */
|
|
1003
|
+
/* @__PURE__ */ jsxs8("div", { className: "space-y-2", children: [
|
|
1004
|
+
/* @__PURE__ */ jsx8(Label, { htmlFor: "user-email", children: "E-mail *" }),
|
|
1005
|
+
/* @__PURE__ */ jsx8(Input, { id: "user-email", name: "email", type: "email", autoComplete: "email", value: email, onChange: (e) => setEmail(e.target.value), placeholder: "email@exemplo.com", required: true, disabled: isPending })
|
|
2269
1006
|
] }),
|
|
2270
|
-
!isEditing && /* @__PURE__ */
|
|
2271
|
-
/* @__PURE__ */
|
|
2272
|
-
/* @__PURE__ */
|
|
1007
|
+
!isEditing && /* @__PURE__ */ jsxs8("div", { className: "space-y-2", children: [
|
|
1008
|
+
/* @__PURE__ */ jsx8(Label, { htmlFor: "user-password", children: "Senha" }),
|
|
1009
|
+
/* @__PURE__ */ jsx8(Input, { id: "user-password", name: "password", type: "password", autoComplete: "new-password", value: password, onChange: (e) => setPassword(e.target.value), placeholder: "Senha inicial (opcional)", disabled: isPending })
|
|
2273
1010
|
] }),
|
|
2274
|
-
/* @__PURE__ */
|
|
2275
|
-
/* @__PURE__ */
|
|
2276
|
-
/* @__PURE__ */
|
|
2277
|
-
/* @__PURE__ */
|
|
2278
|
-
/* @__PURE__ */
|
|
1011
|
+
/* @__PURE__ */ jsxs8("div", { className: "space-y-2", children: [
|
|
1012
|
+
/* @__PURE__ */ jsx8(Label, { htmlFor: "user-profile", children: "Perfil de acesso" }),
|
|
1013
|
+
/* @__PURE__ */ jsxs8(Select, { value: profile, onValueChange: setProfile, disabled: isPending, children: [
|
|
1014
|
+
/* @__PURE__ */ jsx8(SelectTrigger, { id: "user-profile", className: "w-full", children: /* @__PURE__ */ jsx8(SelectValue, {}) }),
|
|
1015
|
+
/* @__PURE__ */ jsx8(SelectContent, { children: PROFILE_OPTIONS.map((opt) => /* @__PURE__ */ jsx8(SelectItem, { value: opt.value, children: opt.label }, opt.value)) })
|
|
2279
1016
|
] })
|
|
2280
1017
|
] }),
|
|
2281
|
-
isEditing && renderPhones && /* @__PURE__ */
|
|
2282
|
-
/* @__PURE__ */
|
|
2283
|
-
/* @__PURE__ */
|
|
2284
|
-
/* @__PURE__ */
|
|
2285
|
-
isPending && /* @__PURE__ */
|
|
1018
|
+
isEditing && renderPhones && /* @__PURE__ */ jsx8("div", { className: "border-t pt-4", children: renderPhones(user.id) }),
|
|
1019
|
+
/* @__PURE__ */ jsxs8(DialogFooter, { children: [
|
|
1020
|
+
/* @__PURE__ */ jsx8(Button, { type: "button", variant: "outline", onClick: () => onOpenChange(false), disabled: isPending, children: "Cancelar" }),
|
|
1021
|
+
/* @__PURE__ */ jsxs8(Button, { type: "submit", disabled: isPending || !name.trim() || !email.trim(), children: [
|
|
1022
|
+
isPending && /* @__PURE__ */ jsx8(Loader22, { "aria-hidden": "true", className: "mr-2 h-4 w-4 animate-spin" }),
|
|
2286
1023
|
isEditing ? "Salvar" : "Criar"
|
|
2287
1024
|
] })
|
|
2288
1025
|
] })
|
|
@@ -2291,7 +1028,7 @@ function UserFormDialog({
|
|
|
2291
1028
|
}
|
|
2292
1029
|
|
|
2293
1030
|
// src/components/users/user-profile-badge.tsx
|
|
2294
|
-
import { jsx as
|
|
1031
|
+
import { jsx as jsx9 } from "react/jsx-runtime";
|
|
2295
1032
|
var profileConfig = {
|
|
2296
1033
|
owner: { label: "Propriet\xE1rio", className: "bg-purple-100 text-purple-800 dark:bg-purple-900 dark:text-purple-200" },
|
|
2297
1034
|
proprietario: { label: "Propriet\xE1rio", className: "bg-purple-100 text-purple-800 dark:bg-purple-900 dark:text-purple-200" },
|
|
@@ -2307,7 +1044,7 @@ var profileConfig = {
|
|
|
2307
1044
|
};
|
|
2308
1045
|
function UserProfileBadge({ profile }) {
|
|
2309
1046
|
const config = profileConfig[profile] || { label: profile, className: "" };
|
|
2310
|
-
return /* @__PURE__ */
|
|
1047
|
+
return /* @__PURE__ */ jsx9(Badge, { variant: "secondary", className: config.className, children: config.label });
|
|
2311
1048
|
}
|
|
2312
1049
|
|
|
2313
1050
|
// src/components/users/data-table.tsx
|
|
@@ -2317,74 +1054,9 @@ import {
|
|
|
2317
1054
|
getSortedRowModel,
|
|
2318
1055
|
useReactTable
|
|
2319
1056
|
} from "@tanstack/react-table";
|
|
2320
|
-
import { useState as
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
import { jsx as jsx26 } from "react/jsx-runtime";
|
|
2324
|
-
function Table({ className, ...props }) {
|
|
2325
|
-
return /* @__PURE__ */ jsx26("div", { "data-slot": "table-container", className: "relative w-full overflow-x-auto", children: /* @__PURE__ */ jsx26(
|
|
2326
|
-
"table",
|
|
2327
|
-
{
|
|
2328
|
-
"data-slot": "table",
|
|
2329
|
-
className: cn("w-full caption-bottom text-sm", className),
|
|
2330
|
-
...props
|
|
2331
|
-
}
|
|
2332
|
-
) });
|
|
2333
|
-
}
|
|
2334
|
-
function TableHeader({ className, ...props }) {
|
|
2335
|
-
return /* @__PURE__ */ jsx26(
|
|
2336
|
-
"thead",
|
|
2337
|
-
{
|
|
2338
|
-
"data-slot": "table-header",
|
|
2339
|
-
className: cn("[&_tr]:border-b", className),
|
|
2340
|
-
...props
|
|
2341
|
-
}
|
|
2342
|
-
);
|
|
2343
|
-
}
|
|
2344
|
-
function TableBody({ className, ...props }) {
|
|
2345
|
-
return /* @__PURE__ */ jsx26(
|
|
2346
|
-
"tbody",
|
|
2347
|
-
{
|
|
2348
|
-
"data-slot": "table-body",
|
|
2349
|
-
className: cn("[&_tr:last-child]:border-0", className),
|
|
2350
|
-
...props
|
|
2351
|
-
}
|
|
2352
|
-
);
|
|
2353
|
-
}
|
|
2354
|
-
function TableRow({ className, ...props }) {
|
|
2355
|
-
return /* @__PURE__ */ jsx26(
|
|
2356
|
-
"tr",
|
|
2357
|
-
{
|
|
2358
|
-
"data-slot": "table-row",
|
|
2359
|
-
className: cn("hover:bg-muted/50 data-[state=selected]:bg-muted border-b transition-colors", className),
|
|
2360
|
-
...props
|
|
2361
|
-
}
|
|
2362
|
-
);
|
|
2363
|
-
}
|
|
2364
|
-
function TableHead({ className, ...props }) {
|
|
2365
|
-
return /* @__PURE__ */ jsx26(
|
|
2366
|
-
"th",
|
|
2367
|
-
{
|
|
2368
|
-
"data-slot": "table-head",
|
|
2369
|
-
className: cn("text-foreground h-10 px-2 text-left align-middle font-medium whitespace-nowrap [&:has([role=checkbox])]:pr-0", className),
|
|
2370
|
-
...props
|
|
2371
|
-
}
|
|
2372
|
-
);
|
|
2373
|
-
}
|
|
2374
|
-
function TableCell({ className, ...props }) {
|
|
2375
|
-
return /* @__PURE__ */ jsx26(
|
|
2376
|
-
"td",
|
|
2377
|
-
{
|
|
2378
|
-
"data-slot": "table-cell",
|
|
2379
|
-
className: cn("p-2 align-middle whitespace-nowrap [&:has([role=checkbox])]:pr-0", className),
|
|
2380
|
-
...props
|
|
2381
|
-
}
|
|
2382
|
-
);
|
|
2383
|
-
}
|
|
2384
|
-
|
|
2385
|
-
// src/components/users/data-table.tsx
|
|
2386
|
-
import { ChevronLeft, ChevronRight as ChevronRight4, ArrowUp, ArrowDown, ArrowUpDown } from "lucide-react";
|
|
2387
|
-
import { jsx as jsx27, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
1057
|
+
import { useState as useState5 } from "react";
|
|
1058
|
+
import { ChevronLeft, ChevronRight as ChevronRight2, ArrowUp, ArrowDown, ArrowUpDown } from "lucide-react";
|
|
1059
|
+
import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
2388
1060
|
function DataTable({
|
|
2389
1061
|
columns,
|
|
2390
1062
|
data,
|
|
@@ -2399,7 +1071,7 @@ function DataTable({
|
|
|
2399
1071
|
getRowId,
|
|
2400
1072
|
compact
|
|
2401
1073
|
}) {
|
|
2402
|
-
const [sorting, setSorting] =
|
|
1074
|
+
const [sorting, setSorting] = useState5([]);
|
|
2403
1075
|
const table = useReactTable({
|
|
2404
1076
|
data,
|
|
2405
1077
|
columns,
|
|
@@ -2410,14 +1082,14 @@ function DataTable({
|
|
|
2410
1082
|
});
|
|
2411
1083
|
const totalPages = total ? Math.ceil(total / pageSize) : 1;
|
|
2412
1084
|
const showPagination = onPageChange && total && total > pageSize;
|
|
2413
|
-
return /* @__PURE__ */
|
|
2414
|
-
/* @__PURE__ */
|
|
2415
|
-
/* @__PURE__ */
|
|
1085
|
+
return /* @__PURE__ */ jsxs9("div", { className: "space-y-4", children: [
|
|
1086
|
+
/* @__PURE__ */ jsx10("div", { className: "rounded-md border", children: /* @__PURE__ */ jsxs9(Table, { children: [
|
|
1087
|
+
/* @__PURE__ */ jsx10(TableHeader, { children: table.getHeaderGroups().map((headerGroup) => /* @__PURE__ */ jsx10(TableRow, { children: headerGroup.headers.map((header) => /* @__PURE__ */ jsx10(
|
|
2416
1088
|
TableHead,
|
|
2417
1089
|
{
|
|
2418
1090
|
className: cn(compact && "py-1.5 text-xs"),
|
|
2419
1091
|
style: { width: header.getSize() !== 150 ? header.getSize() : void 0 },
|
|
2420
|
-
children: header.isPlaceholder ? null : header.column.getCanSort() ? /* @__PURE__ */
|
|
1092
|
+
children: header.isPlaceholder ? null : header.column.getCanSort() ? /* @__PURE__ */ jsxs9(
|
|
2421
1093
|
"button",
|
|
2422
1094
|
{
|
|
2423
1095
|
type: "button",
|
|
@@ -2427,16 +1099,16 @@ function DataTable({
|
|
|
2427
1099
|
children: [
|
|
2428
1100
|
flexRender(header.column.columnDef.header, header.getContext()),
|
|
2429
1101
|
{
|
|
2430
|
-
asc: /* @__PURE__ */
|
|
2431
|
-
desc: /* @__PURE__ */
|
|
2432
|
-
}[header.column.getIsSorted()] ?? /* @__PURE__ */
|
|
1102
|
+
asc: /* @__PURE__ */ jsx10(ArrowUp, { "aria-hidden": "true", className: "h-3.5 w-3.5" }),
|
|
1103
|
+
desc: /* @__PURE__ */ jsx10(ArrowDown, { "aria-hidden": "true", className: "h-3.5 w-3.5" })
|
|
1104
|
+
}[header.column.getIsSorted()] ?? /* @__PURE__ */ jsx10(ArrowUpDown, { "aria-hidden": "true", className: "h-3.5 w-3.5 text-muted-foreground/50" })
|
|
2433
1105
|
]
|
|
2434
1106
|
}
|
|
2435
1107
|
) : flexRender(header.column.columnDef.header, header.getContext())
|
|
2436
1108
|
},
|
|
2437
1109
|
header.id
|
|
2438
1110
|
)) }, headerGroup.id)) }),
|
|
2439
|
-
/* @__PURE__ */
|
|
1111
|
+
/* @__PURE__ */ jsx10(TableBody, { children: isLoading ? Array.from({ length: compact ? 3 : 5 }).map((_, i) => /* @__PURE__ */ jsx10(TableRow, { children: columns.map((_2, j) => /* @__PURE__ */ jsx10(TableCell, { className: cn(compact && "py-1.5"), children: /* @__PURE__ */ jsx10(Skeleton, { className: "h-4 w-full max-w-[120px]" }) }, j)) }, i)) : table.getRowModel().rows.length === 0 ? /* @__PURE__ */ jsx10(TableRow, { children: /* @__PURE__ */ jsx10(
|
|
2440
1112
|
TableCell,
|
|
2441
1113
|
{
|
|
2442
1114
|
colSpan: columns.length,
|
|
@@ -2449,7 +1121,7 @@ function DataTable({
|
|
|
2449
1121
|
) }) : table.getRowModel().rows.map((row) => {
|
|
2450
1122
|
const rowId = getRowId ? getRowId(row.original) : void 0;
|
|
2451
1123
|
const isSelected = selectedRowId != null && rowId != null && rowId === selectedRowId;
|
|
2452
|
-
return /* @__PURE__ */
|
|
1124
|
+
return /* @__PURE__ */ jsx10(
|
|
2453
1125
|
TableRow,
|
|
2454
1126
|
{
|
|
2455
1127
|
className: cn(
|
|
@@ -2457,20 +1129,20 @@ function DataTable({
|
|
|
2457
1129
|
isSelected && "bg-accent"
|
|
2458
1130
|
),
|
|
2459
1131
|
onClick: () => onRowClick?.(row.original),
|
|
2460
|
-
children: row.getVisibleCells().map((cell) => /* @__PURE__ */
|
|
1132
|
+
children: row.getVisibleCells().map((cell) => /* @__PURE__ */ jsx10(TableCell, { className: cn(compact && "py-1.5"), children: flexRender(cell.column.columnDef.cell, cell.getContext()) }, cell.id))
|
|
2461
1133
|
},
|
|
2462
1134
|
row.id
|
|
2463
1135
|
);
|
|
2464
1136
|
}) })
|
|
2465
1137
|
] }) }),
|
|
2466
|
-
showPagination && /* @__PURE__ */
|
|
2467
|
-
/* @__PURE__ */
|
|
1138
|
+
showPagination && /* @__PURE__ */ jsxs9("div", { className: "flex items-center justify-between px-2", children: [
|
|
1139
|
+
/* @__PURE__ */ jsxs9("p", { className: "text-sm text-muted-foreground tabular-nums", children: [
|
|
2468
1140
|
total,
|
|
2469
1141
|
" registro",
|
|
2470
1142
|
total !== 1 ? "s" : ""
|
|
2471
1143
|
] }),
|
|
2472
|
-
/* @__PURE__ */
|
|
2473
|
-
/* @__PURE__ */
|
|
1144
|
+
/* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-2", children: [
|
|
1145
|
+
/* @__PURE__ */ jsxs9(
|
|
2474
1146
|
Button,
|
|
2475
1147
|
{
|
|
2476
1148
|
variant: "outline",
|
|
@@ -2478,17 +1150,17 @@ function DataTable({
|
|
|
2478
1150
|
onClick: () => onPageChange(page - 1),
|
|
2479
1151
|
disabled: page <= 1,
|
|
2480
1152
|
children: [
|
|
2481
|
-
/* @__PURE__ */
|
|
1153
|
+
/* @__PURE__ */ jsx10(ChevronLeft, { "aria-hidden": "true", className: "h-4 w-4" }),
|
|
2482
1154
|
"Anterior"
|
|
2483
1155
|
]
|
|
2484
1156
|
}
|
|
2485
1157
|
),
|
|
2486
|
-
/* @__PURE__ */
|
|
1158
|
+
/* @__PURE__ */ jsxs9("span", { className: "text-sm text-muted-foreground tabular-nums", children: [
|
|
2487
1159
|
page,
|
|
2488
1160
|
" de ",
|
|
2489
1161
|
totalPages
|
|
2490
1162
|
] }),
|
|
2491
|
-
/* @__PURE__ */
|
|
1163
|
+
/* @__PURE__ */ jsxs9(
|
|
2492
1164
|
Button,
|
|
2493
1165
|
{
|
|
2494
1166
|
variant: "outline",
|
|
@@ -2497,7 +1169,7 @@ function DataTable({
|
|
|
2497
1169
|
disabled: page >= totalPages,
|
|
2498
1170
|
children: [
|
|
2499
1171
|
"Pr\xF3ximo",
|
|
2500
|
-
/* @__PURE__ */
|
|
1172
|
+
/* @__PURE__ */ jsx10(ChevronRight2, { "aria-hidden": "true", className: "h-4 w-4" })
|
|
2501
1173
|
]
|
|
2502
1174
|
}
|
|
2503
1175
|
)
|
|
@@ -2506,145 +1178,12 @@ function DataTable({
|
|
|
2506
1178
|
] });
|
|
2507
1179
|
}
|
|
2508
1180
|
|
|
2509
|
-
// src/components/ui/alert-dialog.tsx
|
|
2510
|
-
import { AlertDialog as AlertDialogPrimitive } from "radix-ui";
|
|
2511
|
-
import { jsx as jsx28, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
2512
|
-
function AlertDialog({
|
|
2513
|
-
...props
|
|
2514
|
-
}) {
|
|
2515
|
-
return /* @__PURE__ */ jsx28(AlertDialogPrimitive.Root, { "data-slot": "alert-dialog", ...props });
|
|
2516
|
-
}
|
|
2517
|
-
function AlertDialogPortal({
|
|
2518
|
-
...props
|
|
2519
|
-
}) {
|
|
2520
|
-
return /* @__PURE__ */ jsx28(AlertDialogPrimitive.Portal, { "data-slot": "alert-dialog-portal", ...props });
|
|
2521
|
-
}
|
|
2522
|
-
function AlertDialogOverlay({
|
|
2523
|
-
className,
|
|
2524
|
-
...props
|
|
2525
|
-
}) {
|
|
2526
|
-
return /* @__PURE__ */ jsx28(
|
|
2527
|
-
AlertDialogPrimitive.Overlay,
|
|
2528
|
-
{
|
|
2529
|
-
"data-slot": "alert-dialog-overlay",
|
|
2530
|
-
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 supports-backdrop-filter:backdrop-blur-xs fixed inset-0 z-50", className),
|
|
2531
|
-
...props
|
|
2532
|
-
}
|
|
2533
|
-
);
|
|
2534
|
-
}
|
|
2535
|
-
function AlertDialogContent({
|
|
2536
|
-
className,
|
|
2537
|
-
size = "default",
|
|
2538
|
-
...props
|
|
2539
|
-
}) {
|
|
2540
|
-
return /* @__PURE__ */ jsxs18(AlertDialogPortal, { children: [
|
|
2541
|
-
/* @__PURE__ */ jsx28(AlertDialogOverlay, {}),
|
|
2542
|
-
/* @__PURE__ */ jsx28(
|
|
2543
|
-
AlertDialogPrimitive.Content,
|
|
2544
|
-
{
|
|
2545
|
-
"data-slot": "alert-dialog-content",
|
|
2546
|
-
"data-size": size,
|
|
2547
|
-
className: cn(
|
|
2548
|
-
"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 bg-background ring-foreground/10 gap-6 rounded-xl p-6 ring-1 duration-100 data-[size=default]:max-w-xs data-[size=sm]:max-w-xs data-[size=default]:sm:max-w-lg group/alert-dialog-content fixed top-1/2 left-1/2 z-50 grid w-full -translate-x-1/2 -translate-y-1/2 outline-none",
|
|
2549
|
-
className
|
|
2550
|
-
),
|
|
2551
|
-
...props
|
|
2552
|
-
}
|
|
2553
|
-
)
|
|
2554
|
-
] });
|
|
2555
|
-
}
|
|
2556
|
-
function AlertDialogHeader({
|
|
2557
|
-
className,
|
|
2558
|
-
...props
|
|
2559
|
-
}) {
|
|
2560
|
-
return /* @__PURE__ */ jsx28(
|
|
2561
|
-
"div",
|
|
2562
|
-
{
|
|
2563
|
-
"data-slot": "alert-dialog-header",
|
|
2564
|
-
className: cn("grid grid-rows-[auto_1fr] place-items-center gap-1.5 text-center has-data-[slot=alert-dialog-media]:grid-rows-[auto_auto_1fr] has-data-[slot=alert-dialog-media]:gap-x-6 sm:group-data-[size=default]/alert-dialog-content:place-items-start sm:group-data-[size=default]/alert-dialog-content:text-left sm:group-data-[size=default]/alert-dialog-content:has-data-[slot=alert-dialog-media]:grid-rows-[auto_1fr]", className),
|
|
2565
|
-
...props
|
|
2566
|
-
}
|
|
2567
|
-
);
|
|
2568
|
-
}
|
|
2569
|
-
function AlertDialogFooter({
|
|
2570
|
-
className,
|
|
2571
|
-
...props
|
|
2572
|
-
}) {
|
|
2573
|
-
return /* @__PURE__ */ jsx28(
|
|
2574
|
-
"div",
|
|
2575
|
-
{
|
|
2576
|
-
"data-slot": "alert-dialog-footer",
|
|
2577
|
-
className: cn(
|
|
2578
|
-
"flex flex-col-reverse gap-2 group-data-[size=sm]/alert-dialog-content:grid group-data-[size=sm]/alert-dialog-content:grid-cols-2 sm:flex-row sm:justify-end",
|
|
2579
|
-
className
|
|
2580
|
-
),
|
|
2581
|
-
...props
|
|
2582
|
-
}
|
|
2583
|
-
);
|
|
2584
|
-
}
|
|
2585
|
-
function AlertDialogTitle({
|
|
2586
|
-
className,
|
|
2587
|
-
...props
|
|
2588
|
-
}) {
|
|
2589
|
-
return /* @__PURE__ */ jsx28(
|
|
2590
|
-
AlertDialogPrimitive.Title,
|
|
2591
|
-
{
|
|
2592
|
-
"data-slot": "alert-dialog-title",
|
|
2593
|
-
className: cn("text-lg font-medium sm:group-data-[size=default]/alert-dialog-content:group-has-data-[slot=alert-dialog-media]/alert-dialog-content:col-start-2", className),
|
|
2594
|
-
...props
|
|
2595
|
-
}
|
|
2596
|
-
);
|
|
2597
|
-
}
|
|
2598
|
-
function AlertDialogDescription({
|
|
2599
|
-
className,
|
|
2600
|
-
...props
|
|
2601
|
-
}) {
|
|
2602
|
-
return /* @__PURE__ */ jsx28(
|
|
2603
|
-
AlertDialogPrimitive.Description,
|
|
2604
|
-
{
|
|
2605
|
-
"data-slot": "alert-dialog-description",
|
|
2606
|
-
className: cn("text-muted-foreground *:[a]:hover:text-foreground text-sm text-balance md:text-pretty *:[a]:underline *:[a]:underline-offset-3", className),
|
|
2607
|
-
...props
|
|
2608
|
-
}
|
|
2609
|
-
);
|
|
2610
|
-
}
|
|
2611
|
-
function AlertDialogAction({
|
|
2612
|
-
className,
|
|
2613
|
-
variant = "default",
|
|
2614
|
-
size = "default",
|
|
2615
|
-
...props
|
|
2616
|
-
}) {
|
|
2617
|
-
return /* @__PURE__ */ jsx28(Button, { variant, size, asChild: true, children: /* @__PURE__ */ jsx28(
|
|
2618
|
-
AlertDialogPrimitive.Action,
|
|
2619
|
-
{
|
|
2620
|
-
"data-slot": "alert-dialog-action",
|
|
2621
|
-
className: cn(className),
|
|
2622
|
-
...props
|
|
2623
|
-
}
|
|
2624
|
-
) });
|
|
2625
|
-
}
|
|
2626
|
-
function AlertDialogCancel({
|
|
2627
|
-
className,
|
|
2628
|
-
variant = "outline",
|
|
2629
|
-
size = "default",
|
|
2630
|
-
...props
|
|
2631
|
-
}) {
|
|
2632
|
-
return /* @__PURE__ */ jsx28(Button, { variant, size, asChild: true, children: /* @__PURE__ */ jsx28(
|
|
2633
|
-
AlertDialogPrimitive.Cancel,
|
|
2634
|
-
{
|
|
2635
|
-
"data-slot": "alert-dialog-cancel",
|
|
2636
|
-
className: cn(className),
|
|
2637
|
-
...props
|
|
2638
|
-
}
|
|
2639
|
-
) });
|
|
2640
|
-
}
|
|
2641
|
-
|
|
2642
1181
|
// src/components/users/users-page.tsx
|
|
2643
1182
|
import { Pencil, Trash2 as Trash22, Search, Forward, Plus } from "lucide-react";
|
|
2644
1183
|
import { format } from "date-fns";
|
|
2645
1184
|
import { ptBR } from "date-fns/locale";
|
|
2646
1185
|
import { toast as toast3 } from "sonner";
|
|
2647
|
-
import { jsx as
|
|
1186
|
+
import { jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
2648
1187
|
var PAGE_SIZE = 15;
|
|
2649
1188
|
var PROFILE_FILTER_OPTIONS = [
|
|
2650
1189
|
{ value: "all", label: "Todos os perfis" },
|
|
@@ -2659,8 +1198,8 @@ function useColumns(onEdit, onDelete, onResetPassword) {
|
|
|
2659
1198
|
{
|
|
2660
1199
|
accessorKey: "name",
|
|
2661
1200
|
header: "Nome",
|
|
2662
|
-
cell: ({ row }) => /* @__PURE__ */
|
|
2663
|
-
/* @__PURE__ */
|
|
1201
|
+
cell: ({ row }) => /* @__PURE__ */ jsxs10("div", { className: "flex items-center gap-2", children: [
|
|
1202
|
+
/* @__PURE__ */ jsx11(
|
|
2664
1203
|
EntityAvatar,
|
|
2665
1204
|
{
|
|
2666
1205
|
photo: row.original.photo,
|
|
@@ -2668,7 +1207,7 @@ function useColumns(onEdit, onDelete, onResetPassword) {
|
|
|
2668
1207
|
size: "sm"
|
|
2669
1208
|
}
|
|
2670
1209
|
),
|
|
2671
|
-
/* @__PURE__ */
|
|
1210
|
+
/* @__PURE__ */ jsxs10("span", { className: "font-medium", children: [
|
|
2672
1211
|
row.original.name,
|
|
2673
1212
|
" ",
|
|
2674
1213
|
row.original.last_name
|
|
@@ -2687,45 +1226,45 @@ function useColumns(onEdit, onDelete, onResetPassword) {
|
|
|
2687
1226
|
{
|
|
2688
1227
|
accessorKey: "profile",
|
|
2689
1228
|
header: "Perfil",
|
|
2690
|
-
cell: ({ row }) => /* @__PURE__ */
|
|
1229
|
+
cell: ({ row }) => /* @__PURE__ */ jsx11(UserProfileBadge, { profile: row.original.profile }),
|
|
2691
1230
|
sortingFn: (rowA, rowB) => rowA.original.profile.localeCompare(rowB.original.profile)
|
|
2692
1231
|
},
|
|
2693
1232
|
{
|
|
2694
1233
|
accessorKey: "last_login",
|
|
2695
1234
|
header: "\xDAltimo acesso",
|
|
2696
|
-
cell: ({ row }) => /* @__PURE__ */
|
|
1235
|
+
cell: ({ row }) => /* @__PURE__ */ jsx11("span", { className: "text-muted-foreground text-sm tabular-nums", children: row.original.last_login ? format(new Date(row.original.last_login), "dd/MM/yyyy HH:mm", { locale: ptBR }) : "\u2014" })
|
|
2697
1236
|
},
|
|
2698
1237
|
{
|
|
2699
1238
|
accessorKey: "datetime_add",
|
|
2700
1239
|
header: "Criado em",
|
|
2701
|
-
cell: ({ row }) => /* @__PURE__ */
|
|
1240
|
+
cell: ({ row }) => /* @__PURE__ */ jsx11("span", { className: "text-muted-foreground text-sm tabular-nums", children: format(new Date(row.original.datetime_add), "dd/MM/yyyy", { locale: ptBR }) })
|
|
2702
1241
|
},
|
|
2703
1242
|
{
|
|
2704
1243
|
id: "actions",
|
|
2705
1244
|
size: 120,
|
|
2706
1245
|
enableSorting: false,
|
|
2707
|
-
cell: ({ row }) => /* @__PURE__ */
|
|
2708
|
-
/* @__PURE__ */
|
|
2709
|
-
/* @__PURE__ */
|
|
2710
|
-
/* @__PURE__ */
|
|
1246
|
+
cell: ({ row }) => /* @__PURE__ */ jsxs10("div", { className: "flex items-center gap-1", children: [
|
|
1247
|
+
/* @__PURE__ */ jsxs10(Tooltip, { children: [
|
|
1248
|
+
/* @__PURE__ */ jsx11(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx11(Button, { variant: "ghost", size: "icon", className: "h-8 w-8", onClick: () => onResetPassword(row.original), "aria-label": "Reenviar senha", children: /* @__PURE__ */ jsx11(Forward, { className: "h-4 w-4" }) }) }),
|
|
1249
|
+
/* @__PURE__ */ jsx11(TooltipContent, { children: "Resetar senha" })
|
|
2711
1250
|
] }),
|
|
2712
|
-
/* @__PURE__ */
|
|
2713
|
-
/* @__PURE__ */
|
|
2714
|
-
/* @__PURE__ */
|
|
1251
|
+
/* @__PURE__ */ jsxs10(Tooltip, { children: [
|
|
1252
|
+
/* @__PURE__ */ jsx11(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx11(Button, { variant: "ghost", size: "icon", className: "h-8 w-8", onClick: () => onEdit(row.original), "aria-label": "Editar", children: /* @__PURE__ */ jsx11(Pencil, { className: "h-4 w-4" }) }) }),
|
|
1253
|
+
/* @__PURE__ */ jsx11(TooltipContent, { children: "Editar" })
|
|
2715
1254
|
] }),
|
|
2716
|
-
/* @__PURE__ */
|
|
2717
|
-
/* @__PURE__ */
|
|
2718
|
-
/* @__PURE__ */
|
|
1255
|
+
/* @__PURE__ */ jsxs10(Tooltip, { children: [
|
|
1256
|
+
/* @__PURE__ */ jsx11(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx11(Button, { variant: "ghost", size: "icon", className: "h-8 w-8 text-destructive hover:text-destructive", onClick: () => onDelete(row.original.id), "aria-label": "Excluir", children: /* @__PURE__ */ jsx11(Trash22, { className: "h-4 w-4" }) }) }),
|
|
1257
|
+
/* @__PURE__ */ jsx11(TooltipContent, { children: "Excluir" })
|
|
2719
1258
|
] })
|
|
2720
1259
|
] })
|
|
2721
1260
|
}
|
|
2722
1261
|
];
|
|
2723
1262
|
}
|
|
2724
1263
|
function UsersPage({ config, renderPhones }) {
|
|
2725
|
-
const [search, setSearch] =
|
|
2726
|
-
const [profileFilter, setProfileFilter] =
|
|
2727
|
-
const [page, setPage] =
|
|
2728
|
-
const queryParams =
|
|
1264
|
+
const [search, setSearch] = useState6("");
|
|
1265
|
+
const [profileFilter, setProfileFilter] = useState6("all");
|
|
1266
|
+
const [page, setPage] = useState6(1);
|
|
1267
|
+
const queryParams = useMemo3(() => {
|
|
2729
1268
|
const params = {
|
|
2730
1269
|
limit: String(PAGE_SIZE),
|
|
2731
1270
|
page: String(page)
|
|
@@ -2736,26 +1275,28 @@ function UsersPage({ config, renderPhones }) {
|
|
|
2736
1275
|
const { data, isLoading } = useUsers(config, queryParams);
|
|
2737
1276
|
const deleteUser = useDeleteUser(config);
|
|
2738
1277
|
const resetPassword = useResetPassword(config);
|
|
2739
|
-
const [editUser, setEditUser] =
|
|
2740
|
-
const [formOpen, setFormOpen] =
|
|
2741
|
-
const [deleteId, setDeleteId] =
|
|
2742
|
-
const [resetUser, setResetUser] =
|
|
1278
|
+
const [editUser, setEditUser] = useState6(null);
|
|
1279
|
+
const [formOpen, setFormOpen] = useState6(false);
|
|
1280
|
+
const [deleteId, setDeleteId] = useState6(null);
|
|
1281
|
+
const [resetUser, setResetUser] = useState6(null);
|
|
2743
1282
|
const users = data?.data || [];
|
|
2744
1283
|
const total = data?.total || 0;
|
|
2745
|
-
const filtered =
|
|
1284
|
+
const filtered = useMemo3(() => {
|
|
2746
1285
|
if (!search) return users;
|
|
2747
1286
|
const term = search.toLowerCase();
|
|
2748
1287
|
return users.filter(
|
|
2749
1288
|
(u) => `${u.name} ${u.last_name}`.toLowerCase().includes(term) || u.email.toLowerCase().includes(term)
|
|
2750
1289
|
);
|
|
2751
1290
|
}, [users, search]);
|
|
2752
|
-
const
|
|
2753
|
-
(u)
|
|
2754
|
-
|
|
2755
|
-
|
|
2756
|
-
|
|
2757
|
-
|
|
2758
|
-
|
|
1291
|
+
const onEdit = useCallback3((u) => {
|
|
1292
|
+
setEditUser(u);
|
|
1293
|
+
setFormOpen(true);
|
|
1294
|
+
}, []);
|
|
1295
|
+
const onDelete = useCallback3((id) => setDeleteId(id), []);
|
|
1296
|
+
const onResetPassword = useCallback3((u) => setResetUser(u), []);
|
|
1297
|
+
const columns = useMemo3(
|
|
1298
|
+
() => useColumns(onEdit, onDelete, onResetPassword),
|
|
1299
|
+
[onEdit, onDelete, onResetPassword]
|
|
2759
1300
|
);
|
|
2760
1301
|
function handleDelete() {
|
|
2761
1302
|
if (!deleteId) return;
|
|
@@ -2780,24 +1321,24 @@ function UsersPage({ config, renderPhones }) {
|
|
|
2780
1321
|
}
|
|
2781
1322
|
});
|
|
2782
1323
|
}
|
|
2783
|
-
return /* @__PURE__ */
|
|
2784
|
-
/* @__PURE__ */
|
|
2785
|
-
/* @__PURE__ */
|
|
2786
|
-
/* @__PURE__ */
|
|
2787
|
-
/* @__PURE__ */
|
|
1324
|
+
return /* @__PURE__ */ jsxs10("div", { className: "flex flex-col gap-4 p-4 md:p-6", children: [
|
|
1325
|
+
/* @__PURE__ */ jsxs10("div", { className: "flex items-center justify-between", children: [
|
|
1326
|
+
/* @__PURE__ */ jsxs10("div", { children: [
|
|
1327
|
+
/* @__PURE__ */ jsx11("h1", { className: "text-xl font-semibold", children: "Usu\xE1rios" }),
|
|
1328
|
+
/* @__PURE__ */ jsx11("p", { className: "text-sm text-muted-foreground", children: "Gest\xE3o de usu\xE1rios da conta" })
|
|
2788
1329
|
] }),
|
|
2789
|
-
/* @__PURE__ */
|
|
1330
|
+
/* @__PURE__ */ jsxs10(Button, { onClick: () => {
|
|
2790
1331
|
setEditUser(null);
|
|
2791
1332
|
setFormOpen(true);
|
|
2792
1333
|
}, size: "sm", children: [
|
|
2793
|
-
/* @__PURE__ */
|
|
1334
|
+
/* @__PURE__ */ jsx11(Plus, { "aria-hidden": "true", className: "mr-2 h-4 w-4" }),
|
|
2794
1335
|
"Novo Usu\xE1rio"
|
|
2795
1336
|
] })
|
|
2796
1337
|
] }),
|
|
2797
|
-
/* @__PURE__ */
|
|
2798
|
-
/* @__PURE__ */
|
|
2799
|
-
/* @__PURE__ */
|
|
2800
|
-
/* @__PURE__ */
|
|
1338
|
+
/* @__PURE__ */ jsxs10("div", { className: "flex items-center gap-3", children: [
|
|
1339
|
+
/* @__PURE__ */ jsxs10("div", { className: "relative flex-1 max-w-md", children: [
|
|
1340
|
+
/* @__PURE__ */ jsx11(Search, { "aria-hidden": "true", className: "absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" }),
|
|
1341
|
+
/* @__PURE__ */ jsx11(
|
|
2801
1342
|
Input,
|
|
2802
1343
|
{
|
|
2803
1344
|
placeholder: "Buscar por nome ou e-mail\\u2026",
|
|
@@ -2813,15 +1354,15 @@ function UsersPage({ config, renderPhones }) {
|
|
|
2813
1354
|
}
|
|
2814
1355
|
)
|
|
2815
1356
|
] }),
|
|
2816
|
-
/* @__PURE__ */
|
|
1357
|
+
/* @__PURE__ */ jsxs10(Select, { value: profileFilter, onValueChange: (v) => {
|
|
2817
1358
|
setProfileFilter(v);
|
|
2818
1359
|
setPage(1);
|
|
2819
1360
|
}, children: [
|
|
2820
|
-
/* @__PURE__ */
|
|
2821
|
-
/* @__PURE__ */
|
|
1361
|
+
/* @__PURE__ */ jsx11(SelectTrigger, { className: "w-[180px]", children: /* @__PURE__ */ jsx11(SelectValue, {}) }),
|
|
1362
|
+
/* @__PURE__ */ jsx11(SelectContent, { children: PROFILE_FILTER_OPTIONS.map((opt) => /* @__PURE__ */ jsx11(SelectItem, { value: opt.value, children: opt.label }, opt.value)) })
|
|
2822
1363
|
] })
|
|
2823
1364
|
] }),
|
|
2824
|
-
/* @__PURE__ */
|
|
1365
|
+
/* @__PURE__ */ jsx11(
|
|
2825
1366
|
DataTable,
|
|
2826
1367
|
{
|
|
2827
1368
|
columns,
|
|
@@ -2834,7 +1375,7 @@ function UsersPage({ config, renderPhones }) {
|
|
|
2834
1375
|
pageSize: PAGE_SIZE
|
|
2835
1376
|
}
|
|
2836
1377
|
),
|
|
2837
|
-
/* @__PURE__ */
|
|
1378
|
+
/* @__PURE__ */ jsx11(
|
|
2838
1379
|
UserFormDialog,
|
|
2839
1380
|
{
|
|
2840
1381
|
open: formOpen,
|
|
@@ -2847,22 +1388,22 @@ function UsersPage({ config, renderPhones }) {
|
|
|
2847
1388
|
renderPhones
|
|
2848
1389
|
}
|
|
2849
1390
|
),
|
|
2850
|
-
/* @__PURE__ */
|
|
2851
|
-
/* @__PURE__ */
|
|
2852
|
-
/* @__PURE__ */
|
|
2853
|
-
/* @__PURE__ */
|
|
1391
|
+
/* @__PURE__ */ jsx11(AlertDialog, { open: !!deleteId, onOpenChange: (open) => !open && setDeleteId(null), children: /* @__PURE__ */ jsxs10(AlertDialogContent, { children: [
|
|
1392
|
+
/* @__PURE__ */ jsxs10(AlertDialogHeader, { children: [
|
|
1393
|
+
/* @__PURE__ */ jsx11(AlertDialogTitle, { children: "Excluir usu\xE1rio?" }),
|
|
1394
|
+
/* @__PURE__ */ jsx11(AlertDialogDescription, { children: "Esta a\xE7\xE3o n\xE3o pode ser desfeita. O usu\xE1rio ser\xE1 removido permanentemente." })
|
|
2854
1395
|
] }),
|
|
2855
|
-
/* @__PURE__ */
|
|
2856
|
-
/* @__PURE__ */
|
|
2857
|
-
/* @__PURE__ */
|
|
1396
|
+
/* @__PURE__ */ jsxs10(AlertDialogFooter, { children: [
|
|
1397
|
+
/* @__PURE__ */ jsx11(AlertDialogCancel, { children: "Cancelar" }),
|
|
1398
|
+
/* @__PURE__ */ jsx11(AlertDialogAction, { onClick: handleDelete, className: "bg-destructive text-destructive-foreground hover:bg-destructive/90", children: "Excluir" })
|
|
2858
1399
|
] })
|
|
2859
1400
|
] }) }),
|
|
2860
|
-
/* @__PURE__ */
|
|
2861
|
-
/* @__PURE__ */
|
|
2862
|
-
/* @__PURE__ */
|
|
2863
|
-
/* @__PURE__ */
|
|
1401
|
+
/* @__PURE__ */ jsx11(AlertDialog, { open: !!resetUser, onOpenChange: (open) => !open && setResetUser(null), children: /* @__PURE__ */ jsxs10(AlertDialogContent, { children: [
|
|
1402
|
+
/* @__PURE__ */ jsxs10(AlertDialogHeader, { children: [
|
|
1403
|
+
/* @__PURE__ */ jsx11(AlertDialogTitle, { children: "Resetar senha?" }),
|
|
1404
|
+
/* @__PURE__ */ jsxs10(AlertDialogDescription, { children: [
|
|
2864
1405
|
"A senha de ",
|
|
2865
|
-
/* @__PURE__ */
|
|
1406
|
+
/* @__PURE__ */ jsxs10("strong", { children: [
|
|
2866
1407
|
resetUser?.name,
|
|
2867
1408
|
" ",
|
|
2868
1409
|
resetUser?.last_name
|
|
@@ -2872,9 +1413,9 @@ function UsersPage({ config, renderPhones }) {
|
|
|
2872
1413
|
") ser\xE1 removida e um email com link para definir nova senha ser\xE1 enviado."
|
|
2873
1414
|
] })
|
|
2874
1415
|
] }),
|
|
2875
|
-
/* @__PURE__ */
|
|
2876
|
-
/* @__PURE__ */
|
|
2877
|
-
/* @__PURE__ */
|
|
1416
|
+
/* @__PURE__ */ jsxs10(AlertDialogFooter, { children: [
|
|
1417
|
+
/* @__PURE__ */ jsx11(AlertDialogCancel, { children: "Cancelar" }),
|
|
1418
|
+
/* @__PURE__ */ jsx11(AlertDialogAction, { onClick: handleResetPassword, children: "Resetar e enviar" })
|
|
2878
1419
|
] })
|
|
2879
1420
|
] }) })
|
|
2880
1421
|
] });
|