@cortexasystem/ui 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +2137 -0
- package/dist/index.d.cts +525 -0
- package/dist/index.d.ts +525 -0
- package/dist/index.js +1977 -0
- package/dist/isotipo-cortexa-dark-F2MDSEEV.png +0 -0
- package/dist/isotipo-cortexa-light-LV3O6ASR.png +0 -0
- package/package.json +61 -0
- package/src/styles.css +2 -0
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,2137 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/index.ts
|
|
31
|
+
var index_exports = {};
|
|
32
|
+
__export(index_exports, {
|
|
33
|
+
Alert: () => Alert,
|
|
34
|
+
AlertDescription: () => AlertDescription,
|
|
35
|
+
AlertTitle: () => AlertTitle,
|
|
36
|
+
AppShell: () => AppShell,
|
|
37
|
+
Avatar: () => Avatar,
|
|
38
|
+
AvatarFallback: () => AvatarFallback,
|
|
39
|
+
AvatarGroup: () => AvatarGroup,
|
|
40
|
+
AvatarImage: () => AvatarImage,
|
|
41
|
+
Badge: () => Badge,
|
|
42
|
+
BrandLogo: () => BrandLogo,
|
|
43
|
+
Breadcrumb: () => Breadcrumb,
|
|
44
|
+
BreadcrumbEllipsis: () => BreadcrumbEllipsis,
|
|
45
|
+
BreadcrumbItem: () => BreadcrumbItem,
|
|
46
|
+
BreadcrumbLink: () => BreadcrumbLink,
|
|
47
|
+
BreadcrumbList: () => BreadcrumbList,
|
|
48
|
+
BreadcrumbPage: () => BreadcrumbPage,
|
|
49
|
+
BreadcrumbSeparator: () => BreadcrumbSeparator,
|
|
50
|
+
Button: () => Button,
|
|
51
|
+
Card: () => Card,
|
|
52
|
+
CardContent: () => CardContent,
|
|
53
|
+
CardDescription: () => CardDescription,
|
|
54
|
+
CardFooter: () => CardFooter,
|
|
55
|
+
CardHeader: () => CardHeader,
|
|
56
|
+
CardTitle: () => CardTitle,
|
|
57
|
+
CenteredIconCard: () => CenteredIconCard,
|
|
58
|
+
Checkbox: () => Checkbox,
|
|
59
|
+
CheckboxField: () => CheckboxField,
|
|
60
|
+
ClickableCard: () => ClickableCard,
|
|
61
|
+
DataTable: () => DataTable,
|
|
62
|
+
Dialog: () => Dialog,
|
|
63
|
+
DialogClose: () => DialogClose,
|
|
64
|
+
DialogContent: () => DialogContent,
|
|
65
|
+
DialogDescription: () => DialogDescription,
|
|
66
|
+
DialogFooter: () => DialogFooter,
|
|
67
|
+
DialogHeader: () => DialogHeader,
|
|
68
|
+
DialogOverlay: () => DialogOverlay,
|
|
69
|
+
DialogPortal: () => DialogPortal,
|
|
70
|
+
DialogTitle: () => DialogTitle,
|
|
71
|
+
DialogTrigger: () => DialogTrigger,
|
|
72
|
+
Drawer: () => Drawer,
|
|
73
|
+
DrawerClose: () => DrawerClose,
|
|
74
|
+
DrawerContent: () => DrawerContent,
|
|
75
|
+
DrawerDescription: () => DrawerDescription,
|
|
76
|
+
DrawerFooter: () => DrawerFooter,
|
|
77
|
+
DrawerHeader: () => DrawerHeader,
|
|
78
|
+
DrawerOverlay: () => DrawerOverlay,
|
|
79
|
+
DrawerPortal: () => DrawerPortal,
|
|
80
|
+
DrawerTitle: () => DrawerTitle,
|
|
81
|
+
DrawerTrigger: () => DrawerTrigger,
|
|
82
|
+
DropdownMenu: () => DropdownMenu,
|
|
83
|
+
DropdownMenuCheckboxItem: () => DropdownMenuCheckboxItem,
|
|
84
|
+
DropdownMenuContent: () => DropdownMenuContent,
|
|
85
|
+
DropdownMenuGroup: () => DropdownMenuGroup,
|
|
86
|
+
DropdownMenuItem: () => DropdownMenuItem,
|
|
87
|
+
DropdownMenuLabel: () => DropdownMenuLabel,
|
|
88
|
+
DropdownMenuPortal: () => DropdownMenuPortal,
|
|
89
|
+
DropdownMenuRadioGroup: () => DropdownMenuRadioGroup,
|
|
90
|
+
DropdownMenuRadioItem: () => DropdownMenuRadioItem,
|
|
91
|
+
DropdownMenuSeparator: () => DropdownMenuSeparator,
|
|
92
|
+
DropdownMenuShortcut: () => DropdownMenuShortcut,
|
|
93
|
+
DropdownMenuSub: () => DropdownMenuSub,
|
|
94
|
+
DropdownMenuSubContent: () => DropdownMenuSubContent,
|
|
95
|
+
DropdownMenuSubTrigger: () => DropdownMenuSubTrigger,
|
|
96
|
+
DropdownMenuTrigger: () => DropdownMenuTrigger,
|
|
97
|
+
FeatureIcon: () => FeatureIcon,
|
|
98
|
+
FormSection: () => FormSection,
|
|
99
|
+
Input: () => Input,
|
|
100
|
+
Label: () => Label3,
|
|
101
|
+
LoadingCard: () => LoadingCard,
|
|
102
|
+
LoadingState: () => LoadingState,
|
|
103
|
+
LoadingTableRows: () => LoadingTableRows,
|
|
104
|
+
ModuleIconButton: () => ModuleIconButton,
|
|
105
|
+
Navbar: () => Navbar,
|
|
106
|
+
NotificationAction: () => NotificationAction,
|
|
107
|
+
NotificationMessage: () => NotificationMessage,
|
|
108
|
+
PageBreadcrumb: () => PageBreadcrumb,
|
|
109
|
+
PageHeader: () => PageHeader,
|
|
110
|
+
ProfileAvatar: () => ProfileAvatar,
|
|
111
|
+
ProfileAvatarRow: () => ProfileAvatarRow,
|
|
112
|
+
RadioField: () => RadioField,
|
|
113
|
+
RadioGroup: () => RadioGroup2,
|
|
114
|
+
RadioGroupItem: () => RadioGroupItem,
|
|
115
|
+
SearchableSelect: () => SearchableSelect,
|
|
116
|
+
Select: () => Select,
|
|
117
|
+
SelectContent: () => SelectContent,
|
|
118
|
+
SelectGroup: () => SelectGroup,
|
|
119
|
+
SelectItem: () => SelectItem,
|
|
120
|
+
SelectLabel: () => SelectLabel,
|
|
121
|
+
SelectScrollDownButton: () => SelectScrollDownButton,
|
|
122
|
+
SelectScrollUpButton: () => SelectScrollUpButton,
|
|
123
|
+
SelectSeparator: () => SelectSeparator,
|
|
124
|
+
SelectTrigger: () => SelectTrigger,
|
|
125
|
+
SelectValue: () => SelectValue,
|
|
126
|
+
Separator: () => Separator3,
|
|
127
|
+
Sheet: () => Sheet,
|
|
128
|
+
SheetClose: () => SheetClose,
|
|
129
|
+
SheetContent: () => SheetContent,
|
|
130
|
+
SheetDescription: () => SheetDescription,
|
|
131
|
+
SheetFooter: () => SheetFooter,
|
|
132
|
+
SheetHeader: () => SheetHeader,
|
|
133
|
+
SheetOverlay: () => SheetOverlay,
|
|
134
|
+
SheetPortal: () => SheetPortal,
|
|
135
|
+
SheetTitle: () => SheetTitle,
|
|
136
|
+
SheetTrigger: () => SheetTrigger,
|
|
137
|
+
Sidebar: () => Sidebar,
|
|
138
|
+
Skeleton: () => Skeleton,
|
|
139
|
+
Spinner: () => Spinner,
|
|
140
|
+
StatusBadge: () => StatusBadge,
|
|
141
|
+
Steps: () => Steps,
|
|
142
|
+
Switch: () => Switch,
|
|
143
|
+
SwitchField: () => SwitchField,
|
|
144
|
+
Table: () => Table,
|
|
145
|
+
TableBody: () => TableBody,
|
|
146
|
+
TableCaption: () => TableCaption,
|
|
147
|
+
TableCell: () => TableCell,
|
|
148
|
+
TableFooter: () => TableFooter,
|
|
149
|
+
TableHead: () => TableHead,
|
|
150
|
+
TableHeader: () => TableHeader,
|
|
151
|
+
TableRow: () => TableRow,
|
|
152
|
+
TableRowActions: () => TableRowActions,
|
|
153
|
+
Textarea: () => Textarea,
|
|
154
|
+
ThemeProvider: () => ThemeProvider,
|
|
155
|
+
ThemeToggle: () => ThemeToggle,
|
|
156
|
+
Toaster: () => Toaster,
|
|
157
|
+
Typography: () => Typography,
|
|
158
|
+
badgeVariants: () => badgeVariants,
|
|
159
|
+
buttonVariants: () => buttonVariants,
|
|
160
|
+
cn: () => cn,
|
|
161
|
+
notify: () => notify,
|
|
162
|
+
useTheme: () => useTheme
|
|
163
|
+
});
|
|
164
|
+
module.exports = __toCommonJS(index_exports);
|
|
165
|
+
|
|
166
|
+
// src/providers/theme-provider.tsx
|
|
167
|
+
var import_react = require("react");
|
|
168
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
169
|
+
var ThemeProviderContext = (0, import_react.createContext)(void 0);
|
|
170
|
+
function resolveTheme(theme) {
|
|
171
|
+
if (theme === "system") {
|
|
172
|
+
return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
|
|
173
|
+
}
|
|
174
|
+
return theme;
|
|
175
|
+
}
|
|
176
|
+
function ThemeProvider({
|
|
177
|
+
children,
|
|
178
|
+
defaultTheme = "system",
|
|
179
|
+
forcedTheme,
|
|
180
|
+
storageKey = "cortexa-theme"
|
|
181
|
+
}) {
|
|
182
|
+
const [theme, setThemeState] = (0, import_react.useState)(() => {
|
|
183
|
+
if (typeof window === "undefined") {
|
|
184
|
+
return forcedTheme ?? defaultTheme;
|
|
185
|
+
}
|
|
186
|
+
return window.localStorage.getItem(storageKey) ?? forcedTheme ?? defaultTheme;
|
|
187
|
+
});
|
|
188
|
+
const activeTheme = forcedTheme ?? theme;
|
|
189
|
+
const resolvedTheme = typeof window === "undefined" ? "light" : resolveTheme(activeTheme);
|
|
190
|
+
(0, import_react.useEffect)(() => {
|
|
191
|
+
const root = document.documentElement;
|
|
192
|
+
root.classList.remove("light", "dark");
|
|
193
|
+
root.classList.add(resolvedTheme);
|
|
194
|
+
}, [resolvedTheme]);
|
|
195
|
+
(0, import_react.useEffect)(() => {
|
|
196
|
+
if (forcedTheme || typeof window === "undefined") {
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
window.localStorage.setItem(storageKey, theme);
|
|
200
|
+
}, [forcedTheme, storageKey, theme]);
|
|
201
|
+
const value = (0, import_react.useMemo)(
|
|
202
|
+
() => ({
|
|
203
|
+
theme: activeTheme,
|
|
204
|
+
resolvedTheme,
|
|
205
|
+
setTheme: (nextTheme) => {
|
|
206
|
+
if (!forcedTheme) {
|
|
207
|
+
setThemeState(nextTheme);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}),
|
|
211
|
+
[activeTheme, forcedTheme, resolvedTheme]
|
|
212
|
+
);
|
|
213
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ThemeProviderContext.Provider, { value, children });
|
|
214
|
+
}
|
|
215
|
+
function useTheme() {
|
|
216
|
+
const context = (0, import_react.useContext)(ThemeProviderContext);
|
|
217
|
+
if (!context) {
|
|
218
|
+
throw new Error("useTheme must be used within ThemeProvider");
|
|
219
|
+
}
|
|
220
|
+
return context;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// src/lib/cn.ts
|
|
224
|
+
var import_clsx = require("clsx");
|
|
225
|
+
var import_tailwind_merge = require("tailwind-merge");
|
|
226
|
+
function cn(...inputs) {
|
|
227
|
+
return (0, import_tailwind_merge.twMerge)((0, import_clsx.clsx)(inputs));
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// src/assets/isotipo-cortexa-dark.png
|
|
231
|
+
var isotipo_cortexa_dark_default = "./isotipo-cortexa-dark-F2MDSEEV.png";
|
|
232
|
+
|
|
233
|
+
// src/assets/isotipo-cortexa-light.png
|
|
234
|
+
var isotipo_cortexa_light_default = "./isotipo-cortexa-light-LV3O6ASR.png";
|
|
235
|
+
|
|
236
|
+
// src/components/branding/brand-logo.tsx
|
|
237
|
+
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
238
|
+
var sizeMap = {
|
|
239
|
+
sm: { icon: "h-6 w-6", text: "text-sm", gap: "gap-2" },
|
|
240
|
+
md: { icon: "h-7 w-7", text: "text-lg", gap: "gap-3" },
|
|
241
|
+
lg: { icon: "h-9 w-9", text: "text-xl", gap: "gap-3" }
|
|
242
|
+
};
|
|
243
|
+
function BrandLogo({ className, size = "md", href }) {
|
|
244
|
+
const { resolvedTheme } = useTheme();
|
|
245
|
+
const isDark = resolvedTheme === "dark";
|
|
246
|
+
const s = sizeMap[size];
|
|
247
|
+
const content = /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
|
|
248
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
249
|
+
"div",
|
|
250
|
+
{
|
|
251
|
+
className: cn(
|
|
252
|
+
"flex shrink-0 items-center justify-center rounded-md",
|
|
253
|
+
s.icon,
|
|
254
|
+
isDark ? "bg-[var(--color-brand)] p-1" : "bg-transparent"
|
|
255
|
+
),
|
|
256
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
257
|
+
"img",
|
|
258
|
+
{
|
|
259
|
+
src: isDark ? isotipo_cortexa_dark_default : isotipo_cortexa_light_default,
|
|
260
|
+
alt: "Cortexa",
|
|
261
|
+
className: "max-h-full max-w-full object-contain"
|
|
262
|
+
}
|
|
263
|
+
)
|
|
264
|
+
}
|
|
265
|
+
),
|
|
266
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "flex items-baseline", children: [
|
|
267
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
268
|
+
"span",
|
|
269
|
+
{
|
|
270
|
+
className: cn(
|
|
271
|
+
"font-bold leading-none",
|
|
272
|
+
s.text,
|
|
273
|
+
isDark ? "text-white" : "text-[var(--color-brand)]"
|
|
274
|
+
),
|
|
275
|
+
children: "Cortexa"
|
|
276
|
+
}
|
|
277
|
+
),
|
|
278
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
279
|
+
"span",
|
|
280
|
+
{
|
|
281
|
+
className: cn(
|
|
282
|
+
"ml-1 font-normal leading-none",
|
|
283
|
+
s.text,
|
|
284
|
+
isDark ? "text-white" : "text-[var(--color-accent-blue)]"
|
|
285
|
+
),
|
|
286
|
+
children: "Fiscal"
|
|
287
|
+
}
|
|
288
|
+
)
|
|
289
|
+
] })
|
|
290
|
+
] });
|
|
291
|
+
const wrapperClass = cn("flex items-center", s.gap, className);
|
|
292
|
+
if (href) {
|
|
293
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("a", { href, className: wrapperClass, "aria-label": "Cortexa Fiscal \u2014 Inicio", children: content });
|
|
294
|
+
}
|
|
295
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: wrapperClass, "aria-label": "Cortexa Fiscal", children: content });
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
// src/components/data-display/icons.tsx
|
|
299
|
+
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
300
|
+
var toneStyles = {
|
|
301
|
+
brand: "bg-[var(--color-brand)]/10 text-[var(--color-brand)]",
|
|
302
|
+
info: "bg-[var(--color-info-bg)] text-[var(--color-accent-blue)]",
|
|
303
|
+
success: "bg-[var(--color-success-bg)] text-[var(--color-success)]",
|
|
304
|
+
warning: "bg-[var(--color-warning-bg)] text-[var(--color-warning)]",
|
|
305
|
+
danger: "bg-destructive/10 text-destructive",
|
|
306
|
+
neutral: "bg-muted text-muted-foreground"
|
|
307
|
+
};
|
|
308
|
+
var sizeStyles = {
|
|
309
|
+
sm: { wrapper: "h-8 w-8 rounded-lg", icon: "h-4 w-4" },
|
|
310
|
+
md: { wrapper: "h-10 w-10 rounded-lg", icon: "h-5 w-5" },
|
|
311
|
+
lg: { wrapper: "h-12 w-12 rounded-xl", icon: "h-6 w-6" }
|
|
312
|
+
};
|
|
313
|
+
function FeatureIcon({ className, icon: Icon2, tone = "brand", size = "md", iconClassName }) {
|
|
314
|
+
const classes = sizeStyles[size];
|
|
315
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: cn("inline-flex items-center justify-center", classes.wrapper, toneStyles[tone], className), children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Icon2, { className: cn(classes.icon, iconClassName) }) });
|
|
316
|
+
}
|
|
317
|
+
function ModuleIconButton({
|
|
318
|
+
className,
|
|
319
|
+
type = "button",
|
|
320
|
+
icon,
|
|
321
|
+
label,
|
|
322
|
+
description,
|
|
323
|
+
tone = "brand",
|
|
324
|
+
...props
|
|
325
|
+
}) {
|
|
326
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
327
|
+
"button",
|
|
328
|
+
{
|
|
329
|
+
type,
|
|
330
|
+
className: cn(
|
|
331
|
+
"group flex flex-col items-center gap-3 rounded-lg border border-border bg-card p-5 text-center transition-all hover:bg-accent/30 hover:border-[var(--color-accent-blue)]/50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
|
|
332
|
+
className
|
|
333
|
+
),
|
|
334
|
+
...props,
|
|
335
|
+
children: [
|
|
336
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
337
|
+
FeatureIcon,
|
|
338
|
+
{
|
|
339
|
+
icon,
|
|
340
|
+
tone,
|
|
341
|
+
size: "md",
|
|
342
|
+
className: "transition-colors group-hover:bg-[var(--color-brand)]/20"
|
|
343
|
+
}
|
|
344
|
+
),
|
|
345
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "grid gap-1", children: [
|
|
346
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "text-sm font-medium text-foreground", children: label }),
|
|
347
|
+
description ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "text-xs text-muted-foreground", children: description }) : null
|
|
348
|
+
] })
|
|
349
|
+
]
|
|
350
|
+
}
|
|
351
|
+
);
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
// src/components/primitives/avatar.tsx
|
|
355
|
+
var React = __toESM(require("react"), 1);
|
|
356
|
+
var AvatarPrimitive = __toESM(require("@radix-ui/react-avatar"), 1);
|
|
357
|
+
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
358
|
+
var Avatar = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
359
|
+
AvatarPrimitive.Root,
|
|
360
|
+
{
|
|
361
|
+
ref,
|
|
362
|
+
className: cn("relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full", className),
|
|
363
|
+
...props
|
|
364
|
+
}
|
|
365
|
+
));
|
|
366
|
+
Avatar.displayName = AvatarPrimitive.Root.displayName;
|
|
367
|
+
var AvatarImage = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(AvatarPrimitive.Image, { ref, className: cn("aspect-square h-full w-full", className), ...props }));
|
|
368
|
+
AvatarImage.displayName = AvatarPrimitive.Image.displayName;
|
|
369
|
+
var AvatarFallback = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
370
|
+
AvatarPrimitive.Fallback,
|
|
371
|
+
{
|
|
372
|
+
ref,
|
|
373
|
+
className: cn("flex h-full w-full items-center justify-center rounded-full bg-muted", className),
|
|
374
|
+
...props
|
|
375
|
+
}
|
|
376
|
+
));
|
|
377
|
+
AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName;
|
|
378
|
+
|
|
379
|
+
// src/components/data-display/profile-avatar.tsx
|
|
380
|
+
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
381
|
+
var sizeMap2 = {
|
|
382
|
+
xs: { avatar: "h-8 w-8", text: "text-xs", dot: "h-2.5 w-2.5" },
|
|
383
|
+
sm: { avatar: "h-10 w-10", text: "text-sm", dot: "h-3 w-3" },
|
|
384
|
+
md: { avatar: "h-12 w-12", text: "text-base", dot: "h-3.5 w-3.5" },
|
|
385
|
+
lg: { avatar: "h-16 w-16", text: "text-lg", dot: "h-4 w-4" }
|
|
386
|
+
};
|
|
387
|
+
var statusMap = {
|
|
388
|
+
online: "bg-[var(--color-success)]",
|
|
389
|
+
away: "bg-[var(--color-warning)]",
|
|
390
|
+
offline: "bg-muted-foreground",
|
|
391
|
+
inactive: "bg-border"
|
|
392
|
+
};
|
|
393
|
+
function getInitials(name) {
|
|
394
|
+
return name.trim().split(/\s+/).slice(0, 2).map((part) => part[0]?.toUpperCase() ?? "").join("");
|
|
395
|
+
}
|
|
396
|
+
function ProfileAvatar({
|
|
397
|
+
className,
|
|
398
|
+
avatarClassName,
|
|
399
|
+
fallbackClassName,
|
|
400
|
+
name,
|
|
401
|
+
src,
|
|
402
|
+
alt,
|
|
403
|
+
initials,
|
|
404
|
+
size = "sm",
|
|
405
|
+
status
|
|
406
|
+
}) {
|
|
407
|
+
const classes = sizeMap2[size];
|
|
408
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: cn("relative inline-flex", className), children: [
|
|
409
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Avatar, { className: cn(classes.avatar, avatarClassName), children: [
|
|
410
|
+
src ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(AvatarImage, { src, alt: alt ?? name }) : null,
|
|
411
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(AvatarFallback, { className: cn("bg-[var(--color-brand)] text-white font-medium", classes.text, fallbackClassName), children: initials ?? getInitials(name) })
|
|
412
|
+
] }),
|
|
413
|
+
status ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
414
|
+
"span",
|
|
415
|
+
{
|
|
416
|
+
"aria-hidden": "true",
|
|
417
|
+
className: cn("absolute bottom-0 right-0 rounded-full border-2 border-card", classes.dot, statusMap[status])
|
|
418
|
+
}
|
|
419
|
+
) : null
|
|
420
|
+
] });
|
|
421
|
+
}
|
|
422
|
+
function AvatarGroup({ className, users, size = "xs", limit = 4, extraLabel }) {
|
|
423
|
+
const visibleUsers = users.slice(0, limit);
|
|
424
|
+
const hiddenCount = Math.max(0, users.length - limit);
|
|
425
|
+
const classes = sizeMap2[size];
|
|
426
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: cn("flex items-center gap-3", className), children: [
|
|
427
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "flex -space-x-2", children: [
|
|
428
|
+
visibleUsers.map((user) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
429
|
+
ProfileAvatar,
|
|
430
|
+
{
|
|
431
|
+
name: user.name,
|
|
432
|
+
src: user.src,
|
|
433
|
+
initials: user.initials,
|
|
434
|
+
size,
|
|
435
|
+
status: user.status,
|
|
436
|
+
avatarClassName: "border-2 border-card"
|
|
437
|
+
},
|
|
438
|
+
user.id ?? user.name
|
|
439
|
+
)),
|
|
440
|
+
hiddenCount > 0 ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
441
|
+
"div",
|
|
442
|
+
{
|
|
443
|
+
className: cn(
|
|
444
|
+
"flex items-center justify-center rounded-full border-2 border-card bg-muted text-muted-foreground font-medium",
|
|
445
|
+
classes.avatar,
|
|
446
|
+
classes.text
|
|
447
|
+
),
|
|
448
|
+
children: [
|
|
449
|
+
"+",
|
|
450
|
+
hiddenCount
|
|
451
|
+
]
|
|
452
|
+
}
|
|
453
|
+
) : null
|
|
454
|
+
] }),
|
|
455
|
+
extraLabel ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "text-sm text-muted-foreground", children: extraLabel }) : null
|
|
456
|
+
] });
|
|
457
|
+
}
|
|
458
|
+
function ProfileAvatarRow({ className, name, role, src, initials, status, size = "sm", aside }) {
|
|
459
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: cn("flex items-center justify-between gap-3", className), children: [
|
|
460
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "flex items-center gap-3", children: [
|
|
461
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ProfileAvatar, { name, src, initials, status, size }),
|
|
462
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "grid gap-0.5", children: [
|
|
463
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "text-sm font-medium text-foreground", children: name }),
|
|
464
|
+
role ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "text-xs text-muted-foreground", children: role }) : null
|
|
465
|
+
] })
|
|
466
|
+
] }),
|
|
467
|
+
aside
|
|
468
|
+
] });
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
// src/components/data-display/typography.tsx
|
|
472
|
+
var import_class_variance_authority = require("class-variance-authority");
|
|
473
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
474
|
+
var typographyVariants = (0, import_class_variance_authority.cva)("text-foreground", {
|
|
475
|
+
variants: {
|
|
476
|
+
variant: {
|
|
477
|
+
h1: "font-display text-4xl font-bold tracking-tight",
|
|
478
|
+
h2: "font-display text-3xl font-bold tracking-tight",
|
|
479
|
+
h3: "font-display text-2xl font-semibold tracking-tight",
|
|
480
|
+
h4: "text-xl font-semibold",
|
|
481
|
+
lead: "text-lg text-muted-foreground",
|
|
482
|
+
body: "text-base",
|
|
483
|
+
small: "text-sm text-muted-foreground",
|
|
484
|
+
muted: "text-sm text-muted-foreground",
|
|
485
|
+
code: "font-mono text-sm"
|
|
486
|
+
}
|
|
487
|
+
},
|
|
488
|
+
defaultVariants: {
|
|
489
|
+
variant: "body"
|
|
490
|
+
}
|
|
491
|
+
});
|
|
492
|
+
function Typography({
|
|
493
|
+
as,
|
|
494
|
+
className,
|
|
495
|
+
variant,
|
|
496
|
+
children,
|
|
497
|
+
...props
|
|
498
|
+
}) {
|
|
499
|
+
const Component = as ?? "p";
|
|
500
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Component, { className: cn(typographyVariants({ variant }), className), ...props, children });
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
// src/components/primitives/card.tsx
|
|
504
|
+
var React2 = __toESM(require("react"), 1);
|
|
505
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
506
|
+
var cardBaseClassName = "rounded-lg border bg-card text-card-foreground shadow-sm";
|
|
507
|
+
var Card = React2.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { ref, className: cn(cardBaseClassName, className), ...props }));
|
|
508
|
+
Card.displayName = "Card";
|
|
509
|
+
var ClickableCard = React2.forwardRef(
|
|
510
|
+
({ className, type = "button", ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
511
|
+
"button",
|
|
512
|
+
{
|
|
513
|
+
ref,
|
|
514
|
+
type,
|
|
515
|
+
className: cn(
|
|
516
|
+
cardBaseClassName,
|
|
517
|
+
"w-full cursor-pointer text-left transition-all hover:bg-accent/30 hover:border-[var(--color-accent-blue)]/50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
|
|
518
|
+
className
|
|
519
|
+
),
|
|
520
|
+
...props
|
|
521
|
+
}
|
|
522
|
+
)
|
|
523
|
+
);
|
|
524
|
+
ClickableCard.displayName = "ClickableCard";
|
|
525
|
+
var CenteredIconCard = React2.forwardRef(
|
|
526
|
+
({ className, type = "button", icon: Icon2, title, iconClassName, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
527
|
+
"button",
|
|
528
|
+
{
|
|
529
|
+
ref,
|
|
530
|
+
type,
|
|
531
|
+
className: cn(
|
|
532
|
+
cardBaseClassName,
|
|
533
|
+
"flex w-full cursor-pointer flex-col items-center justify-center gap-4 p-6 text-center transition-all hover:bg-accent/30 hover:border-[var(--color-accent-blue)]/50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
|
|
534
|
+
className
|
|
535
|
+
),
|
|
536
|
+
...props,
|
|
537
|
+
children: [
|
|
538
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "flex h-12 w-12 items-center justify-center rounded-xl bg-[var(--color-brand)]/10 text-[var(--color-brand)]", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Icon2, { className: cn("h-6 w-6", iconClassName) }) }),
|
|
539
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "text-sm font-semibold text-foreground", children: title })
|
|
540
|
+
]
|
|
541
|
+
}
|
|
542
|
+
)
|
|
543
|
+
);
|
|
544
|
+
CenteredIconCard.displayName = "CenteredIconCard";
|
|
545
|
+
var CardHeader = React2.forwardRef(
|
|
546
|
+
({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { ref, className: cn("flex flex-col space-y-1.5 p-6", className), ...props })
|
|
547
|
+
);
|
|
548
|
+
CardHeader.displayName = "CardHeader";
|
|
549
|
+
var CardTitle = React2.forwardRef(
|
|
550
|
+
({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { ref, className: cn("text-2xl font-semibold leading-none tracking-tight", className), ...props })
|
|
551
|
+
);
|
|
552
|
+
CardTitle.displayName = "CardTitle";
|
|
553
|
+
var CardDescription = React2.forwardRef(
|
|
554
|
+
({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { ref, className: cn("text-sm text-muted-foreground", className), ...props })
|
|
555
|
+
);
|
|
556
|
+
CardDescription.displayName = "CardDescription";
|
|
557
|
+
var CardContent = React2.forwardRef(
|
|
558
|
+
({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { ref, className: cn("p-6 pt-0", className), ...props })
|
|
559
|
+
);
|
|
560
|
+
CardContent.displayName = "CardContent";
|
|
561
|
+
var CardFooter = React2.forwardRef(
|
|
562
|
+
({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { ref, className: cn("flex items-center p-6 pt-0", className), ...props })
|
|
563
|
+
);
|
|
564
|
+
CardFooter.displayName = "CardFooter";
|
|
565
|
+
|
|
566
|
+
// src/components/feedback/skeleton.tsx
|
|
567
|
+
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
568
|
+
function Skeleton({ className, ...props }) {
|
|
569
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: cn("animate-pulse rounded-md bg-muted", className), ...props });
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
// src/components/feedback/spinner.tsx
|
|
573
|
+
var import_lucide_react = require("lucide-react");
|
|
574
|
+
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
575
|
+
var sizeMap3 = {
|
|
576
|
+
sm: "h-4 w-4",
|
|
577
|
+
md: "h-5 w-5",
|
|
578
|
+
lg: "h-7 w-7"
|
|
579
|
+
};
|
|
580
|
+
function Spinner({ className, size = "md" }) {
|
|
581
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react.Loader2, { className: cn("animate-spin text-current", sizeMap3[size], className) });
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
// src/components/tables/table.tsx
|
|
585
|
+
var React3 = __toESM(require("react"), 1);
|
|
586
|
+
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
587
|
+
var Table = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "relative w-full overflow-auto", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("table", { ref, className: cn("w-full caption-bottom text-sm", className), ...props }) }));
|
|
588
|
+
Table.displayName = "Table";
|
|
589
|
+
var TableHeader = React3.forwardRef(
|
|
590
|
+
({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("thead", { ref, className: cn("[&_tr]:border-b", className), ...props })
|
|
591
|
+
);
|
|
592
|
+
TableHeader.displayName = "TableHeader";
|
|
593
|
+
var TableBody = React3.forwardRef(
|
|
594
|
+
({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("tbody", { ref, className: cn("[&_tr:last-child]:border-0", className), ...props })
|
|
595
|
+
);
|
|
596
|
+
TableBody.displayName = "TableBody";
|
|
597
|
+
var TableFooter = React3.forwardRef(
|
|
598
|
+
({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
599
|
+
"tfoot",
|
|
600
|
+
{
|
|
601
|
+
ref,
|
|
602
|
+
className: cn("border-t bg-muted/50 font-medium [&>tr]:last:border-b-0", className),
|
|
603
|
+
...props
|
|
604
|
+
}
|
|
605
|
+
)
|
|
606
|
+
);
|
|
607
|
+
TableFooter.displayName = "TableFooter";
|
|
608
|
+
var TableRow = React3.forwardRef(
|
|
609
|
+
({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
610
|
+
"tr",
|
|
611
|
+
{
|
|
612
|
+
ref,
|
|
613
|
+
className: cn("border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted", className),
|
|
614
|
+
...props
|
|
615
|
+
}
|
|
616
|
+
)
|
|
617
|
+
);
|
|
618
|
+
TableRow.displayName = "TableRow";
|
|
619
|
+
var TableHead = React3.forwardRef(
|
|
620
|
+
({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
621
|
+
"th",
|
|
622
|
+
{
|
|
623
|
+
ref,
|
|
624
|
+
className: cn("h-12 px-4 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0", className),
|
|
625
|
+
...props
|
|
626
|
+
}
|
|
627
|
+
)
|
|
628
|
+
);
|
|
629
|
+
TableHead.displayName = "TableHead";
|
|
630
|
+
var TableCell = React3.forwardRef(
|
|
631
|
+
({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("td", { ref, className: cn("p-4 align-middle [&:has([role=checkbox])]:pr-0", className), ...props })
|
|
632
|
+
);
|
|
633
|
+
TableCell.displayName = "TableCell";
|
|
634
|
+
var TableCaption = React3.forwardRef(
|
|
635
|
+
({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("caption", { ref, className: cn("mt-4 text-sm text-muted-foreground", className), ...props })
|
|
636
|
+
);
|
|
637
|
+
TableCaption.displayName = "TableCaption";
|
|
638
|
+
|
|
639
|
+
// src/components/feedback/loading-state.tsx
|
|
640
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
641
|
+
function LoadingState({
|
|
642
|
+
className,
|
|
643
|
+
title = "Cargando datos",
|
|
644
|
+
description = "Estamos preparando la informacion para ti.",
|
|
645
|
+
size = "md",
|
|
646
|
+
icon
|
|
647
|
+
}) {
|
|
648
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
649
|
+
"div",
|
|
650
|
+
{
|
|
651
|
+
role: "status",
|
|
652
|
+
"aria-live": "polite",
|
|
653
|
+
className: cn("flex items-center gap-3 rounded-xl border border-border bg-card px-4 py-3 text-foreground", className),
|
|
654
|
+
children: [
|
|
655
|
+
icon ?? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Spinner, { size, className: "text-primary" }),
|
|
656
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "grid gap-0.5", children: [
|
|
657
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "text-sm font-medium", children: title }),
|
|
658
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "text-xs text-muted-foreground", children: description })
|
|
659
|
+
] })
|
|
660
|
+
]
|
|
661
|
+
}
|
|
662
|
+
);
|
|
663
|
+
}
|
|
664
|
+
function LoadingCard({ className, rows = 3 }) {
|
|
665
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Card, { className, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(CardContent, { className: "grid gap-3 p-5", children: [
|
|
666
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Skeleton, { className: "h-6 w-40" }),
|
|
667
|
+
Array.from({ length: rows }).map((_, index) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Skeleton, { className: cn("h-4", index === rows - 1 ? "w-2/3" : "w-full") }, index)),
|
|
668
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Skeleton, { className: "mt-1 h-10 w-full rounded-lg" })
|
|
669
|
+
] }) });
|
|
670
|
+
}
|
|
671
|
+
function LoadingTableRows({ className, columns = 5, rows = 4 }) {
|
|
672
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: cn("rounded-xl border", className), children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Table, { children: [
|
|
673
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(TableHeader, { children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(TableRow, { children: Array.from({ length: columns }).map((_, index) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(TableHead, { children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Skeleton, { className: "h-4 w-20" }) }, index)) }) }),
|
|
674
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(TableBody, { children: Array.from({ length: rows }).map((_, rowIndex) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(TableRow, { children: Array.from({ length: columns }).map((_2, columnIndex) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(TableCell, { children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Skeleton, { className: cn("h-4", columnIndex === 0 ? "w-24" : "w-full") }) }, columnIndex)) }, rowIndex)) })
|
|
675
|
+
] }) });
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
// src/components/feedback/notification.tsx
|
|
679
|
+
var import_lucide_react2 = require("lucide-react");
|
|
680
|
+
var import_sonner = require("sonner");
|
|
681
|
+
|
|
682
|
+
// src/components/primitives/button.tsx
|
|
683
|
+
var React4 = __toESM(require("react"), 1);
|
|
684
|
+
var import_react_slot = require("@radix-ui/react-slot");
|
|
685
|
+
var import_class_variance_authority2 = require("class-variance-authority");
|
|
686
|
+
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
687
|
+
var buttonVariants = (0, import_class_variance_authority2.cva)(
|
|
688
|
+
"inline-flex cursor-pointer items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium shadow-sm ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
|
|
689
|
+
{
|
|
690
|
+
variants: {
|
|
691
|
+
variant: {
|
|
692
|
+
default: "bg-primary text-primary-foreground hover:bg-primary/90",
|
|
693
|
+
destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
|
|
694
|
+
outline: "border border-input bg-background text-foreground hover:bg-accent hover:text-accent-foreground",
|
|
695
|
+
secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
|
|
696
|
+
ghost: "text-foreground shadow-none hover:bg-accent hover:text-accent-foreground",
|
|
697
|
+
link: "h-auto px-0 py-0 text-primary underline-offset-4 shadow-none hover:underline"
|
|
698
|
+
},
|
|
699
|
+
size: {
|
|
700
|
+
default: "h-10 px-4 py-2",
|
|
701
|
+
sm: "h-9 rounded-md px-3",
|
|
702
|
+
lg: "h-11 rounded-md px-8",
|
|
703
|
+
icon: "h-10 w-10"
|
|
704
|
+
}
|
|
705
|
+
},
|
|
706
|
+
defaultVariants: {
|
|
707
|
+
variant: "default",
|
|
708
|
+
size: "default"
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
);
|
|
712
|
+
var Button = React4.forwardRef(
|
|
713
|
+
({ className, variant, size, asChild = false, ...props }, ref) => {
|
|
714
|
+
const Comp = asChild ? import_react_slot.Slot : "button";
|
|
715
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Comp, { className: cn(buttonVariants({ variant, size, className })), ref, ...props });
|
|
716
|
+
}
|
|
717
|
+
);
|
|
718
|
+
Button.displayName = "Button";
|
|
719
|
+
|
|
720
|
+
// src/components/feedback/notification.tsx
|
|
721
|
+
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
722
|
+
var notificationStyles = {
|
|
723
|
+
info: "bg-[var(--color-info-bg)] text-[var(--color-accent-blue)] border-[var(--color-accent-blue)]/30",
|
|
724
|
+
success: "bg-[var(--color-success-bg)] text-[var(--color-success)] border-[var(--color-success)]/30",
|
|
725
|
+
warning: "bg-[var(--color-warning-bg)] text-[var(--color-warning)] border-[var(--color-warning)]/30",
|
|
726
|
+
danger: "bg-destructive/10 text-destructive border-destructive/30",
|
|
727
|
+
loading: "bg-[var(--color-info-bg)] text-[var(--color-accent-blue)] border-[var(--color-accent-blue)]/30"
|
|
728
|
+
};
|
|
729
|
+
var notificationIcons = {
|
|
730
|
+
info: import_lucide_react2.Info,
|
|
731
|
+
success: import_lucide_react2.CheckCircle2,
|
|
732
|
+
warning: import_lucide_react2.AlertTriangle,
|
|
733
|
+
danger: import_lucide_react2.AlertCircle,
|
|
734
|
+
loading: import_lucide_react2.Loader2
|
|
735
|
+
};
|
|
736
|
+
function NotificationMessage({
|
|
737
|
+
className,
|
|
738
|
+
tone = "info",
|
|
739
|
+
title,
|
|
740
|
+
description,
|
|
741
|
+
action,
|
|
742
|
+
icon
|
|
743
|
+
}) {
|
|
744
|
+
const Icon2 = icon ?? notificationIcons[tone];
|
|
745
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
746
|
+
"div",
|
|
747
|
+
{
|
|
748
|
+
role: "status",
|
|
749
|
+
className: cn("flex items-start justify-between gap-3 rounded-lg border px-4 py-3", notificationStyles[tone], className),
|
|
750
|
+
children: [
|
|
751
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex items-start gap-3", children: [
|
|
752
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Icon2, { className: cn("mt-0.5 h-4 w-4 shrink-0", tone === "loading" && "animate-spin") }),
|
|
753
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "grid gap-1", children: [
|
|
754
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { className: "text-sm font-medium", children: title }),
|
|
755
|
+
description ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "text-xs opacity-85", children: description }) : null
|
|
756
|
+
] })
|
|
757
|
+
] }),
|
|
758
|
+
action ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "shrink-0", children: action }) : null
|
|
759
|
+
]
|
|
760
|
+
}
|
|
761
|
+
);
|
|
762
|
+
}
|
|
763
|
+
function buildToastOptions(payload) {
|
|
764
|
+
return {
|
|
765
|
+
description: payload.description,
|
|
766
|
+
action: payload.actionLabel ? {
|
|
767
|
+
label: payload.actionLabel,
|
|
768
|
+
onClick: payload.onAction ?? (() => void 0)
|
|
769
|
+
} : void 0
|
|
770
|
+
};
|
|
771
|
+
}
|
|
772
|
+
var notify = {
|
|
773
|
+
info: (payload) => (0, import_sonner.toast)(payload.title, buildToastOptions(payload)),
|
|
774
|
+
success: (payload) => import_sonner.toast.success(payload.title, buildToastOptions(payload)),
|
|
775
|
+
warning: (payload) => (0, import_sonner.toast)(payload.title, {
|
|
776
|
+
...buildToastOptions(payload),
|
|
777
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react2.AlertTriangle, { className: "h-4 w-4 text-[var(--color-warning)]" })
|
|
778
|
+
}),
|
|
779
|
+
danger: (payload) => import_sonner.toast.error(payload.title, buildToastOptions(payload)),
|
|
780
|
+
loading: (payload) => import_sonner.toast.loading(payload.title, buildToastOptions(payload))
|
|
781
|
+
};
|
|
782
|
+
function NotificationAction({ children, variant = "outline", size = "sm", ...props }) {
|
|
783
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Button, { variant, size, ...props, children });
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
// src/components/feedback/status-badge.tsx
|
|
787
|
+
var import_lucide_react3 = require("lucide-react");
|
|
788
|
+
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
789
|
+
var toneStyles2 = {
|
|
790
|
+
success: "border-transparent bg-[var(--color-success-bg)] text-[var(--color-success)]",
|
|
791
|
+
warning: "border-transparent bg-[var(--color-warning-bg)] text-[var(--color-warning)]",
|
|
792
|
+
danger: "border-transparent bg-destructive/10 text-destructive",
|
|
793
|
+
info: "border-transparent bg-[var(--color-info-bg)] text-[var(--color-accent-blue)]",
|
|
794
|
+
loading: "border-transparent bg-muted text-muted-foreground"
|
|
795
|
+
};
|
|
796
|
+
var toneIcons = {
|
|
797
|
+
success: import_lucide_react3.CheckCircle2,
|
|
798
|
+
warning: import_lucide_react3.Clock3,
|
|
799
|
+
danger: import_lucide_react3.AlertCircle,
|
|
800
|
+
info: import_lucide_react3.CheckCircle2,
|
|
801
|
+
loading: import_lucide_react3.Loader2
|
|
802
|
+
};
|
|
803
|
+
function StatusBadge({ children, tone = "info", className }) {
|
|
804
|
+
const Icon2 = toneIcons[tone];
|
|
805
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
|
|
806
|
+
"span",
|
|
807
|
+
{
|
|
808
|
+
className: cn(
|
|
809
|
+
"inline-flex items-center gap-1.5 rounded-full border px-2.5 py-1 text-xs font-medium",
|
|
810
|
+
toneStyles2[tone],
|
|
811
|
+
className
|
|
812
|
+
),
|
|
813
|
+
children: [
|
|
814
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Icon2, { className: cn("h-3.5 w-3.5", tone === "loading" && "animate-spin") }),
|
|
815
|
+
children
|
|
816
|
+
]
|
|
817
|
+
}
|
|
818
|
+
);
|
|
819
|
+
}
|
|
820
|
+
|
|
821
|
+
// src/components/feedback/toaster.tsx
|
|
822
|
+
var import_sonner2 = require("sonner");
|
|
823
|
+
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
824
|
+
function Toaster(props) {
|
|
825
|
+
const { resolvedTheme } = useTheme();
|
|
826
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
827
|
+
import_sonner2.Toaster,
|
|
828
|
+
{
|
|
829
|
+
theme: resolvedTheme,
|
|
830
|
+
className: "toaster group",
|
|
831
|
+
closeButton: true,
|
|
832
|
+
toastOptions: {
|
|
833
|
+
classNames: {
|
|
834
|
+
toast: "group toast group-[.toaster]:bg-background group-[.toaster]:text-foreground group-[.toaster]:border-border group-[.toaster]:shadow-lg",
|
|
835
|
+
description: "group-[.toast]:text-muted-foreground",
|
|
836
|
+
actionButton: "group-[.toast]:bg-primary group-[.toast]:text-primary-foreground",
|
|
837
|
+
cancelButton: "group-[.toast]:bg-muted group-[.toast]:text-muted-foreground"
|
|
838
|
+
}
|
|
839
|
+
},
|
|
840
|
+
...props
|
|
841
|
+
}
|
|
842
|
+
);
|
|
843
|
+
}
|
|
844
|
+
|
|
845
|
+
// src/components/forms/searchable-select.tsx
|
|
846
|
+
var React6 = __toESM(require("react"), 1);
|
|
847
|
+
var import_lucide_react4 = require("lucide-react");
|
|
848
|
+
|
|
849
|
+
// src/components/primitives/input.tsx
|
|
850
|
+
var React5 = __toESM(require("react"), 1);
|
|
851
|
+
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
852
|
+
var Input = React5.forwardRef(
|
|
853
|
+
({ className, type, ...props }, ref) => {
|
|
854
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
855
|
+
"input",
|
|
856
|
+
{
|
|
857
|
+
type,
|
|
858
|
+
className: cn(
|
|
859
|
+
"flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-base ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
|
|
860
|
+
className
|
|
861
|
+
),
|
|
862
|
+
ref,
|
|
863
|
+
...props
|
|
864
|
+
}
|
|
865
|
+
);
|
|
866
|
+
}
|
|
867
|
+
);
|
|
868
|
+
Input.displayName = "Input";
|
|
869
|
+
|
|
870
|
+
// src/components/forms/searchable-select.tsx
|
|
871
|
+
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
872
|
+
function normalize(str) {
|
|
873
|
+
return str.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "");
|
|
874
|
+
}
|
|
875
|
+
var SearchableSelect = React6.forwardRef(
|
|
876
|
+
({
|
|
877
|
+
options: options2,
|
|
878
|
+
value,
|
|
879
|
+
onValueChange,
|
|
880
|
+
placeholder = "Select an option...",
|
|
881
|
+
searchPlaceholder = "Search...",
|
|
882
|
+
disabled = false,
|
|
883
|
+
loading = false,
|
|
884
|
+
emptyMessage = "No results found.",
|
|
885
|
+
id,
|
|
886
|
+
className
|
|
887
|
+
}, ref) => {
|
|
888
|
+
const [open, setOpen] = React6.useState(false);
|
|
889
|
+
const [search, setSearch] = React6.useState("");
|
|
890
|
+
const wrapperRef = React6.useRef(null);
|
|
891
|
+
const searchRef = React6.useRef(null);
|
|
892
|
+
const selected = React6.useMemo(() => options2.find((option) => option.value === value) ?? null, [options2, value]);
|
|
893
|
+
const filtered = React6.useMemo(() => {
|
|
894
|
+
if (!search.trim()) {
|
|
895
|
+
return options2;
|
|
896
|
+
}
|
|
897
|
+
const query = normalize(search);
|
|
898
|
+
return options2.filter(
|
|
899
|
+
(option) => normalize(option.label).includes(query) || normalize(option.sublabel ?? "").includes(query)
|
|
900
|
+
);
|
|
901
|
+
}, [options2, search]);
|
|
902
|
+
function handleOpen() {
|
|
903
|
+
if (disabled || loading) {
|
|
904
|
+
return;
|
|
905
|
+
}
|
|
906
|
+
setOpen((previous) => !previous);
|
|
907
|
+
}
|
|
908
|
+
function handleSelect(optionValue) {
|
|
909
|
+
onValueChange(optionValue);
|
|
910
|
+
setOpen(false);
|
|
911
|
+
setSearch("");
|
|
912
|
+
}
|
|
913
|
+
function handleKeyDown(event) {
|
|
914
|
+
if (event.key === "Escape") {
|
|
915
|
+
setOpen(false);
|
|
916
|
+
setSearch("");
|
|
917
|
+
}
|
|
918
|
+
}
|
|
919
|
+
React6.useEffect(() => {
|
|
920
|
+
if (!open) {
|
|
921
|
+
return;
|
|
922
|
+
}
|
|
923
|
+
function handleMouseDown(event) {
|
|
924
|
+
if (wrapperRef.current && !wrapperRef.current.contains(event.target)) {
|
|
925
|
+
setOpen(false);
|
|
926
|
+
setSearch("");
|
|
927
|
+
}
|
|
928
|
+
}
|
|
929
|
+
document.addEventListener("mousedown", handleMouseDown);
|
|
930
|
+
return () => document.removeEventListener("mousedown", handleMouseDown);
|
|
931
|
+
}, [open]);
|
|
932
|
+
React6.useEffect(() => {
|
|
933
|
+
if (!open) {
|
|
934
|
+
return;
|
|
935
|
+
}
|
|
936
|
+
const timer = setTimeout(() => searchRef.current?.focus(), 50);
|
|
937
|
+
return () => clearTimeout(timer);
|
|
938
|
+
}, [open]);
|
|
939
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { ref: wrapperRef, className: cn("relative w-full", className), onKeyDown: handleKeyDown, children: [
|
|
940
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
941
|
+
"button",
|
|
942
|
+
{
|
|
943
|
+
ref,
|
|
944
|
+
id,
|
|
945
|
+
type: "button",
|
|
946
|
+
role: "combobox",
|
|
947
|
+
"aria-expanded": open,
|
|
948
|
+
"aria-haspopup": "listbox",
|
|
949
|
+
disabled: disabled || loading,
|
|
950
|
+
onClick: handleOpen,
|
|
951
|
+
className: cn(
|
|
952
|
+
"flex h-10 w-full items-center justify-between rounded-md border border-input bg-background px-3 py-2 text-left text-sm ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50"
|
|
953
|
+
),
|
|
954
|
+
children: [
|
|
955
|
+
loading ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("span", { className: "flex items-center gap-2 text-muted-foreground", children: [
|
|
956
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_lucide_react4.Loader2, { className: "h-4 w-4 animate-spin" }),
|
|
957
|
+
"Loading..."
|
|
958
|
+
] }) : selected ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("span", { className: "flex items-center gap-2 truncate", children: [
|
|
959
|
+
selected.sublabel ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "shrink-0 font-mono text-xs text-muted-foreground", children: selected.sublabel }) : null,
|
|
960
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "truncate", children: selected.label })
|
|
961
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "text-muted-foreground", children: placeholder }),
|
|
962
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "ml-2 shrink-0 opacity-50", children: open ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_lucide_react4.ChevronUp, { className: "h-4 w-4" }) : /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_lucide_react4.ChevronDown, { className: "h-4 w-4" }) })
|
|
963
|
+
]
|
|
964
|
+
}
|
|
965
|
+
),
|
|
966
|
+
open ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
967
|
+
"div",
|
|
968
|
+
{
|
|
969
|
+
role: "listbox",
|
|
970
|
+
className: "animate-in fade-in-0 zoom-in-95 absolute z-50 mt-1 w-full rounded-md border border-border bg-popover text-popover-foreground shadow-md",
|
|
971
|
+
children: [
|
|
972
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "sticky top-0 flex items-center gap-2 border-b border-border bg-popover px-3 py-2", children: [
|
|
973
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_lucide_react4.Search, { className: "h-4 w-4 shrink-0 text-muted-foreground" }),
|
|
974
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
975
|
+
Input,
|
|
976
|
+
{
|
|
977
|
+
ref: searchRef,
|
|
978
|
+
type: "text",
|
|
979
|
+
value: search,
|
|
980
|
+
onChange: (event) => setSearch(event.target.value),
|
|
981
|
+
placeholder: searchPlaceholder,
|
|
982
|
+
className: "h-7 border-0 bg-transparent px-0 text-sm shadow-none focus-visible:ring-0 focus-visible:ring-offset-0 placeholder:text-muted-foreground"
|
|
983
|
+
}
|
|
984
|
+
)
|
|
985
|
+
] }),
|
|
986
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("ul", { className: "max-h-60 overflow-y-auto overscroll-contain p-1", children: filtered.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("li", { className: "px-4 py-3 text-center text-xs text-muted-foreground", children: emptyMessage }) : filtered.map((option) => {
|
|
987
|
+
const isSelected = option.value === value;
|
|
988
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
989
|
+
"li",
|
|
990
|
+
{
|
|
991
|
+
role: "option",
|
|
992
|
+
"aria-selected": isSelected,
|
|
993
|
+
onClick: () => handleSelect(option.value),
|
|
994
|
+
className: cn(
|
|
995
|
+
"relative flex cursor-pointer select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground",
|
|
996
|
+
isSelected && "bg-accent/50 font-medium"
|
|
997
|
+
),
|
|
998
|
+
children: [
|
|
999
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: isSelected ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_lucide_react4.Check, { className: "h-4 w-4" }) : null }),
|
|
1000
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("span", { className: "flex items-center gap-2 truncate", children: [
|
|
1001
|
+
option.sublabel ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "shrink-0 font-mono text-xs text-muted-foreground", children: option.sublabel }) : null,
|
|
1002
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "truncate", children: option.label })
|
|
1003
|
+
] })
|
|
1004
|
+
]
|
|
1005
|
+
},
|
|
1006
|
+
option.value
|
|
1007
|
+
);
|
|
1008
|
+
}) })
|
|
1009
|
+
]
|
|
1010
|
+
}
|
|
1011
|
+
) : null
|
|
1012
|
+
] });
|
|
1013
|
+
}
|
|
1014
|
+
);
|
|
1015
|
+
SearchableSelect.displayName = "SearchableSelect";
|
|
1016
|
+
|
|
1017
|
+
// src/components/forms/select.tsx
|
|
1018
|
+
var React7 = __toESM(require("react"), 1);
|
|
1019
|
+
var SelectPrimitive = __toESM(require("@radix-ui/react-select"), 1);
|
|
1020
|
+
var import_lucide_react5 = require("lucide-react");
|
|
1021
|
+
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
1022
|
+
var Select = SelectPrimitive.Root;
|
|
1023
|
+
var SelectGroup = SelectPrimitive.Group;
|
|
1024
|
+
var SelectValue = SelectPrimitive.Value;
|
|
1025
|
+
var SelectTrigger = React7.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
|
|
1026
|
+
SelectPrimitive.Trigger,
|
|
1027
|
+
{
|
|
1028
|
+
ref,
|
|
1029
|
+
className: cn(
|
|
1030
|
+
"flex h-10 w-full items-center justify-between rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background data-[placeholder]:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1",
|
|
1031
|
+
className
|
|
1032
|
+
),
|
|
1033
|
+
...props,
|
|
1034
|
+
children: [
|
|
1035
|
+
children,
|
|
1036
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(SelectPrimitive.Icon, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_lucide_react5.ChevronDown, { className: "h-4 w-4 opacity-50" }) })
|
|
1037
|
+
]
|
|
1038
|
+
}
|
|
1039
|
+
));
|
|
1040
|
+
SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
|
|
1041
|
+
var SelectScrollUpButton = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(SelectPrimitive.ScrollUpButton, { ref, className: cn("flex cursor-default items-center justify-center py-1", className), ...props, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_lucide_react5.ChevronUp, { className: "h-4 w-4" }) }));
|
|
1042
|
+
SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName;
|
|
1043
|
+
var SelectScrollDownButton = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
1044
|
+
SelectPrimitive.ScrollDownButton,
|
|
1045
|
+
{
|
|
1046
|
+
ref,
|
|
1047
|
+
className: cn("flex cursor-default items-center justify-center py-1", className),
|
|
1048
|
+
...props,
|
|
1049
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_lucide_react5.ChevronDown, { className: "h-4 w-4" })
|
|
1050
|
+
}
|
|
1051
|
+
));
|
|
1052
|
+
SelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName;
|
|
1053
|
+
var SelectContent = React7.forwardRef(({ className, children, position = "popper", ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(SelectPrimitive.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
|
|
1054
|
+
SelectPrimitive.Content,
|
|
1055
|
+
{
|
|
1056
|
+
ref,
|
|
1057
|
+
className: cn(
|
|
1058
|
+
"relative z-50 max-h-[--radix-select-content-available-height] min-w-[8rem] overflow-y-auto overflow-x-hidden rounded-md border bg-popover text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 origin-[--radix-select-content-transform-origin]",
|
|
1059
|
+
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",
|
|
1060
|
+
className
|
|
1061
|
+
),
|
|
1062
|
+
position,
|
|
1063
|
+
...props,
|
|
1064
|
+
children: [
|
|
1065
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(SelectScrollUpButton, {}),
|
|
1066
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
1067
|
+
SelectPrimitive.Viewport,
|
|
1068
|
+
{
|
|
1069
|
+
className: cn(
|
|
1070
|
+
"p-1",
|
|
1071
|
+
position === "popper" && "h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]"
|
|
1072
|
+
),
|
|
1073
|
+
children
|
|
1074
|
+
}
|
|
1075
|
+
),
|
|
1076
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(SelectScrollDownButton, {})
|
|
1077
|
+
]
|
|
1078
|
+
}
|
|
1079
|
+
) }));
|
|
1080
|
+
SelectContent.displayName = SelectPrimitive.Content.displayName;
|
|
1081
|
+
var SelectLabel = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(SelectPrimitive.Label, { ref, className: cn("py-1.5 pl-8 pr-2 text-sm font-semibold", className), ...props }));
|
|
1082
|
+
SelectLabel.displayName = SelectPrimitive.Label.displayName;
|
|
1083
|
+
var SelectItem = React7.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
|
|
1084
|
+
SelectPrimitive.Item,
|
|
1085
|
+
{
|
|
1086
|
+
ref,
|
|
1087
|
+
className: cn(
|
|
1088
|
+
"relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
|
1089
|
+
className
|
|
1090
|
+
),
|
|
1091
|
+
...props,
|
|
1092
|
+
children: [
|
|
1093
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(SelectPrimitive.ItemIndicator, { children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_lucide_react5.Check, { className: "h-4 w-4" }) }) }),
|
|
1094
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(SelectPrimitive.ItemText, { children })
|
|
1095
|
+
]
|
|
1096
|
+
}
|
|
1097
|
+
));
|
|
1098
|
+
SelectItem.displayName = SelectPrimitive.Item.displayName;
|
|
1099
|
+
var SelectSeparator = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(SelectPrimitive.Separator, { ref, className: cn("-mx-1 my-1 h-px bg-muted", className), ...props }));
|
|
1100
|
+
SelectSeparator.displayName = SelectPrimitive.Separator.displayName;
|
|
1101
|
+
|
|
1102
|
+
// src/components/layout/app-shell.tsx
|
|
1103
|
+
var import_react2 = require("react");
|
|
1104
|
+
|
|
1105
|
+
// src/components/overlays/drawer.tsx
|
|
1106
|
+
var React8 = __toESM(require("react"), 1);
|
|
1107
|
+
var import_vaul = require("vaul");
|
|
1108
|
+
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
1109
|
+
var Drawer = ({ shouldScaleBackground = true, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_vaul.Drawer.Root, { shouldScaleBackground, ...props });
|
|
1110
|
+
Drawer.displayName = "Drawer";
|
|
1111
|
+
var DrawerTrigger = import_vaul.Drawer.Trigger;
|
|
1112
|
+
var DrawerPortal = import_vaul.Drawer.Portal;
|
|
1113
|
+
var DrawerClose = import_vaul.Drawer.Close;
|
|
1114
|
+
var DrawerOverlay = React8.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_vaul.Drawer.Overlay, { ref, className: cn("fixed inset-0 z-50 bg-black/80", className), ...props }));
|
|
1115
|
+
DrawerOverlay.displayName = import_vaul.Drawer.Overlay.displayName;
|
|
1116
|
+
var DrawerContent = React8.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(DrawerPortal, { children: [
|
|
1117
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(DrawerOverlay, {}),
|
|
1118
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
|
|
1119
|
+
import_vaul.Drawer.Content,
|
|
1120
|
+
{
|
|
1121
|
+
ref,
|
|
1122
|
+
className: cn("fixed inset-x-0 bottom-0 z-50 mt-24 flex h-auto flex-col rounded-t-[10px] border bg-background", className),
|
|
1123
|
+
...props,
|
|
1124
|
+
children: [
|
|
1125
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "mx-auto mt-4 h-2 w-[100px] rounded-full bg-muted" }),
|
|
1126
|
+
children
|
|
1127
|
+
]
|
|
1128
|
+
}
|
|
1129
|
+
)
|
|
1130
|
+
] }));
|
|
1131
|
+
DrawerContent.displayName = "DrawerContent";
|
|
1132
|
+
var DrawerHeader = ({ className, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: cn("grid gap-1.5 p-4 text-center sm:text-left", className), ...props });
|
|
1133
|
+
DrawerHeader.displayName = "DrawerHeader";
|
|
1134
|
+
var DrawerFooter = ({ className, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: cn("mt-auto flex flex-col gap-2 p-4", className), ...props });
|
|
1135
|
+
DrawerFooter.displayName = "DrawerFooter";
|
|
1136
|
+
var DrawerTitle = React8.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_vaul.Drawer.Title, { ref, className: cn("text-lg font-semibold leading-none tracking-tight", className), ...props }));
|
|
1137
|
+
DrawerTitle.displayName = import_vaul.Drawer.Title.displayName;
|
|
1138
|
+
var DrawerDescription = React8.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_vaul.Drawer.Description, { ref, className: cn("text-sm text-muted-foreground", className), ...props }));
|
|
1139
|
+
DrawerDescription.displayName = import_vaul.Drawer.Description.displayName;
|
|
1140
|
+
|
|
1141
|
+
// src/components/navigation/navbar.tsx
|
|
1142
|
+
var import_lucide_react6 = require("lucide-react");
|
|
1143
|
+
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
1144
|
+
function Navbar({ brand, actions, onMenuClick, className }) {
|
|
1145
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("header", { className: cn("h-14 shrink-0 border-b border-border bg-card/80 px-4 backdrop-blur-sm", className), children: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "mx-auto flex h-full w-full max-w-7xl items-center justify-between gap-3", children: [
|
|
1146
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex min-w-0 flex-1 items-center gap-3", children: [
|
|
1147
|
+
onMenuClick ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Button, { type: "button", variant: "ghost", size: "icon", onClick: onMenuClick, "aria-label": "Open navigation", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react6.Menu, { size: 20 }) }) : null,
|
|
1148
|
+
brand
|
|
1149
|
+
] }),
|
|
1150
|
+
actions ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "flex shrink-0 items-center gap-3", children: actions }) : null
|
|
1151
|
+
] }) });
|
|
1152
|
+
}
|
|
1153
|
+
|
|
1154
|
+
// src/components/navigation/sidebar.tsx
|
|
1155
|
+
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
1156
|
+
function getInitials2(name) {
|
|
1157
|
+
return name.trim().split(" ").filter(Boolean).slice(0, 2).map((part) => part[0]?.toUpperCase() ?? "").join("");
|
|
1158
|
+
}
|
|
1159
|
+
function Sidebar({ brand, groups, user, footerAction, className }) {
|
|
1160
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("aside", { className: cn("flex h-full w-72 max-w-[85vw] flex-col border-r border-border bg-background", className), children: [
|
|
1161
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "border-b border-border px-5 py-4", children: brand }),
|
|
1162
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("nav", { className: "flex-1 space-y-6 overflow-y-auto px-3 py-4", children: groups.map((group) => /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { children: [
|
|
1163
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("p", { className: "mb-2 px-2 text-xs font-semibold uppercase tracking-widest text-muted-foreground", children: group.label }),
|
|
1164
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("ul", { className: "space-y-0.5", children: group.items.map((item) => {
|
|
1165
|
+
const Icon2 = item.icon;
|
|
1166
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
|
|
1167
|
+
"a",
|
|
1168
|
+
{
|
|
1169
|
+
href: item.href,
|
|
1170
|
+
onClick: item.onClick,
|
|
1171
|
+
className: cn(
|
|
1172
|
+
"flex items-center gap-3 rounded-lg px-3 py-2.5 text-sm font-medium transition-colors",
|
|
1173
|
+
item.active ? "bg-primary text-primary-foreground" : "text-foreground hover:bg-accent hover:text-accent-foreground"
|
|
1174
|
+
),
|
|
1175
|
+
children: [
|
|
1176
|
+
Icon2 ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Icon2, { size: 17, className: "shrink-0" }) : null,
|
|
1177
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "flex-1", children: item.label })
|
|
1178
|
+
]
|
|
1179
|
+
}
|
|
1180
|
+
) }, `${group.label}-${item.label}`);
|
|
1181
|
+
}) })
|
|
1182
|
+
] }, group.label)) }),
|
|
1183
|
+
user ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "border-t border-border px-5 py-4", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex items-center gap-3", children: [
|
|
1184
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Avatar, { className: "h-9 w-9 shrink-0", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(AvatarFallback, { className: "bg-primary text-xs font-semibold text-primary-foreground", children: user.initials ?? getInitials2(user.name) }) }),
|
|
1185
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "min-w-0 flex-1", children: [
|
|
1186
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("p", { className: "truncate text-sm font-medium text-foreground", children: user.name }),
|
|
1187
|
+
user.role ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("p", { className: "truncate text-xs text-muted-foreground", children: user.role }) : null
|
|
1188
|
+
] }),
|
|
1189
|
+
footerAction ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Button, { type: "button", variant: "ghost", size: "sm", onClick: footerAction.onClick, children: footerAction.label }) : null
|
|
1190
|
+
] }) }) : null
|
|
1191
|
+
] });
|
|
1192
|
+
}
|
|
1193
|
+
|
|
1194
|
+
// src/components/layout/app-shell.tsx
|
|
1195
|
+
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
1196
|
+
function AppShell({
|
|
1197
|
+
brand,
|
|
1198
|
+
actions,
|
|
1199
|
+
sidebarGroups,
|
|
1200
|
+
sidebarUser,
|
|
1201
|
+
sidebarFooterAction,
|
|
1202
|
+
children
|
|
1203
|
+
}) {
|
|
1204
|
+
const [open, setOpen] = (0, import_react2.useState)(false);
|
|
1205
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "min-h-screen bg-background", children: [
|
|
1206
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Navbar, { brand, actions, onMenuClick: () => setOpen(true) }),
|
|
1207
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Drawer, { open, onOpenChange: setOpen, direction: "left", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(DrawerContent, { className: "h-full w-72 rounded-none border-r border-border p-0", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Sidebar, { brand, groups: sidebarGroups, user: sidebarUser, footerAction: sidebarFooterAction }) }) }),
|
|
1208
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("main", { className: "mx-auto w-full max-w-7xl px-4 py-6 sm:px-6", children })
|
|
1209
|
+
] });
|
|
1210
|
+
}
|
|
1211
|
+
|
|
1212
|
+
// src/components/layout/form-section.tsx
|
|
1213
|
+
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
1214
|
+
function FormSection({ title, description, children }) {
|
|
1215
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(Card, { children: [
|
|
1216
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(CardHeader, { children: [
|
|
1217
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(CardTitle, { children: title }),
|
|
1218
|
+
description ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(CardDescription, { children: description }) : null
|
|
1219
|
+
] }),
|
|
1220
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(CardContent, { children })
|
|
1221
|
+
] });
|
|
1222
|
+
}
|
|
1223
|
+
|
|
1224
|
+
// src/components/layout/page-header.tsx
|
|
1225
|
+
var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
1226
|
+
function PageHeader({ title, description, action }) {
|
|
1227
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex items-start justify-between gap-4 sm:flex-row sm:items-center", children: [
|
|
1228
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { children: [
|
|
1229
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("h1", { className: "text-2xl font-semibold text-foreground", style: { fontFamily: "var(--font-display)" }, children: title }),
|
|
1230
|
+
description ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { className: "mt-0.5 text-sm text-muted-foreground", children: description }) : null
|
|
1231
|
+
] }),
|
|
1232
|
+
action ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { children: action }) : null
|
|
1233
|
+
] });
|
|
1234
|
+
}
|
|
1235
|
+
|
|
1236
|
+
// src/components/layout/theme-toggle.tsx
|
|
1237
|
+
var import_lucide_react7 = require("lucide-react");
|
|
1238
|
+
var import_jsx_runtime25 = require("react/jsx-runtime");
|
|
1239
|
+
var options = [
|
|
1240
|
+
{ value: "light", Icon: import_lucide_react7.Sun, label: "Light" },
|
|
1241
|
+
{ value: "dark", Icon: import_lucide_react7.Moon, label: "Dark" }
|
|
1242
|
+
];
|
|
1243
|
+
function ThemeToggle({ className }) {
|
|
1244
|
+
const { theme, setTheme } = useTheme();
|
|
1245
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: cn("flex items-center gap-1 rounded-lg border border-border bg-muted p-1", className), children: options.map(({ value, Icon: Icon2, label }) => /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
|
|
1246
|
+
"button",
|
|
1247
|
+
{
|
|
1248
|
+
type: "button",
|
|
1249
|
+
onClick: () => setTheme(value),
|
|
1250
|
+
"aria-label": label,
|
|
1251
|
+
className: cn(
|
|
1252
|
+
"flex cursor-pointer items-center gap-1.5 rounded-md px-3 py-1.5 text-xs font-medium transition-all",
|
|
1253
|
+
theme === value ? "bg-card text-foreground shadow-sm" : "text-muted-foreground hover:text-foreground"
|
|
1254
|
+
),
|
|
1255
|
+
children: [
|
|
1256
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Icon2, { size: 13 }),
|
|
1257
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { children: label })
|
|
1258
|
+
]
|
|
1259
|
+
},
|
|
1260
|
+
value
|
|
1261
|
+
)) });
|
|
1262
|
+
}
|
|
1263
|
+
|
|
1264
|
+
// src/components/navigation/breadcrumb.tsx
|
|
1265
|
+
var React9 = __toESM(require("react"), 1);
|
|
1266
|
+
var import_react_slot2 = require("@radix-ui/react-slot");
|
|
1267
|
+
var import_lucide_react8 = require("lucide-react");
|
|
1268
|
+
var import_jsx_runtime26 = require("react/jsx-runtime");
|
|
1269
|
+
var Breadcrumb = React9.forwardRef(({ ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("nav", { ref, "aria-label": "breadcrumb", ...props }));
|
|
1270
|
+
Breadcrumb.displayName = "Breadcrumb";
|
|
1271
|
+
var BreadcrumbList = React9.forwardRef(
|
|
1272
|
+
({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
1273
|
+
"ol",
|
|
1274
|
+
{
|
|
1275
|
+
ref,
|
|
1276
|
+
className: cn("flex flex-wrap items-center gap-1.5 break-words text-sm text-muted-foreground sm:gap-2.5", className),
|
|
1277
|
+
...props
|
|
1278
|
+
}
|
|
1279
|
+
)
|
|
1280
|
+
);
|
|
1281
|
+
BreadcrumbList.displayName = "BreadcrumbList";
|
|
1282
|
+
var BreadcrumbItem = React9.forwardRef(
|
|
1283
|
+
({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("li", { ref, className: cn("inline-flex items-center gap-1.5", className), ...props })
|
|
1284
|
+
);
|
|
1285
|
+
BreadcrumbItem.displayName = "BreadcrumbItem";
|
|
1286
|
+
var BreadcrumbLink = React9.forwardRef(({ asChild, className, ...props }, ref) => {
|
|
1287
|
+
const Comp = asChild ? import_react_slot2.Slot : "a";
|
|
1288
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(Comp, { ref, className: cn("transition-colors hover:text-foreground", className), ...props });
|
|
1289
|
+
});
|
|
1290
|
+
BreadcrumbLink.displayName = "BreadcrumbLink";
|
|
1291
|
+
var BreadcrumbPage = React9.forwardRef(
|
|
1292
|
+
({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
1293
|
+
"span",
|
|
1294
|
+
{
|
|
1295
|
+
ref,
|
|
1296
|
+
role: "link",
|
|
1297
|
+
"aria-disabled": "true",
|
|
1298
|
+
"aria-current": "page",
|
|
1299
|
+
className: cn("font-normal text-foreground", className),
|
|
1300
|
+
...props
|
|
1301
|
+
}
|
|
1302
|
+
)
|
|
1303
|
+
);
|
|
1304
|
+
BreadcrumbPage.displayName = "BreadcrumbPage";
|
|
1305
|
+
var BreadcrumbSeparator = ({ children, className, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("li", { role: "presentation", "aria-hidden": "true", className: cn("[&>svg]:h-3.5 [&>svg]:w-3.5", className), ...props, children: children ?? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_lucide_react8.ChevronRight, {}) });
|
|
1306
|
+
BreadcrumbSeparator.displayName = "BreadcrumbSeparator";
|
|
1307
|
+
var BreadcrumbEllipsis = ({ className, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("span", { role: "presentation", "aria-hidden": "true", className: cn("flex h-9 w-9 items-center justify-center", className), ...props, children: [
|
|
1308
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_lucide_react8.MoreHorizontal, { className: "h-4 w-4" }),
|
|
1309
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "sr-only", children: "More" })
|
|
1310
|
+
] });
|
|
1311
|
+
BreadcrumbEllipsis.displayName = "BreadcrumbElipssis";
|
|
1312
|
+
|
|
1313
|
+
// src/components/navigation/page-breadcrumb.tsx
|
|
1314
|
+
var import_react3 = require("react");
|
|
1315
|
+
var import_jsx_runtime27 = require("react/jsx-runtime");
|
|
1316
|
+
function PageBreadcrumb({ items }) {
|
|
1317
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(Breadcrumb, { children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(BreadcrumbList, { children: items.map((item, index) => {
|
|
1318
|
+
const isLast = index === items.length - 1;
|
|
1319
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(import_react3.Fragment, { children: [
|
|
1320
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(BreadcrumbItem, { children: !isLast && item.href ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(BreadcrumbLink, { href: item.href, children: item.label }) : /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(BreadcrumbPage, { children: item.label }) }),
|
|
1321
|
+
!isLast ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(BreadcrumbSeparator, {}) : null
|
|
1322
|
+
] }, `${item.label}-${index}`);
|
|
1323
|
+
}) }) });
|
|
1324
|
+
}
|
|
1325
|
+
|
|
1326
|
+
// src/components/navigation/steps.tsx
|
|
1327
|
+
var import_lucide_react9 = require("lucide-react");
|
|
1328
|
+
var import_jsx_runtime28 = require("react/jsx-runtime");
|
|
1329
|
+
var indicatorStyles = {
|
|
1330
|
+
complete: "border-primary bg-primary text-primary-foreground",
|
|
1331
|
+
current: "border-primary bg-primary/10 text-primary",
|
|
1332
|
+
upcoming: "border-border bg-background text-muted-foreground",
|
|
1333
|
+
error: "border-destructive bg-destructive/10 text-destructive"
|
|
1334
|
+
};
|
|
1335
|
+
function Steps({ className, items, orientation = "horizontal" }) {
|
|
1336
|
+
return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("ol", { className: cn("flex", orientation === "horizontal" ? "flex-col gap-4 md:flex-row" : "flex-col", className), children: items.map((item, index) => {
|
|
1337
|
+
const status = item.status ?? "upcoming";
|
|
1338
|
+
const isLast = index === items.length - 1;
|
|
1339
|
+
return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
|
|
1340
|
+
"li",
|
|
1341
|
+
{
|
|
1342
|
+
className: cn("relative", orientation === "horizontal" ? "flex-1" : "pb-6 last:pb-0"),
|
|
1343
|
+
children: [
|
|
1344
|
+
!isLast ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
1345
|
+
"span",
|
|
1346
|
+
{
|
|
1347
|
+
"aria-hidden": "true",
|
|
1348
|
+
className: cn(
|
|
1349
|
+
"absolute bg-border",
|
|
1350
|
+
orientation === "horizontal" ? "left-[calc(50%+1rem)] top-4 hidden h-px w-[calc(100%-1rem)] md:block" : "left-4 top-9 h-[calc(100%-1rem)] w-px"
|
|
1351
|
+
)
|
|
1352
|
+
}
|
|
1353
|
+
) : null,
|
|
1354
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: cn(
|
|
1355
|
+
orientation === "horizontal" ? "flex flex-col items-center gap-2 text-center" : "flex items-start gap-3"
|
|
1356
|
+
), children: [
|
|
1357
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
|
|
1358
|
+
"span",
|
|
1359
|
+
{
|
|
1360
|
+
className: cn(
|
|
1361
|
+
"relative z-10 inline-flex h-8 w-8 items-center justify-center rounded-full border text-sm font-semibold shadow-sm",
|
|
1362
|
+
indicatorStyles[status]
|
|
1363
|
+
),
|
|
1364
|
+
children: [
|
|
1365
|
+
status === "complete" ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_lucide_react9.Check, { className: "h-4 w-4" }) : null,
|
|
1366
|
+
status === "error" ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_lucide_react9.AlertCircle, { className: "h-4 w-4" }) : null,
|
|
1367
|
+
status === "current" || status === "upcoming" ? index + 1 : null
|
|
1368
|
+
]
|
|
1369
|
+
}
|
|
1370
|
+
),
|
|
1371
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: cn("grid gap-1", orientation === "vertical" && "pt-1"), children: [
|
|
1372
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("p", { className: cn("text-sm font-medium", status === "upcoming" ? "text-muted-foreground" : "text-foreground"), children: item.title }),
|
|
1373
|
+
item.description ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("p", { className: "text-xs text-muted-foreground", children: item.description }) : null
|
|
1374
|
+
] })
|
|
1375
|
+
] })
|
|
1376
|
+
]
|
|
1377
|
+
},
|
|
1378
|
+
item.id ?? item.title
|
|
1379
|
+
);
|
|
1380
|
+
}) });
|
|
1381
|
+
}
|
|
1382
|
+
|
|
1383
|
+
// src/components/overlays/dialog.tsx
|
|
1384
|
+
var React10 = __toESM(require("react"), 1);
|
|
1385
|
+
var DialogPrimitive = __toESM(require("@radix-ui/react-dialog"), 1);
|
|
1386
|
+
var import_lucide_react10 = require("lucide-react");
|
|
1387
|
+
var import_jsx_runtime29 = require("react/jsx-runtime");
|
|
1388
|
+
var Dialog = DialogPrimitive.Root;
|
|
1389
|
+
var DialogTrigger = DialogPrimitive.Trigger;
|
|
1390
|
+
var DialogPortal = DialogPrimitive.Portal;
|
|
1391
|
+
var DialogClose = DialogPrimitive.Close;
|
|
1392
|
+
var DialogOverlay = React10.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
1393
|
+
DialogPrimitive.Overlay,
|
|
1394
|
+
{
|
|
1395
|
+
ref,
|
|
1396
|
+
className: cn(
|
|
1397
|
+
"fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
|
|
1398
|
+
className
|
|
1399
|
+
),
|
|
1400
|
+
...props
|
|
1401
|
+
}
|
|
1402
|
+
));
|
|
1403
|
+
DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;
|
|
1404
|
+
var DialogContent = React10.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(DialogPortal, { children: [
|
|
1405
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(DialogOverlay, {}),
|
|
1406
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
|
|
1407
|
+
DialogPrimitive.Content,
|
|
1408
|
+
{
|
|
1409
|
+
ref,
|
|
1410
|
+
className: cn(
|
|
1411
|
+
"fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",
|
|
1412
|
+
className
|
|
1413
|
+
),
|
|
1414
|
+
...props,
|
|
1415
|
+
children: [
|
|
1416
|
+
children,
|
|
1417
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(DialogPrimitive.Close, { className: "absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground", children: [
|
|
1418
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_lucide_react10.X, { className: "h-4 w-4" }),
|
|
1419
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "sr-only", children: "Close" })
|
|
1420
|
+
] })
|
|
1421
|
+
]
|
|
1422
|
+
}
|
|
1423
|
+
)
|
|
1424
|
+
] }));
|
|
1425
|
+
DialogContent.displayName = DialogPrimitive.Content.displayName;
|
|
1426
|
+
var DialogHeader = ({ className, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: cn("flex flex-col space-y-1.5 text-center sm:text-left", className), ...props });
|
|
1427
|
+
DialogHeader.displayName = "DialogHeader";
|
|
1428
|
+
var DialogFooter = ({ className, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: cn("flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2", className), ...props });
|
|
1429
|
+
DialogFooter.displayName = "DialogFooter";
|
|
1430
|
+
var DialogTitle = React10.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(DialogPrimitive.Title, { ref, className: cn("text-lg font-semibold leading-none tracking-tight", className), ...props }));
|
|
1431
|
+
DialogTitle.displayName = DialogPrimitive.Title.displayName;
|
|
1432
|
+
var DialogDescription = React10.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(DialogPrimitive.Description, { ref, className: cn("text-sm text-muted-foreground", className), ...props }));
|
|
1433
|
+
DialogDescription.displayName = DialogPrimitive.Description.displayName;
|
|
1434
|
+
|
|
1435
|
+
// src/components/overlays/dropdown-menu.tsx
|
|
1436
|
+
var React11 = __toESM(require("react"), 1);
|
|
1437
|
+
var DropdownMenuPrimitive = __toESM(require("@radix-ui/react-dropdown-menu"), 1);
|
|
1438
|
+
var import_lucide_react11 = require("lucide-react");
|
|
1439
|
+
var import_jsx_runtime30 = require("react/jsx-runtime");
|
|
1440
|
+
var DropdownMenu = DropdownMenuPrimitive.Root;
|
|
1441
|
+
var DropdownMenuTrigger = DropdownMenuPrimitive.Trigger;
|
|
1442
|
+
var DropdownMenuGroup = DropdownMenuPrimitive.Group;
|
|
1443
|
+
var DropdownMenuPortal = DropdownMenuPrimitive.Portal;
|
|
1444
|
+
var DropdownMenuSub = DropdownMenuPrimitive.Sub;
|
|
1445
|
+
var DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup;
|
|
1446
|
+
var DropdownMenuSubTrigger = React11.forwardRef(({ className, inset, children, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
|
|
1447
|
+
DropdownMenuPrimitive.SubTrigger,
|
|
1448
|
+
{
|
|
1449
|
+
ref,
|
|
1450
|
+
className: cn(
|
|
1451
|
+
"flex cursor-default select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent data-[state=open]:bg-accent [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
|
|
1452
|
+
inset && "pl-8",
|
|
1453
|
+
className
|
|
1454
|
+
),
|
|
1455
|
+
...props,
|
|
1456
|
+
children: [
|
|
1457
|
+
children,
|
|
1458
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_lucide_react11.ChevronRight, { className: "ml-auto" })
|
|
1459
|
+
]
|
|
1460
|
+
}
|
|
1461
|
+
));
|
|
1462
|
+
DropdownMenuSubTrigger.displayName = DropdownMenuPrimitive.SubTrigger.displayName;
|
|
1463
|
+
var DropdownMenuSubContent = React11.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
1464
|
+
DropdownMenuPrimitive.SubContent,
|
|
1465
|
+
{
|
|
1466
|
+
ref,
|
|
1467
|
+
className: cn(
|
|
1468
|
+
"z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 origin-[--radix-dropdown-menu-content-transform-origin]",
|
|
1469
|
+
className
|
|
1470
|
+
),
|
|
1471
|
+
...props
|
|
1472
|
+
}
|
|
1473
|
+
));
|
|
1474
|
+
DropdownMenuSubContent.displayName = DropdownMenuPrimitive.SubContent.displayName;
|
|
1475
|
+
var DropdownMenuContent = React11.forwardRef(({ className, sideOffset = 4, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(DropdownMenuPrimitive.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
1476
|
+
DropdownMenuPrimitive.Content,
|
|
1477
|
+
{
|
|
1478
|
+
ref,
|
|
1479
|
+
sideOffset,
|
|
1480
|
+
className: cn(
|
|
1481
|
+
"z-50 max-h-[var(--radix-dropdown-menu-content-available-height)] min-w-[8rem] overflow-y-auto overflow-x-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 origin-[--radix-dropdown-menu-content-transform-origin]",
|
|
1482
|
+
className
|
|
1483
|
+
),
|
|
1484
|
+
...props
|
|
1485
|
+
}
|
|
1486
|
+
) }));
|
|
1487
|
+
DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName;
|
|
1488
|
+
var DropdownMenuItem = React11.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
1489
|
+
DropdownMenuPrimitive.Item,
|
|
1490
|
+
{
|
|
1491
|
+
ref,
|
|
1492
|
+
className: cn(
|
|
1493
|
+
"relative flex cursor-default select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
|
|
1494
|
+
inset && "pl-8",
|
|
1495
|
+
className
|
|
1496
|
+
),
|
|
1497
|
+
...props
|
|
1498
|
+
}
|
|
1499
|
+
));
|
|
1500
|
+
DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName;
|
|
1501
|
+
var DropdownMenuCheckboxItem = React11.forwardRef(({ className, children, checked, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
|
|
1502
|
+
DropdownMenuPrimitive.CheckboxItem,
|
|
1503
|
+
{
|
|
1504
|
+
ref,
|
|
1505
|
+
className: cn(
|
|
1506
|
+
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
|
1507
|
+
className
|
|
1508
|
+
),
|
|
1509
|
+
...checked !== void 0 ? { checked } : {},
|
|
1510
|
+
...props,
|
|
1511
|
+
children: [
|
|
1512
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(DropdownMenuPrimitive.ItemIndicator, { children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_lucide_react11.Check, { className: "h-4 w-4" }) }) }),
|
|
1513
|
+
children
|
|
1514
|
+
]
|
|
1515
|
+
}
|
|
1516
|
+
));
|
|
1517
|
+
DropdownMenuCheckboxItem.displayName = DropdownMenuPrimitive.CheckboxItem.displayName;
|
|
1518
|
+
var DropdownMenuRadioItem = React11.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
|
|
1519
|
+
DropdownMenuPrimitive.RadioItem,
|
|
1520
|
+
{
|
|
1521
|
+
ref,
|
|
1522
|
+
className: cn(
|
|
1523
|
+
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
|
1524
|
+
className
|
|
1525
|
+
),
|
|
1526
|
+
...props,
|
|
1527
|
+
children: [
|
|
1528
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(DropdownMenuPrimitive.ItemIndicator, { children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_lucide_react11.Circle, { className: "h-2 w-2 fill-current" }) }) }),
|
|
1529
|
+
children
|
|
1530
|
+
]
|
|
1531
|
+
}
|
|
1532
|
+
));
|
|
1533
|
+
DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName;
|
|
1534
|
+
var DropdownMenuLabel = React11.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(DropdownMenuPrimitive.Label, { ref, className: cn("px-2 py-1.5 text-sm font-semibold", inset && "pl-8", className), ...props }));
|
|
1535
|
+
DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName;
|
|
1536
|
+
var DropdownMenuSeparator = React11.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(DropdownMenuPrimitive.Separator, { ref, className: cn("-mx-1 my-1 h-px bg-muted", className), ...props }));
|
|
1537
|
+
DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName;
|
|
1538
|
+
var DropdownMenuShortcut = ({ className, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: cn("ml-auto text-xs tracking-widest opacity-60", className), ...props });
|
|
1539
|
+
DropdownMenuShortcut.displayName = "DropdownMenuShortcut";
|
|
1540
|
+
|
|
1541
|
+
// src/components/overlays/sheet.tsx
|
|
1542
|
+
var React12 = __toESM(require("react"), 1);
|
|
1543
|
+
var SheetPrimitive = __toESM(require("@radix-ui/react-dialog"), 1);
|
|
1544
|
+
var import_class_variance_authority3 = require("class-variance-authority");
|
|
1545
|
+
var import_lucide_react12 = require("lucide-react");
|
|
1546
|
+
var import_jsx_runtime31 = require("react/jsx-runtime");
|
|
1547
|
+
var Sheet = SheetPrimitive.Root;
|
|
1548
|
+
var SheetTrigger = SheetPrimitive.Trigger;
|
|
1549
|
+
var SheetClose = SheetPrimitive.Close;
|
|
1550
|
+
var SheetPortal = SheetPrimitive.Portal;
|
|
1551
|
+
var SheetOverlay = React12.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
|
|
1552
|
+
SheetPrimitive.Overlay,
|
|
1553
|
+
{
|
|
1554
|
+
className: cn(
|
|
1555
|
+
"fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
|
|
1556
|
+
className
|
|
1557
|
+
),
|
|
1558
|
+
...props,
|
|
1559
|
+
ref
|
|
1560
|
+
}
|
|
1561
|
+
));
|
|
1562
|
+
SheetOverlay.displayName = SheetPrimitive.Overlay.displayName;
|
|
1563
|
+
var sheetVariants = (0, import_class_variance_authority3.cva)(
|
|
1564
|
+
"fixed z-50 gap-4 bg-background p-6 shadow-lg transition ease-in-out data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:duration-300 data-[state=open]:duration-500",
|
|
1565
|
+
{
|
|
1566
|
+
variants: {
|
|
1567
|
+
side: {
|
|
1568
|
+
top: "inset-x-0 top-0 border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top",
|
|
1569
|
+
bottom: "inset-x-0 bottom-0 border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom",
|
|
1570
|
+
left: "inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm",
|
|
1571
|
+
right: "inset-y-0 right-0 h-full w-3/4 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm"
|
|
1572
|
+
}
|
|
1573
|
+
},
|
|
1574
|
+
defaultVariants: {
|
|
1575
|
+
side: "right"
|
|
1576
|
+
}
|
|
1577
|
+
}
|
|
1578
|
+
);
|
|
1579
|
+
var SheetContent = React12.forwardRef(
|
|
1580
|
+
({ side = "right", className, children, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(SheetPortal, { children: [
|
|
1581
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(SheetOverlay, {}),
|
|
1582
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(SheetPrimitive.Content, { ref, className: cn(sheetVariants({ side }), className), ...props, children: [
|
|
1583
|
+
children,
|
|
1584
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(SheetPrimitive.Close, { className: "absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-secondary", children: [
|
|
1585
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_lucide_react12.X, { className: "h-4 w-4" }),
|
|
1586
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "sr-only", children: "Close" })
|
|
1587
|
+
] })
|
|
1588
|
+
] })
|
|
1589
|
+
] })
|
|
1590
|
+
);
|
|
1591
|
+
SheetContent.displayName = SheetPrimitive.Content.displayName;
|
|
1592
|
+
var SheetHeader = ({ className, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: cn("flex flex-col space-y-2 text-center sm:text-left", className), ...props });
|
|
1593
|
+
SheetHeader.displayName = "SheetHeader";
|
|
1594
|
+
var SheetFooter = ({ className, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: cn("flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2", className), ...props });
|
|
1595
|
+
SheetFooter.displayName = "SheetFooter";
|
|
1596
|
+
var SheetTitle = React12.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(SheetPrimitive.Title, { ref, className: cn("text-lg font-semibold text-foreground", className), ...props }));
|
|
1597
|
+
SheetTitle.displayName = SheetPrimitive.Title.displayName;
|
|
1598
|
+
var SheetDescription = React12.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(SheetPrimitive.Description, { ref, className: cn("text-sm text-muted-foreground", className), ...props }));
|
|
1599
|
+
SheetDescription.displayName = SheetPrimitive.Description.displayName;
|
|
1600
|
+
|
|
1601
|
+
// src/components/primitives/alert.tsx
|
|
1602
|
+
var React13 = __toESM(require("react"), 1);
|
|
1603
|
+
var import_class_variance_authority4 = require("class-variance-authority");
|
|
1604
|
+
var import_jsx_runtime32 = require("react/jsx-runtime");
|
|
1605
|
+
var alertVariants = (0, import_class_variance_authority4.cva)("relative w-full rounded-lg border p-4 [&>svg~*]:pl-7 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground", {
|
|
1606
|
+
variants: {
|
|
1607
|
+
variant: {
|
|
1608
|
+
default: "bg-background text-foreground",
|
|
1609
|
+
destructive: "border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive"
|
|
1610
|
+
}
|
|
1611
|
+
},
|
|
1612
|
+
defaultVariants: {
|
|
1613
|
+
variant: "default"
|
|
1614
|
+
}
|
|
1615
|
+
});
|
|
1616
|
+
var Alert = React13.forwardRef(({ className, variant, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { ref, role: "alert", className: cn(alertVariants({ variant }), className), ...props }));
|
|
1617
|
+
Alert.displayName = "Alert";
|
|
1618
|
+
var AlertTitle = React13.forwardRef(
|
|
1619
|
+
({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("h5", { ref, className: cn("mb-1 font-medium leading-none tracking-tight", className), ...props })
|
|
1620
|
+
);
|
|
1621
|
+
AlertTitle.displayName = "AlertTitle";
|
|
1622
|
+
var AlertDescription = React13.forwardRef(
|
|
1623
|
+
({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { ref, className: cn("text-sm [&_p]:leading-relaxed", className), ...props })
|
|
1624
|
+
);
|
|
1625
|
+
AlertDescription.displayName = "AlertDescription";
|
|
1626
|
+
|
|
1627
|
+
// src/components/primitives/badge.tsx
|
|
1628
|
+
var import_class_variance_authority5 = require("class-variance-authority");
|
|
1629
|
+
var import_jsx_runtime33 = require("react/jsx-runtime");
|
|
1630
|
+
var badgeVariants = (0, import_class_variance_authority5.cva)("inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2", {
|
|
1631
|
+
variants: {
|
|
1632
|
+
variant: {
|
|
1633
|
+
default: "border-transparent bg-primary text-primary-foreground hover:bg-primary/80",
|
|
1634
|
+
secondary: "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80",
|
|
1635
|
+
destructive: "border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80",
|
|
1636
|
+
outline: "text-foreground"
|
|
1637
|
+
}
|
|
1638
|
+
},
|
|
1639
|
+
defaultVariants: {
|
|
1640
|
+
variant: "default"
|
|
1641
|
+
}
|
|
1642
|
+
});
|
|
1643
|
+
function Badge({ className, variant, ...props }) {
|
|
1644
|
+
return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: cn(badgeVariants({ variant }), className), ...props });
|
|
1645
|
+
}
|
|
1646
|
+
|
|
1647
|
+
// src/components/primitives/checkbox.tsx
|
|
1648
|
+
var React14 = __toESM(require("react"), 1);
|
|
1649
|
+
var import_lucide_react13 = require("lucide-react");
|
|
1650
|
+
var import_jsx_runtime34 = require("react/jsx-runtime");
|
|
1651
|
+
var Checkbox = React14.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("span", { className: "relative inline-flex h-4 w-4 shrink-0", children: [
|
|
1652
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
1653
|
+
"input",
|
|
1654
|
+
{
|
|
1655
|
+
ref,
|
|
1656
|
+
type: "checkbox",
|
|
1657
|
+
className: cn(
|
|
1658
|
+
"peer absolute inset-0 h-4 w-4 cursor-pointer appearance-none rounded-[4px] border border-input bg-background shadow-sm ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 checked:border-primary checked:bg-primary",
|
|
1659
|
+
className
|
|
1660
|
+
),
|
|
1661
|
+
...props
|
|
1662
|
+
}
|
|
1663
|
+
),
|
|
1664
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
1665
|
+
import_lucide_react13.Check,
|
|
1666
|
+
{
|
|
1667
|
+
"aria-hidden": "true",
|
|
1668
|
+
className: "pointer-events-none absolute left-1/2 top-1/2 h-3 w-3 -translate-x-1/2 -translate-y-1/2 text-primary-foreground opacity-0 transition-opacity peer-checked:opacity-100"
|
|
1669
|
+
}
|
|
1670
|
+
)
|
|
1671
|
+
] }));
|
|
1672
|
+
Checkbox.displayName = "Checkbox";
|
|
1673
|
+
function CheckboxField({ id, label, description, containerClassName, className, ...props }) {
|
|
1674
|
+
const generatedId = React14.useId();
|
|
1675
|
+
const inputId = id ?? generatedId;
|
|
1676
|
+
return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
|
|
1677
|
+
"label",
|
|
1678
|
+
{
|
|
1679
|
+
htmlFor: inputId,
|
|
1680
|
+
className: cn("flex items-center gap-3 rounded-lg border border-border bg-card p-3 transition-colors hover:bg-accent/30", containerClassName),
|
|
1681
|
+
children: [
|
|
1682
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(Checkbox, { id: inputId, className, ...props }),
|
|
1683
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("span", { className: "grid gap-1", children: [
|
|
1684
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { className: "text-sm font-medium text-foreground", children: label }),
|
|
1685
|
+
description ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { className: "text-xs text-muted-foreground", children: description }) : null
|
|
1686
|
+
] })
|
|
1687
|
+
]
|
|
1688
|
+
}
|
|
1689
|
+
);
|
|
1690
|
+
}
|
|
1691
|
+
|
|
1692
|
+
// src/components/primitives/label.tsx
|
|
1693
|
+
var React15 = __toESM(require("react"), 1);
|
|
1694
|
+
var LabelPrimitive = __toESM(require("@radix-ui/react-label"), 1);
|
|
1695
|
+
var import_class_variance_authority6 = require("class-variance-authority");
|
|
1696
|
+
var import_jsx_runtime35 = require("react/jsx-runtime");
|
|
1697
|
+
var labelVariants = (0, import_class_variance_authority6.cva)("text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70");
|
|
1698
|
+
var Label3 = React15.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(LabelPrimitive.Root, { ref, className: cn(labelVariants(), className), ...props }));
|
|
1699
|
+
Label3.displayName = LabelPrimitive.Root.displayName;
|
|
1700
|
+
|
|
1701
|
+
// src/components/primitives/radio-group.tsx
|
|
1702
|
+
var React16 = __toESM(require("react"), 1);
|
|
1703
|
+
var import_jsx_runtime36 = require("react/jsx-runtime");
|
|
1704
|
+
var RadioGroup2 = React16.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { ref, role: "radiogroup", className: cn("grid gap-3", className), ...props }));
|
|
1705
|
+
RadioGroup2.displayName = "RadioGroup";
|
|
1706
|
+
var RadioGroupItem = React16.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("span", { className: "relative inline-flex h-4 w-4 shrink-0", children: [
|
|
1707
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
1708
|
+
"input",
|
|
1709
|
+
{
|
|
1710
|
+
ref,
|
|
1711
|
+
type: "radio",
|
|
1712
|
+
className: cn(
|
|
1713
|
+
"peer absolute inset-0 h-4 w-4 cursor-pointer appearance-none rounded-full border border-input bg-background shadow-sm ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 checked:border-primary",
|
|
1714
|
+
className
|
|
1715
|
+
),
|
|
1716
|
+
...props
|
|
1717
|
+
}
|
|
1718
|
+
),
|
|
1719
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
1720
|
+
"span",
|
|
1721
|
+
{
|
|
1722
|
+
"aria-hidden": "true",
|
|
1723
|
+
className: "pointer-events-none absolute left-1/2 top-1/2 h-2 w-2 -translate-x-1/2 -translate-y-1/2 rounded-full bg-primary opacity-0 transition-opacity peer-checked:opacity-100"
|
|
1724
|
+
}
|
|
1725
|
+
)
|
|
1726
|
+
] }));
|
|
1727
|
+
RadioGroupItem.displayName = "RadioGroupItem";
|
|
1728
|
+
function RadioField({ id, label, description, containerClassName, className, ...props }) {
|
|
1729
|
+
const generatedId = React16.useId();
|
|
1730
|
+
const inputId = id ?? generatedId;
|
|
1731
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
|
|
1732
|
+
"label",
|
|
1733
|
+
{
|
|
1734
|
+
htmlFor: inputId,
|
|
1735
|
+
className: cn("flex items-center gap-3 rounded-lg border border-border bg-card p-3 transition-colors hover:bg-accent/30", containerClassName),
|
|
1736
|
+
children: [
|
|
1737
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(RadioGroupItem, { id: inputId, className, ...props }),
|
|
1738
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("span", { className: "grid gap-1", children: [
|
|
1739
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { className: "text-sm font-medium text-foreground", children: label }),
|
|
1740
|
+
description ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { className: "text-xs text-muted-foreground", children: description }) : null
|
|
1741
|
+
] })
|
|
1742
|
+
]
|
|
1743
|
+
}
|
|
1744
|
+
);
|
|
1745
|
+
}
|
|
1746
|
+
|
|
1747
|
+
// src/components/primitives/separator.tsx
|
|
1748
|
+
var React17 = __toESM(require("react"), 1);
|
|
1749
|
+
var SeparatorPrimitive = __toESM(require("@radix-ui/react-separator"), 1);
|
|
1750
|
+
var import_jsx_runtime37 = require("react/jsx-runtime");
|
|
1751
|
+
var Separator3 = React17.forwardRef(({ className, orientation = "horizontal", decorative = true, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
1752
|
+
SeparatorPrimitive.Root,
|
|
1753
|
+
{
|
|
1754
|
+
ref,
|
|
1755
|
+
decorative,
|
|
1756
|
+
orientation,
|
|
1757
|
+
className: cn("shrink-0 bg-border", orientation === "horizontal" ? "h-[1px] w-full" : "h-full w-[1px]", className),
|
|
1758
|
+
...props
|
|
1759
|
+
}
|
|
1760
|
+
));
|
|
1761
|
+
Separator3.displayName = SeparatorPrimitive.Root.displayName;
|
|
1762
|
+
|
|
1763
|
+
// src/components/primitives/switch.tsx
|
|
1764
|
+
var React18 = __toESM(require("react"), 1);
|
|
1765
|
+
var import_jsx_runtime38 = require("react/jsx-runtime");
|
|
1766
|
+
var Switch = React18.forwardRef(({ className, size = "default", ...props }, ref) => {
|
|
1767
|
+
const isSm = size === "sm";
|
|
1768
|
+
return /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(
|
|
1769
|
+
"span",
|
|
1770
|
+
{
|
|
1771
|
+
className: cn(
|
|
1772
|
+
"relative inline-flex shrink-0",
|
|
1773
|
+
isSm ? "h-4 w-7" : "h-6 w-10"
|
|
1774
|
+
),
|
|
1775
|
+
children: [
|
|
1776
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
1777
|
+
"input",
|
|
1778
|
+
{
|
|
1779
|
+
ref,
|
|
1780
|
+
type: "checkbox",
|
|
1781
|
+
role: "switch",
|
|
1782
|
+
className: cn(
|
|
1783
|
+
"peer absolute inset-0 cursor-pointer appearance-none rounded-full border border-input bg-input",
|
|
1784
|
+
"transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
|
|
1785
|
+
"disabled:cursor-not-allowed disabled:opacity-50",
|
|
1786
|
+
"checked:border-primary checked:bg-primary",
|
|
1787
|
+
className
|
|
1788
|
+
),
|
|
1789
|
+
...props
|
|
1790
|
+
}
|
|
1791
|
+
),
|
|
1792
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
1793
|
+
"span",
|
|
1794
|
+
{
|
|
1795
|
+
"aria-hidden": "true",
|
|
1796
|
+
className: cn(
|
|
1797
|
+
"pointer-events-none absolute rounded-full bg-background shadow-sm transition-transform",
|
|
1798
|
+
isSm ? "top-0.5 left-0.5 h-3 w-3 peer-checked:translate-x-3" : "top-1 left-1 h-4 w-4 peer-checked:translate-x-4"
|
|
1799
|
+
)
|
|
1800
|
+
}
|
|
1801
|
+
)
|
|
1802
|
+
]
|
|
1803
|
+
}
|
|
1804
|
+
);
|
|
1805
|
+
});
|
|
1806
|
+
Switch.displayName = "Switch";
|
|
1807
|
+
function SwitchField({ id, label, description, containerClassName, size, className, ...props }) {
|
|
1808
|
+
const generatedId = React18.useId();
|
|
1809
|
+
const inputId = id ?? generatedId;
|
|
1810
|
+
return /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(
|
|
1811
|
+
"label",
|
|
1812
|
+
{
|
|
1813
|
+
htmlFor: inputId,
|
|
1814
|
+
className: cn(
|
|
1815
|
+
"flex cursor-pointer items-center justify-between gap-4 rounded-lg border border-border bg-card p-3 transition-colors hover:bg-accent/30",
|
|
1816
|
+
props.disabled && "cursor-not-allowed opacity-50 hover:bg-card",
|
|
1817
|
+
containerClassName
|
|
1818
|
+
),
|
|
1819
|
+
children: [
|
|
1820
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("span", { className: "grid gap-0.5", children: [
|
|
1821
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { className: "text-sm font-medium text-foreground", children: label }),
|
|
1822
|
+
description ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { className: "text-xs text-muted-foreground", children: description }) : null
|
|
1823
|
+
] }),
|
|
1824
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(Switch, { id: inputId, size, className, ...props })
|
|
1825
|
+
]
|
|
1826
|
+
}
|
|
1827
|
+
);
|
|
1828
|
+
}
|
|
1829
|
+
|
|
1830
|
+
// src/components/primitives/textarea.tsx
|
|
1831
|
+
var React19 = __toESM(require("react"), 1);
|
|
1832
|
+
var import_jsx_runtime39 = require("react/jsx-runtime");
|
|
1833
|
+
var Textarea = React19.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
1834
|
+
"textarea",
|
|
1835
|
+
{
|
|
1836
|
+
ref,
|
|
1837
|
+
className: cn(
|
|
1838
|
+
"flex min-h-24 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
|
|
1839
|
+
className
|
|
1840
|
+
),
|
|
1841
|
+
...props
|
|
1842
|
+
}
|
|
1843
|
+
));
|
|
1844
|
+
Textarea.displayName = "Textarea";
|
|
1845
|
+
|
|
1846
|
+
// src/components/tables/data-table.tsx
|
|
1847
|
+
var import_react4 = require("react");
|
|
1848
|
+
var import_lucide_react14 = require("lucide-react");
|
|
1849
|
+
var import_jsx_runtime40 = require("react/jsx-runtime");
|
|
1850
|
+
function getCellContent(row, column) {
|
|
1851
|
+
if (column.render) {
|
|
1852
|
+
return column.render(row);
|
|
1853
|
+
}
|
|
1854
|
+
const value = row[column.key];
|
|
1855
|
+
if (value === null || value === void 0) {
|
|
1856
|
+
return /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("span", { className: "text-muted-foreground/40", children: "-" });
|
|
1857
|
+
}
|
|
1858
|
+
if (typeof value === "boolean") {
|
|
1859
|
+
return value ? "Yes" : "No";
|
|
1860
|
+
}
|
|
1861
|
+
return String(value);
|
|
1862
|
+
}
|
|
1863
|
+
var SKELETON_ROWS = 5;
|
|
1864
|
+
function DataTable({
|
|
1865
|
+
data,
|
|
1866
|
+
columns,
|
|
1867
|
+
isLoading = false,
|
|
1868
|
+
actions,
|
|
1869
|
+
emptyMessage = "No records found",
|
|
1870
|
+
pageSize = 10
|
|
1871
|
+
}) {
|
|
1872
|
+
const [search, setSearch] = (0, import_react4.useState)("");
|
|
1873
|
+
const [page, setPage] = (0, import_react4.useState)(0);
|
|
1874
|
+
const filtered = (0, import_react4.useMemo)(() => {
|
|
1875
|
+
const query = search.toLowerCase().trim();
|
|
1876
|
+
if (!query) {
|
|
1877
|
+
return data;
|
|
1878
|
+
}
|
|
1879
|
+
return data.filter(
|
|
1880
|
+
(row) => Object.values(row).some(
|
|
1881
|
+
(value) => value != null && String(value).toLowerCase().includes(query)
|
|
1882
|
+
)
|
|
1883
|
+
);
|
|
1884
|
+
}, [data, search]);
|
|
1885
|
+
const totalPages = Math.max(1, Math.ceil(filtered.length / pageSize));
|
|
1886
|
+
const currentPage = Math.min(page, totalPages - 1);
|
|
1887
|
+
const paginated = filtered.slice(currentPage * pageSize, (currentPage + 1) * pageSize);
|
|
1888
|
+
const mobileColumns = columns.filter((column) => !column.mobileHide);
|
|
1889
|
+
function handleSearch(value) {
|
|
1890
|
+
setSearch(value);
|
|
1891
|
+
setPage(0);
|
|
1892
|
+
}
|
|
1893
|
+
return /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { className: "space-y-4", children: [
|
|
1894
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { className: "relative", children: [
|
|
1895
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_lucide_react14.Search, { className: "pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" }),
|
|
1896
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
1897
|
+
Input,
|
|
1898
|
+
{
|
|
1899
|
+
placeholder: "Search...",
|
|
1900
|
+
value: search,
|
|
1901
|
+
onChange: (event) => handleSearch(event.target.value),
|
|
1902
|
+
className: "pl-9"
|
|
1903
|
+
}
|
|
1904
|
+
)
|
|
1905
|
+
] }),
|
|
1906
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)("div", { className: "hidden rounded-lg border md:block", children: /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(Table, { children: [
|
|
1907
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(TableHeader, { children: /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(TableRow, { children: [
|
|
1908
|
+
columns.map((column) => /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(TableHead, { children: column.label }, String(column.key))),
|
|
1909
|
+
actions ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(TableHead, { className: "w-[100px] text-right", children: "Actions" }) : null
|
|
1910
|
+
] }) }),
|
|
1911
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(TableBody, { children: isLoading ? Array.from({ length: SKELETON_ROWS }).map((_, index) => /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(TableRow, { children: [
|
|
1912
|
+
columns.map((column) => /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(TableCell, { children: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(Skeleton, { className: "h-4 w-full" }) }, String(column.key))),
|
|
1913
|
+
actions ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(TableCell, { children: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(Skeleton, { className: "ml-auto h-8 w-20" }) }) : null
|
|
1914
|
+
] }, index)) : paginated.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(TableRow, { children: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(TableCell, { colSpan: columns.length + (actions ? 1 : 0), className: "py-12 text-center text-muted-foreground", children: emptyMessage }) }) : paginated.map((row, index) => /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(TableRow, { children: [
|
|
1915
|
+
columns.map((column) => /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(TableCell, { children: getCellContent(row, column) }, String(column.key))),
|
|
1916
|
+
actions ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(TableCell, { children: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("div", { className: "flex justify-end gap-1.5", children: actions(row) }) }) : null
|
|
1917
|
+
] }, index)) })
|
|
1918
|
+
] }) }),
|
|
1919
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)("div", { className: "space-y-3 md:hidden", children: isLoading ? Array.from({ length: SKELETON_ROWS }).map((_, index) => /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(Card, { children: /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(CardContent, { className: "space-y-2 p-4", children: [
|
|
1920
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(Skeleton, { className: "h-5 w-1/2" }),
|
|
1921
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(Skeleton, { className: "h-4 w-2/3" }),
|
|
1922
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(Skeleton, { className: "h-4 w-1/3" })
|
|
1923
|
+
] }) }, index)) : paginated.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("p", { className: "py-10 text-center text-muted-foreground", children: emptyMessage }) : paginated.map((row, index) => /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(Card, { children: /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(CardContent, { className: "space-y-3 p-4", children: [
|
|
1924
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)("div", { className: "space-y-1.5", children: mobileColumns.map((column, mobileIndex) => /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(
|
|
1925
|
+
"div",
|
|
1926
|
+
{
|
|
1927
|
+
className: cn(
|
|
1928
|
+
"flex items-center gap-1.5",
|
|
1929
|
+
mobileIndex === 0 ? "text-sm font-medium text-foreground" : "text-xs text-muted-foreground"
|
|
1930
|
+
),
|
|
1931
|
+
children: [
|
|
1932
|
+
mobileIndex > 0 ? /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("span", { className: "shrink-0 font-medium text-foreground/50", children: [
|
|
1933
|
+
column.label,
|
|
1934
|
+
":"
|
|
1935
|
+
] }) : null,
|
|
1936
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)("span", { className: "truncate", children: getCellContent(row, column) })
|
|
1937
|
+
]
|
|
1938
|
+
},
|
|
1939
|
+
String(column.key)
|
|
1940
|
+
)) }),
|
|
1941
|
+
actions ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("div", { className: "flex gap-2 border-t border-border pt-2", children: actions(row) }) : null
|
|
1942
|
+
] }) }, index)) }),
|
|
1943
|
+
!isLoading && filtered.length > pageSize ? /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
1944
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("span", { className: "text-sm text-muted-foreground", children: [
|
|
1945
|
+
filtered.length,
|
|
1946
|
+
" records \xB7 Page ",
|
|
1947
|
+
currentPage + 1,
|
|
1948
|
+
" of ",
|
|
1949
|
+
totalPages
|
|
1950
|
+
] }),
|
|
1951
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { className: "flex gap-1", children: [
|
|
1952
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
1953
|
+
Button,
|
|
1954
|
+
{
|
|
1955
|
+
variant: "outline",
|
|
1956
|
+
size: "icon",
|
|
1957
|
+
className: "h-8 w-8",
|
|
1958
|
+
onClick: () => setPage((previous) => Math.max(0, previous - 1)),
|
|
1959
|
+
disabled: currentPage === 0,
|
|
1960
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_lucide_react14.ChevronLeft, { className: "h-4 w-4" })
|
|
1961
|
+
}
|
|
1962
|
+
),
|
|
1963
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
1964
|
+
Button,
|
|
1965
|
+
{
|
|
1966
|
+
variant: "outline",
|
|
1967
|
+
size: "icon",
|
|
1968
|
+
className: "h-8 w-8",
|
|
1969
|
+
onClick: () => setPage((previous) => Math.min(totalPages - 1, previous + 1)),
|
|
1970
|
+
disabled: currentPage >= totalPages - 1,
|
|
1971
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_lucide_react14.ChevronRight, { className: "h-4 w-4" })
|
|
1972
|
+
}
|
|
1973
|
+
)
|
|
1974
|
+
] })
|
|
1975
|
+
] }) : null
|
|
1976
|
+
] });
|
|
1977
|
+
}
|
|
1978
|
+
|
|
1979
|
+
// src/components/tables/table-row-actions.tsx
|
|
1980
|
+
var import_lucide_react15 = require("lucide-react");
|
|
1981
|
+
var import_jsx_runtime41 = require("react/jsx-runtime");
|
|
1982
|
+
function TableRowActions({ className, label = "Abrir acciones", menuLabel = "Acciones", items }) {
|
|
1983
|
+
return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(DropdownMenu, { children: [
|
|
1984
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(Button, { variant: "ghost", size: "icon", className: cn("h-8 w-8 shadow-none", className), "aria-label": label, children: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_lucide_react15.MoreHorizontal, { className: "h-4 w-4" }) }) }),
|
|
1985
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(DropdownMenuContent, { align: "end", className: "w-48", children: [
|
|
1986
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(DropdownMenuLabel, { children: menuLabel }),
|
|
1987
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(DropdownMenuSeparator, {}),
|
|
1988
|
+
items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(
|
|
1989
|
+
DropdownMenuItem,
|
|
1990
|
+
{
|
|
1991
|
+
disabled: item.disabled,
|
|
1992
|
+
onSelect: item.onSelect,
|
|
1993
|
+
className: cn(item.destructive && "text-destructive focus:bg-destructive/10 focus:text-destructive"),
|
|
1994
|
+
children: [
|
|
1995
|
+
item.icon,
|
|
1996
|
+
item.label,
|
|
1997
|
+
item.shortcut ? /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(DropdownMenuShortcut, { children: item.shortcut }) : null
|
|
1998
|
+
]
|
|
1999
|
+
},
|
|
2000
|
+
item.label
|
|
2001
|
+
))
|
|
2002
|
+
] })
|
|
2003
|
+
] });
|
|
2004
|
+
}
|
|
2005
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
2006
|
+
0 && (module.exports = {
|
|
2007
|
+
Alert,
|
|
2008
|
+
AlertDescription,
|
|
2009
|
+
AlertTitle,
|
|
2010
|
+
AppShell,
|
|
2011
|
+
Avatar,
|
|
2012
|
+
AvatarFallback,
|
|
2013
|
+
AvatarGroup,
|
|
2014
|
+
AvatarImage,
|
|
2015
|
+
Badge,
|
|
2016
|
+
BrandLogo,
|
|
2017
|
+
Breadcrumb,
|
|
2018
|
+
BreadcrumbEllipsis,
|
|
2019
|
+
BreadcrumbItem,
|
|
2020
|
+
BreadcrumbLink,
|
|
2021
|
+
BreadcrumbList,
|
|
2022
|
+
BreadcrumbPage,
|
|
2023
|
+
BreadcrumbSeparator,
|
|
2024
|
+
Button,
|
|
2025
|
+
Card,
|
|
2026
|
+
CardContent,
|
|
2027
|
+
CardDescription,
|
|
2028
|
+
CardFooter,
|
|
2029
|
+
CardHeader,
|
|
2030
|
+
CardTitle,
|
|
2031
|
+
CenteredIconCard,
|
|
2032
|
+
Checkbox,
|
|
2033
|
+
CheckboxField,
|
|
2034
|
+
ClickableCard,
|
|
2035
|
+
DataTable,
|
|
2036
|
+
Dialog,
|
|
2037
|
+
DialogClose,
|
|
2038
|
+
DialogContent,
|
|
2039
|
+
DialogDescription,
|
|
2040
|
+
DialogFooter,
|
|
2041
|
+
DialogHeader,
|
|
2042
|
+
DialogOverlay,
|
|
2043
|
+
DialogPortal,
|
|
2044
|
+
DialogTitle,
|
|
2045
|
+
DialogTrigger,
|
|
2046
|
+
Drawer,
|
|
2047
|
+
DrawerClose,
|
|
2048
|
+
DrawerContent,
|
|
2049
|
+
DrawerDescription,
|
|
2050
|
+
DrawerFooter,
|
|
2051
|
+
DrawerHeader,
|
|
2052
|
+
DrawerOverlay,
|
|
2053
|
+
DrawerPortal,
|
|
2054
|
+
DrawerTitle,
|
|
2055
|
+
DrawerTrigger,
|
|
2056
|
+
DropdownMenu,
|
|
2057
|
+
DropdownMenuCheckboxItem,
|
|
2058
|
+
DropdownMenuContent,
|
|
2059
|
+
DropdownMenuGroup,
|
|
2060
|
+
DropdownMenuItem,
|
|
2061
|
+
DropdownMenuLabel,
|
|
2062
|
+
DropdownMenuPortal,
|
|
2063
|
+
DropdownMenuRadioGroup,
|
|
2064
|
+
DropdownMenuRadioItem,
|
|
2065
|
+
DropdownMenuSeparator,
|
|
2066
|
+
DropdownMenuShortcut,
|
|
2067
|
+
DropdownMenuSub,
|
|
2068
|
+
DropdownMenuSubContent,
|
|
2069
|
+
DropdownMenuSubTrigger,
|
|
2070
|
+
DropdownMenuTrigger,
|
|
2071
|
+
FeatureIcon,
|
|
2072
|
+
FormSection,
|
|
2073
|
+
Input,
|
|
2074
|
+
Label,
|
|
2075
|
+
LoadingCard,
|
|
2076
|
+
LoadingState,
|
|
2077
|
+
LoadingTableRows,
|
|
2078
|
+
ModuleIconButton,
|
|
2079
|
+
Navbar,
|
|
2080
|
+
NotificationAction,
|
|
2081
|
+
NotificationMessage,
|
|
2082
|
+
PageBreadcrumb,
|
|
2083
|
+
PageHeader,
|
|
2084
|
+
ProfileAvatar,
|
|
2085
|
+
ProfileAvatarRow,
|
|
2086
|
+
RadioField,
|
|
2087
|
+
RadioGroup,
|
|
2088
|
+
RadioGroupItem,
|
|
2089
|
+
SearchableSelect,
|
|
2090
|
+
Select,
|
|
2091
|
+
SelectContent,
|
|
2092
|
+
SelectGroup,
|
|
2093
|
+
SelectItem,
|
|
2094
|
+
SelectLabel,
|
|
2095
|
+
SelectScrollDownButton,
|
|
2096
|
+
SelectScrollUpButton,
|
|
2097
|
+
SelectSeparator,
|
|
2098
|
+
SelectTrigger,
|
|
2099
|
+
SelectValue,
|
|
2100
|
+
Separator,
|
|
2101
|
+
Sheet,
|
|
2102
|
+
SheetClose,
|
|
2103
|
+
SheetContent,
|
|
2104
|
+
SheetDescription,
|
|
2105
|
+
SheetFooter,
|
|
2106
|
+
SheetHeader,
|
|
2107
|
+
SheetOverlay,
|
|
2108
|
+
SheetPortal,
|
|
2109
|
+
SheetTitle,
|
|
2110
|
+
SheetTrigger,
|
|
2111
|
+
Sidebar,
|
|
2112
|
+
Skeleton,
|
|
2113
|
+
Spinner,
|
|
2114
|
+
StatusBadge,
|
|
2115
|
+
Steps,
|
|
2116
|
+
Switch,
|
|
2117
|
+
SwitchField,
|
|
2118
|
+
Table,
|
|
2119
|
+
TableBody,
|
|
2120
|
+
TableCaption,
|
|
2121
|
+
TableCell,
|
|
2122
|
+
TableFooter,
|
|
2123
|
+
TableHead,
|
|
2124
|
+
TableHeader,
|
|
2125
|
+
TableRow,
|
|
2126
|
+
TableRowActions,
|
|
2127
|
+
Textarea,
|
|
2128
|
+
ThemeProvider,
|
|
2129
|
+
ThemeToggle,
|
|
2130
|
+
Toaster,
|
|
2131
|
+
Typography,
|
|
2132
|
+
badgeVariants,
|
|
2133
|
+
buttonVariants,
|
|
2134
|
+
cn,
|
|
2135
|
+
notify,
|
|
2136
|
+
useTheme
|
|
2137
|
+
});
|