@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.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: () => import_next_themes.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: () => import_next_themes.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
- // explicit bg + border + shadow so it never relies on missing CSS vars
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/data/data-table.tsx
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, import_jsx_runtime22.jsxs)("div", { className: "space-y-4", children: [
1129
- selection && selection.selected.length > 0 && actions && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "flex items-center gap-2 rounded-md border bg-muted/50 p-2", children: [
1130
- /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("span", { className: "text-sm text-muted-foreground", children: [
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, import_jsx_runtime22.jsx)("div", { className: "rounded-md border", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "overflow-x-auto", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("table", { className: "w-full text-sm", children: [
1137
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("tr", { className: "border-b bg-muted/50", children: [
1138
- selection && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("th", { className: "w-12 px-4 py-3", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
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, import_jsx_runtime22.jsx)(
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, import_jsx_runtime22.jsx)("tbody", { children: loading ? Array.from({ length: 5 }).map((_, i) => /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("tr", { className: "border-b", children: [
1161
- selection && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("td", { className: "px-4 py-3", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Skeleton, { className: "h-4 w-4" }) }),
1162
- columns.map((col) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("td", { className: "px-4 py-3", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Skeleton, { className: "h-4 w-24" }) }, String(col.key)))
1163
- ] }, i)) : data.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("tr", { children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
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, import_jsx_runtime22.jsx)("p", { className: "text-muted-foreground", children: "No data found" })
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, import_jsx_runtime22.jsxs)(
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, import_jsx_runtime22.jsx)(
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, import_jsx_runtime22.jsx)(
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, import_jsx_runtime22.jsx)("td", { className: "px-4 py-3", children: col.cell ? col.cell(row) : String(row[col.key] ?? "") }, String(col.key)))
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, import_jsx_runtime22.jsxs)("div", { className: "flex items-center justify-between px-2", children: [
1205
- /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "text-sm text-muted-foreground", children: [
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, import_jsx_runtime22.jsxs)("div", { className: "flex items-center gap-2", children: [
1215
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
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, import_jsx_runtime22.jsx)(
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 import_jsx_runtime23 = require("react/jsx-runtime");
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, import_jsx_runtime23.jsxs)(
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, import_jsx_runtime23.jsx)("div", { className: "mb-4 rounded-full bg-muted p-3", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Icon2, { className: "h-6 w-6 text-muted-foreground" }) }),
1256
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("h3", { className: "text-lg font-semibold", children: title }),
1257
- description && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "mt-1 max-w-sm text-sm text-muted-foreground", children: description }),
1258
- action && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "mt-4", children: action })
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 React17 = __toESM(require("react"));
1687
+ var React19 = __toESM(require("react"));
1266
1688
  var import_lucide_react8 = require("lucide-react");
1267
- var import_jsx_runtime24 = require("react/jsx-runtime");
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 = React17.useMemo(() => {
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, import_jsx_runtime24.jsxs)("nav", { className: cn("flex items-center gap-1", className), children: [
1291
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
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, import_jsx_runtime24.jsx)(import_lucide_react8.ChevronLeft, { className: "h-4 w-4" })
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, import_jsx_runtime24.jsx)("span", { className: "px-2 text-muted-foreground", children: "..." }, `e-${i}`) : /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
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, import_jsx_runtime24.jsx)(
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, import_jsx_runtime24.jsx)(import_lucide_react8.ChevronRight, { className: "h-4 w-4" })
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 import_jsx_runtime25 = require("react/jsx-runtime");
1750
+ var import_jsx_runtime29 = require("react/jsx-runtime");
1329
1751
  function Stats({ stats, columns = 4, className }) {
1330
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
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, import_jsx_runtime25.jsxs)(
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, import_jsx_runtime25.jsxs)("div", { className: "flex items-center justify-between", children: [
1348
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("p", { className: "text-sm font-medium text-muted-foreground", children: stat.label }),
1349
- Icon2 && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Icon2, { className: "h-4 w-4 text-muted-foreground" })
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, import_jsx_runtime25.jsxs)("div", { className: "mt-2 flex items-baseline gap-2", children: [
1352
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("p", { className: "text-2xl font-bold", children: stat.value }),
1353
- stat.change && /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
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, import_jsx_runtime25.jsx)(import_lucide_react9.ArrowUp, { className: "mr-0.5 h-3 w-3" }) : /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react9.ArrowDown, { className: "mr-0.5 h-3 w-3" }),
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 import_jsx_runtime26 = require("react/jsx-runtime");
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, import_jsx_runtime26.jsxs)("div", { className: cn("space-y-2", className), children: [
1388
- /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(Label2, { children: [
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, import_jsx_runtime26.jsx)("span", { className: "ml-1 text-destructive", children: "*" })
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, import_jsx_runtime26.jsx)("p", { className: "text-sm text-muted-foreground", children: hint }),
1394
- error && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("p", { className: "text-sm text-destructive", children: error })
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 import_jsx_runtime27 = require("react/jsx-runtime");
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, import_jsx_runtime27.jsxs)(
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, import_jsx_runtime27.jsxs)("div", { className: "border-b p-6", children: [
1416
- title && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("h3", { className: "text-lg font-semibold", children: title }),
1417
- description && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("p", { className: "mt-1 text-sm text-muted-foreground", children: description })
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, import_jsx_runtime27.jsx)("div", { className: "space-y-6 p-6", children }),
1420
- actions && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "flex items-center justify-end gap-2 border-t px-6 py-4", children: actions })
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 import_jsx_runtime28 = require("react/jsx-runtime");
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, import_jsx_runtime28.jsxs)("div", { className: cn("space-y-4", className), children: [
1435
- /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { children: [
1436
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("h4", { className: "text-sm font-medium", children: title }),
1437
- description && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("p", { className: "mt-1 text-sm text-muted-foreground", children: description })
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, import_jsx_runtime28.jsx)("div", { className: "space-y-4", children })
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 import_jsx_runtime29 = require("react/jsx-runtime");
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, import_jsx_runtime29.jsxs)(
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, import_jsx_runtime29.jsx)(Icon2, { className: "mt-0.5 h-5 w-5 shrink-0" }),
1485
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex-1", children: [
1486
- title && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("p", { className: "font-medium", children: title }),
1487
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: cn("text-sm", title && "mt-1"), children })
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, import_jsx_runtime29.jsx)(
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, import_jsx_runtime29.jsx)(import_lucide_react10.X, { className: "h-4 w-4" })
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 import_jsx_runtime30 = require("react/jsx-runtime");
1505
- var sizeMap = {
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, import_jsx_runtime30.jsx)(
2456
+ return /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
1512
2457
  import_lucide_react11.Loader2,
1513
2458
  {
1514
- className: cn("animate-spin text-muted-foreground", sizeMap[size], className)
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 import_jsx_runtime31 = require("react/jsx-runtime");
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, import_jsx_runtime31.jsx)(Dialog, { open, onOpenChange, children: /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(DialogContent, { children: [
1533
- /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(DialogHeader, { children: [
1534
- /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(DialogTitle, { children: title }),
1535
- description && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(DialogDescription, { children: description })
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, import_jsx_runtime31.jsxs)(DialogFooter, { children: [
1538
- /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
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, import_jsx_runtime31.jsxs)(
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, import_jsx_runtime31.jsx)(LoadingSpinner, { size: "sm", className: "mr-2" }),
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 import_jsx_runtime32 = require("react/jsx-runtime");
2527
+ var import_jsx_runtime42 = require("react/jsx-runtime");
1583
2528
  function AuthShell({ children, pattern = "dots", maxWidth = "520px" }) {
1584
- return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
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, import_jsx_runtime32.jsx)(
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, import_jsx_runtime32.jsx)(
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, import_jsx_runtime32.jsx)("div", { style: { position: "relative", zIndex: 1, width: "100%", maxWidth }, children })
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 import_jsx_runtime33 = require("react/jsx-runtime");
2579
+ var import_jsx_runtime43 = require("react/jsx-runtime");
1635
2580
  function AuthCard({ children, padding = "24px 28px" }) {
1636
- return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
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 import_jsx_runtime34 = require("react/jsx-runtime");
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, import_jsx_runtime34.jsxs)("div", { style: { display: "flex", alignItems: "center", justifyContent: "center", gap: "10px", marginBottom: "28px" }, children: [
1656
- imageUrl ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
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, import_jsx_runtime34.jsx)(
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, import_jsx_runtime34.jsx)(
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 import_jsx_runtime35 = require("react/jsx-runtime");
2645
+ var import_jsx_runtime45 = require("react/jsx-runtime");
1701
2646
  function AuthHeader({ title, description }) {
1702
- return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { style: { marginBottom: "24px", textAlign: "center" }, children: [
1703
- /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
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, import_jsx_runtime35.jsx)(
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 import_jsx_runtime36 = require("react/jsx-runtime");
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, import_jsx_runtime36.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: "6px" }, children: [
1736
- /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between" }, children: [
1737
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
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, import_jsx_runtime36.jsx)("span", { style: { fontSize: "0.8125rem" }, children: rightLabel })
2694
+ rightLabel && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { style: { fontSize: "0.8125rem" }, children: rightLabel })
1750
2695
  ] }),
1751
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
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, import_jsx_runtime36.jsx)("p", { style: { fontSize: "0.8rem", color: "var(--destructive)", margin: 0 }, children: error }),
1782
- hint && !error && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("p", { style: { fontSize: "0.8rem", color: "var(--muted-foreground)", margin: 0 }, children: hint })
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 import_jsx_runtime37 = require("react/jsx-runtime");
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, import_jsx_runtime37.jsx)(
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, import_jsx_runtime37.jsxs)(import_jsx_runtime37.Fragment, { children: [
1843
- /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
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 import_jsx_runtime38 = require("react/jsx-runtime");
2809
+ var import_jsx_runtime48 = require("react/jsx-runtime");
1865
2810
  function AuthDivider({ label = "or" }) {
1866
- return /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: "12px", margin: "20px 0" }, children: [
1867
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { style: { flex: 1, height: 1, background: "var(--border)" } }),
1868
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { style: { fontSize: "0.75rem", color: "var(--muted-foreground)", userSelect: "none" }, children: label }),
1869
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { style: { flex: 1, height: 1, background: "var(--border)" } })
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 import_jsx_runtime39 = require("react/jsx-runtime");
2819
+ var import_jsx_runtime49 = require("react/jsx-runtime");
1875
2820
  function AuthFootnote({ text, linkText, linkHref }) {
1876
- return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("p", { style: {
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, import_jsx_runtime39.jsx)(
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 import_jsx_runtime40 = require("react/jsx-runtime");
2847
+ var import_jsx_runtime50 = require("react/jsx-runtime");
1903
2848
  function Skeleton2({ width = "100%", height = 16, rounded, style }) {
1904
- return /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
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, import_jsx_runtime40.jsx)(
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 import_next_themes = require("next-themes");
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,