@webdevarif/dashui 0.1.8 → 0.2.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.d.mts +144 -1
- package/dist/index.d.ts +144 -1
- package/dist/index.js +1086 -131
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1078 -133
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -2
package/dist/index.js
CHANGED
|
@@ -50,6 +50,7 @@ __export(index_exports, {
|
|
|
50
50
|
CardTitle: () => CardTitle,
|
|
51
51
|
Checkbox: () => Checkbox,
|
|
52
52
|
ConfirmDialog: () => ConfirmDialog,
|
|
53
|
+
DashboardLayout: () => DashboardLayout,
|
|
53
54
|
DataTable: () => DataTable,
|
|
54
55
|
Dialog: () => Dialog,
|
|
55
56
|
DialogClose: () => DialogClose,
|
|
@@ -80,15 +81,22 @@ __export(index_exports, {
|
|
|
80
81
|
FormField: () => FormField,
|
|
81
82
|
FormLayout: () => FormLayout,
|
|
82
83
|
FormSection: () => FormSection,
|
|
84
|
+
ImagePickerField: () => ImagePickerField,
|
|
83
85
|
Input: () => Input,
|
|
84
86
|
Label: () => Label2,
|
|
85
87
|
LoadingSpinner: () => LoadingSpinner,
|
|
88
|
+
MediaCard: () => MediaCard,
|
|
89
|
+
MediaGrid: () => MediaGrid,
|
|
90
|
+
MediaPickerDialog: () => MediaPickerDialog,
|
|
91
|
+
NotificationBell: () => NotificationBell,
|
|
86
92
|
Page: () => Page,
|
|
87
93
|
PageSection: () => PageSection,
|
|
88
94
|
Pagination: () => Pagination,
|
|
95
|
+
PlanBadge: () => PlanBadge,
|
|
89
96
|
Popover: () => Popover,
|
|
90
97
|
PopoverContent: () => PopoverContent,
|
|
91
98
|
PopoverTrigger: () => PopoverTrigger,
|
|
99
|
+
SearchBar: () => SearchBar,
|
|
92
100
|
Select: () => Select,
|
|
93
101
|
SelectContent: () => SelectContent,
|
|
94
102
|
SelectGroup: () => SelectGroup,
|
|
@@ -103,13 +111,15 @@ __export(index_exports, {
|
|
|
103
111
|
Sidebar: () => Sidebar,
|
|
104
112
|
Skeleton: () => Skeleton2,
|
|
105
113
|
Stats: () => Stats,
|
|
114
|
+
StorageBar: () => StorageBar,
|
|
106
115
|
Switch: () => Switch,
|
|
107
116
|
Tabs: () => Tabs,
|
|
108
117
|
TabsContent: () => TabsContent,
|
|
109
118
|
TabsList: () => TabsList,
|
|
110
119
|
TabsTrigger: () => TabsTrigger,
|
|
111
120
|
Textarea: () => Textarea,
|
|
112
|
-
ThemeProvider: () =>
|
|
121
|
+
ThemeProvider: () => import_next_themes2.ThemeProvider,
|
|
122
|
+
ThemeToggle: () => ThemeToggle,
|
|
113
123
|
Tooltip: () => Tooltip,
|
|
114
124
|
TooltipContent: () => TooltipContent,
|
|
115
125
|
TooltipProvider: () => TooltipProvider,
|
|
@@ -120,7 +130,7 @@ __export(index_exports, {
|
|
|
120
130
|
cn: () => cn,
|
|
121
131
|
useDisclosure: () => useDisclosure,
|
|
122
132
|
usePagination: () => usePagination,
|
|
123
|
-
useTheme: () =>
|
|
133
|
+
useTheme: () => import_next_themes2.useTheme
|
|
124
134
|
});
|
|
125
135
|
module.exports = __toCommonJS(index_exports);
|
|
126
136
|
|
|
@@ -629,9 +639,9 @@ var SelectContent = React9.forwardRef(({ className, children, position = "popper
|
|
|
629
639
|
SelectPrimitive.Content,
|
|
630
640
|
{
|
|
631
641
|
ref,
|
|
642
|
+
style: { background: "#ffffff", border: "1px solid #e5e7eb", borderRadius: 10, boxShadow: "0 8px 32px rgba(0,0,0,0.12)", zIndex: 9999, overflow: "hidden" },
|
|
632
643
|
className: cn(
|
|
633
|
-
|
|
634
|
-
"relative z-50 max-h-96 min-w-[8rem] overflow-hidden",
|
|
644
|
+
"relative max-h-96 min-w-[8rem] overflow-hidden",
|
|
635
645
|
"rounded-lg border border-border bg-white text-foreground shadow-lg",
|
|
636
646
|
"dark:bg-zinc-900 dark:border-zinc-700",
|
|
637
647
|
"data-[state=open]:animate-in data-[state=closed]:animate-out",
|
|
@@ -1092,8 +1102,420 @@ function PageSection({
|
|
|
1092
1102
|
);
|
|
1093
1103
|
}
|
|
1094
1104
|
|
|
1095
|
-
// src/components/
|
|
1105
|
+
// src/components/layout/search-bar.tsx
|
|
1096
1106
|
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
1107
|
+
function SearchBar({
|
|
1108
|
+
value,
|
|
1109
|
+
onChange,
|
|
1110
|
+
placeholder = "Search\u2026",
|
|
1111
|
+
shortcut,
|
|
1112
|
+
className,
|
|
1113
|
+
width = "max-w-xs"
|
|
1114
|
+
}) {
|
|
1115
|
+
const shortcuts = shortcut ? shortcut.split(" ") : [];
|
|
1116
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: cn("relative flex items-center", width, className), children: [
|
|
1117
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
|
|
1118
|
+
"svg",
|
|
1119
|
+
{
|
|
1120
|
+
className: "pointer-events-none absolute left-2.5 h-3.5 w-3.5 text-muted-foreground",
|
|
1121
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
1122
|
+
viewBox: "0 0 24 24",
|
|
1123
|
+
fill: "none",
|
|
1124
|
+
stroke: "currentColor",
|
|
1125
|
+
strokeWidth: "2",
|
|
1126
|
+
strokeLinecap: "round",
|
|
1127
|
+
strokeLinejoin: "round",
|
|
1128
|
+
children: [
|
|
1129
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("circle", { cx: "11", cy: "11", r: "8" }),
|
|
1130
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("path", { d: "m21 21-4.35-4.35" })
|
|
1131
|
+
]
|
|
1132
|
+
}
|
|
1133
|
+
),
|
|
1134
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
1135
|
+
"input",
|
|
1136
|
+
{
|
|
1137
|
+
type: "search",
|
|
1138
|
+
value,
|
|
1139
|
+
onChange: (e) => onChange?.(e.target.value),
|
|
1140
|
+
placeholder,
|
|
1141
|
+
className: cn(
|
|
1142
|
+
"h-8 w-full rounded-lg border border-input bg-muted/50 pl-8 text-sm outline-none transition-colors",
|
|
1143
|
+
"placeholder:text-muted-foreground",
|
|
1144
|
+
"focus:border-primary focus:ring-1 focus:ring-primary",
|
|
1145
|
+
shortcut ? "pr-16" : "pr-3"
|
|
1146
|
+
)
|
|
1147
|
+
}
|
|
1148
|
+
),
|
|
1149
|
+
shortcuts.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "pointer-events-none absolute right-2 flex items-center gap-0.5", children: shortcuts.map((key, i) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
1150
|
+
"kbd",
|
|
1151
|
+
{
|
|
1152
|
+
className: "inline-flex h-5 items-center rounded border border-border bg-background px-1 font-mono text-[10px] text-muted-foreground",
|
|
1153
|
+
children: key
|
|
1154
|
+
},
|
|
1155
|
+
i
|
|
1156
|
+
)) })
|
|
1157
|
+
] });
|
|
1158
|
+
}
|
|
1159
|
+
|
|
1160
|
+
// src/components/layout/notification-bell.tsx
|
|
1161
|
+
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
1162
|
+
function NotificationBell({
|
|
1163
|
+
count = 0,
|
|
1164
|
+
onClick,
|
|
1165
|
+
className
|
|
1166
|
+
}) {
|
|
1167
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
1168
|
+
"button",
|
|
1169
|
+
{
|
|
1170
|
+
onClick,
|
|
1171
|
+
className: cn(
|
|
1172
|
+
"relative flex h-8 w-8 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground",
|
|
1173
|
+
className
|
|
1174
|
+
),
|
|
1175
|
+
"aria-label": count > 0 ? `${count} unread notifications` : "Notifications",
|
|
1176
|
+
children: [
|
|
1177
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
1178
|
+
"svg",
|
|
1179
|
+
{
|
|
1180
|
+
className: "h-4 w-4",
|
|
1181
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
1182
|
+
viewBox: "0 0 24 24",
|
|
1183
|
+
fill: "none",
|
|
1184
|
+
stroke: "currentColor",
|
|
1185
|
+
strokeWidth: "2",
|
|
1186
|
+
strokeLinecap: "round",
|
|
1187
|
+
strokeLinejoin: "round",
|
|
1188
|
+
children: [
|
|
1189
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("path", { d: "M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9" }),
|
|
1190
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("path", { d: "M10.3 21a1.94 1.94 0 0 0 3.4 0" })
|
|
1191
|
+
]
|
|
1192
|
+
}
|
|
1193
|
+
),
|
|
1194
|
+
count > 0 && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "absolute right-1.5 top-1.5 h-2 w-2 rounded-full bg-green-500" })
|
|
1195
|
+
]
|
|
1196
|
+
}
|
|
1197
|
+
);
|
|
1198
|
+
}
|
|
1199
|
+
|
|
1200
|
+
// src/components/layout/theme-toggle.tsx
|
|
1201
|
+
var React17 = __toESM(require("react"));
|
|
1202
|
+
var import_next_themes = require("next-themes");
|
|
1203
|
+
var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
1204
|
+
function ThemeToggle({ className }) {
|
|
1205
|
+
const { resolvedTheme, setTheme } = (0, import_next_themes.useTheme)();
|
|
1206
|
+
const [mounted, setMounted] = React17.useState(false);
|
|
1207
|
+
React17.useEffect(() => {
|
|
1208
|
+
setMounted(true);
|
|
1209
|
+
}, []);
|
|
1210
|
+
if (!mounted) {
|
|
1211
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
1212
|
+
"button",
|
|
1213
|
+
{
|
|
1214
|
+
className: cn(
|
|
1215
|
+
"flex h-8 w-8 items-center justify-center rounded-md text-muted-foreground",
|
|
1216
|
+
className
|
|
1217
|
+
),
|
|
1218
|
+
"aria-label": "Toggle theme",
|
|
1219
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "h-4 w-4" })
|
|
1220
|
+
}
|
|
1221
|
+
);
|
|
1222
|
+
}
|
|
1223
|
+
const isDark = resolvedTheme === "dark";
|
|
1224
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
1225
|
+
"button",
|
|
1226
|
+
{
|
|
1227
|
+
onClick: () => setTheme(isDark ? "light" : "dark"),
|
|
1228
|
+
className: cn(
|
|
1229
|
+
"flex h-8 w-8 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground",
|
|
1230
|
+
className
|
|
1231
|
+
),
|
|
1232
|
+
"aria-label": isDark ? "Switch to light mode" : "Switch to dark mode",
|
|
1233
|
+
children: isDark ? (
|
|
1234
|
+
/* Sun icon */
|
|
1235
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
|
|
1236
|
+
"svg",
|
|
1237
|
+
{
|
|
1238
|
+
className: "h-4 w-4",
|
|
1239
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
1240
|
+
viewBox: "0 0 24 24",
|
|
1241
|
+
fill: "none",
|
|
1242
|
+
stroke: "currentColor",
|
|
1243
|
+
strokeWidth: "2",
|
|
1244
|
+
strokeLinecap: "round",
|
|
1245
|
+
strokeLinejoin: "round",
|
|
1246
|
+
children: [
|
|
1247
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("circle", { cx: "12", cy: "12", r: "4" }),
|
|
1248
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("path", { d: "M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41" })
|
|
1249
|
+
]
|
|
1250
|
+
}
|
|
1251
|
+
)
|
|
1252
|
+
) : (
|
|
1253
|
+
/* Moon icon */
|
|
1254
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
1255
|
+
"svg",
|
|
1256
|
+
{
|
|
1257
|
+
className: "h-4 w-4",
|
|
1258
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
1259
|
+
viewBox: "0 0 24 24",
|
|
1260
|
+
fill: "none",
|
|
1261
|
+
stroke: "currentColor",
|
|
1262
|
+
strokeWidth: "2",
|
|
1263
|
+
strokeLinecap: "round",
|
|
1264
|
+
strokeLinejoin: "round",
|
|
1265
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("path", { d: "M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z" })
|
|
1266
|
+
}
|
|
1267
|
+
)
|
|
1268
|
+
)
|
|
1269
|
+
}
|
|
1270
|
+
);
|
|
1271
|
+
}
|
|
1272
|
+
|
|
1273
|
+
// src/components/layout/dashboard-layout.tsx
|
|
1274
|
+
var React18 = __toESM(require("react"));
|
|
1275
|
+
var import_jsx_runtime25 = require("react/jsx-runtime");
|
|
1276
|
+
function isActive(itemHref, activeHref) {
|
|
1277
|
+
if (!activeHref) return false;
|
|
1278
|
+
return activeHref === itemHref || activeHref.startsWith(itemHref + "/");
|
|
1279
|
+
}
|
|
1280
|
+
function NavItemRow({
|
|
1281
|
+
item,
|
|
1282
|
+
collapsed,
|
|
1283
|
+
activeHref,
|
|
1284
|
+
onNavigate,
|
|
1285
|
+
depth = 0
|
|
1286
|
+
}) {
|
|
1287
|
+
const active = isActive(item.href, activeHref);
|
|
1288
|
+
const hasChildren = item.children && item.children.length > 0;
|
|
1289
|
+
const childActive = hasChildren && item.children.some((c) => isActive(c.href, activeHref));
|
|
1290
|
+
const [open, setOpen] = React18.useState(active || childActive);
|
|
1291
|
+
const handleClick = (e) => {
|
|
1292
|
+
if (onNavigate) {
|
|
1293
|
+
e.preventDefault();
|
|
1294
|
+
onNavigate(item.href);
|
|
1295
|
+
}
|
|
1296
|
+
if (hasChildren) {
|
|
1297
|
+
e.preventDefault();
|
|
1298
|
+
setOpen((v) => !v);
|
|
1299
|
+
}
|
|
1300
|
+
};
|
|
1301
|
+
const rowClasses = cn(
|
|
1302
|
+
"flex w-full items-center gap-2.5 rounded-md px-3 py-2 text-sm font-medium transition-colors",
|
|
1303
|
+
active ? "bg-sidebar-accent text-sidebar-accent-foreground" : "text-sidebar-foreground hover:bg-sidebar-accent/60 hover:text-sidebar-accent-foreground",
|
|
1304
|
+
depth > 0 && "py-1.5"
|
|
1305
|
+
);
|
|
1306
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { children: [
|
|
1307
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
|
|
1308
|
+
"a",
|
|
1309
|
+
{
|
|
1310
|
+
href: item.href,
|
|
1311
|
+
onClick: hasChildren ? (e) => {
|
|
1312
|
+
e.preventDefault();
|
|
1313
|
+
setOpen((v) => !v);
|
|
1314
|
+
} : onNavigate ? handleClick : void 0,
|
|
1315
|
+
className: rowClasses,
|
|
1316
|
+
title: collapsed ? item.label : void 0,
|
|
1317
|
+
children: [
|
|
1318
|
+
item.icon && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "flex h-4 w-4 shrink-0 items-center justify-center", children: item.icon }),
|
|
1319
|
+
!collapsed && /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_jsx_runtime25.Fragment, { children: [
|
|
1320
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "flex-1 truncate", children: item.label }),
|
|
1321
|
+
item.badge !== void 0 && !hasChildren && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "rounded-full bg-primary/15 px-2 py-0.5 text-[11px] font-semibold text-primary", children: item.badge }),
|
|
1322
|
+
hasChildren && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
1323
|
+
"svg",
|
|
1324
|
+
{
|
|
1325
|
+
className: cn("h-3.5 w-3.5 shrink-0 transition-transform text-sidebar-foreground/50", open && "rotate-180"),
|
|
1326
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
1327
|
+
viewBox: "0 0 24 24",
|
|
1328
|
+
fill: "none",
|
|
1329
|
+
stroke: "currentColor",
|
|
1330
|
+
strokeWidth: "2",
|
|
1331
|
+
strokeLinecap: "round",
|
|
1332
|
+
strokeLinejoin: "round",
|
|
1333
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("path", { d: "m6 9 6 6 6-6" })
|
|
1334
|
+
}
|
|
1335
|
+
)
|
|
1336
|
+
] })
|
|
1337
|
+
]
|
|
1338
|
+
}
|
|
1339
|
+
),
|
|
1340
|
+
hasChildren && open && !collapsed && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "mt-0.5 ml-[22px] space-y-0.5 border-l border-sidebar-border/60 pl-3", children: item.children.map((child) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
1341
|
+
NavItemRow,
|
|
1342
|
+
{
|
|
1343
|
+
item: child,
|
|
1344
|
+
collapsed,
|
|
1345
|
+
activeHref,
|
|
1346
|
+
onNavigate,
|
|
1347
|
+
depth: depth + 1
|
|
1348
|
+
},
|
|
1349
|
+
child.href
|
|
1350
|
+
)) })
|
|
1351
|
+
] });
|
|
1352
|
+
}
|
|
1353
|
+
function UserAvatar({ user, size = "sm" }) {
|
|
1354
|
+
const initials = user.name.split(" ").map((n) => n[0]).join("").toUpperCase().slice(0, 2);
|
|
1355
|
+
const sizeClass = size === "md" ? "h-8 w-8 text-xs" : "h-7 w-7 text-[10px]";
|
|
1356
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: cn("flex shrink-0 items-center justify-center rounded-full bg-primary font-semibold text-primary-foreground overflow-hidden", sizeClass), children: user.avatar ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("img", { src: user.avatar, alt: user.name, className: "h-full w-full object-cover" }) : initials });
|
|
1357
|
+
}
|
|
1358
|
+
function DashboardLayout({
|
|
1359
|
+
logo,
|
|
1360
|
+
appName = "Dashboard",
|
|
1361
|
+
navItems,
|
|
1362
|
+
bottomNavItems,
|
|
1363
|
+
activeHref,
|
|
1364
|
+
onNavigate,
|
|
1365
|
+
searchPlaceholder,
|
|
1366
|
+
searchShortcut,
|
|
1367
|
+
notificationCount,
|
|
1368
|
+
onNotificationClick,
|
|
1369
|
+
user,
|
|
1370
|
+
onSignOut,
|
|
1371
|
+
children,
|
|
1372
|
+
defaultCollapsed = false,
|
|
1373
|
+
footerContent
|
|
1374
|
+
}) {
|
|
1375
|
+
const [collapsed, setCollapsed] = React18.useState(defaultCollapsed);
|
|
1376
|
+
const [userMenuOpen, setUserMenuOpen] = React18.useState(false);
|
|
1377
|
+
const [searchValue, setSearchValue] = React18.useState("");
|
|
1378
|
+
const userMenuRef = React18.useRef(null);
|
|
1379
|
+
React18.useEffect(() => {
|
|
1380
|
+
function handler(e) {
|
|
1381
|
+
if (userMenuRef.current && !userMenuRef.current.contains(e.target)) {
|
|
1382
|
+
setUserMenuOpen(false);
|
|
1383
|
+
}
|
|
1384
|
+
}
|
|
1385
|
+
document.addEventListener("mousedown", handler);
|
|
1386
|
+
return () => document.removeEventListener("mousedown", handler);
|
|
1387
|
+
}, []);
|
|
1388
|
+
const ToggleIcon = () => /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
|
|
1389
|
+
"svg",
|
|
1390
|
+
{
|
|
1391
|
+
className: "h-4 w-4",
|
|
1392
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
1393
|
+
viewBox: "0 0 24 24",
|
|
1394
|
+
fill: "none",
|
|
1395
|
+
stroke: "currentColor",
|
|
1396
|
+
strokeWidth: "2",
|
|
1397
|
+
strokeLinecap: "round",
|
|
1398
|
+
strokeLinejoin: "round",
|
|
1399
|
+
children: [
|
|
1400
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("line", { x1: "3", y1: "6", x2: "21", y2: "6" }),
|
|
1401
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("line", { x1: "3", y1: "12", x2: "21", y2: "12" }),
|
|
1402
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("line", { x1: "3", y1: "18", x2: "21", y2: "18" })
|
|
1403
|
+
]
|
|
1404
|
+
}
|
|
1405
|
+
);
|
|
1406
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex h-screen overflow-hidden bg-background", children: [
|
|
1407
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
|
|
1408
|
+
"aside",
|
|
1409
|
+
{
|
|
1410
|
+
className: cn(
|
|
1411
|
+
"flex shrink-0 flex-col border-r bg-sidebar transition-all duration-200 ease-in-out",
|
|
1412
|
+
collapsed ? "w-16" : "w-80"
|
|
1413
|
+
),
|
|
1414
|
+
children: [
|
|
1415
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "flex h-14 shrink-0 items-center border-b border-sidebar-border px-4", children: collapsed ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "flex h-8 w-8 items-center justify-center rounded-md bg-primary/10", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "text-sm font-bold text-primary", children: appName?.[0] ?? "D" }) }) : logo ?? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "text-base font-semibold text-sidebar-foreground", children: appName }) }),
|
|
1416
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("nav", { className: "flex-1 space-y-0.5 overflow-y-auto p-2", children: navItems.map((item) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
1417
|
+
NavItemRow,
|
|
1418
|
+
{
|
|
1419
|
+
item,
|
|
1420
|
+
collapsed,
|
|
1421
|
+
activeHref,
|
|
1422
|
+
onNavigate
|
|
1423
|
+
},
|
|
1424
|
+
item.href
|
|
1425
|
+
)) }),
|
|
1426
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "border-t border-sidebar-border p-2", children: [
|
|
1427
|
+
bottomNavItems && bottomNavItems.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "mb-2 space-y-0.5", children: bottomNavItems.map((item) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
1428
|
+
NavItemRow,
|
|
1429
|
+
{
|
|
1430
|
+
item,
|
|
1431
|
+
collapsed,
|
|
1432
|
+
activeHref,
|
|
1433
|
+
onNavigate
|
|
1434
|
+
},
|
|
1435
|
+
item.href
|
|
1436
|
+
)) }),
|
|
1437
|
+
footerContent && !collapsed && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "mb-2", children: footerContent }),
|
|
1438
|
+
user && /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "relative", ref: userMenuRef, children: [
|
|
1439
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
|
|
1440
|
+
"button",
|
|
1441
|
+
{
|
|
1442
|
+
onClick: () => setUserMenuOpen((v) => !v),
|
|
1443
|
+
className: "flex w-full items-center gap-2.5 rounded-md px-2 py-1.5 text-sm transition-colors hover:bg-sidebar-accent/60",
|
|
1444
|
+
children: [
|
|
1445
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(UserAvatar, { user }),
|
|
1446
|
+
!collapsed && /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex-1 overflow-hidden text-left", children: [
|
|
1447
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "truncate text-xs font-medium text-sidebar-foreground", children: user.name }),
|
|
1448
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "truncate text-[11px] text-sidebar-foreground/60", children: user.email })
|
|
1449
|
+
] })
|
|
1450
|
+
]
|
|
1451
|
+
}
|
|
1452
|
+
),
|
|
1453
|
+
userMenuOpen && /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: cn(
|
|
1454
|
+
"absolute bottom-full mb-1 z-50 min-w-[180px] rounded-md border bg-popover shadow-md",
|
|
1455
|
+
collapsed ? "left-full ml-2 bottom-0" : "left-0"
|
|
1456
|
+
), children: [
|
|
1457
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "px-3 py-2 border-b", children: [
|
|
1458
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("p", { className: "text-xs font-medium", children: user.name }),
|
|
1459
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("p", { className: "text-[11px] text-muted-foreground truncate", children: user.email })
|
|
1460
|
+
] }),
|
|
1461
|
+
onSignOut && /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
|
|
1462
|
+
"button",
|
|
1463
|
+
{
|
|
1464
|
+
onClick: () => {
|
|
1465
|
+
setUserMenuOpen(false);
|
|
1466
|
+
onSignOut();
|
|
1467
|
+
},
|
|
1468
|
+
className: "flex w-full items-center gap-2 px-3 py-2 text-sm text-destructive hover:bg-accent transition-colors",
|
|
1469
|
+
children: [
|
|
1470
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("svg", { className: "h-3.5 w-3.5", xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
1471
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("path", { d: "M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4" }),
|
|
1472
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("polyline", { points: "16 17 21 12 16 7" }),
|
|
1473
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("line", { x1: "21", y1: "12", x2: "9", y2: "12" })
|
|
1474
|
+
] }),
|
|
1475
|
+
"Sign out"
|
|
1476
|
+
]
|
|
1477
|
+
}
|
|
1478
|
+
)
|
|
1479
|
+
] })
|
|
1480
|
+
] })
|
|
1481
|
+
] })
|
|
1482
|
+
]
|
|
1483
|
+
}
|
|
1484
|
+
),
|
|
1485
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex flex-1 flex-col overflow-hidden", children: [
|
|
1486
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("header", { className: "flex h-14 shrink-0 items-center gap-3 border-b bg-background px-4", children: [
|
|
1487
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
1488
|
+
"button",
|
|
1489
|
+
{
|
|
1490
|
+
onClick: () => setCollapsed((v) => !v),
|
|
1491
|
+
className: "flex h-8 w-8 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground",
|
|
1492
|
+
"aria-label": "Toggle sidebar",
|
|
1493
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ToggleIcon, {})
|
|
1494
|
+
}
|
|
1495
|
+
),
|
|
1496
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "flex flex-1 items-center gap-2", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
1497
|
+
SearchBar,
|
|
1498
|
+
{
|
|
1499
|
+
value: searchValue,
|
|
1500
|
+
onChange: setSearchValue,
|
|
1501
|
+
placeholder: searchPlaceholder,
|
|
1502
|
+
shortcut: searchShortcut,
|
|
1503
|
+
width: "max-w-sm"
|
|
1504
|
+
}
|
|
1505
|
+
) }),
|
|
1506
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex items-center gap-1", children: [
|
|
1507
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ThemeToggle, {}),
|
|
1508
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(NotificationBell, { count: notificationCount, onClick: onNotificationClick }),
|
|
1509
|
+
user && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "ml-1", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(UserAvatar, { user, size: "md" }) })
|
|
1510
|
+
] })
|
|
1511
|
+
] }),
|
|
1512
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("main", { className: "flex-1 overflow-y-auto bg-muted/30 p-6", children })
|
|
1513
|
+
] })
|
|
1514
|
+
] });
|
|
1515
|
+
}
|
|
1516
|
+
|
|
1517
|
+
// src/components/data/data-table.tsx
|
|
1518
|
+
var import_jsx_runtime26 = require("react/jsx-runtime");
|
|
1097
1519
|
function DataTable({
|
|
1098
1520
|
columns,
|
|
1099
1521
|
data,
|
|
@@ -1125,17 +1547,17 @@ function DataTable({
|
|
|
1125
1547
|
}
|
|
1126
1548
|
}
|
|
1127
1549
|
const totalPages = pagination ? Math.ceil(pagination.total / pagination.pageSize) : 1;
|
|
1128
|
-
return /* @__PURE__ */ (0,
|
|
1129
|
-
selection && selection.selected.length > 0 && actions && /* @__PURE__ */ (0,
|
|
1130
|
-
/* @__PURE__ */ (0,
|
|
1550
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "space-y-4", children: [
|
|
1551
|
+
selection && selection.selected.length > 0 && actions && /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex items-center gap-2 rounded-md border bg-muted/50 p-2", children: [
|
|
1552
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("span", { className: "text-sm text-muted-foreground", children: [
|
|
1131
1553
|
selection.selected.length,
|
|
1132
1554
|
" selected"
|
|
1133
1555
|
] }),
|
|
1134
1556
|
actions
|
|
1135
1557
|
] }),
|
|
1136
|
-
/* @__PURE__ */ (0,
|
|
1137
|
-
/* @__PURE__ */ (0,
|
|
1138
|
-
selection && /* @__PURE__ */ (0,
|
|
1558
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "rounded-md border", children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "overflow-x-auto", children: /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("table", { className: "w-full text-sm", children: [
|
|
1559
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("tr", { className: "border-b bg-muted/50", children: [
|
|
1560
|
+
selection && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("th", { className: "w-12 px-4 py-3", children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
1139
1561
|
Checkbox,
|
|
1140
1562
|
{
|
|
1141
1563
|
checked: allSelected,
|
|
@@ -1147,7 +1569,7 @@ function DataTable({
|
|
|
1147
1569
|
onCheckedChange: toggleAll
|
|
1148
1570
|
}
|
|
1149
1571
|
) }),
|
|
1150
|
-
columns.map((col) => /* @__PURE__ */ (0,
|
|
1572
|
+
columns.map((col) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
1151
1573
|
"th",
|
|
1152
1574
|
{
|
|
1153
1575
|
className: "px-4 py-3 text-left font-medium text-muted-foreground",
|
|
@@ -1157,20 +1579,20 @@ function DataTable({
|
|
|
1157
1579
|
String(col.key)
|
|
1158
1580
|
))
|
|
1159
1581
|
] }) }),
|
|
1160
|
-
/* @__PURE__ */ (0,
|
|
1161
|
-
selection && /* @__PURE__ */ (0,
|
|
1162
|
-
columns.map((col) => /* @__PURE__ */ (0,
|
|
1163
|
-
] }, i)) : data.length === 0 ? /* @__PURE__ */ (0,
|
|
1582
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("tbody", { children: loading ? Array.from({ length: 5 }).map((_, i) => /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("tr", { className: "border-b", children: [
|
|
1583
|
+
selection && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("td", { className: "px-4 py-3", children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(Skeleton, { className: "h-4 w-4" }) }),
|
|
1584
|
+
columns.map((col) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("td", { className: "px-4 py-3", children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(Skeleton, { className: "h-4 w-24" }) }, String(col.key)))
|
|
1585
|
+
] }, i)) : data.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("tr", { children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
1164
1586
|
"td",
|
|
1165
1587
|
{
|
|
1166
1588
|
colSpan: columns.length + (selection ? 1 : 0),
|
|
1167
1589
|
className: "py-12 text-center",
|
|
1168
|
-
children: emptyState || /* @__PURE__ */ (0,
|
|
1590
|
+
children: emptyState || /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("p", { className: "text-muted-foreground", children: "No data found" })
|
|
1169
1591
|
}
|
|
1170
1592
|
) }) : data.map((row, idx) => {
|
|
1171
1593
|
const rowId = String(row[idKey] ?? idx);
|
|
1172
1594
|
const isSelected = selection?.selected.includes(rowId);
|
|
1173
|
-
return /* @__PURE__ */ (0,
|
|
1595
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
|
|
1174
1596
|
"tr",
|
|
1175
1597
|
{
|
|
1176
1598
|
className: cn(
|
|
@@ -1180,12 +1602,12 @@ function DataTable({
|
|
|
1180
1602
|
),
|
|
1181
1603
|
onClick: () => onRowClick?.(row),
|
|
1182
1604
|
children: [
|
|
1183
|
-
selection && /* @__PURE__ */ (0,
|
|
1605
|
+
selection && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
1184
1606
|
"td",
|
|
1185
1607
|
{
|
|
1186
1608
|
className: "px-4 py-3",
|
|
1187
1609
|
onClick: (e) => e.stopPropagation(),
|
|
1188
|
-
children: /* @__PURE__ */ (0,
|
|
1610
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
1189
1611
|
Checkbox,
|
|
1190
1612
|
{
|
|
1191
1613
|
checked: isSelected,
|
|
@@ -1194,15 +1616,15 @@ function DataTable({
|
|
|
1194
1616
|
)
|
|
1195
1617
|
}
|
|
1196
1618
|
),
|
|
1197
|
-
columns.map((col) => /* @__PURE__ */ (0,
|
|
1619
|
+
columns.map((col) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("td", { className: "px-4 py-3", children: col.cell ? col.cell(row) : String(row[col.key] ?? "") }, String(col.key)))
|
|
1198
1620
|
]
|
|
1199
1621
|
},
|
|
1200
1622
|
rowId
|
|
1201
1623
|
);
|
|
1202
1624
|
}) })
|
|
1203
1625
|
] }) }) }),
|
|
1204
|
-
pagination && totalPages > 1 && /* @__PURE__ */ (0,
|
|
1205
|
-
/* @__PURE__ */ (0,
|
|
1626
|
+
pagination && totalPages > 1 && /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex items-center justify-between px-2", children: [
|
|
1627
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "text-sm text-muted-foreground", children: [
|
|
1206
1628
|
"Page ",
|
|
1207
1629
|
pagination.page,
|
|
1208
1630
|
" of ",
|
|
@@ -1211,8 +1633,8 @@ function DataTable({
|
|
|
1211
1633
|
pagination.total,
|
|
1212
1634
|
" total)"
|
|
1213
1635
|
] }),
|
|
1214
|
-
/* @__PURE__ */ (0,
|
|
1215
|
-
/* @__PURE__ */ (0,
|
|
1636
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
1637
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
1216
1638
|
"button",
|
|
1217
1639
|
{
|
|
1218
1640
|
className: "rounded-md border px-3 py-1.5 text-sm disabled:opacity-50",
|
|
@@ -1221,7 +1643,7 @@ function DataTable({
|
|
|
1221
1643
|
children: "Previous"
|
|
1222
1644
|
}
|
|
1223
1645
|
),
|
|
1224
|
-
/* @__PURE__ */ (0,
|
|
1646
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
1225
1647
|
"button",
|
|
1226
1648
|
{
|
|
1227
1649
|
className: "rounded-md border px-3 py-1.5 text-sm disabled:opacity-50",
|
|
@@ -1236,7 +1658,7 @@ function DataTable({
|
|
|
1236
1658
|
}
|
|
1237
1659
|
|
|
1238
1660
|
// src/components/data/empty-state.tsx
|
|
1239
|
-
var
|
|
1661
|
+
var import_jsx_runtime27 = require("react/jsx-runtime");
|
|
1240
1662
|
function EmptyState({
|
|
1241
1663
|
icon: Icon2,
|
|
1242
1664
|
title,
|
|
@@ -1244,7 +1666,7 @@ function EmptyState({
|
|
|
1244
1666
|
action,
|
|
1245
1667
|
className
|
|
1246
1668
|
}) {
|
|
1247
|
-
return /* @__PURE__ */ (0,
|
|
1669
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
|
|
1248
1670
|
"div",
|
|
1249
1671
|
{
|
|
1250
1672
|
className: cn(
|
|
@@ -1252,26 +1674,26 @@ function EmptyState({
|
|
|
1252
1674
|
className
|
|
1253
1675
|
),
|
|
1254
1676
|
children: [
|
|
1255
|
-
Icon2 && /* @__PURE__ */ (0,
|
|
1256
|
-
/* @__PURE__ */ (0,
|
|
1257
|
-
description && /* @__PURE__ */ (0,
|
|
1258
|
-
action && /* @__PURE__ */ (0,
|
|
1677
|
+
Icon2 && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "mb-4 rounded-full bg-muted p-3", children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(Icon2, { className: "h-6 w-6 text-muted-foreground" }) }),
|
|
1678
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("h3", { className: "text-lg font-semibold", children: title }),
|
|
1679
|
+
description && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("p", { className: "mt-1 max-w-sm text-sm text-muted-foreground", children: description }),
|
|
1680
|
+
action && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "mt-4", children: action })
|
|
1259
1681
|
]
|
|
1260
1682
|
}
|
|
1261
1683
|
);
|
|
1262
1684
|
}
|
|
1263
1685
|
|
|
1264
1686
|
// src/components/data/pagination.tsx
|
|
1265
|
-
var
|
|
1687
|
+
var React19 = __toESM(require("react"));
|
|
1266
1688
|
var import_lucide_react8 = require("lucide-react");
|
|
1267
|
-
var
|
|
1689
|
+
var import_jsx_runtime28 = require("react/jsx-runtime");
|
|
1268
1690
|
function Pagination({
|
|
1269
1691
|
page,
|
|
1270
1692
|
totalPages,
|
|
1271
1693
|
onPageChange,
|
|
1272
1694
|
className
|
|
1273
1695
|
}) {
|
|
1274
|
-
const pages =
|
|
1696
|
+
const pages = React19.useMemo(() => {
|
|
1275
1697
|
const items = [];
|
|
1276
1698
|
if (totalPages <= 7) {
|
|
1277
1699
|
for (let i = 1; i <= totalPages; i++) items.push(i);
|
|
@@ -1287,18 +1709,18 @@ function Pagination({
|
|
|
1287
1709
|
return items;
|
|
1288
1710
|
}, [page, totalPages]);
|
|
1289
1711
|
if (totalPages <= 1) return null;
|
|
1290
|
-
return /* @__PURE__ */ (0,
|
|
1291
|
-
/* @__PURE__ */ (0,
|
|
1712
|
+
return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("nav", { className: cn("flex items-center gap-1", className), children: [
|
|
1713
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
1292
1714
|
"button",
|
|
1293
1715
|
{
|
|
1294
1716
|
className: "inline-flex h-9 w-9 items-center justify-center rounded-md border text-sm disabled:opacity-50",
|
|
1295
1717
|
disabled: page <= 1,
|
|
1296
1718
|
onClick: () => onPageChange(page - 1),
|
|
1297
|
-
children: /* @__PURE__ */ (0,
|
|
1719
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_lucide_react8.ChevronLeft, { className: "h-4 w-4" })
|
|
1298
1720
|
}
|
|
1299
1721
|
),
|
|
1300
1722
|
pages.map(
|
|
1301
|
-
(p, i) => p === "ellipsis" ? /* @__PURE__ */ (0,
|
|
1723
|
+
(p, i) => p === "ellipsis" ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "px-2 text-muted-foreground", children: "..." }, `e-${i}`) : /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
1302
1724
|
"button",
|
|
1303
1725
|
{
|
|
1304
1726
|
className: cn(
|
|
@@ -1311,13 +1733,13 @@ function Pagination({
|
|
|
1311
1733
|
p
|
|
1312
1734
|
)
|
|
1313
1735
|
),
|
|
1314
|
-
/* @__PURE__ */ (0,
|
|
1736
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
1315
1737
|
"button",
|
|
1316
1738
|
{
|
|
1317
1739
|
className: "inline-flex h-9 w-9 items-center justify-center rounded-md border text-sm disabled:opacity-50",
|
|
1318
1740
|
disabled: page >= totalPages,
|
|
1319
1741
|
onClick: () => onPageChange(page + 1),
|
|
1320
|
-
children: /* @__PURE__ */ (0,
|
|
1742
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_lucide_react8.ChevronRight, { className: "h-4 w-4" })
|
|
1321
1743
|
}
|
|
1322
1744
|
)
|
|
1323
1745
|
] });
|
|
@@ -1325,9 +1747,9 @@ function Pagination({
|
|
|
1325
1747
|
|
|
1326
1748
|
// src/components/data/stats.tsx
|
|
1327
1749
|
var import_lucide_react9 = require("lucide-react");
|
|
1328
|
-
var
|
|
1750
|
+
var import_jsx_runtime29 = require("react/jsx-runtime");
|
|
1329
1751
|
function Stats({ stats, columns = 4, className }) {
|
|
1330
|
-
return /* @__PURE__ */ (0,
|
|
1752
|
+
return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
1331
1753
|
"div",
|
|
1332
1754
|
{
|
|
1333
1755
|
className: cn(
|
|
@@ -1339,18 +1761,18 @@ function Stats({ stats, columns = 4, className }) {
|
|
|
1339
1761
|
),
|
|
1340
1762
|
children: stats.map((stat, index) => {
|
|
1341
1763
|
const Icon2 = stat.icon;
|
|
1342
|
-
return /* @__PURE__ */ (0,
|
|
1764
|
+
return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
|
|
1343
1765
|
"div",
|
|
1344
1766
|
{
|
|
1345
1767
|
className: "rounded-lg border bg-card p-6 text-card-foreground shadow-sm",
|
|
1346
1768
|
children: [
|
|
1347
|
-
/* @__PURE__ */ (0,
|
|
1348
|
-
/* @__PURE__ */ (0,
|
|
1349
|
-
Icon2 && /* @__PURE__ */ (0,
|
|
1769
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
1770
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("p", { className: "text-sm font-medium text-muted-foreground", children: stat.label }),
|
|
1771
|
+
Icon2 && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(Icon2, { className: "h-4 w-4 text-muted-foreground" })
|
|
1350
1772
|
] }),
|
|
1351
|
-
/* @__PURE__ */ (0,
|
|
1352
|
-
/* @__PURE__ */ (0,
|
|
1353
|
-
stat.change && /* @__PURE__ */ (0,
|
|
1773
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "mt-2 flex items-baseline gap-2", children: [
|
|
1774
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("p", { className: "text-2xl font-bold", children: stat.value }),
|
|
1775
|
+
stat.change && /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
|
|
1354
1776
|
"span",
|
|
1355
1777
|
{
|
|
1356
1778
|
className: cn(
|
|
@@ -1358,7 +1780,7 @@ function Stats({ stats, columns = 4, className }) {
|
|
|
1358
1780
|
stat.change.type === "increase" ? "text-green-600 dark:text-green-400" : "text-red-600 dark:text-red-400"
|
|
1359
1781
|
),
|
|
1360
1782
|
children: [
|
|
1361
|
-
stat.change.type === "increase" ? /* @__PURE__ */ (0,
|
|
1783
|
+
stat.change.type === "increase" ? /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_lucide_react9.ArrowUp, { className: "mr-0.5 h-3 w-3" }) : /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_lucide_react9.ArrowDown, { className: "mr-0.5 h-3 w-3" }),
|
|
1362
1784
|
stat.change.value,
|
|
1363
1785
|
"%"
|
|
1364
1786
|
]
|
|
@@ -1374,8 +1796,531 @@ function Stats({ stats, columns = 4, className }) {
|
|
|
1374
1796
|
);
|
|
1375
1797
|
}
|
|
1376
1798
|
|
|
1799
|
+
// src/components/data/plan-badge.tsx
|
|
1800
|
+
var import_jsx_runtime30 = require("react/jsx-runtime");
|
|
1801
|
+
var PLAN_STYLES = {
|
|
1802
|
+
BASIC: "bg-muted text-muted-foreground",
|
|
1803
|
+
GROW: "bg-primary text-primary-foreground",
|
|
1804
|
+
ADVANCED: "bg-zinc-900 text-amber-400 dark:bg-zinc-800"
|
|
1805
|
+
};
|
|
1806
|
+
function PlanBadge({ plan, size = "md", className }) {
|
|
1807
|
+
const colorClass = PLAN_STYLES[plan.toUpperCase()] ?? "bg-muted text-muted-foreground";
|
|
1808
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
1809
|
+
"span",
|
|
1810
|
+
{
|
|
1811
|
+
className: cn(
|
|
1812
|
+
"inline-flex items-center rounded font-semibold uppercase tracking-wide",
|
|
1813
|
+
colorClass,
|
|
1814
|
+
size === "sm" ? "px-1.5 py-0.5 text-[10px]" : "px-2 py-1 text-xs",
|
|
1815
|
+
className
|
|
1816
|
+
),
|
|
1817
|
+
children: plan
|
|
1818
|
+
}
|
|
1819
|
+
);
|
|
1820
|
+
}
|
|
1821
|
+
|
|
1822
|
+
// src/components/data/storage-bar.tsx
|
|
1823
|
+
var import_jsx_runtime31 = require("react/jsx-runtime");
|
|
1824
|
+
function formatBytes(bytes) {
|
|
1825
|
+
if (bytes < 1024) return `${bytes} B`;
|
|
1826
|
+
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
|
|
1827
|
+
if (bytes < 1024 * 1024 * 1024) return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
1828
|
+
return `${(bytes / (1024 * 1024 * 1024)).toFixed(2)} GB`;
|
|
1829
|
+
}
|
|
1830
|
+
function getBarColor(pct) {
|
|
1831
|
+
if (pct >= 90) return "bg-destructive";
|
|
1832
|
+
if (pct >= 70) return "bg-amber-500";
|
|
1833
|
+
return "bg-primary";
|
|
1834
|
+
}
|
|
1835
|
+
function StorageIcon({ className }) {
|
|
1836
|
+
return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(
|
|
1837
|
+
"svg",
|
|
1838
|
+
{
|
|
1839
|
+
className,
|
|
1840
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
1841
|
+
viewBox: "0 0 24 24",
|
|
1842
|
+
fill: "none",
|
|
1843
|
+
stroke: "currentColor",
|
|
1844
|
+
strokeWidth: "2",
|
|
1845
|
+
strokeLinecap: "round",
|
|
1846
|
+
strokeLinejoin: "round",
|
|
1847
|
+
children: [
|
|
1848
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)("ellipse", { cx: "12", cy: "5", rx: "9", ry: "3" }),
|
|
1849
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)("path", { d: "M3 5v14c0 1.66 4.03 3 9 3s9-1.34 9-3V5" }),
|
|
1850
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)("path", { d: "M3 12c0 1.66 4.03 3 9 3s9-1.34 9-3" })
|
|
1851
|
+
]
|
|
1852
|
+
}
|
|
1853
|
+
);
|
|
1854
|
+
}
|
|
1855
|
+
function StorageBar({
|
|
1856
|
+
used,
|
|
1857
|
+
limit,
|
|
1858
|
+
plan,
|
|
1859
|
+
collapsed = false,
|
|
1860
|
+
className
|
|
1861
|
+
}) {
|
|
1862
|
+
const pct = limit ? Math.min(100, used / limit * 100) : 0;
|
|
1863
|
+
const barColor = getBarColor(pct);
|
|
1864
|
+
if (collapsed) {
|
|
1865
|
+
return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: cn("flex justify-center", className), children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(StorageIcon, { className: "h-4 w-4 text-muted-foreground" }) });
|
|
1866
|
+
}
|
|
1867
|
+
return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: cn("space-y-1.5 px-1", className), children: [
|
|
1868
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: "flex items-center gap-1.5", children: [
|
|
1869
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(StorageIcon, { className: "h-3.5 w-3.5 shrink-0 text-muted-foreground" }),
|
|
1870
|
+
limit === null ? /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("p", { className: "text-[11px] text-muted-foreground", children: [
|
|
1871
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "font-medium text-foreground", children: formatBytes(used) }),
|
|
1872
|
+
" \xB7 Unlimited"
|
|
1873
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("p", { className: "text-[11px] text-muted-foreground", children: [
|
|
1874
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "font-medium text-foreground", children: formatBytes(used) }),
|
|
1875
|
+
" / ",
|
|
1876
|
+
formatBytes(limit)
|
|
1877
|
+
] })
|
|
1878
|
+
] }),
|
|
1879
|
+
limit !== null && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: "h-1 w-full overflow-hidden rounded-full bg-muted", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
|
|
1880
|
+
"div",
|
|
1881
|
+
{
|
|
1882
|
+
className: cn("h-full rounded-full transition-all duration-300", barColor),
|
|
1883
|
+
style: { width: `${pct}%` }
|
|
1884
|
+
}
|
|
1885
|
+
) }),
|
|
1886
|
+
plan && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("p", { className: "text-[10px] uppercase tracking-wide text-muted-foreground", children: plan })
|
|
1887
|
+
] });
|
|
1888
|
+
}
|
|
1889
|
+
|
|
1890
|
+
// src/components/media/media-card.tsx
|
|
1891
|
+
var import_jsx_runtime32 = require("react/jsx-runtime");
|
|
1892
|
+
function stripExtension(name) {
|
|
1893
|
+
return name.replace(/\.[^/.]+$/, "");
|
|
1894
|
+
}
|
|
1895
|
+
function getFileEmoji(mimeType) {
|
|
1896
|
+
if (mimeType.startsWith("video/")) return "\u{1F3AC}";
|
|
1897
|
+
if (mimeType.startsWith("audio/")) return "\u{1F3B5}";
|
|
1898
|
+
if (mimeType === "application/pdf") return "\u{1F4C4}";
|
|
1899
|
+
return "\u{1F4CE}";
|
|
1900
|
+
}
|
|
1901
|
+
function MediaCard({ file, selected = false, onClick, className }) {
|
|
1902
|
+
const isImage = file.mimeType.startsWith("image/");
|
|
1903
|
+
const displayName = stripExtension(file.name);
|
|
1904
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
|
|
1905
|
+
"div",
|
|
1906
|
+
{
|
|
1907
|
+
role: "button",
|
|
1908
|
+
tabIndex: 0,
|
|
1909
|
+
onClick,
|
|
1910
|
+
onKeyDown: (e) => {
|
|
1911
|
+
if (e.key === "Enter" || e.key === " ") onClick?.();
|
|
1912
|
+
},
|
|
1913
|
+
className: cn(
|
|
1914
|
+
"group relative aspect-square cursor-pointer rounded-xl overflow-hidden border-2 transition-all duration-150",
|
|
1915
|
+
selected ? "border-[color:var(--primary)] shadow-[0_0_0_2px_rgba(40,127,113,0.2)]" : "border-transparent hover:border-[color:var(--primary)]/40",
|
|
1916
|
+
className
|
|
1917
|
+
),
|
|
1918
|
+
children: [
|
|
1919
|
+
isImage ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
1920
|
+
"img",
|
|
1921
|
+
{
|
|
1922
|
+
src: file.url,
|
|
1923
|
+
alt: file.name,
|
|
1924
|
+
className: "h-full w-full object-cover transition-transform duration-150 group-hover:scale-[1.03]",
|
|
1925
|
+
loading: "lazy"
|
|
1926
|
+
}
|
|
1927
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "flex h-full w-full items-center justify-center bg-muted text-4xl", children: getFileEmoji(file.mimeType) }),
|
|
1928
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "absolute inset-0 flex items-end bg-gradient-to-t from-black/60 via-transparent to-transparent opacity-0 transition-opacity duration-150 group-hover:opacity-100", children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("p", { className: "truncate px-2 pb-2 text-[11px] font-medium text-white", children: displayName }) }),
|
|
1929
|
+
selected && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "absolute right-1.5 top-1.5 flex h-5 w-5 items-center justify-center rounded-full bg-primary shadow", children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
1930
|
+
"svg",
|
|
1931
|
+
{
|
|
1932
|
+
className: "h-3 w-3 text-white",
|
|
1933
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
1934
|
+
viewBox: "0 0 24 24",
|
|
1935
|
+
fill: "none",
|
|
1936
|
+
stroke: "currentColor",
|
|
1937
|
+
strokeWidth: "3",
|
|
1938
|
+
strokeLinecap: "round",
|
|
1939
|
+
strokeLinejoin: "round",
|
|
1940
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("polyline", { points: "20 6 9 17 4 12" })
|
|
1941
|
+
}
|
|
1942
|
+
) })
|
|
1943
|
+
]
|
|
1944
|
+
}
|
|
1945
|
+
);
|
|
1946
|
+
}
|
|
1947
|
+
|
|
1948
|
+
// src/components/media/media-grid.tsx
|
|
1949
|
+
var import_jsx_runtime33 = require("react/jsx-runtime");
|
|
1950
|
+
var columnsClass = {
|
|
1951
|
+
4: "grid-cols-2 sm:grid-cols-3 md:grid-cols-4",
|
|
1952
|
+
5: "grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5",
|
|
1953
|
+
6: "grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-6"
|
|
1954
|
+
};
|
|
1955
|
+
function MediaGrid({
|
|
1956
|
+
files,
|
|
1957
|
+
selected,
|
|
1958
|
+
onSelect,
|
|
1959
|
+
loading = false,
|
|
1960
|
+
columns = 5,
|
|
1961
|
+
emptyMessage = "No files yet.",
|
|
1962
|
+
onUploadClick,
|
|
1963
|
+
className
|
|
1964
|
+
}) {
|
|
1965
|
+
if (loading) {
|
|
1966
|
+
return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: cn("grid gap-2", columnsClass[columns] ?? columnsClass[5], className), children: Array.from({ length: columns * 2 }).map((_, i) => /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
1967
|
+
"div",
|
|
1968
|
+
{
|
|
1969
|
+
className: "aspect-square animate-pulse rounded-xl bg-muted"
|
|
1970
|
+
},
|
|
1971
|
+
i
|
|
1972
|
+
)) });
|
|
1973
|
+
}
|
|
1974
|
+
if (files.length === 0) {
|
|
1975
|
+
return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: cn("flex flex-col items-center justify-center gap-3 py-16 text-center", className), children: [
|
|
1976
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "flex h-14 w-14 items-center justify-center rounded-full bg-muted", children: /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(
|
|
1977
|
+
"svg",
|
|
1978
|
+
{
|
|
1979
|
+
className: "h-7 w-7 text-muted-foreground",
|
|
1980
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
1981
|
+
viewBox: "0 0 24 24",
|
|
1982
|
+
fill: "none",
|
|
1983
|
+
stroke: "currentColor",
|
|
1984
|
+
strokeWidth: "1.5",
|
|
1985
|
+
strokeLinecap: "round",
|
|
1986
|
+
strokeLinejoin: "round",
|
|
1987
|
+
children: [
|
|
1988
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)("rect", { width: "18", height: "18", x: "3", y: "3", rx: "2", ry: "2" }),
|
|
1989
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)("circle", { cx: "9", cy: "9", r: "2" }),
|
|
1990
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)("path", { d: "m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21" })
|
|
1991
|
+
]
|
|
1992
|
+
}
|
|
1993
|
+
) }),
|
|
1994
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)("p", { className: "text-sm text-muted-foreground", children: emptyMessage }),
|
|
1995
|
+
onUploadClick && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
1996
|
+
"button",
|
|
1997
|
+
{
|
|
1998
|
+
onClick: onUploadClick,
|
|
1999
|
+
className: "rounded-md bg-primary px-4 py-1.5 text-sm font-medium text-primary-foreground transition-opacity hover:opacity-90",
|
|
2000
|
+
children: "Upload files"
|
|
2001
|
+
}
|
|
2002
|
+
)
|
|
2003
|
+
] });
|
|
2004
|
+
}
|
|
2005
|
+
return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: cn("grid gap-2", columnsClass[columns] ?? columnsClass[5], className), children: files.map((file) => /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
2006
|
+
MediaCard,
|
|
2007
|
+
{
|
|
2008
|
+
file,
|
|
2009
|
+
selected: selected?.has(file.id),
|
|
2010
|
+
onClick: () => onSelect?.(file)
|
|
2011
|
+
},
|
|
2012
|
+
file.id
|
|
2013
|
+
)) });
|
|
2014
|
+
}
|
|
2015
|
+
|
|
2016
|
+
// src/components/media/media-picker-dialog.tsx
|
|
2017
|
+
var React20 = __toESM(require("react"));
|
|
2018
|
+
var import_jsx_runtime34 = require("react/jsx-runtime");
|
|
2019
|
+
var TYPE_OPTIONS = [
|
|
2020
|
+
{ value: "", label: "All" },
|
|
2021
|
+
{ value: "image", label: "Images" },
|
|
2022
|
+
{ value: "video", label: "Videos" },
|
|
2023
|
+
{ value: "audio", label: "Audio" },
|
|
2024
|
+
{ value: "document", label: "Docs" }
|
|
2025
|
+
];
|
|
2026
|
+
function MediaPickerDialog({
|
|
2027
|
+
open,
|
|
2028
|
+
onOpenChange,
|
|
2029
|
+
title = "Media Library",
|
|
2030
|
+
files,
|
|
2031
|
+
folders = [],
|
|
2032
|
+
loading = false,
|
|
2033
|
+
total,
|
|
2034
|
+
uploads = [],
|
|
2035
|
+
typeFilter = "",
|
|
2036
|
+
onTypeChange,
|
|
2037
|
+
search = "",
|
|
2038
|
+
onSearch,
|
|
2039
|
+
activeFolderId,
|
|
2040
|
+
onFolderChange,
|
|
2041
|
+
onUpload,
|
|
2042
|
+
onLoadMore,
|
|
2043
|
+
hasMore = false,
|
|
2044
|
+
multiple = false,
|
|
2045
|
+
accept = "all",
|
|
2046
|
+
onSelect
|
|
2047
|
+
}) {
|
|
2048
|
+
const [localSelected, setLocalSelected] = React20.useState(/* @__PURE__ */ new Set());
|
|
2049
|
+
const fileInputRef = React20.useRef(null);
|
|
2050
|
+
const handleFileSelect = (file) => {
|
|
2051
|
+
if (multiple) {
|
|
2052
|
+
setLocalSelected((prev) => {
|
|
2053
|
+
const next = new Set(prev);
|
|
2054
|
+
if (next.has(file.id)) {
|
|
2055
|
+
next.delete(file.id);
|
|
2056
|
+
} else {
|
|
2057
|
+
next.add(file.id);
|
|
2058
|
+
}
|
|
2059
|
+
return next;
|
|
2060
|
+
});
|
|
2061
|
+
} else {
|
|
2062
|
+
const selected = files.filter((f) => f.id === file.id);
|
|
2063
|
+
onSelect(selected);
|
|
2064
|
+
onOpenChange(false);
|
|
2065
|
+
}
|
|
2066
|
+
};
|
|
2067
|
+
const handleConfirm = () => {
|
|
2068
|
+
const selected = files.filter((f) => localSelected.has(f.id));
|
|
2069
|
+
onSelect(selected);
|
|
2070
|
+
onOpenChange(false);
|
|
2071
|
+
};
|
|
2072
|
+
const handleUploadChange = (e) => {
|
|
2073
|
+
if (e.target.files && onUpload) {
|
|
2074
|
+
onUpload(e.target.files);
|
|
2075
|
+
}
|
|
2076
|
+
};
|
|
2077
|
+
const activeUploads = uploads.filter((u) => u.status === "uploading");
|
|
2078
|
+
return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(Dialog, { open, onOpenChange, children: /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(DialogContent, { className: "flex h-[85vh] max-h-[700px] max-w-4xl flex-col gap-0 p-0", children: [
|
|
2079
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(DialogHeader, { className: "flex-row items-center justify-between border-b px-5 py-3", children: [
|
|
2080
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(DialogTitle, { className: "text-base", children: title }),
|
|
2081
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
2082
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("span", { className: "text-xs text-muted-foreground", children: [
|
|
2083
|
+
total,
|
|
2084
|
+
" files"
|
|
2085
|
+
] }),
|
|
2086
|
+
onUpload && /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(import_jsx_runtime34.Fragment, { children: [
|
|
2087
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
2088
|
+
"input",
|
|
2089
|
+
{
|
|
2090
|
+
ref: fileInputRef,
|
|
2091
|
+
type: "file",
|
|
2092
|
+
className: "hidden",
|
|
2093
|
+
multiple: true,
|
|
2094
|
+
accept: accept === "images" ? "image/*" : void 0,
|
|
2095
|
+
onChange: handleUploadChange
|
|
2096
|
+
}
|
|
2097
|
+
),
|
|
2098
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
|
|
2099
|
+
"button",
|
|
2100
|
+
{
|
|
2101
|
+
onClick: () => fileInputRef.current?.click(),
|
|
2102
|
+
className: "flex items-center gap-1.5 rounded-md bg-primary px-3 py-1.5 text-xs font-medium text-primary-foreground transition-opacity hover:opacity-90",
|
|
2103
|
+
children: [
|
|
2104
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("svg", { className: "h-3.5 w-3.5", xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
2105
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }),
|
|
2106
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("polyline", { points: "17 8 12 3 7 8" }),
|
|
2107
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("line", { x1: "12", y1: "3", x2: "12", y2: "15" })
|
|
2108
|
+
] }),
|
|
2109
|
+
"Upload"
|
|
2110
|
+
]
|
|
2111
|
+
}
|
|
2112
|
+
)
|
|
2113
|
+
] })
|
|
2114
|
+
] })
|
|
2115
|
+
] }),
|
|
2116
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "flex flex-1 overflow-hidden", children: [
|
|
2117
|
+
folders.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("aside", { className: "flex w-44 shrink-0 flex-col gap-0.5 overflow-y-auto border-r p-2", children: [
|
|
2118
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
|
|
2119
|
+
"button",
|
|
2120
|
+
{
|
|
2121
|
+
onClick: () => onFolderChange?.(""),
|
|
2122
|
+
className: cn(
|
|
2123
|
+
"flex w-full items-center gap-2 rounded-md px-2.5 py-1.5 text-sm transition-colors",
|
|
2124
|
+
!activeFolderId ? "bg-primary/10 font-medium text-primary" : "text-muted-foreground hover:bg-accent"
|
|
2125
|
+
),
|
|
2126
|
+
children: [
|
|
2127
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("svg", { className: "h-3.5 w-3.5", xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("path", { d: "M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z" }) }),
|
|
2128
|
+
"All files"
|
|
2129
|
+
]
|
|
2130
|
+
}
|
|
2131
|
+
),
|
|
2132
|
+
folders.map((folder) => /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
|
|
2133
|
+
"button",
|
|
2134
|
+
{
|
|
2135
|
+
onClick: () => onFolderChange?.(folder.id),
|
|
2136
|
+
className: cn(
|
|
2137
|
+
"flex w-full items-center gap-2 rounded-md px-2.5 py-1.5 text-sm transition-colors",
|
|
2138
|
+
activeFolderId === folder.id ? "bg-primary/10 font-medium text-primary" : "text-muted-foreground hover:bg-accent"
|
|
2139
|
+
),
|
|
2140
|
+
children: [
|
|
2141
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { className: "text-base leading-none", children: folder.icon ?? "\u{1F4C1}" }),
|
|
2142
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { className: "truncate", children: folder.name })
|
|
2143
|
+
]
|
|
2144
|
+
},
|
|
2145
|
+
folder.id
|
|
2146
|
+
))
|
|
2147
|
+
] }),
|
|
2148
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "flex flex-1 flex-col overflow-hidden", children: [
|
|
2149
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "flex items-center gap-2 border-b px-4 py-2", children: [
|
|
2150
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "relative flex-1", children: [
|
|
2151
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("svg", { className: "pointer-events-none absolute left-2.5 top-1/2 h-3.5 w-3.5 -translate-y-1/2 text-muted-foreground", xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
2152
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("circle", { cx: "11", cy: "11", r: "8" }),
|
|
2153
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("path", { d: "m21 21-4.35-4.35" })
|
|
2154
|
+
] }),
|
|
2155
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
2156
|
+
"input",
|
|
2157
|
+
{
|
|
2158
|
+
type: "search",
|
|
2159
|
+
value: search,
|
|
2160
|
+
onChange: (e) => onSearch?.(e.target.value),
|
|
2161
|
+
placeholder: "Search files\u2026",
|
|
2162
|
+
className: "h-7 w-full rounded-md border border-input bg-muted/50 pl-8 pr-3 text-xs outline-none focus:border-primary focus:ring-1 focus:ring-primary"
|
|
2163
|
+
}
|
|
2164
|
+
)
|
|
2165
|
+
] }),
|
|
2166
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "flex gap-1", children: TYPE_OPTIONS.filter((o) => accept === "images" ? o.value === "" || o.value === "image" : true).map((opt) => /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
2167
|
+
"button",
|
|
2168
|
+
{
|
|
2169
|
+
onClick: () => onTypeChange?.(opt.value),
|
|
2170
|
+
className: cn(
|
|
2171
|
+
"rounded px-2 py-1 text-xs transition-colors",
|
|
2172
|
+
typeFilter === opt.value ? "bg-primary text-primary-foreground" : "text-muted-foreground hover:bg-accent"
|
|
2173
|
+
),
|
|
2174
|
+
children: opt.label
|
|
2175
|
+
},
|
|
2176
|
+
opt.value
|
|
2177
|
+
)) })
|
|
2178
|
+
] }),
|
|
2179
|
+
activeUploads.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "border-b px-4 py-2 space-y-1.5", children: activeUploads.map((u, i) => /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
2180
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { className: "flex-1 truncate text-xs text-muted-foreground", children: u.name }),
|
|
2181
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "h-1.5 w-24 overflow-hidden rounded-full bg-muted", children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
2182
|
+
"div",
|
|
2183
|
+
{
|
|
2184
|
+
className: "h-full rounded-full bg-primary transition-all",
|
|
2185
|
+
style: { width: `${u.progress}%` }
|
|
2186
|
+
}
|
|
2187
|
+
) }),
|
|
2188
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("span", { className: "text-[10px] text-muted-foreground", children: [
|
|
2189
|
+
u.progress,
|
|
2190
|
+
"%"
|
|
2191
|
+
] })
|
|
2192
|
+
] }, i)) }),
|
|
2193
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "flex-1 overflow-y-auto p-4", children: [
|
|
2194
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
2195
|
+
MediaGrid,
|
|
2196
|
+
{
|
|
2197
|
+
files,
|
|
2198
|
+
selected: localSelected,
|
|
2199
|
+
onSelect: handleFileSelect,
|
|
2200
|
+
loading,
|
|
2201
|
+
columns: 5,
|
|
2202
|
+
onUploadClick: onUpload ? () => fileInputRef.current?.click() : void 0
|
|
2203
|
+
}
|
|
2204
|
+
),
|
|
2205
|
+
hasMore && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "mt-4 flex justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
2206
|
+
"button",
|
|
2207
|
+
{
|
|
2208
|
+
onClick: onLoadMore,
|
|
2209
|
+
className: "rounded-md border px-4 py-2 text-sm text-muted-foreground transition-colors hover:bg-accent",
|
|
2210
|
+
children: "Load more"
|
|
2211
|
+
}
|
|
2212
|
+
) })
|
|
2213
|
+
] }),
|
|
2214
|
+
multiple && localSelected.size > 0 && /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "flex items-center justify-between border-t px-4 py-3", children: [
|
|
2215
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("span", { className: "text-sm text-muted-foreground", children: [
|
|
2216
|
+
localSelected.size,
|
|
2217
|
+
" selected"
|
|
2218
|
+
] }),
|
|
2219
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "flex gap-2", children: [
|
|
2220
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
2221
|
+
"button",
|
|
2222
|
+
{
|
|
2223
|
+
onClick: () => setLocalSelected(/* @__PURE__ */ new Set()),
|
|
2224
|
+
className: "rounded-md px-3 py-1.5 text-sm text-muted-foreground transition-colors hover:bg-accent",
|
|
2225
|
+
children: "Clear"
|
|
2226
|
+
}
|
|
2227
|
+
),
|
|
2228
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
|
|
2229
|
+
"button",
|
|
2230
|
+
{
|
|
2231
|
+
onClick: handleConfirm,
|
|
2232
|
+
className: "rounded-md bg-primary px-4 py-1.5 text-sm font-medium text-primary-foreground transition-opacity hover:opacity-90",
|
|
2233
|
+
children: [
|
|
2234
|
+
"Insert ",
|
|
2235
|
+
localSelected.size,
|
|
2236
|
+
" file",
|
|
2237
|
+
localSelected.size !== 1 ? "s" : ""
|
|
2238
|
+
]
|
|
2239
|
+
}
|
|
2240
|
+
)
|
|
2241
|
+
] })
|
|
2242
|
+
] })
|
|
2243
|
+
] })
|
|
2244
|
+
] })
|
|
2245
|
+
] }) });
|
|
2246
|
+
}
|
|
2247
|
+
|
|
2248
|
+
// src/components/media/image-picker-field.tsx
|
|
2249
|
+
var import_jsx_runtime35 = require("react/jsx-runtime");
|
|
2250
|
+
var sizeMap = {
|
|
2251
|
+
sm: { box: "h-12 w-12", icon: "h-4 w-4", text: "text-[9px]" },
|
|
2252
|
+
md: { box: "h-20 w-20", icon: "h-5 w-5", text: "text-[10px]" },
|
|
2253
|
+
lg: { box: "h-24 w-24", icon: "h-6 w-6", text: "text-xs" }
|
|
2254
|
+
};
|
|
2255
|
+
function ImagePickerField({
|
|
2256
|
+
value,
|
|
2257
|
+
filename,
|
|
2258
|
+
onPickerOpen,
|
|
2259
|
+
onRemove,
|
|
2260
|
+
size = "md",
|
|
2261
|
+
emptyLabel = "Click to select",
|
|
2262
|
+
className
|
|
2263
|
+
}) {
|
|
2264
|
+
const sz = sizeMap[size];
|
|
2265
|
+
return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: cn("relative inline-flex shrink-0", className), children: [
|
|
2266
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
2267
|
+
"button",
|
|
2268
|
+
{
|
|
2269
|
+
type: "button",
|
|
2270
|
+
onClick: onPickerOpen,
|
|
2271
|
+
className: cn(
|
|
2272
|
+
"group flex items-center justify-center rounded-lg border-2 border-dashed transition-all duration-150",
|
|
2273
|
+
sz.box,
|
|
2274
|
+
value ? "border-border overflow-hidden" : "border-border hover:border-[color:var(--primary)] hover:bg-primary/5"
|
|
2275
|
+
),
|
|
2276
|
+
children: value ? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
2277
|
+
"img",
|
|
2278
|
+
{
|
|
2279
|
+
src: value,
|
|
2280
|
+
alt: filename ?? "Selected image",
|
|
2281
|
+
className: "h-full w-full rounded-md object-cover"
|
|
2282
|
+
}
|
|
2283
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: "flex flex-col items-center gap-1", children: [
|
|
2284
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(
|
|
2285
|
+
"svg",
|
|
2286
|
+
{
|
|
2287
|
+
className: cn(sz.icon, "text-muted-foreground transition-colors group-hover:text-primary"),
|
|
2288
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
2289
|
+
viewBox: "0 0 24 24",
|
|
2290
|
+
fill: "none",
|
|
2291
|
+
stroke: "currentColor",
|
|
2292
|
+
strokeWidth: "1.5",
|
|
2293
|
+
strokeLinecap: "round",
|
|
2294
|
+
strokeLinejoin: "round",
|
|
2295
|
+
children: [
|
|
2296
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)("rect", { width: "18", height: "18", x: "3", y: "3", rx: "2", ry: "2" }),
|
|
2297
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)("circle", { cx: "9", cy: "9", r: "2" }),
|
|
2298
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)("path", { d: "m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21" })
|
|
2299
|
+
]
|
|
2300
|
+
}
|
|
2301
|
+
),
|
|
2302
|
+
size !== "sm" && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: cn(sz.text, "text-muted-foreground text-center leading-tight transition-colors group-hover:text-primary"), children: emptyLabel })
|
|
2303
|
+
] })
|
|
2304
|
+
}
|
|
2305
|
+
),
|
|
2306
|
+
value && onRemove && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
2307
|
+
"button",
|
|
2308
|
+
{
|
|
2309
|
+
type: "button",
|
|
2310
|
+
onClick: (e) => {
|
|
2311
|
+
e.stopPropagation();
|
|
2312
|
+
onRemove();
|
|
2313
|
+
},
|
|
2314
|
+
className: "absolute -right-1.5 -top-1.5 flex h-5 w-5 items-center justify-center rounded-full bg-destructive text-destructive-foreground shadow-sm transition-opacity hover:opacity-90",
|
|
2315
|
+
"aria-label": "Remove image",
|
|
2316
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("svg", { className: "h-2.5 w-2.5", xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "3", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("path", { d: "M18 6 6 18M6 6l12 12" }) })
|
|
2317
|
+
}
|
|
2318
|
+
)
|
|
2319
|
+
] });
|
|
2320
|
+
}
|
|
2321
|
+
|
|
1377
2322
|
// src/components/form/form-field.tsx
|
|
1378
|
-
var
|
|
2323
|
+
var import_jsx_runtime36 = require("react/jsx-runtime");
|
|
1379
2324
|
function FormField({
|
|
1380
2325
|
label,
|
|
1381
2326
|
error,
|
|
@@ -1384,19 +2329,19 @@ function FormField({
|
|
|
1384
2329
|
children,
|
|
1385
2330
|
className
|
|
1386
2331
|
}) {
|
|
1387
|
-
return /* @__PURE__ */ (0,
|
|
1388
|
-
/* @__PURE__ */ (0,
|
|
2332
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: cn("space-y-2", className), children: [
|
|
2333
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(Label2, { children: [
|
|
1389
2334
|
label,
|
|
1390
|
-
required && /* @__PURE__ */ (0,
|
|
2335
|
+
required && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { className: "ml-1 text-destructive", children: "*" })
|
|
1391
2336
|
] }),
|
|
1392
2337
|
children,
|
|
1393
|
-
hint && !error && /* @__PURE__ */ (0,
|
|
1394
|
-
error && /* @__PURE__ */ (0,
|
|
2338
|
+
hint && !error && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("p", { className: "text-sm text-muted-foreground", children: hint }),
|
|
2339
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("p", { className: "text-sm text-destructive", children: error })
|
|
1395
2340
|
] });
|
|
1396
2341
|
}
|
|
1397
2342
|
|
|
1398
2343
|
// src/components/form/form-layout.tsx
|
|
1399
|
-
var
|
|
2344
|
+
var import_jsx_runtime37 = require("react/jsx-runtime");
|
|
1400
2345
|
function FormLayout({
|
|
1401
2346
|
title,
|
|
1402
2347
|
description,
|
|
@@ -1404,7 +2349,7 @@ function FormLayout({
|
|
|
1404
2349
|
actions,
|
|
1405
2350
|
className
|
|
1406
2351
|
}) {
|
|
1407
|
-
return /* @__PURE__ */ (0,
|
|
2352
|
+
return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(
|
|
1408
2353
|
"div",
|
|
1409
2354
|
{
|
|
1410
2355
|
className: cn(
|
|
@@ -1412,37 +2357,37 @@ function FormLayout({
|
|
|
1412
2357
|
className
|
|
1413
2358
|
),
|
|
1414
2359
|
children: [
|
|
1415
|
-
(title || description) && /* @__PURE__ */ (0,
|
|
1416
|
-
title && /* @__PURE__ */ (0,
|
|
1417
|
-
description && /* @__PURE__ */ (0,
|
|
2360
|
+
(title || description) && /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "border-b p-6", children: [
|
|
2361
|
+
title && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("h3", { className: "text-lg font-semibold", children: title }),
|
|
2362
|
+
description && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("p", { className: "mt-1 text-sm text-muted-foreground", children: description })
|
|
1418
2363
|
] }),
|
|
1419
|
-
/* @__PURE__ */ (0,
|
|
1420
|
-
actions && /* @__PURE__ */ (0,
|
|
2364
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: "space-y-6 p-6", children }),
|
|
2365
|
+
actions && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: "flex items-center justify-end gap-2 border-t px-6 py-4", children: actions })
|
|
1421
2366
|
]
|
|
1422
2367
|
}
|
|
1423
2368
|
);
|
|
1424
2369
|
}
|
|
1425
2370
|
|
|
1426
2371
|
// src/components/form/form-section.tsx
|
|
1427
|
-
var
|
|
2372
|
+
var import_jsx_runtime38 = require("react/jsx-runtime");
|
|
1428
2373
|
function FormSection({
|
|
1429
2374
|
title,
|
|
1430
2375
|
description,
|
|
1431
2376
|
children,
|
|
1432
2377
|
className
|
|
1433
2378
|
}) {
|
|
1434
|
-
return /* @__PURE__ */ (0,
|
|
1435
|
-
/* @__PURE__ */ (0,
|
|
1436
|
-
/* @__PURE__ */ (0,
|
|
1437
|
-
description && /* @__PURE__ */ (0,
|
|
2379
|
+
return /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { className: cn("space-y-4", className), children: [
|
|
2380
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { children: [
|
|
2381
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)("h4", { className: "text-sm font-medium", children: title }),
|
|
2382
|
+
description && /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("p", { className: "mt-1 text-sm text-muted-foreground", children: description })
|
|
1438
2383
|
] }),
|
|
1439
|
-
/* @__PURE__ */ (0,
|
|
2384
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: "space-y-4", children })
|
|
1440
2385
|
] });
|
|
1441
2386
|
}
|
|
1442
2387
|
|
|
1443
2388
|
// src/components/feedback/alert.tsx
|
|
1444
2389
|
var import_lucide_react10 = require("lucide-react");
|
|
1445
|
-
var
|
|
2390
|
+
var import_jsx_runtime39 = require("react/jsx-runtime");
|
|
1446
2391
|
var variantConfig = {
|
|
1447
2392
|
info: {
|
|
1448
2393
|
icon: import_lucide_react10.Info,
|
|
@@ -1471,7 +2416,7 @@ function Alert({
|
|
|
1471
2416
|
}) {
|
|
1472
2417
|
const config = variantConfig[variant];
|
|
1473
2418
|
const Icon2 = config.icon;
|
|
1474
|
-
return /* @__PURE__ */ (0,
|
|
2419
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(
|
|
1475
2420
|
"div",
|
|
1476
2421
|
{
|
|
1477
2422
|
className: cn(
|
|
@@ -1481,17 +2426,17 @@ function Alert({
|
|
|
1481
2426
|
),
|
|
1482
2427
|
role: "alert",
|
|
1483
2428
|
children: [
|
|
1484
|
-
/* @__PURE__ */ (0,
|
|
1485
|
-
/* @__PURE__ */ (0,
|
|
1486
|
-
title && /* @__PURE__ */ (0,
|
|
1487
|
-
/* @__PURE__ */ (0,
|
|
2429
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)(Icon2, { className: "mt-0.5 h-5 w-5 shrink-0" }),
|
|
2430
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "flex-1", children: [
|
|
2431
|
+
title && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("p", { className: "font-medium", children: title }),
|
|
2432
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: cn("text-sm", title && "mt-1"), children })
|
|
1488
2433
|
] }),
|
|
1489
|
-
dismissible && /* @__PURE__ */ (0,
|
|
2434
|
+
dismissible && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
1490
2435
|
"button",
|
|
1491
2436
|
{
|
|
1492
2437
|
onClick: onDismiss,
|
|
1493
2438
|
className: "absolute right-3 top-3 rounded-md p-1 opacity-70 hover:opacity-100",
|
|
1494
|
-
children: /* @__PURE__ */ (0,
|
|
2439
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_lucide_react10.X, { className: "h-4 w-4" })
|
|
1495
2440
|
}
|
|
1496
2441
|
)
|
|
1497
2442
|
]
|
|
@@ -1501,23 +2446,23 @@ function Alert({
|
|
|
1501
2446
|
|
|
1502
2447
|
// src/components/feedback/loading-spinner.tsx
|
|
1503
2448
|
var import_lucide_react11 = require("lucide-react");
|
|
1504
|
-
var
|
|
1505
|
-
var
|
|
2449
|
+
var import_jsx_runtime40 = require("react/jsx-runtime");
|
|
2450
|
+
var sizeMap2 = {
|
|
1506
2451
|
sm: "h-4 w-4",
|
|
1507
2452
|
md: "h-6 w-6",
|
|
1508
2453
|
lg: "h-8 w-8"
|
|
1509
2454
|
};
|
|
1510
2455
|
function LoadingSpinner({ size = "md", className }) {
|
|
1511
|
-
return /* @__PURE__ */ (0,
|
|
2456
|
+
return /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
1512
2457
|
import_lucide_react11.Loader2,
|
|
1513
2458
|
{
|
|
1514
|
-
className: cn("animate-spin text-muted-foreground",
|
|
2459
|
+
className: cn("animate-spin text-muted-foreground", sizeMap2[size], className)
|
|
1515
2460
|
}
|
|
1516
2461
|
);
|
|
1517
2462
|
}
|
|
1518
2463
|
|
|
1519
2464
|
// src/components/feedback/confirm-dialog.tsx
|
|
1520
|
-
var
|
|
2465
|
+
var import_jsx_runtime41 = require("react/jsx-runtime");
|
|
1521
2466
|
function ConfirmDialog({
|
|
1522
2467
|
open,
|
|
1523
2468
|
onOpenChange,
|
|
@@ -1529,13 +2474,13 @@ function ConfirmDialog({
|
|
|
1529
2474
|
loading,
|
|
1530
2475
|
variant = "default"
|
|
1531
2476
|
}) {
|
|
1532
|
-
return /* @__PURE__ */ (0,
|
|
1533
|
-
/* @__PURE__ */ (0,
|
|
1534
|
-
/* @__PURE__ */ (0,
|
|
1535
|
-
description && /* @__PURE__ */ (0,
|
|
2477
|
+
return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(Dialog, { open, onOpenChange, children: /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(DialogContent, { children: [
|
|
2478
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(DialogHeader, { children: [
|
|
2479
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(DialogTitle, { children: title }),
|
|
2480
|
+
description && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(DialogDescription, { children: description })
|
|
1536
2481
|
] }),
|
|
1537
|
-
/* @__PURE__ */ (0,
|
|
1538
|
-
/* @__PURE__ */ (0,
|
|
2482
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(DialogFooter, { children: [
|
|
2483
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
1539
2484
|
Button,
|
|
1540
2485
|
{
|
|
1541
2486
|
variant: "outline",
|
|
@@ -1544,14 +2489,14 @@ function ConfirmDialog({
|
|
|
1544
2489
|
children: cancelLabel
|
|
1545
2490
|
}
|
|
1546
2491
|
),
|
|
1547
|
-
/* @__PURE__ */ (0,
|
|
2492
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(
|
|
1548
2493
|
Button,
|
|
1549
2494
|
{
|
|
1550
2495
|
variant: variant === "destructive" ? "destructive" : "default",
|
|
1551
2496
|
onClick: onConfirm,
|
|
1552
2497
|
disabled: loading,
|
|
1553
2498
|
children: [
|
|
1554
|
-
loading && /* @__PURE__ */ (0,
|
|
2499
|
+
loading && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(LoadingSpinner, { size: "sm", className: "mr-2" }),
|
|
1555
2500
|
confirmLabel
|
|
1556
2501
|
]
|
|
1557
2502
|
}
|
|
@@ -1579,9 +2524,9 @@ function usePagination(total, pageSize = 20) {
|
|
|
1579
2524
|
}
|
|
1580
2525
|
|
|
1581
2526
|
// src/components/auth/AuthShell.tsx
|
|
1582
|
-
var
|
|
2527
|
+
var import_jsx_runtime42 = require("react/jsx-runtime");
|
|
1583
2528
|
function AuthShell({ children, pattern = "dots", maxWidth = "520px" }) {
|
|
1584
|
-
return /* @__PURE__ */ (0,
|
|
2529
|
+
return /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
|
|
1585
2530
|
"div",
|
|
1586
2531
|
{
|
|
1587
2532
|
style: {
|
|
@@ -1596,7 +2541,7 @@ function AuthShell({ children, pattern = "dots", maxWidth = "520px" }) {
|
|
|
1596
2541
|
overflow: "hidden"
|
|
1597
2542
|
},
|
|
1598
2543
|
children: [
|
|
1599
|
-
pattern === "dots" && /* @__PURE__ */ (0,
|
|
2544
|
+
pattern === "dots" && /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
1600
2545
|
"div",
|
|
1601
2546
|
{
|
|
1602
2547
|
"aria-hidden": true,
|
|
@@ -1610,7 +2555,7 @@ function AuthShell({ children, pattern = "dots", maxWidth = "520px" }) {
|
|
|
1610
2555
|
}
|
|
1611
2556
|
}
|
|
1612
2557
|
),
|
|
1613
|
-
pattern === "grid" && /* @__PURE__ */ (0,
|
|
2558
|
+
pattern === "grid" && /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
1614
2559
|
"div",
|
|
1615
2560
|
{
|
|
1616
2561
|
"aria-hidden": true,
|
|
@@ -1624,16 +2569,16 @@ function AuthShell({ children, pattern = "dots", maxWidth = "520px" }) {
|
|
|
1624
2569
|
}
|
|
1625
2570
|
}
|
|
1626
2571
|
),
|
|
1627
|
-
/* @__PURE__ */ (0,
|
|
2572
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)("div", { style: { position: "relative", zIndex: 1, width: "100%", maxWidth }, children })
|
|
1628
2573
|
]
|
|
1629
2574
|
}
|
|
1630
2575
|
);
|
|
1631
2576
|
}
|
|
1632
2577
|
|
|
1633
2578
|
// src/components/auth/AuthCard.tsx
|
|
1634
|
-
var
|
|
2579
|
+
var import_jsx_runtime43 = require("react/jsx-runtime");
|
|
1635
2580
|
function AuthCard({ children, padding = "24px 28px" }) {
|
|
1636
|
-
return /* @__PURE__ */ (0,
|
|
2581
|
+
return /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
1637
2582
|
"div",
|
|
1638
2583
|
{
|
|
1639
2584
|
style: {
|
|
@@ -1650,10 +2595,10 @@ function AuthCard({ children, padding = "24px 28px" }) {
|
|
|
1650
2595
|
}
|
|
1651
2596
|
|
|
1652
2597
|
// src/components/auth/AuthLogo.tsx
|
|
1653
|
-
var
|
|
2598
|
+
var import_jsx_runtime44 = require("react/jsx-runtime");
|
|
1654
2599
|
function AuthLogo({ appName = "Builify CMS", letter = "B", imageUrl, size = 36 }) {
|
|
1655
|
-
return /* @__PURE__ */ (0,
|
|
1656
|
-
imageUrl ? /* @__PURE__ */ (0,
|
|
2600
|
+
return /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { style: { display: "flex", alignItems: "center", justifyContent: "center", gap: "10px", marginBottom: "28px" }, children: [
|
|
2601
|
+
imageUrl ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
|
|
1657
2602
|
"img",
|
|
1658
2603
|
{
|
|
1659
2604
|
src: imageUrl,
|
|
@@ -1662,7 +2607,7 @@ function AuthLogo({ appName = "Builify CMS", letter = "B", imageUrl, size = 36 }
|
|
|
1662
2607
|
height: size,
|
|
1663
2608
|
style: { borderRadius: "calc(var(--radius, 0.5rem) * 1.2)", flexShrink: 0, display: "block" }
|
|
1664
2609
|
}
|
|
1665
|
-
) : /* @__PURE__ */ (0,
|
|
2610
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
|
|
1666
2611
|
"div",
|
|
1667
2612
|
{
|
|
1668
2613
|
style: {
|
|
@@ -1681,7 +2626,7 @@ function AuthLogo({ appName = "Builify CMS", letter = "B", imageUrl, size = 36 }
|
|
|
1681
2626
|
children: letter
|
|
1682
2627
|
}
|
|
1683
2628
|
),
|
|
1684
|
-
/* @__PURE__ */ (0,
|
|
2629
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
|
|
1685
2630
|
"span",
|
|
1686
2631
|
{
|
|
1687
2632
|
style: {
|
|
@@ -1697,10 +2642,10 @@ function AuthLogo({ appName = "Builify CMS", letter = "B", imageUrl, size = 36 }
|
|
|
1697
2642
|
}
|
|
1698
2643
|
|
|
1699
2644
|
// src/components/auth/AuthHeader.tsx
|
|
1700
|
-
var
|
|
2645
|
+
var import_jsx_runtime45 = require("react/jsx-runtime");
|
|
1701
2646
|
function AuthHeader({ title, description }) {
|
|
1702
|
-
return /* @__PURE__ */ (0,
|
|
1703
|
-
/* @__PURE__ */ (0,
|
|
2647
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { style: { marginBottom: "24px", textAlign: "center" }, children: [
|
|
2648
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
1704
2649
|
"h1",
|
|
1705
2650
|
{
|
|
1706
2651
|
style: {
|
|
@@ -1713,7 +2658,7 @@ function AuthHeader({ title, description }) {
|
|
|
1713
2658
|
children: title
|
|
1714
2659
|
}
|
|
1715
2660
|
),
|
|
1716
|
-
description && /* @__PURE__ */ (0,
|
|
2661
|
+
description && /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
1717
2662
|
"p",
|
|
1718
2663
|
{
|
|
1719
2664
|
style: {
|
|
@@ -1729,12 +2674,12 @@ function AuthHeader({ title, description }) {
|
|
|
1729
2674
|
}
|
|
1730
2675
|
|
|
1731
2676
|
// src/components/auth/AuthField.tsx
|
|
1732
|
-
var
|
|
2677
|
+
var import_jsx_runtime46 = require("react/jsx-runtime");
|
|
1733
2678
|
function AuthField({ label, error, hint, rightLabel, id, ...props }) {
|
|
1734
2679
|
const fieldId = id ?? label.toLowerCase().replace(/\s+/g, "-");
|
|
1735
|
-
return /* @__PURE__ */ (0,
|
|
1736
|
-
/* @__PURE__ */ (0,
|
|
1737
|
-
/* @__PURE__ */ (0,
|
|
2680
|
+
return /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: "6px" }, children: [
|
|
2681
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between" }, children: [
|
|
2682
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
1738
2683
|
"label",
|
|
1739
2684
|
{
|
|
1740
2685
|
htmlFor: fieldId,
|
|
@@ -1746,9 +2691,9 @@ function AuthField({ label, error, hint, rightLabel, id, ...props }) {
|
|
|
1746
2691
|
children: label
|
|
1747
2692
|
}
|
|
1748
2693
|
),
|
|
1749
|
-
rightLabel && /* @__PURE__ */ (0,
|
|
2694
|
+
rightLabel && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { style: { fontSize: "0.8125rem" }, children: rightLabel })
|
|
1750
2695
|
] }),
|
|
1751
|
-
/* @__PURE__ */ (0,
|
|
2696
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
1752
2697
|
"input",
|
|
1753
2698
|
{
|
|
1754
2699
|
id: fieldId,
|
|
@@ -1778,13 +2723,13 @@ function AuthField({ label, error, hint, rightLabel, id, ...props }) {
|
|
|
1778
2723
|
...props
|
|
1779
2724
|
}
|
|
1780
2725
|
),
|
|
1781
|
-
error && /* @__PURE__ */ (0,
|
|
1782
|
-
hint && !error && /* @__PURE__ */ (0,
|
|
2726
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("p", { style: { fontSize: "0.8rem", color: "var(--destructive)", margin: 0 }, children: error }),
|
|
2727
|
+
hint && !error && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("p", { style: { fontSize: "0.8rem", color: "var(--muted-foreground)", margin: 0 }, children: hint })
|
|
1783
2728
|
] });
|
|
1784
2729
|
}
|
|
1785
2730
|
|
|
1786
2731
|
// src/components/auth/AuthButton.tsx
|
|
1787
|
-
var
|
|
2732
|
+
var import_jsx_runtime47 = require("react/jsx-runtime");
|
|
1788
2733
|
function AuthButton({
|
|
1789
2734
|
loading,
|
|
1790
2735
|
variant = "primary",
|
|
@@ -1827,7 +2772,7 @@ function AuthButton({
|
|
|
1827
2772
|
color: "var(--foreground)"
|
|
1828
2773
|
}
|
|
1829
2774
|
};
|
|
1830
|
-
return /* @__PURE__ */ (0,
|
|
2775
|
+
return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
|
|
1831
2776
|
"button",
|
|
1832
2777
|
{
|
|
1833
2778
|
disabled: loading || disabled,
|
|
@@ -1839,8 +2784,8 @@ function AuthButton({
|
|
|
1839
2784
|
e.currentTarget.style.filter = "none";
|
|
1840
2785
|
},
|
|
1841
2786
|
...props,
|
|
1842
|
-
children: loading ? /* @__PURE__ */ (0,
|
|
1843
|
-
/* @__PURE__ */ (0,
|
|
2787
|
+
children: loading ? /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(import_jsx_runtime47.Fragment, { children: [
|
|
2788
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
|
|
1844
2789
|
"span",
|
|
1845
2790
|
{
|
|
1846
2791
|
style: {
|
|
@@ -1861,19 +2806,19 @@ function AuthButton({
|
|
|
1861
2806
|
}
|
|
1862
2807
|
|
|
1863
2808
|
// src/components/auth/AuthDivider.tsx
|
|
1864
|
-
var
|
|
2809
|
+
var import_jsx_runtime48 = require("react/jsx-runtime");
|
|
1865
2810
|
function AuthDivider({ label = "or" }) {
|
|
1866
|
-
return /* @__PURE__ */ (0,
|
|
1867
|
-
/* @__PURE__ */ (0,
|
|
1868
|
-
/* @__PURE__ */ (0,
|
|
1869
|
-
/* @__PURE__ */ (0,
|
|
2811
|
+
return /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: "12px", margin: "20px 0" }, children: [
|
|
2812
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", { style: { flex: 1, height: 1, background: "var(--border)" } }),
|
|
2813
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)("span", { style: { fontSize: "0.75rem", color: "var(--muted-foreground)", userSelect: "none" }, children: label }),
|
|
2814
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", { style: { flex: 1, height: 1, background: "var(--border)" } })
|
|
1870
2815
|
] });
|
|
1871
2816
|
}
|
|
1872
2817
|
|
|
1873
2818
|
// src/components/auth/AuthFootnote.tsx
|
|
1874
|
-
var
|
|
2819
|
+
var import_jsx_runtime49 = require("react/jsx-runtime");
|
|
1875
2820
|
function AuthFootnote({ text, linkText, linkHref }) {
|
|
1876
|
-
return /* @__PURE__ */ (0,
|
|
2821
|
+
return /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("p", { style: {
|
|
1877
2822
|
textAlign: "center",
|
|
1878
2823
|
marginTop: "20px",
|
|
1879
2824
|
fontSize: "0.8125rem",
|
|
@@ -1881,7 +2826,7 @@ function AuthFootnote({ text, linkText, linkHref }) {
|
|
|
1881
2826
|
}, children: [
|
|
1882
2827
|
text,
|
|
1883
2828
|
" ",
|
|
1884
|
-
/* @__PURE__ */ (0,
|
|
2829
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
|
|
1885
2830
|
"a",
|
|
1886
2831
|
{
|
|
1887
2832
|
href: linkHref,
|
|
@@ -1899,9 +2844,9 @@ function AuthFootnote({ text, linkText, linkHref }) {
|
|
|
1899
2844
|
}
|
|
1900
2845
|
|
|
1901
2846
|
// src/components/Skeleton.tsx
|
|
1902
|
-
var
|
|
2847
|
+
var import_jsx_runtime50 = require("react/jsx-runtime");
|
|
1903
2848
|
function Skeleton2({ width = "100%", height = 16, rounded, style }) {
|
|
1904
|
-
return /* @__PURE__ */ (0,
|
|
2849
|
+
return /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
|
|
1905
2850
|
"div",
|
|
1906
2851
|
{
|
|
1907
2852
|
style: {
|
|
@@ -1914,7 +2859,7 @@ function Skeleton2({ width = "100%", height = 16, rounded, style }) {
|
|
|
1914
2859
|
flexShrink: 0,
|
|
1915
2860
|
...style
|
|
1916
2861
|
},
|
|
1917
|
-
children: /* @__PURE__ */ (0,
|
|
2862
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
|
|
1918
2863
|
"div",
|
|
1919
2864
|
{
|
|
1920
2865
|
style: {
|
|
@@ -1930,7 +2875,7 @@ function Skeleton2({ width = "100%", height = 16, rounded, style }) {
|
|
|
1930
2875
|
}
|
|
1931
2876
|
|
|
1932
2877
|
// src/index.ts
|
|
1933
|
-
var
|
|
2878
|
+
var import_next_themes2 = require("next-themes");
|
|
1934
2879
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1935
2880
|
0 && (module.exports = {
|
|
1936
2881
|
Alert,
|
|
@@ -1953,6 +2898,7 @@ var import_next_themes = require("next-themes");
|
|
|
1953
2898
|
CardTitle,
|
|
1954
2899
|
Checkbox,
|
|
1955
2900
|
ConfirmDialog,
|
|
2901
|
+
DashboardLayout,
|
|
1956
2902
|
DataTable,
|
|
1957
2903
|
Dialog,
|
|
1958
2904
|
DialogClose,
|
|
@@ -1983,15 +2929,22 @@ var import_next_themes = require("next-themes");
|
|
|
1983
2929
|
FormField,
|
|
1984
2930
|
FormLayout,
|
|
1985
2931
|
FormSection,
|
|
2932
|
+
ImagePickerField,
|
|
1986
2933
|
Input,
|
|
1987
2934
|
Label,
|
|
1988
2935
|
LoadingSpinner,
|
|
2936
|
+
MediaCard,
|
|
2937
|
+
MediaGrid,
|
|
2938
|
+
MediaPickerDialog,
|
|
2939
|
+
NotificationBell,
|
|
1989
2940
|
Page,
|
|
1990
2941
|
PageSection,
|
|
1991
2942
|
Pagination,
|
|
2943
|
+
PlanBadge,
|
|
1992
2944
|
Popover,
|
|
1993
2945
|
PopoverContent,
|
|
1994
2946
|
PopoverTrigger,
|
|
2947
|
+
SearchBar,
|
|
1995
2948
|
Select,
|
|
1996
2949
|
SelectContent,
|
|
1997
2950
|
SelectGroup,
|
|
@@ -2006,6 +2959,7 @@ var import_next_themes = require("next-themes");
|
|
|
2006
2959
|
Sidebar,
|
|
2007
2960
|
Skeleton,
|
|
2008
2961
|
Stats,
|
|
2962
|
+
StorageBar,
|
|
2009
2963
|
Switch,
|
|
2010
2964
|
Tabs,
|
|
2011
2965
|
TabsContent,
|
|
@@ -2013,6 +2967,7 @@ var import_next_themes = require("next-themes");
|
|
|
2013
2967
|
TabsTrigger,
|
|
2014
2968
|
Textarea,
|
|
2015
2969
|
ThemeProvider,
|
|
2970
|
+
ThemeToggle,
|
|
2016
2971
|
Tooltip,
|
|
2017
2972
|
TooltipContent,
|
|
2018
2973
|
TooltipProvider,
|