primus-react-ui 1.0.10 → 1.0.12

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
@@ -33,8 +33,13 @@ __export(index_exports, {
33
33
  AICopilot: () => AICopilot,
34
34
  AccountDashboard: () => AccountDashboard,
35
35
  AgentDirectory: () => AgentDirectory,
36
+ Badge: () => Badge,
37
+ Button: () => Button,
38
+ Card: () => Card,
39
+ Checkbox: () => Checkbox,
36
40
  CheckoutForm: () => CheckoutForm,
37
41
  ClaimStatusTracker: () => ClaimStatusTracker,
42
+ Container: () => Container,
38
43
  CreditCardVisual: () => CreditCardVisual,
39
44
  CreditScoreCard: () => CreditScoreCard,
40
45
  DashboardGrid: () => DashboardGrid,
@@ -42,29 +47,64 @@ __export(index_exports, {
42
47
  FeatureFlagToggle: () => FeatureFlagToggle,
43
48
  FileUploader: () => FileUploader,
44
49
  FraudDetectionDashboard: () => FraudDetectionDashboard,
50
+ Grid: () => Grid,
51
+ Input: () => Input,
45
52
  KYCVerification: () => KYCVerification,
46
53
  LoanCalculator: () => LoanCalculator,
47
54
  LogViewer: () => LogViewer,
48
55
  LoginPage: () => LoginPage,
56
+ Modal: () => Modal,
49
57
  NotificationBell: () => NotificationBell,
50
- NotificationFeed: () => NotificationFeed,
58
+ NotificationFeed: () => PrimusNotificationFeed,
51
59
  PolicyCard: () => PolicyCard,
52
60
  PremiumCalculator: () => PremiumCalculator,
61
+ PrimusActivityFeed: () => PrimusActivityFeed,
62
+ PrimusAreaChart: () => PrimusAreaChart,
63
+ PrimusBadge: () => Badge,
64
+ PrimusBarChart: () => PrimusBarChart,
65
+ PrimusButton: () => Button,
66
+ PrimusCard: () => Card,
67
+ PrimusChartBase: () => PrimusChartBase,
68
+ PrimusCheckbox: () => Checkbox,
69
+ PrimusContainer: () => Container,
53
70
  PrimusDashboard: () => PrimusDashboard,
54
71
  PrimusDataTable: () => PrimusDataTable,
72
+ PrimusDateRangePicker: () => PrimusDateRangePicker,
73
+ PrimusExportMenu: () => PrimusExportMenu,
74
+ PrimusFilterBar: () => PrimusFilterBar,
75
+ PrimusGrid: () => Grid,
55
76
  PrimusHeader: () => PrimusHeader,
77
+ PrimusInput: () => Input,
56
78
  PrimusLayout: () => PrimusLayout,
79
+ PrimusLineChart: () => PrimusLineChart,
57
80
  PrimusLogin: () => PrimusLogin,
58
81
  PrimusModal: () => PrimusModal,
82
+ PrimusModalComponent: () => Modal,
59
83
  PrimusNotificationCenter: () => PrimusNotificationCenter,
84
+ PrimusNotificationFeed: () => PrimusNotificationFeed,
60
85
  PrimusNotifications: () => PrimusNotifications,
86
+ PrimusPieChart: () => PrimusPieChart,
61
87
  PrimusProvider: () => PrimusProvider,
88
+ PrimusRadioGroup: () => RadioGroup,
89
+ PrimusSearch: () => PrimusSearch,
90
+ PrimusSelect: () => Select,
62
91
  PrimusSidebar: () => PrimusSidebar,
92
+ PrimusSparkline: () => PrimusSparkline,
93
+ PrimusStack: () => Stack,
63
94
  PrimusStatCard: () => PrimusStatCard,
95
+ PrimusTable: () => Table,
96
+ PrimusTextarea: () => Textarea,
64
97
  PrimusThemeProvider: () => PrimusThemeProvider,
65
98
  PrimusThemeToggle: () => PrimusThemeToggle,
99
+ PrimusToggle: () => Toggle,
66
100
  QuoteComparison: () => QuoteComparison,
101
+ RadioGroup: () => RadioGroup,
67
102
  SecurityDashboard: () => SecurityDashboard,
103
+ Select: () => Select,
104
+ Stack: () => Stack,
105
+ Table: () => Table,
106
+ Textarea: () => Textarea,
107
+ Toggle: () => Toggle,
68
108
  TransactionHistory: () => TransactionHistory,
69
109
  UserProfile: () => UserProfile,
70
110
  themeColors: () => themeColors,
@@ -1191,75 +1231,191 @@ var usePrimusAuth = () => {
1191
1231
 
1192
1232
  // src/components/shared/Button.tsx
1193
1233
  var import_react15 = __toESM(require("react"));
1194
- var import_clsx = require("clsx");
1195
- var import_tailwind_merge = require("tailwind-merge");
1196
1234
  var import_jsx_runtime15 = require("react/jsx-runtime");
1197
- function cn(...inputs) {
1198
- return (0, import_tailwind_merge.twMerge)((0, import_clsx.clsx)(inputs));
1199
- }
1200
1235
  var Button = import_react15.default.forwardRef(
1201
- ({ className, variant = "primary", size = "md", ...props }, ref) => {
1236
+ ({ style, variant = "primary", size = "md", color = "sapphire", disabled, ...props }, ref) => {
1237
+ const [isHovered, setIsHovered] = import_react15.default.useState(false);
1238
+ const colorStyles = {
1239
+ sapphire: {
1240
+ solid: "#1341a7",
1241
+ // Updated to user spec
1242
+ text: "#ffffff",
1243
+ hover: "rgba(19, 65, 167, 0.9)",
1244
+ subtle: "rgba(19, 65, 167, 0.12)"
1245
+ },
1246
+ emerald: {
1247
+ solid: "#418872",
1248
+ // Updated to user spec
1249
+ text: "#ffffff",
1250
+ hover: "rgba(65, 136, 114, 0.9)",
1251
+ subtle: "rgba(65, 136, 114, 0.12)"
1252
+ },
1253
+ ruby: {
1254
+ solid: "#ac0f0f",
1255
+ // Updated to user spec
1256
+ text: "#ffffff",
1257
+ hover: "rgba(172, 15, 15, 0.9)",
1258
+ subtle: "rgba(172, 15, 15, 0.12)"
1259
+ }
1260
+ };
1261
+ const selectedColor = colorStyles[color];
1262
+ const baseStyles = {
1263
+ display: "inline-flex",
1264
+ alignItems: "center",
1265
+ justifyContent: "center",
1266
+ whiteSpace: "nowrap",
1267
+ borderRadius: "0.5rem",
1268
+ fontSize: "0.875rem",
1269
+ lineHeight: "1.25rem",
1270
+ fontWeight: "600",
1271
+ transition: "all 0.15s cubic-bezier(0.4, 0, 0.2, 1)",
1272
+ cursor: disabled ? "not-allowed" : "pointer",
1273
+ opacity: disabled ? 0.5 : 1,
1274
+ pointerEvents: disabled ? "none" : "auto",
1275
+ outline: "none",
1276
+ border: "none",
1277
+ boxShadow: isHovered && !disabled ? "0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)" : "0 1px 2px 0 rgba(0, 0, 0, 0.05)",
1278
+ transform: isHovered && !disabled ? "translateY(-1px)" : "none"
1279
+ };
1280
+ const variantStyles = {
1281
+ primary: {
1282
+ normal: {
1283
+ backgroundColor: selectedColor.solid,
1284
+ color: selectedColor.text
1285
+ },
1286
+ hover: {
1287
+ backgroundColor: selectedColor.hover
1288
+ }
1289
+ },
1290
+ secondary: {
1291
+ normal: {
1292
+ backgroundColor: "#f3f4f6",
1293
+ color: "#111827"
1294
+ },
1295
+ hover: {
1296
+ backgroundColor: "rgba(243, 244, 246, 0.8)"
1297
+ }
1298
+ },
1299
+ outline: {
1300
+ normal: {
1301
+ backgroundColor: "#ffffff",
1302
+ color: selectedColor.solid,
1303
+ border: `1px solid ${selectedColor.solid}`
1304
+ },
1305
+ hover: {
1306
+ backgroundColor: selectedColor.subtle
1307
+ }
1308
+ },
1309
+ ghost: {
1310
+ normal: {
1311
+ backgroundColor: "transparent",
1312
+ color: selectedColor.solid
1313
+ },
1314
+ hover: {
1315
+ backgroundColor: selectedColor.subtle
1316
+ }
1317
+ }
1318
+ };
1319
+ const sizeStyles = {
1320
+ sm: { height: "2.25rem", padding: "0 0.75rem" },
1321
+ md: { height: "2.5rem", padding: "0.5rem 1rem" },
1322
+ lg: { height: "2.75rem", padding: "0 2rem" }
1323
+ };
1324
+ const currentVariant = variantStyles[variant];
1325
+ const combinedStyles = {
1326
+ ...baseStyles,
1327
+ ...currentVariant.normal,
1328
+ ...isHovered && !disabled ? currentVariant.hover : {},
1329
+ ...sizeStyles[size],
1330
+ ...style
1331
+ };
1202
1332
  return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1203
1333
  "button",
1204
1334
  {
1205
1335
  ref,
1206
- className: cn(
1207
- "inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-white transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-gray-950 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
1208
- {
1209
- "bg-gray-900 text-gray-50 hover:bg-gray-900/90": variant === "primary",
1210
- "bg-gray-100 text-gray-900 hover:bg-gray-100/80": variant === "secondary",
1211
- "border border-gray-200 bg-white hover:bg-gray-100 hover:text-gray-900": variant === "outline",
1212
- "hover:bg-gray-100 hover:text-gray-900": variant === "ghost",
1213
- "h-9 px-3": size === "sm",
1214
- "h-10 px-4 py-2": size === "md",
1215
- "h-11 px-8": size === "lg"
1216
- },
1217
- className
1218
- ),
1336
+ style: combinedStyles,
1337
+ onMouseEnter: () => setIsHovered(true),
1338
+ onMouseLeave: () => setIsHovered(false),
1339
+ disabled,
1219
1340
  ...props
1220
1341
  }
1221
1342
  );
1222
1343
  }
1223
1344
  );
1345
+ Button.displayName = "Button";
1224
1346
 
1225
1347
  // src/components/auth/UserProfile.tsx
1226
1348
  var import_jsx_runtime16 = require("react/jsx-runtime");
1227
- var UserProfile = () => {
1228
- const { user, logout, isAuthenticated } = usePrimusAuth();
1229
- if (!isAuthenticated || !user) {
1349
+ var UserProfile = ({
1350
+ user: userOverride,
1351
+ showLogout = true,
1352
+ onLogout
1353
+ }) => {
1354
+ const { user: contextUser, logout, isAuthenticated } = usePrimusAuth();
1355
+ const resolvedUser = userOverride ?? (isAuthenticated ? contextUser : null);
1356
+ if (!resolvedUser) {
1230
1357
  return null;
1231
1358
  }
1359
+ const handleLogout = async () => {
1360
+ if (onLogout) {
1361
+ onLogout();
1362
+ return;
1363
+ }
1364
+ await logout();
1365
+ };
1232
1366
  return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex items-center gap-4 p-4 rounded-lg bg-gray-50 border border-gray-200", children: [
1233
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "h-10 w-10 rounded-full bg-primus-100 flex items-center justify-center text-primus-600 font-bold", children: user.name?.charAt(0) || "U" }),
1367
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "h-10 w-10 rounded-full bg-primus-100 flex items-center justify-center text-primus-600 font-bold", children: resolvedUser.name?.charAt(0) || "U" }),
1234
1368
  /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex-1", children: [
1235
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { className: "text-sm font-medium text-gray-900", children: user.name }),
1236
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { className: "text-xs text-gray-500", children: user.email })
1369
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { className: "text-sm font-medium text-gray-900", children: resolvedUser.name }),
1370
+ resolvedUser.email && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { className: "text-xs text-gray-500", children: resolvedUser.email })
1237
1371
  ] }),
1238
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Button, { variant: "outline", size: "sm", onClick: () => logout(), children: "Sign out" })
1372
+ showLogout && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Button, { variant: "outline", size: "sm", onClick: handleLogout, children: "Sign out" })
1239
1373
  ] });
1240
1374
  };
1241
1375
 
1242
1376
  // src/hooks/useNotifications.ts
1243
1377
  var import_react16 = require("react");
1244
- var useNotifications = (apiUrl = "http://localhost:5221") => {
1378
+ var useNotifications = ({
1379
+ apiUrl = "http://localhost:5221",
1380
+ useMock = false,
1381
+ mockData = []
1382
+ } = {}) => {
1245
1383
  const [notifications, setNotifications] = (0, import_react16.useState)([]);
1246
1384
  const [unreadCount, setUnreadCount] = (0, import_react16.useState)(0);
1247
1385
  const [loading, setLoading] = (0, import_react16.useState)(true);
1386
+ const safeMockData = (0, import_react16.useMemo)(() => mockData || [], [JSON.stringify(mockData)]);
1387
+ const DEFAULT_MOCK_DATA = [
1388
+ { id: "1", title: "Welcome", message: "Welcome to Primus UI", type: "info", timestamp: (/* @__PURE__ */ new Date()).toISOString(), read: false },
1389
+ { id: "2", title: "System Update", message: "Maintenance scheduled", type: "warning", timestamp: (/* @__PURE__ */ new Date()).toISOString(), read: false },
1390
+ { id: "3", title: "Payment Success", message: "Your payment was processed", type: "success", timestamp: (/* @__PURE__ */ new Date()).toISOString(), read: false }
1391
+ ];
1248
1392
  (0, import_react16.useEffect)(() => {
1393
+ if (useMock) {
1394
+ const data = safeMockData.length > 0 ? safeMockData : DEFAULT_MOCK_DATA;
1395
+ setNotifications(data);
1396
+ setUnreadCount(data.filter((n) => !n.read).length);
1397
+ setLoading(false);
1398
+ return;
1399
+ }
1249
1400
  fetchNotifications();
1250
- const interval = setInterval(fetchNotifications, 3e3);
1401
+ const interval = setInterval(fetchNotifications, 1e4);
1251
1402
  return () => clearInterval(interval);
1252
- }, []);
1403
+ }, [useMock, safeMockData]);
1253
1404
  const fetchNotifications = async () => {
1405
+ if (useMock) return;
1254
1406
  try {
1255
1407
  const response = await fetch(`${apiUrl}/notifications`);
1256
1408
  if (response.ok) {
1257
1409
  const data = await response.json();
1258
1410
  setNotifications(data);
1259
1411
  setUnreadCount(data.filter((n) => !n.read).length);
1412
+ } else {
1413
+ throw new Error("API unavailable");
1260
1414
  }
1261
1415
  } catch (error) {
1262
- console.error("Failed to fetch notifications:", error);
1416
+ console.warn("Failed to fetch notifications, using mock data:", error);
1417
+ setNotifications((prev) => prev.length === 0 ? DEFAULT_MOCK_DATA : prev);
1418
+ setUnreadCount((prev) => notifications.length === 0 ? DEFAULT_MOCK_DATA.filter((n) => !n.read).length : prev);
1263
1419
  } finally {
1264
1420
  setLoading(false);
1265
1421
  }
@@ -1286,7 +1442,7 @@ var useNotifications = (apiUrl = "http://localhost:5221") => {
1286
1442
  var import_outline = require("@heroicons/react/24/outline");
1287
1443
  var import_react17 = require("@headlessui/react");
1288
1444
  var import_react18 = require("react");
1289
- var import_clsx2 = require("clsx");
1445
+ var import_clsx = require("clsx");
1290
1446
  var import_jsx_runtime17 = require("react/jsx-runtime");
1291
1447
  var NotificationIcon = ({ type }) => {
1292
1448
  switch (type) {
@@ -1300,10 +1456,10 @@ var NotificationIcon = ({ type }) => {
1300
1456
  return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_outline.InformationCircleIcon, { className: "h-6 w-6 text-blue-500" });
1301
1457
  }
1302
1458
  };
1303
- var NotificationFeed = () => {
1304
- const { notifications, unreadCount, markAsRead, markAllAsRead } = useNotifications();
1305
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_react17.Popover, { className: "relative", children: ({ open }) => /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
1306
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_react17.Popover.Button, { className: (0, import_clsx2.clsx)(
1459
+ var PrimusNotificationFeed = ({ useMock, mockData, apiUrl, className }) => {
1460
+ const { notifications, unreadCount, markAsRead, markAllAsRead } = useNotifications({ useMock, mockData, apiUrl });
1461
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_react17.Popover, { className: (0, import_clsx.clsx)("relative", className), children: ({ open }) => /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
1462
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_react17.Popover.Button, { className: (0, import_clsx.clsx)(
1307
1463
  "relative p-2 rounded-full hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-primus-500",
1308
1464
  open && "bg-gray-100"
1309
1465
  ), children: [
@@ -1335,7 +1491,7 @@ var NotificationFeed = () => {
1335
1491
  /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "max-h-96 overflow-y-auto", children: notifications.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "px-4 py-6 text-center text-sm text-gray-500", children: "No new notifications" }) : /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "divide-y divide-gray-100", children: notifications.map((notification) => /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
1336
1492
  "div",
1337
1493
  {
1338
- className: (0, import_clsx2.clsx)(
1494
+ className: (0, import_clsx.clsx)(
1339
1495
  "flex gap-3 px-4 py-4 hover:bg-gray-50 transition-colors cursor-pointer",
1340
1496
  !notification.read && "bg-blue-50/50"
1341
1497
  ),
@@ -1364,7 +1520,13 @@ var import_react19 = require("react");
1364
1520
  var import_lucide_react = require("lucide-react");
1365
1521
  var import_jsx_runtime18 = require("react/jsx-runtime");
1366
1522
  var API_URL = "http://localhost:5222";
1367
- function PrimusNotificationCenter({ theme: themeOverride, apiUrl = API_URL }) {
1523
+ function PrimusNotificationCenter({
1524
+ theme: themeOverride,
1525
+ apiUrl = API_URL,
1526
+ pollInterval = 3e3,
1527
+ useMock = false,
1528
+ mockData
1529
+ }) {
1368
1530
  const themeContext = usePrimusTheme();
1369
1531
  const theme = themeOverride || themeContext.theme;
1370
1532
  const t = themeColors[theme];
@@ -1388,13 +1550,37 @@ function PrimusNotificationCenter({ theme: themeOverride, apiUrl = API_URL }) {
1388
1550
  }
1389
1551
  }, [apiUrl]);
1390
1552
  (0, import_react19.useEffect)(() => {
1553
+ if (useMock || mockData) {
1554
+ const next = mockData ?? [];
1555
+ setNotifications(next);
1556
+ setUnreadCount(next.filter((n) => !n.read).length);
1557
+ return;
1558
+ }
1391
1559
  fetchNotifications();
1392
- const interval = setInterval(fetchNotifications, 3e3);
1560
+ const interval = setInterval(fetchNotifications, pollInterval);
1393
1561
  return () => clearInterval(interval);
1394
- }, [fetchNotifications]);
1562
+ }, [fetchNotifications, pollInterval, useMock, mockData]);
1395
1563
  const sendNotification = async () => {
1396
1564
  if (!newTitle.trim() || !newMessage.trim()) return;
1397
1565
  setSending(true);
1566
+ if (useMock || mockData) {
1567
+ const next = {
1568
+ id: `mock-${Date.now()}`,
1569
+ title: newTitle,
1570
+ message: newMessage,
1571
+ type: newType,
1572
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
1573
+ read: false
1574
+ };
1575
+ setNotifications((prev) => [next, ...prev]);
1576
+ setUnreadCount((prev) => prev + 1);
1577
+ setNewTitle("");
1578
+ setNewMessage("");
1579
+ setNewType("info");
1580
+ setShowSendForm(false);
1581
+ setSending(false);
1582
+ return;
1583
+ }
1398
1584
  try {
1399
1585
  const response = await fetch(`${apiUrl}/api/notifications`, {
1400
1586
  method: "POST",
@@ -1414,8 +1600,13 @@ function PrimusNotificationCenter({ theme: themeOverride, apiUrl = API_URL }) {
1414
1600
  setSending(false);
1415
1601
  };
1416
1602
  const markAsRead = async (id) => {
1603
+ if (useMock || mockData) {
1604
+ setNotifications((prev) => prev.map((n) => n.id === id ? { ...n, read: true } : n));
1605
+ setUnreadCount((prev) => Math.max(0, prev - 1));
1606
+ return;
1607
+ }
1417
1608
  try {
1418
- await fetch(`${apiUrl}/api/notifications/${id}/read`, { method: "PUT" });
1609
+ await fetch(`${apiUrl}/api/notifications/${id}/read`, { method: "POST" });
1419
1610
  setNotifications((prev) => prev.map((n) => n.id === id ? { ...n, read: true } : n));
1420
1611
  setUnreadCount((prev) => Math.max(0, prev - 1));
1421
1612
  } catch {
@@ -1655,35 +1846,84 @@ var import_react22 = require("react");
1655
1846
 
1656
1847
  // src/components/shared/Input.tsx
1657
1848
  var import_react21 = __toESM(require("react"));
1658
- var import_clsx3 = require("clsx");
1659
- var import_tailwind_merge2 = require("tailwind-merge");
1849
+ var import_clsx2 = require("clsx");
1850
+ var import_solid = require("@heroicons/react/20/solid");
1660
1851
  var import_jsx_runtime19 = require("react/jsx-runtime");
1661
- function cn2(...inputs) {
1662
- return (0, import_tailwind_merge2.twMerge)((0, import_clsx3.clsx)(inputs));
1663
- }
1852
+ var sizeClasses = {
1853
+ sm: "h-8 text-xs",
1854
+ md: "h-10 text-sm",
1855
+ lg: "h-12 text-base"
1856
+ };
1857
+ var iconSizeClasses = {
1858
+ sm: "w-4 h-4 [&>*]:w-full [&>*]:h-full",
1859
+ md: "w-5 h-5 [&>*]:w-full [&>*]:h-full",
1860
+ lg: "w-6 h-6 [&>*]:w-full [&>*]:h-full"
1861
+ };
1664
1862
  var Input = import_react21.default.forwardRef(
1665
- ({ className, label, error, ...props }, ref) => {
1666
- return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "w-full", children: [
1667
- label && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("label", { className: "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70 mb-2 block text-gray-700", children: label }),
1668
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
1669
- "input",
1670
- {
1671
- ref,
1672
- className: cn2(
1673
- "flex h-10 w-full rounded-md border border-gray-200 bg-white px-3 py-2 text-sm ring-offset-white file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-gray-500 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-gray-950 focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
1674
- error && "border-red-500 focus-visible:ring-red-500",
1675
- className
1676
- ),
1677
- ...props
1678
- }
1679
- ),
1680
- error && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { className: "text-sm text-red-500 mt-1", children: error })
1863
+ ({ className, style, label, error, disabled, startIcon, endIcon, onClear, value, onChange, size = "md", loading = false, ...props }, ref) => {
1864
+ const hasValue = value !== void 0 && value !== "" && value !== null;
1865
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: (0, import_clsx2.clsx)("w-full", className), style, children: [
1866
+ label && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("label", { className: (0, import_clsx2.clsx)(
1867
+ "block font-medium mb-1.5",
1868
+ size === "sm" ? "text-xs" : "text-sm",
1869
+ disabled ? "text-gray-400 opacity-70" : "text-gray-700"
1870
+ ), children: label }),
1871
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: (0, import_clsx2.clsx)(
1872
+ "relative flex items-center w-full rounded-lg transition-all duration-200 ease-in-out bg-white overflow-hidden",
1873
+ "border",
1874
+ error ? "border-red-500 hover:border-red-600 focus-within:ring-2 focus-within:ring-red-500/20 focus-within:border-red-500" : "border-gray-200 hover:border-gray-300 focus-within:ring-2 focus-within:ring-primus-500/20 focus-within:border-primus-500",
1875
+ disabled && "bg-gray-50 opacity-60 cursor-not-allowed"
1876
+ ), children: [
1877
+ startIcon && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: (0, import_clsx2.clsx)(
1878
+ "flex-shrink-0 pl-3 pr-2 text-gray-400 select-none pointer-events-none flex items-center justify-center",
1879
+ iconSizeClasses[size]
1880
+ ), children: startIcon }),
1881
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
1882
+ "input",
1883
+ {
1884
+ ref,
1885
+ disabled,
1886
+ value,
1887
+ onChange,
1888
+ className: (0, import_clsx2.clsx)(
1889
+ "flex-1 w-full border-none bg-transparent p-0 placeholder:text-gray-400 focus:ring-0 outline-none",
1890
+ sizeClasses[size],
1891
+ // Adjust padding based on icon presence
1892
+ !startIcon && "pl-3",
1893
+ !endIcon && !onClear && !loading && "pr-3"
1894
+ ),
1895
+ ...props
1896
+ }
1897
+ ),
1898
+ onClear && hasValue && !disabled && !loading && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "flex-shrink-0 pr-2 flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
1899
+ "button",
1900
+ {
1901
+ type: "button",
1902
+ onClick: (e) => {
1903
+ e.stopPropagation();
1904
+ onClear();
1905
+ },
1906
+ className: "p-1 rounded-full text-gray-400 hover:text-gray-600 hover:bg-gray-100 transition-colors",
1907
+ children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_solid.XMarkIcon, { className: "h-4 w-4" })
1908
+ }
1909
+ ) }),
1910
+ loading && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "flex-shrink-0 pr-3 pl-2 flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("svg", { className: "animate-spin h-5 w-5 text-primus-500", xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", children: [
1911
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }),
1912
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" })
1913
+ ] }) }),
1914
+ endIcon && !loading && (onClear ? !hasValue : true) && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: (0, import_clsx2.clsx)(
1915
+ "flex-shrink-0 pr-3 pl-2 text-gray-400 select-none pointer-events-none flex items-center justify-center",
1916
+ iconSizeClasses[size]
1917
+ ), children: endIcon })
1918
+ ] }),
1919
+ error && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { className: "mt-1.5 text-xs text-red-500 flex items-center gap-1 animate-in slide-in-from-top-1 fade-in duration-200", children: error })
1681
1920
  ] });
1682
1921
  }
1683
1922
  );
1923
+ Input.displayName = "Input";
1684
1924
 
1685
1925
  // src/components/payments/CheckoutForm.tsx
1686
- var import_solid = require("@heroicons/react/24/solid");
1926
+ var import_solid2 = require("@heroicons/react/24/solid");
1687
1927
  var import_jsx_runtime20 = require("react/jsx-runtime");
1688
1928
  var CheckoutForm = ({
1689
1929
  amount,
@@ -1742,7 +1982,7 @@ var CheckoutForm = ({
1742
1982
  /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex justify-between items-center mb-6", children: [
1743
1983
  /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("h3", { className: "text-lg font-medium text-gray-900", children: "Payment Details" }),
1744
1984
  /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex items-center text-gray-500 text-sm", children: [
1745
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_solid.LockClosedIcon, { className: "h-4 w-4 mr-1" }),
1985
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_solid2.LockClosedIcon, { className: "h-4 w-4 mr-1" }),
1746
1986
  "Secure Payment"
1747
1987
  ] })
1748
1988
  ] }),
@@ -1751,11 +1991,11 @@ var CheckoutForm = ({
1751
1991
  /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "text-2xl font-bold text-gray-900", children: new Intl.NumberFormat("en-US", { style: "currency", currency }).format(amount) })
1752
1992
  ] }),
1753
1993
  error && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "mb-4 p-3 bg-red-50 border border-red-200 rounded-lg flex items-start gap-2", children: [
1754
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_solid.XCircleIcon, { className: "h-5 w-5 text-red-500 flex-shrink-0 mt-0.5" }),
1994
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_solid2.XCircleIcon, { className: "h-5 w-5 text-red-500 flex-shrink-0 mt-0.5" }),
1755
1995
  /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("p", { className: "text-sm text-red-700", children: error })
1756
1996
  ] }),
1757
1997
  success && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "mb-4 p-3 bg-green-50 border border-green-200 rounded-lg flex items-start gap-2", children: [
1758
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_solid.CheckCircleIcon, { className: "h-5 w-5 text-green-500 flex-shrink-0 mt-0.5" }),
1998
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_solid2.CheckCircleIcon, { className: "h-5 w-5 text-green-500 flex-shrink-0 mt-0.5" }),
1759
1999
  /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("p", { className: "text-sm text-green-700", children: "Payment successful!" })
1760
2000
  ] }),
1761
2001
  /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("form", { onSubmit: handleSubmit, className: "space-y-4", children: [
@@ -1826,18 +2066,18 @@ var CheckoutForm = ({
1826
2066
  var import_outline2 = require("@heroicons/react/24/outline");
1827
2067
  var import_jsx_runtime21 = require("react/jsx-runtime");
1828
2068
  var DocumentViewer = ({
1829
- document,
2069
+ document: document2,
1830
2070
  onClose,
1831
2071
  onDownload
1832
2072
  }) => {
1833
2073
  const renderContent = () => {
1834
- switch (document.type) {
2074
+ switch (document2.type) {
1835
2075
  case "image":
1836
2076
  return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
1837
2077
  "img",
1838
2078
  {
1839
- src: document.url,
1840
- alt: document.name,
2079
+ src: document2.url,
2080
+ alt: document2.name,
1841
2081
  className: "max-w-full max-h-[80vh] object-contain mx-auto shadow-lg rounded"
1842
2082
  }
1843
2083
  );
@@ -1845,14 +2085,14 @@ var DocumentViewer = ({
1845
2085
  return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "bg-gray-100 p-8 rounded-lg text-center h-[600px] flex items-center justify-center border-2 border-dashed border-gray-300", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "text-gray-500", children: [
1846
2086
  /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_outline2.DocumentArrowDownIcon, { className: "h-16 w-16 mx-auto mb-4 text-gray-400" }),
1847
2087
  /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("p", { className: "font-medium", children: "PDF Preview" }),
1848
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("p", { className: "text-sm mt-2", children: document.name }),
2088
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("p", { className: "text-sm mt-2", children: document2.name }),
1849
2089
  /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Button, { variant: "outline", size: "sm", className: "mt-4", onClick: onDownload, children: "Download to view" })
1850
2090
  ] }) });
1851
2091
  default:
1852
2092
  return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "bg-white p-8 rounded shadow border border-gray-200 h-[600px] overflow-auto font-mono text-sm leading-relaxed", children: [
1853
2093
  /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("p", { children: [
1854
2094
  "Document Content: ",
1855
- document.name
2095
+ document2.name
1856
2096
  ] }),
1857
2097
  /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("p", { className: "mt-4 text-gray-500", children: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua." })
1858
2098
  ] });
@@ -1861,13 +2101,13 @@ var DocumentViewer = ({
1861
2101
  return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex flex-col h-full bg-gray-50 rounded-lg overflow-hidden border border-gray-200", children: [
1862
2102
  /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "bg-white border-b border-gray-200 px-4 py-3 flex items-center justify-between shadow-sm", children: [
1863
2103
  /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex items-center gap-3", children: [
1864
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "h-8 w-8 bg-primus-100 rounded flex items-center justify-center text-primus-700", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "uppercase text-xs font-bold", children: document.type }) }),
2104
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "h-8 w-8 bg-primus-100 rounded flex items-center justify-center text-primus-700", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "uppercase text-xs font-bold", children: document2.type }) }),
1865
2105
  /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { children: [
1866
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("h3", { className: "text-sm font-semibold text-gray-900", children: document.name }),
1867
- document.size && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("p", { className: "text-xs text-gray-500", children: [
1868
- document.size,
2106
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("h3", { className: "text-sm font-semibold text-gray-900", children: document2.name }),
2107
+ document2.size && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("p", { className: "text-xs text-gray-500", children: [
2108
+ document2.size,
1869
2109
  " \u2022 ",
1870
- document.date
2110
+ document2.date
1871
2111
  ] })
1872
2112
  ] })
1873
2113
  ] }),
@@ -1883,7 +2123,7 @@ var DocumentViewer = ({
1883
2123
  };
1884
2124
 
1885
2125
  // src/components/banking/cards/CreditCardVisual.tsx
1886
- var import_clsx4 = require("clsx");
2126
+ var import_clsx3 = require("clsx");
1887
2127
  var import_outline3 = require("@heroicons/react/24/outline");
1888
2128
  var import_jsx_runtime22 = require("react/jsx-runtime");
1889
2129
  var CreditCardVisual = ({
@@ -1905,7 +2145,7 @@ var CreditCardVisual = ({
1905
2145
  return "bg-gradient-to-br from-gray-900 to-gray-800";
1906
2146
  }
1907
2147
  };
1908
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: (0, import_clsx4.clsx)(
2148
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: (0, import_clsx3.clsx)(
1909
2149
  "w-80 h-48 rounded-2xl p-6 text-white shadow-xl relative overflow-hidden transition-transform hover:scale-105 duration-300",
1910
2150
  getBackground()
1911
2151
  ), children: [
@@ -1935,7 +2175,7 @@ var CreditCardVisual = ({
1935
2175
 
1936
2176
  // src/components/banking/transactions/TransactionHistory.tsx
1937
2177
  var import_outline4 = require("@heroicons/react/24/outline");
1938
- var import_clsx5 = require("clsx");
2178
+ var import_clsx4 = require("clsx");
1939
2179
  var import_jsx_runtime23 = require("react/jsx-runtime");
1940
2180
  var TransactionHistory = ({
1941
2181
  transactions,
@@ -1958,7 +2198,7 @@ var TransactionHistory = ({
1958
2198
  className: "px-6 py-4 flex items-center justify-between hover:bg-gray-50 cursor-pointer transition-colors",
1959
2199
  children: [
1960
2200
  /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex items-center gap-4", children: [
1961
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: (0, import_clsx5.clsx)(
2201
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: (0, import_clsx4.clsx)(
1962
2202
  "h-10 w-10 rounded-full flex items-center justify-center",
1963
2203
  t.type === "credit" ? "bg-green-100" : "bg-gray-100"
1964
2204
  ), children: getIcon(t) }),
@@ -1968,7 +2208,7 @@ var TransactionHistory = ({
1968
2208
  ] })
1969
2209
  ] }),
1970
2210
  /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "text-right", children: [
1971
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("p", { className: (0, import_clsx5.clsx)(
2211
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("p", { className: (0, import_clsx4.clsx)(
1972
2212
  "text-sm font-semibold",
1973
2213
  t.type === "credit" ? "text-green-600" : "text-gray-900"
1974
2214
  ), children: [
@@ -1985,7 +2225,7 @@ var TransactionHistory = ({
1985
2225
  };
1986
2226
 
1987
2227
  // src/components/insurance/policies/PolicyCard.tsx
1988
- var import_clsx6 = require("clsx");
2228
+ var import_clsx5 = require("clsx");
1989
2229
  var import_outline5 = require("@heroicons/react/24/outline");
1990
2230
  var import_jsx_runtime24 = require("react/jsx-runtime");
1991
2231
  var PolicyCard = ({
@@ -2005,7 +2245,7 @@ var PolicyCard = ({
2005
2245
  " Insurance"
2006
2246
  ] })
2007
2247
  ] }),
2008
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: (0, import_clsx6.clsx)(
2248
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: (0, import_clsx5.clsx)(
2009
2249
  "px-2.5 py-0.5 rounded-full text-xs font-medium uppercase tracking-wide",
2010
2250
  status === "active" ? "bg-green-100 text-green-800" : status === "pending" ? "bg-yellow-100 text-yellow-800" : "bg-gray-100 text-gray-800"
2011
2251
  ), children: status })
@@ -2044,8 +2284,8 @@ var PolicyCard = ({
2044
2284
  };
2045
2285
 
2046
2286
  // src/components/insurance/claims/ClaimStatusTracker.tsx
2047
- var import_clsx7 = require("clsx");
2048
- var import_solid2 = require("@heroicons/react/24/solid");
2287
+ var import_clsx6 = require("clsx");
2288
+ var import_solid3 = require("@heroicons/react/24/solid");
2049
2289
  var import_jsx_runtime25 = require("react/jsx-runtime");
2050
2290
  var ClaimStatusTracker = ({
2051
2291
  claimId,
@@ -2059,14 +2299,14 @@ var ClaimStatusTracker = ({
2059
2299
  claimId
2060
2300
  ] })
2061
2301
  ] }),
2062
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("nav", { "aria-label": "Progress", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("ol", { role: "list", className: "overflow-hidden", children: steps.map((step, stepIdx) => /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("li", { className: (0, import_clsx7.clsx)(
2302
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("nav", { "aria-label": "Progress", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("ol", { role: "list", className: "overflow-hidden", children: steps.map((step, stepIdx) => /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("li", { className: (0, import_clsx6.clsx)(
2063
2303
  "relative pb-10",
2064
2304
  stepIdx === steps.length - 1 ? "pb-0" : ""
2065
2305
  ), children: [
2066
2306
  stepIdx !== steps.length - 1 ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
2067
2307
  "div",
2068
2308
  {
2069
- className: (0, import_clsx7.clsx)(
2309
+ className: (0, import_clsx6.clsx)(
2070
2310
  "absolute top-4 left-4 -ml-px h-full w-0.5",
2071
2311
  step.status === "completed" ? "bg-primus-600" : "bg-gray-200"
2072
2312
  ),
@@ -2074,12 +2314,12 @@ var ClaimStatusTracker = ({
2074
2314
  }
2075
2315
  ) : null,
2076
2316
  /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "relative flex items-start group", children: [
2077
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "h-9 flex items-center", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: (0, import_clsx7.clsx)(
2317
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "h-9 flex items-center", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: (0, import_clsx6.clsx)(
2078
2318
  "relative z-10 w-8 h-8 flex items-center justify-center rounded-full ring-1 ring-white",
2079
2319
  step.status === "completed" ? "bg-primus-600" : step.status === "current" ? "bg-white border-2 border-primus-600" : "bg-white border-2 border-gray-300"
2080
- ), children: step.status === "completed" ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_solid2.CheckIcon, { className: "w-5 h-5 text-white", "aria-hidden": "true" }) : step.status === "current" ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "h-2.5 w-2.5 bg-primus-600 rounded-full" }) : null }) }),
2320
+ ), children: step.status === "completed" ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_solid3.CheckIcon, { className: "w-5 h-5 text-white", "aria-hidden": "true" }) : step.status === "current" ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "h-2.5 w-2.5 bg-primus-600 rounded-full" }) : null }) }),
2081
2321
  /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("span", { className: "ml-4 min-w-0 flex flex-col", children: [
2082
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: (0, import_clsx7.clsx)(
2322
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: (0, import_clsx6.clsx)(
2083
2323
  "text-sm font-medium",
2084
2324
  step.status === "upcoming" ? "text-gray-500" : "text-gray-900"
2085
2325
  ), children: step.label }),
@@ -2235,9 +2475,14 @@ var PrimusSidebar = ({
2235
2475
  logo && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "h-20 flex items-center px-6 relative z-10 border-b border-white/5", children: logo }),
2236
2476
  /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("nav", { className: "flex-1 py-6 px-3 overflow-y-auto relative z-10", children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("ul", { className: "space-y-1", children: items.map((item) => {
2237
2477
  const isActive = activeId === item.id || item.active;
2478
+ const link = item.href ?? item.route;
2479
+ const Wrapper = link ? "a" : "button";
2238
2480
  return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
2239
- "button",
2481
+ Wrapper,
2240
2482
  {
2483
+ href: link,
2484
+ target: item.target,
2485
+ rel: item.target === "_blank" ? "noreferrer" : void 0,
2241
2486
  onClick: () => {
2242
2487
  item.onClick?.();
2243
2488
  onItemClick?.(item);
@@ -2310,11 +2555,16 @@ function PrimusDataTable({
2310
2555
  actions,
2311
2556
  emptyMessage = "No data available",
2312
2557
  searchPlaceholder = "Filter...",
2313
- searchable = true
2558
+ searchable = true,
2559
+ paginated = false,
2560
+ pageSize = 10,
2561
+ pageIndex,
2562
+ onPageChange
2314
2563
  }) {
2315
2564
  const [search, setSearch] = (0, import_react26.useState)("");
2316
2565
  const [sortKey, setSortKey] = (0, import_react26.useState)(null);
2317
2566
  const [sortDir, setSortDir] = (0, import_react26.useState)("asc");
2567
+ const [internalPageIndex, setInternalPageIndex] = (0, import_react26.useState)(0);
2318
2568
  const filteredData = (0, import_react26.useMemo)(() => {
2319
2569
  let result = [...data];
2320
2570
  if (search) {
@@ -2342,16 +2592,33 @@ function PrimusDataTable({
2342
2592
  setSortKey(key);
2343
2593
  setSortDir("asc");
2344
2594
  }
2595
+ if (paginated) {
2596
+ goToPage(0);
2597
+ }
2598
+ };
2599
+ const effectivePageIndex = pageIndex ?? internalPageIndex;
2600
+ const totalPages = Math.max(1, Math.ceil(filteredData.length / Math.max(pageSize, 1)));
2601
+ const currentPageIndex = Math.min(Math.max(effectivePageIndex, 0), totalPages - 1);
2602
+ const pageData = paginated ? filteredData.slice(currentPageIndex * pageSize, currentPageIndex * pageSize + pageSize) : filteredData;
2603
+ const selectionScope = paginated ? pageData : filteredData;
2604
+ const isScopeSelected = selectionScope.length > 0 && selectionScope.every((row) => selectedKeys.includes(row[rowKey]));
2605
+ const goToPage = (nextIndex) => {
2606
+ const clamped = Math.min(Math.max(nextIndex, 0), totalPages - 1);
2607
+ if (pageIndex === void 0) {
2608
+ setInternalPageIndex(clamped);
2609
+ }
2610
+ onPageChange?.({ pageIndex: clamped, pageSize });
2345
2611
  };
2346
2612
  const toggleSelect = (key) => {
2347
2613
  const newKeys = selectedKeys.includes(key) ? selectedKeys.filter((k) => k !== key) : [...selectedKeys, key];
2348
2614
  onSelectionChange?.(newKeys);
2349
2615
  };
2350
2616
  const toggleSelectAll = () => {
2351
- if (selectedKeys.length === filteredData.length) {
2617
+ const scopeKeys = selectionScope.map((row) => row[rowKey]);
2618
+ if (isScopeSelected) {
2352
2619
  onSelectionChange?.([]);
2353
2620
  } else {
2354
- onSelectionChange?.(filteredData.map((row) => row[rowKey]));
2621
+ onSelectionChange?.(scopeKeys);
2355
2622
  }
2356
2623
  };
2357
2624
  return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: "flex flex-col space-y-4", children: [
@@ -2363,7 +2630,12 @@ function PrimusDataTable({
2363
2630
  type: "text",
2364
2631
  placeholder: searchPlaceholder,
2365
2632
  value: search,
2366
- onChange: (e) => setSearch(e.target.value),
2633
+ onChange: (e) => {
2634
+ setSearch(e.target.value);
2635
+ if (paginated) {
2636
+ goToPage(0);
2637
+ }
2638
+ },
2367
2639
  className: "w-64 pl-10 pr-4 py-2 bg-white/5 border border-white/10 rounded-lg text-sm text-gray-200 placeholder-gray-500 focus:outline-none focus:ring-1 focus:ring-purple-500/50 focus:bg-white/10 transition-all hover:bg-white/10"
2368
2640
  }
2369
2641
  )
@@ -2374,7 +2646,7 @@ function PrimusDataTable({
2374
2646
  "input",
2375
2647
  {
2376
2648
  type: "checkbox",
2377
- checked: selectedKeys.length === filteredData.length && filteredData.length > 0,
2649
+ checked: isScopeSelected,
2378
2650
  onChange: toggleSelectAll,
2379
2651
  className: "rounded border-gray-600 bg-gray-800 text-purple-600 focus:ring-offset-gray-900 focus:ring-purple-500 transition-colors cursor-pointer"
2380
2652
  }
@@ -2397,7 +2669,7 @@ function PrimusDataTable({
2397
2669
  /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("tbody", { className: "divide-y divide-white/5", children: loading ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("tr", { children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("td", { colSpan: columns.length + (selectable ? 1 : 0) + (actions ? 1 : 0), className: "px-6 py-24 text-center text-gray-500", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: "flex flex-col items-center justify-center gap-3", children: [
2398
2670
  /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: "w-6 h-6 border-2 border-purple-500/50 border-t-purple-500 rounded-full animate-spin" }),
2399
2671
  /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "text-sm font-medium", children: "Loading data..." })
2400
- ] }) }) }) : filteredData.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("tr", { children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("td", { colSpan: columns.length + (selectable ? 1 : 0) + (actions ? 1 : 0), className: "px-6 py-24 text-center text-gray-500", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("p", { className: "text-sm", children: emptyMessage }) }) }) : filteredData.map((row) => /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(
2672
+ ] }) }) }) : filteredData.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("tr", { children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("td", { colSpan: columns.length + (selectable ? 1 : 0) + (actions ? 1 : 0), className: "px-6 py-24 text-center text-gray-500", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("p", { className: "text-sm", children: emptyMessage }) }) }) : pageData.map((row) => /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(
2401
2673
  "tr",
2402
2674
  {
2403
2675
  onClick: () => onRowClick?.(row),
@@ -2422,7 +2694,35 @@ function PrimusDataTable({
2422
2694
  },
2423
2695
  String(row[rowKey])
2424
2696
  )) })
2425
- ] }) }) })
2697
+ ] }) }) }),
2698
+ paginated && totalPages > 1 && /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: "flex items-center justify-between text-sm text-gray-400 px-2", children: [
2699
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
2700
+ "button",
2701
+ {
2702
+ type: "button",
2703
+ onClick: () => goToPage(currentPageIndex - 1),
2704
+ disabled: currentPageIndex === 0,
2705
+ className: "px-3 py-2 rounded-lg border border-white/10 bg-white/5 hover:bg-white/10 disabled:opacity-50 disabled:cursor-not-allowed",
2706
+ children: "Previous"
2707
+ }
2708
+ ),
2709
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("span", { children: [
2710
+ "Page ",
2711
+ currentPageIndex + 1,
2712
+ " of ",
2713
+ totalPages
2714
+ ] }),
2715
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
2716
+ "button",
2717
+ {
2718
+ type: "button",
2719
+ onClick: () => goToPage(currentPageIndex + 1),
2720
+ disabled: currentPageIndex >= totalPages - 1,
2721
+ className: "px-3 py-2 rounded-lg border border-white/10 bg-white/5 hover:bg-white/10 disabled:opacity-50 disabled:cursor-not-allowed",
2722
+ children: "Next"
2723
+ }
2724
+ )
2725
+ ] })
2426
2726
  ] });
2427
2727
  }
2428
2728
 
@@ -2437,7 +2737,7 @@ var PrimusModal = ({
2437
2737
  size = "md"
2438
2738
  }) => {
2439
2739
  if (!open) return null;
2440
- const sizeClasses = {
2740
+ const sizeClasses2 = {
2441
2741
  sm: "max-w-sm",
2442
2742
  md: "max-w-md",
2443
2743
  lg: "max-w-lg",
@@ -2451,7 +2751,7 @@ var PrimusModal = ({
2451
2751
  onClick: onClose
2452
2752
  }
2453
2753
  ),
2454
- /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: `relative w-full ${sizeClasses[size]} mx-4 bg-gray-800 rounded-xl border border-gray-700 shadow-2xl`, children: [
2754
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: `relative w-full ${sizeClasses2[size]} mx-4 bg-gray-800 rounded-xl border border-gray-700 shadow-2xl`, children: [
2455
2755
  title && /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "flex items-center justify-between px-6 py-4 border-b border-gray-700", children: [
2456
2756
  /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("h2", { className: "text-lg font-semibold text-white", children: title }),
2457
2757
  /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
@@ -2491,12 +2791,28 @@ var PrimusStatCard = ({
2491
2791
  neutral: "\u2192"
2492
2792
  };
2493
2793
  const renderSparkline = () => {
2494
- return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("svg", { className: "w-full h-12 opacity-50 absolute bottom-0 left-0", preserveAspectRatio: "none", "data-trend": trend.join(","), children: [
2495
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("path", { d: "M0 40 Q 20 20 40 40 T 80 40 T 120 40 T 160 30 V 50 H 0 Z", fill: `url(#gradient-${title.replace(/\s/g, "")})`, stroke: "none" }),
2496
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("defs", { children: /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("linearGradient", { id: `gradient-${title.replace(/\s/g, "")}`, x1: "0", y1: "0", x2: "0", y2: "1", children: [
2497
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("stop", { offset: "0%", stopColor: "currentColor", stopOpacity: "0.2" }),
2794
+ if (!trend || trend.length === 0) {
2795
+ return null;
2796
+ }
2797
+ const max = Math.max(...trend);
2798
+ const min = Math.min(...trend);
2799
+ const range = max - min || 1;
2800
+ const divisor = trend.length > 1 ? trend.length - 1 : 1;
2801
+ const points = trend.map((value2, index) => {
2802
+ const x = index / divisor * 100;
2803
+ const y = 100 - (value2 - min) / range * 100;
2804
+ return { x, y };
2805
+ });
2806
+ const linePath = points.map((point, index) => `${index === 0 ? "M" : "L"} ${point.x} ${point.y}`).join(" ");
2807
+ const areaPath = `${linePath} L 100 100 L 0 100 Z`;
2808
+ const gradientId = `gradient-${title.replace(/\s/g, "")}`;
2809
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("svg", { className: "w-full h-12 opacity-60 absolute bottom-0 left-0", viewBox: "0 0 100 100", preserveAspectRatio: "none", "data-trend": trend.join(","), children: [
2810
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("defs", { children: /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("linearGradient", { id: gradientId, x1: "0", y1: "0", x2: "0", y2: "1", children: [
2811
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("stop", { offset: "0%", stopColor: "currentColor", stopOpacity: "0.25" }),
2498
2812
  /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("stop", { offset: "100%", stopColor: "currentColor", stopOpacity: "0" })
2499
- ] }) })
2813
+ ] }) }),
2814
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("path", { d: areaPath, fill: `url(#${gradientId})`, stroke: "none" }),
2815
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("path", { d: linePath, fill: "none", stroke: "currentColor", strokeWidth: "1.8", opacity: "0.6" })
2500
2816
  ] });
2501
2817
  };
2502
2818
  return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "relative overflow-hidden bg-slate-900/40 backdrop-blur-md rounded-2xl border border-white/5 hover:border-white/10 transition-all duration-300 group", children: [
@@ -2550,13 +2866,1423 @@ var DashboardGrid = ({
2550
2866
  };
2551
2867
  return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: `grid gap-6 ${colClasses[columns]}`, children });
2552
2868
  };
2869
+
2870
+ // src/components/dashboard/PrimusActivityFeed.tsx
2871
+ var import_react27 = require("react");
2872
+ var import_jsx_runtime34 = require("react/jsx-runtime");
2873
+ var statusClasses = {
2874
+ success: "bg-emerald-500/10 text-emerald-300 border-emerald-500/30",
2875
+ warning: "bg-amber-500/10 text-amber-300 border-amber-500/30",
2876
+ error: "bg-rose-500/10 text-rose-300 border-rose-500/30",
2877
+ info: "bg-blue-500/10 text-blue-300 border-blue-500/30"
2878
+ };
2879
+ var PrimusActivityFeed = ({
2880
+ items,
2881
+ maxItems = 10,
2882
+ showTimestamps = true,
2883
+ groupByDate = false,
2884
+ loading = false
2885
+ }) => {
2886
+ const visibleItems = (0, import_react27.useMemo)(() => items.slice(0, maxItems), [items, maxItems]);
2887
+ const groups = (0, import_react27.useMemo)(() => {
2888
+ if (!groupByDate) {
2889
+ return [{ label: "", items: visibleItems }];
2890
+ }
2891
+ const map = /* @__PURE__ */ new Map();
2892
+ visibleItems.forEach((item) => {
2893
+ const label = formatDate(item.timestamp);
2894
+ const list = map.get(label) ?? [];
2895
+ list.push(item);
2896
+ map.set(label, list);
2897
+ });
2898
+ return Array.from(map.entries()).map(([label, groupItems]) => ({ label, items: groupItems }));
2899
+ }, [groupByDate, visibleItems]);
2900
+ if (loading) {
2901
+ return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "rounded-xl border border-white/10 bg-slate-900/40 p-6 text-sm text-gray-400", children: "Loading activity..." });
2902
+ }
2903
+ return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "rounded-xl border border-white/10 bg-slate-900/40 p-6 space-y-6", children: groups.map((group, index) => /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { children: [
2904
+ group.label && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "text-xs uppercase tracking-wide text-gray-500 mb-3", children: group.label }),
2905
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "space-y-4", children: group.items.map((item, itemIndex) => /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "flex items-start gap-4", children: [
2906
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: `mt-1 h-2.5 w-2.5 rounded-full border ${statusClasses[item.status ?? "info"]}` }),
2907
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "flex-1", children: [
2908
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "flex items-center justify-between gap-4", children: [
2909
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "text-sm font-medium text-gray-100", children: item.title }),
2910
+ showTimestamps && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "text-xs text-gray-500", children: formatTime(item.timestamp) })
2911
+ ] }),
2912
+ item.description && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "text-xs text-gray-400 mt-1", children: item.description })
2913
+ ] })
2914
+ ] }, item.id ?? `${itemIndex}-${item.title}`)) })
2915
+ ] }, `${group.label}-${index}`)) });
2916
+ };
2917
+ var formatDate = (value) => {
2918
+ if (!value) {
2919
+ return "";
2920
+ }
2921
+ const date = value instanceof Date ? value : new Date(value);
2922
+ if (Number.isNaN(date.getTime())) {
2923
+ return String(value);
2924
+ }
2925
+ return date.toLocaleDateString();
2926
+ };
2927
+ var formatTime = (value) => {
2928
+ if (!value) {
2929
+ return "";
2930
+ }
2931
+ const date = value instanceof Date ? value : new Date(value);
2932
+ if (Number.isNaN(date.getTime())) {
2933
+ return "";
2934
+ }
2935
+ return date.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" });
2936
+ };
2937
+
2938
+ // src/components/charts/PrimusChartBase.tsx
2939
+ var import_react28 = require("react");
2940
+ var import_chart = require("chart.js");
2941
+ var import_jsx_runtime35 = require("react/jsx-runtime");
2942
+ var registered = false;
2943
+ var ensureRegistered = () => {
2944
+ if (!registered) {
2945
+ import_chart.Chart.register(...import_chart.registerables);
2946
+ registered = true;
2947
+ }
2948
+ };
2949
+ var PrimusChartBase = ({
2950
+ type,
2951
+ data,
2952
+ labels = [],
2953
+ series = [],
2954
+ options,
2955
+ responsive = true,
2956
+ maintainAspectRatio = false,
2957
+ legend = true,
2958
+ height = 300,
2959
+ width,
2960
+ ariaLabel = "Chart",
2961
+ className,
2962
+ datasetTransform
2963
+ }) => {
2964
+ const canvasRef = (0, import_react28.useRef)(null);
2965
+ const chartRef = (0, import_react28.useRef)(null);
2966
+ const builtData = (0, import_react28.useMemo)(() => {
2967
+ if (data) {
2968
+ return data;
2969
+ }
2970
+ const datasets = series.map((item) => {
2971
+ const color = item.color ?? item.borderColor ?? "#3b82f6";
2972
+ const background = item.backgroundColor ?? color;
2973
+ let dataset = {
2974
+ label: item.name,
2975
+ data: item.data,
2976
+ borderColor: item.borderColor ?? color,
2977
+ backgroundColor: background,
2978
+ fill: item.fill
2979
+ };
2980
+ if (datasetTransform) {
2981
+ dataset = datasetTransform(dataset);
2982
+ }
2983
+ return dataset;
2984
+ });
2985
+ return {
2986
+ labels,
2987
+ datasets
2988
+ };
2989
+ }, [data, labels, series, datasetTransform]);
2990
+ const builtOptions = (0, import_react28.useMemo)(() => {
2991
+ const mergedPlugins = {
2992
+ ...options?.plugins ?? {},
2993
+ legend: {
2994
+ display: legend,
2995
+ ...options?.plugins?.legend ?? {}
2996
+ }
2997
+ };
2998
+ return {
2999
+ responsive,
3000
+ maintainAspectRatio,
3001
+ ...options ?? {},
3002
+ plugins: mergedPlugins,
3003
+ scales: {
3004
+ ...options?.scales ?? {}
3005
+ }
3006
+ };
3007
+ }, [options, responsive, maintainAspectRatio, legend]);
3008
+ (0, import_react28.useEffect)(() => {
3009
+ ensureRegistered();
3010
+ const canvas = canvasRef.current;
3011
+ if (!canvas) {
3012
+ return void 0;
3013
+ }
3014
+ const ctx = canvas.getContext("2d");
3015
+ if (!ctx) {
3016
+ return void 0;
3017
+ }
3018
+ if (chartRef.current) {
3019
+ chartRef.current.destroy();
3020
+ chartRef.current = null;
3021
+ }
3022
+ chartRef.current = new import_chart.Chart(ctx, {
3023
+ type,
3024
+ data: builtData,
3025
+ options: builtOptions
3026
+ });
3027
+ return () => {
3028
+ chartRef.current?.destroy();
3029
+ chartRef.current = null;
3030
+ };
3031
+ }, [type, builtData, builtOptions]);
3032
+ return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className, style: { height, width }, children: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("canvas", { ref: canvasRef, "aria-label": ariaLabel, role: "img" }) });
3033
+ };
3034
+
3035
+ // src/components/charts/PrimusLineChart.tsx
3036
+ var import_jsx_runtime36 = require("react/jsx-runtime");
3037
+ var PrimusLineChart = (props) => {
3038
+ return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
3039
+ PrimusChartBase,
3040
+ {
3041
+ ...props,
3042
+ type: "line",
3043
+ datasetTransform: (dataset) => ({
3044
+ tension: 0.35,
3045
+ pointRadius: 2,
3046
+ pointHoverRadius: 4,
3047
+ borderWidth: 2,
3048
+ fill: dataset.fill ?? false,
3049
+ ...dataset
3050
+ })
3051
+ }
3052
+ );
3053
+ };
3054
+
3055
+ // src/components/charts/PrimusAreaChart.tsx
3056
+ var import_jsx_runtime37 = require("react/jsx-runtime");
3057
+ var PrimusAreaChart = (props) => {
3058
+ return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
3059
+ PrimusChartBase,
3060
+ {
3061
+ ...props,
3062
+ type: "line",
3063
+ datasetTransform: (dataset) => ({
3064
+ tension: 0.35,
3065
+ pointRadius: 2,
3066
+ pointHoverRadius: 4,
3067
+ borderWidth: 2,
3068
+ fill: dataset.fill ?? true,
3069
+ ...dataset
3070
+ })
3071
+ }
3072
+ );
3073
+ };
3074
+
3075
+ // src/components/charts/PrimusBarChart.tsx
3076
+ var import_jsx_runtime38 = require("react/jsx-runtime");
3077
+ var PrimusBarChart = ({ stacked = false, options, ...props }) => {
3078
+ const mergedOptions = {
3079
+ ...options,
3080
+ scales: {
3081
+ x: { stacked, ...options?.scales?.x ?? {} },
3082
+ y: { stacked, ...options?.scales?.y ?? {} },
3083
+ ...options?.scales ?? {}
3084
+ }
3085
+ };
3086
+ return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
3087
+ PrimusChartBase,
3088
+ {
3089
+ ...props,
3090
+ type: "bar",
3091
+ options: mergedOptions,
3092
+ datasetTransform: (dataset) => ({
3093
+ borderRadius: 6,
3094
+ borderSkipped: false,
3095
+ ...dataset
3096
+ })
3097
+ }
3098
+ );
3099
+ };
3100
+
3101
+ // src/components/charts/PrimusPieChart.tsx
3102
+ var import_jsx_runtime39 = require("react/jsx-runtime");
3103
+ var PrimusPieChart = ({ donut = false, cutout = "55%", options, ...props }) => {
3104
+ const mergedOptions = {
3105
+ ...options,
3106
+ cutout: donut ? cutout : void 0
3107
+ };
3108
+ return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
3109
+ PrimusChartBase,
3110
+ {
3111
+ ...props,
3112
+ type: donut ? "doughnut" : "pie",
3113
+ options: mergedOptions,
3114
+ datasetTransform: (dataset) => ({
3115
+ borderWidth: 1,
3116
+ borderColor: "transparent",
3117
+ ...dataset
3118
+ })
3119
+ }
3120
+ );
3121
+ };
3122
+
3123
+ // src/components/charts/PrimusSparkline.tsx
3124
+ var import_react29 = require("react");
3125
+ var import_jsx_runtime40 = require("react/jsx-runtime");
3126
+ var PrimusSparkline = ({
3127
+ series = [],
3128
+ data,
3129
+ type = "line",
3130
+ height = 48,
3131
+ width = 160,
3132
+ strokeWidth = 2,
3133
+ className,
3134
+ ariaLabel = "Sparkline"
3135
+ }) => {
3136
+ const values = data ?? series[0]?.data ?? [];
3137
+ const color = series[0]?.color ?? series[0]?.borderColor ?? "#3b82f6";
3138
+ const { linePath, areaPath } = (0, import_react29.useMemo)(() => {
3139
+ if (!values.length) {
3140
+ return { linePath: "", areaPath: "" };
3141
+ }
3142
+ const max = Math.max(...values);
3143
+ const min = Math.min(...values);
3144
+ const range = max - min || 1;
3145
+ const divisor = values.length > 1 ? values.length - 1 : 1;
3146
+ const points = values.map((value, index) => {
3147
+ const x = index / divisor * 100;
3148
+ const y = 100 - (value - min) / range * 100;
3149
+ return { x, y };
3150
+ });
3151
+ const line = points.map((point, index) => `${index === 0 ? "M" : "L"} ${point.x} ${point.y}`).join(" ");
3152
+ const area = `${line} L 100 100 L 0 100 Z`;
3153
+ return { linePath: line, areaPath: area };
3154
+ }, [values]);
3155
+ if (!values.length) {
3156
+ return null;
3157
+ }
3158
+ return /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(
3159
+ "svg",
3160
+ {
3161
+ className,
3162
+ width,
3163
+ height,
3164
+ viewBox: "0 0 100 100",
3165
+ preserveAspectRatio: "none",
3166
+ "aria-label": ariaLabel,
3167
+ role: "img",
3168
+ children: [
3169
+ type === "area" && /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("path", { d: areaPath, fill: color, opacity: 0.2, stroke: "none" }),
3170
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("path", { d: linePath, fill: "none", stroke: color, strokeWidth })
3171
+ ]
3172
+ }
3173
+ );
3174
+ };
3175
+
3176
+ // src/components/shared/Checkbox.tsx
3177
+ var import_react30 = __toESM(require("react"));
3178
+ var import_jsx_runtime41 = require("react/jsx-runtime");
3179
+ var Checkbox = import_react30.default.forwardRef(
3180
+ ({ style, label, error, disabled, className, ...props }, ref) => {
3181
+ const containerStyles = {
3182
+ display: "flex",
3183
+ alignItems: "center",
3184
+ gap: "0.5rem"
3185
+ };
3186
+ const checkboxWrapperStyles = {
3187
+ position: "relative",
3188
+ display: "inline-flex",
3189
+ alignItems: "center",
3190
+ justifyContent: "center"
3191
+ };
3192
+ const checkboxStyles = {
3193
+ width: "1.25rem",
3194
+ height: "1.25rem",
3195
+ borderRadius: "0.25rem",
3196
+ border: error ? "2px solid #ef4444" : "2px solid #e5e7eb",
3197
+ cursor: disabled ? "not-allowed" : "pointer",
3198
+ opacity: disabled ? 0.5 : 1,
3199
+ accentColor: "#111827"
3200
+ };
3201
+ const labelStyles = {
3202
+ fontSize: "0.875rem",
3203
+ lineHeight: "1.25rem",
3204
+ color: "#374151",
3205
+ cursor: disabled ? "not-allowed" : "pointer",
3206
+ opacity: disabled ? 0.7 : 1,
3207
+ userSelect: "none"
3208
+ };
3209
+ const errorTextStyles = {
3210
+ fontSize: "0.875rem",
3211
+ lineHeight: "1.25rem",
3212
+ color: "#ef4444",
3213
+ marginTop: "0.25rem",
3214
+ marginLeft: "1.75rem"
3215
+ };
3216
+ return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { children: [
3217
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { style: containerStyles, children: [
3218
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { style: checkboxWrapperStyles, children: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
3219
+ "input",
3220
+ {
3221
+ ref,
3222
+ type: "checkbox",
3223
+ style: {
3224
+ ...checkboxStyles,
3225
+ ...style
3226
+ },
3227
+ disabled,
3228
+ ...props
3229
+ }
3230
+ ) }),
3231
+ label && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("label", { style: labelStyles, onClick: (e) => {
3232
+ if (!disabled) {
3233
+ const input = e.currentTarget.previousElementSibling?.querySelector("input");
3234
+ input?.click();
3235
+ }
3236
+ }, children: label })
3237
+ ] }),
3238
+ error && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("p", { style: errorTextStyles, children: error })
3239
+ ] });
3240
+ }
3241
+ );
3242
+ Checkbox.displayName = "Checkbox";
3243
+
3244
+ // src/components/shared/RadioGroup.tsx
3245
+ var import_jsx_runtime42 = require("react/jsx-runtime");
3246
+ var RadioGroup = ({
3247
+ name,
3248
+ options,
3249
+ value,
3250
+ onChange,
3251
+ error,
3252
+ disabled,
3253
+ orientation = "vertical"
3254
+ }) => {
3255
+ const containerStyles = {
3256
+ display: "flex",
3257
+ flexDirection: orientation === "vertical" ? "column" : "row",
3258
+ gap: orientation === "vertical" ? "0.75rem" : "1.5rem"
3259
+ };
3260
+ const optionStyles = {
3261
+ display: "flex",
3262
+ alignItems: "center",
3263
+ gap: "0.5rem"
3264
+ };
3265
+ const radioStyles = {
3266
+ width: "1.25rem",
3267
+ height: "1.25rem",
3268
+ cursor: disabled ? "not-allowed" : "pointer",
3269
+ opacity: disabled ? 0.5 : 1,
3270
+ accentColor: "#111827"
3271
+ };
3272
+ const labelStyles = {
3273
+ fontSize: "0.875rem",
3274
+ lineHeight: "1.25rem",
3275
+ color: "#374151",
3276
+ cursor: disabled ? "not-allowed" : "pointer",
3277
+ userSelect: "none"
3278
+ };
3279
+ const errorTextStyles = {
3280
+ fontSize: "0.875rem",
3281
+ lineHeight: "1.25rem",
3282
+ color: "#ef4444",
3283
+ marginTop: "0.5rem"
3284
+ };
3285
+ return /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { children: [
3286
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("div", { style: containerStyles, children: options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { style: optionStyles, children: [
3287
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
3288
+ "input",
3289
+ {
3290
+ type: "radio",
3291
+ name,
3292
+ value: option.value,
3293
+ checked: value === option.value,
3294
+ onChange: () => onChange?.(option.value),
3295
+ disabled: disabled || option.disabled,
3296
+ style: radioStyles
3297
+ }
3298
+ ),
3299
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
3300
+ "label",
3301
+ {
3302
+ style: {
3303
+ ...labelStyles,
3304
+ opacity: disabled || option.disabled ? 0.5 : 1
3305
+ },
3306
+ onClick: () => {
3307
+ if (!disabled && !option.disabled) {
3308
+ onChange?.(option.value);
3309
+ }
3310
+ },
3311
+ children: option.label
3312
+ }
3313
+ )
3314
+ ] }, option.value)) }),
3315
+ error && /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("p", { style: errorTextStyles, children: error })
3316
+ ] });
3317
+ };
3318
+ RadioGroup.displayName = "RadioGroup";
3319
+
3320
+ // src/components/shared/Select.tsx
3321
+ var import_react31 = __toESM(require("react"));
3322
+ var import_react32 = require("@headlessui/react");
3323
+ var import_solid4 = require("@heroicons/react/20/solid");
3324
+ var import_clsx7 = require("clsx");
3325
+ var import_jsx_runtime43 = require("react/jsx-runtime");
3326
+ var Select = ({
3327
+ label,
3328
+ error,
3329
+ options,
3330
+ placeholder = "Select option...",
3331
+ value,
3332
+ onChange,
3333
+ multiple = false,
3334
+ disabled = false,
3335
+ className
3336
+ }) => {
3337
+ const [query, setQuery] = (0, import_react31.useState)("");
3338
+ const filteredOptions = query === "" ? options : options.filter(
3339
+ (option) => option.label.toLowerCase().replace(/\s+/g, "").includes(query.toLowerCase().replace(/\s+/g, ""))
3340
+ );
3341
+ const getLabel = (val) => options.find((o) => o.value === val)?.label || val;
3342
+ const removeChip = (valToRemove) => {
3343
+ if (Array.isArray(value)) {
3344
+ onChange?.(value.filter((v) => v !== valToRemove));
3345
+ }
3346
+ };
3347
+ return /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", { className: (0, import_clsx7.clsx)("w-full", className), children: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
3348
+ import_react32.Combobox,
3349
+ {
3350
+ value,
3351
+ onChange: (val) => {
3352
+ onChange?.(val);
3353
+ },
3354
+ multiple,
3355
+ disabled,
3356
+ children: ({}) => /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: "relative", children: [
3357
+ label && /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_react32.Combobox.Label, { className: "block text-sm font-medium text-gray-700 mb-1", children: label }),
3358
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: (0, import_clsx7.clsx)(
3359
+ "relative w-full cursor-default overflow-hidden rounded-lg bg-white text-left focus-within:ring-2 focus-within:ring-primus-500",
3360
+ "border transition-all duration-200 ease-in-out",
3361
+ error ? "border-red-500 focus-within:ring-red-500" : "border-gray-300",
3362
+ disabled && "opacity-50 cursor-not-allowed bg-gray-50"
3363
+ ), children: [
3364
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: (0, import_clsx7.clsx)(
3365
+ "flex flex-wrap items-center gap-1.5 w-full py-1.5 pl-3 pr-10 text-sm",
3366
+ "min-h-[2.5rem]"
3367
+ ), children: [
3368
+ multiple && Array.isArray(value) && value.map((val) => /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("span", { className: "inline-flex items-center gap-1 rounded bg-primus-50 px-2 py-0.5 text-xs font-medium text-primus-700 ring-1 ring-inset ring-primus-700/10 max-w-[150px]", children: [
3369
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("span", { className: "truncate", children: getLabel(val) }),
3370
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(
3371
+ "button",
3372
+ {
3373
+ type: "button",
3374
+ className: "group relative -mr-1 h-3.5 w-3.5 rounded-sm hover:bg-primus-600/20 flex-shrink-0 cursor-pointer",
3375
+ onClick: (e) => {
3376
+ e.preventDefault();
3377
+ e.stopPropagation();
3378
+ removeChip(val);
3379
+ },
3380
+ onMouseDown: (e) => e.preventDefault(),
3381
+ children: [
3382
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("span", { className: "sr-only", children: "Remove" }),
3383
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_solid4.XMarkIcon, { className: "h-3.5 w-3.5", "aria-hidden": "true" })
3384
+ ]
3385
+ }
3386
+ )
3387
+ ] }, val)),
3388
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
3389
+ import_react32.Combobox.Input,
3390
+ {
3391
+ className: "border-none p-0 text-gray-900 focus:ring-0 outline-none placeholder:text-gray-400 bg-transparent min-w-[50px] flex-1 text-sm leading-5 py-0.5",
3392
+ displayValue: (val) => !multiple && val ? getLabel(val) : query,
3393
+ placeholder: multiple && Array.isArray(value) && value.length > 0 ? "" : placeholder,
3394
+ onChange: (event) => setQuery(event.target.value)
3395
+ }
3396
+ )
3397
+ ] }),
3398
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_react32.Combobox.Button, { className: "absolute inset-y-0 right-0 flex items-center pr-2", children: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
3399
+ import_solid4.ChevronUpDownIcon,
3400
+ {
3401
+ className: "h-5 w-5 text-gray-400",
3402
+ "aria-hidden": "true"
3403
+ }
3404
+ ) })
3405
+ ] }),
3406
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
3407
+ import_react32.Transition,
3408
+ {
3409
+ as: import_react31.default.Fragment,
3410
+ leave: "transition ease-in duration-100",
3411
+ leaveFrom: "opacity-100",
3412
+ leaveTo: "opacity-0",
3413
+ afterLeave: () => setQuery(""),
3414
+ children: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_react32.Combobox.Options, { className: "absolute z-50 mt-1 max-h-60 w-full overflow-auto rounded-md bg-white py-1 text-base shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none sm:text-sm", children: filteredOptions.length === 0 && query !== "" ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", { className: "relative cursor-default select-none py-2 px-4 text-gray-700", children: "Nothing found." }) : filteredOptions.map((option) => /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
3415
+ import_react32.Combobox.Option,
3416
+ {
3417
+ className: ({ active }) => (0, import_clsx7.clsx)(
3418
+ "relative cursor-default select-none py-2 pl-10 pr-4",
3419
+ active ? "bg-primus-600 text-white" : "text-gray-900"
3420
+ ),
3421
+ value: option.value,
3422
+ disabled: option.disabled,
3423
+ children: ({ selected, active }) => /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(import_jsx_runtime43.Fragment, { children: [
3424
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("span", { className: (0, import_clsx7.clsx)("block truncate", selected ? "font-medium" : "font-normal"), children: option.label }),
3425
+ selected ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
3426
+ "span",
3427
+ {
3428
+ className: (0, import_clsx7.clsx)(
3429
+ "absolute inset-y-0 left-0 flex items-center pl-3",
3430
+ active ? "text-white" : "text-primus-600"
3431
+ ),
3432
+ children: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_solid4.CheckIcon, { className: "h-5 w-5", "aria-hidden": "true" })
3433
+ }
3434
+ ) : null
3435
+ ] })
3436
+ },
3437
+ option.value
3438
+ )) })
3439
+ }
3440
+ ),
3441
+ error && /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("p", { className: "mt-1 text-sm text-red-500", children: error })
3442
+ ] })
3443
+ }
3444
+ ) });
3445
+ };
3446
+
3447
+ // src/components/shared/Toggle.tsx
3448
+ var import_react33 = __toESM(require("react"));
3449
+ var import_jsx_runtime44 = require("react/jsx-runtime");
3450
+ var Toggle = ({
3451
+ checked = false,
3452
+ onChange,
3453
+ disabled = false,
3454
+ label,
3455
+ size = "md"
3456
+ }) => {
3457
+ const [isHovered, setIsHovered] = import_react33.default.useState(false);
3458
+ const sizes = {
3459
+ sm: { width: "2.25rem", height: "1.25rem", thumbSize: "0.875rem" },
3460
+ md: { width: "2.75rem", height: "1.5rem", thumbSize: "1.125rem" },
3461
+ lg: { width: "3.5rem", height: "2rem", thumbSize: "1.625rem" }
3462
+ };
3463
+ const currentSize = sizes[size];
3464
+ const containerStyles = {
3465
+ display: "flex",
3466
+ alignItems: "center",
3467
+ gap: "0.75rem"
3468
+ };
3469
+ const switchStyles = {
3470
+ position: "relative",
3471
+ display: "inline-block",
3472
+ width: currentSize.width,
3473
+ height: currentSize.height,
3474
+ backgroundColor: checked ? "#111827" : "#e5e7eb",
3475
+ borderRadius: "9999px",
3476
+ cursor: disabled ? "not-allowed" : "pointer",
3477
+ transition: "background-color 0.2s ease",
3478
+ opacity: disabled ? 0.5 : isHovered ? 0.9 : 1
3479
+ };
3480
+ const thumbStyles = {
3481
+ position: "absolute",
3482
+ top: "50%",
3483
+ left: checked ? `calc(100% - ${currentSize.thumbSize} - 0.125rem)` : "0.125rem",
3484
+ transform: "translateY(-50%)",
3485
+ width: currentSize.thumbSize,
3486
+ height: currentSize.thumbSize,
3487
+ backgroundColor: "#ffffff",
3488
+ borderRadius: "50%",
3489
+ transition: "left 0.2s ease",
3490
+ boxShadow: "0 1px 3px rgba(0, 0, 0, 0.1)"
3491
+ };
3492
+ const labelStyles = {
3493
+ fontSize: "0.875rem",
3494
+ lineHeight: "1.25rem",
3495
+ color: "#374151",
3496
+ cursor: disabled ? "not-allowed" : "pointer",
3497
+ userSelect: "none"
3498
+ };
3499
+ const handleClick = () => {
3500
+ if (!disabled) {
3501
+ onChange?.(!checked);
3502
+ }
3503
+ };
3504
+ return /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { style: containerStyles, children: [
3505
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
3506
+ "div",
3507
+ {
3508
+ style: switchStyles,
3509
+ onClick: handleClick,
3510
+ onMouseEnter: () => setIsHovered(true),
3511
+ onMouseLeave: () => setIsHovered(false),
3512
+ role: "switch",
3513
+ "aria-checked": checked,
3514
+ tabIndex: disabled ? -1 : 0,
3515
+ onKeyDown: (e) => {
3516
+ if (e.key === " " || e.key === "Enter") {
3517
+ e.preventDefault();
3518
+ handleClick();
3519
+ }
3520
+ },
3521
+ children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", { style: thumbStyles })
3522
+ }
3523
+ ),
3524
+ label && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("label", { style: labelStyles, onClick: handleClick, children: label })
3525
+ ] });
3526
+ };
3527
+ Toggle.displayName = "Toggle";
3528
+
3529
+ // src/components/shared/Textarea.tsx
3530
+ var import_react34 = __toESM(require("react"));
3531
+ var import_jsx_runtime45 = require("react/jsx-runtime");
3532
+ var Textarea = import_react34.default.forwardRef(
3533
+ ({ style, label, error, disabled, resize = "vertical", ...props }, ref) => {
3534
+ const [isFocused, setIsFocused] = import_react34.default.useState(false);
3535
+ const containerStyles = {
3536
+ width: "100%"
3537
+ };
3538
+ const labelStyles = {
3539
+ fontSize: "0.875rem",
3540
+ lineHeight: "1.25rem",
3541
+ fontWeight: "500",
3542
+ marginBottom: "0.5rem",
3543
+ display: "block",
3544
+ color: "#374151",
3545
+ cursor: disabled ? "not-allowed" : "default",
3546
+ opacity: disabled ? 0.7 : 1
3547
+ };
3548
+ const textareaStyles = {
3549
+ display: "flex",
3550
+ minHeight: "5rem",
3551
+ width: "100%",
3552
+ borderRadius: "0.375rem",
3553
+ border: error ? "1px solid #ef4444" : "1px solid #e5e7eb",
3554
+ backgroundColor: "#ffffff",
3555
+ padding: "0.5rem 0.75rem",
3556
+ fontSize: "0.875rem",
3557
+ lineHeight: "1.5rem",
3558
+ outline: "none",
3559
+ transition: "all 0.2s ease",
3560
+ cursor: disabled ? "not-allowed" : "text",
3561
+ opacity: disabled ? 0.5 : 1,
3562
+ resize,
3563
+ fontFamily: "inherit",
3564
+ boxShadow: isFocused ? error ? "0 0 0 2px rgba(239, 68, 68, 0.2)" : "0 0 0 2px rgba(3, 7, 18, 0.1)" : "none"
3565
+ };
3566
+ const errorTextStyles = {
3567
+ fontSize: "0.875rem",
3568
+ lineHeight: "1.25rem",
3569
+ color: "#ef4444",
3570
+ marginTop: "0.25rem"
3571
+ };
3572
+ return /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { style: containerStyles, children: [
3573
+ label && /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("label", { style: labelStyles, children: label }),
3574
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
3575
+ "textarea",
3576
+ {
3577
+ ref,
3578
+ style: {
3579
+ ...textareaStyles,
3580
+ ...style
3581
+ },
3582
+ onFocus: () => setIsFocused(true),
3583
+ onBlur: () => setIsFocused(false),
3584
+ disabled,
3585
+ ...props
3586
+ }
3587
+ ),
3588
+ error && /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("p", { style: errorTextStyles, children: error })
3589
+ ] });
3590
+ }
3591
+ );
3592
+ Textarea.displayName = "Textarea";
3593
+
3594
+ // src/components/shared/Card.tsx
3595
+ var import_react35 = __toESM(require("react"));
3596
+ var import_jsx_runtime46 = require("react/jsx-runtime");
3597
+ var Card = import_react35.default.forwardRef(
3598
+ ({ style, variant = "default", padding = "md", children, ...props }, ref) => {
3599
+ const [isHovered, setIsHovered] = import_react35.default.useState(false);
3600
+ const paddingStyles = {
3601
+ none: "0",
3602
+ sm: "0.75rem",
3603
+ md: "1.5rem",
3604
+ lg: "2rem"
3605
+ };
3606
+ const variantStyles = {
3607
+ default: {
3608
+ normal: {
3609
+ backgroundColor: "#ffffff",
3610
+ border: "1px solid #e5e7eb",
3611
+ boxShadow: "0 1px 2px rgba(0, 0, 0, 0.05)"
3612
+ },
3613
+ hover: {
3614
+ boxShadow: "0 4px 6px rgba(0, 0, 0, 0.1)"
3615
+ }
3616
+ },
3617
+ outlined: {
3618
+ normal: {
3619
+ backgroundColor: "#ffffff",
3620
+ border: "2px solid #e5e7eb",
3621
+ boxShadow: "none"
3622
+ },
3623
+ hover: {
3624
+ borderColor: "#d1d5db"
3625
+ }
3626
+ },
3627
+ elevated: {
3628
+ normal: {
3629
+ backgroundColor: "#ffffff",
3630
+ border: "none",
3631
+ boxShadow: "0 4px 6px rgba(0, 0, 0, 0.1)"
3632
+ },
3633
+ hover: {
3634
+ boxShadow: "0 10px 15px rgba(0, 0, 0, 0.15)",
3635
+ transform: "translateY(-2px)"
3636
+ }
3637
+ }
3638
+ };
3639
+ const baseStyles = {
3640
+ borderRadius: "0.5rem",
3641
+ padding: paddingStyles[padding],
3642
+ transition: "all 0.2s ease"
3643
+ };
3644
+ const currentVariant = variantStyles[variant];
3645
+ const combinedStyles = {
3646
+ ...baseStyles,
3647
+ ...currentVariant.normal,
3648
+ ...isHovered ? currentVariant.hover : {},
3649
+ ...style
3650
+ };
3651
+ return /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
3652
+ "div",
3653
+ {
3654
+ ref,
3655
+ style: combinedStyles,
3656
+ onMouseEnter: () => setIsHovered(true),
3657
+ onMouseLeave: () => setIsHovered(false),
3658
+ ...props,
3659
+ children
3660
+ }
3661
+ );
3662
+ }
3663
+ );
3664
+ Card.displayName = "Card";
3665
+
3666
+ // src/components/shared/Badge.tsx
3667
+ var import_react36 = __toESM(require("react"));
3668
+ var import_jsx_runtime47 = require("react/jsx-runtime");
3669
+ var Badge = import_react36.default.forwardRef(
3670
+ ({ style, variant = "default", size = "md", children, ...props }, ref) => {
3671
+ const variantStyles = {
3672
+ default: {
3673
+ backgroundColor: "#f3f4f6",
3674
+ color: "#374151"
3675
+ },
3676
+ success: {
3677
+ backgroundColor: "#d1fae5",
3678
+ color: "#065f46"
3679
+ },
3680
+ warning: {
3681
+ backgroundColor: "#fef3c7",
3682
+ color: "#92400e"
3683
+ },
3684
+ error: {
3685
+ backgroundColor: "#fee2e2",
3686
+ color: "#991b1b"
3687
+ },
3688
+ info: {
3689
+ backgroundColor: "#dbeafe",
3690
+ color: "#1e40af"
3691
+ }
3692
+ };
3693
+ const sizeStyles = {
3694
+ sm: {
3695
+ fontSize: "0.75rem",
3696
+ lineHeight: "1rem",
3697
+ padding: "0.125rem 0.5rem"
3698
+ },
3699
+ md: {
3700
+ fontSize: "0.875rem",
3701
+ lineHeight: "1.25rem",
3702
+ padding: "0.25rem 0.75rem"
3703
+ },
3704
+ lg: {
3705
+ fontSize: "1rem",
3706
+ lineHeight: "1.5rem",
3707
+ padding: "0.375rem 1rem"
3708
+ }
3709
+ };
3710
+ const baseStyles = {
3711
+ display: "inline-flex",
3712
+ alignItems: "center",
3713
+ borderRadius: "9999px",
3714
+ fontWeight: "500",
3715
+ whiteSpace: "nowrap"
3716
+ };
3717
+ const combinedStyles = {
3718
+ ...baseStyles,
3719
+ ...variantStyles[variant],
3720
+ ...sizeStyles[size],
3721
+ ...style
3722
+ };
3723
+ return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { ref, style: combinedStyles, ...props, children });
3724
+ }
3725
+ );
3726
+ Badge.displayName = "Badge";
3727
+
3728
+ // src/components/shared/Table.tsx
3729
+ var import_react37 = __toESM(require("react"));
3730
+ var import_jsx_runtime48 = require("react/jsx-runtime");
3731
+ function Table({
3732
+ columns,
3733
+ data,
3734
+ striped = false,
3735
+ hoverable = true,
3736
+ bordered = true,
3737
+ style
3738
+ }) {
3739
+ const [hoveredRow, setHoveredRow] = import_react37.default.useState(null);
3740
+ const tableStyles = {
3741
+ width: "100%",
3742
+ borderCollapse: "collapse",
3743
+ fontSize: "0.875rem",
3744
+ lineHeight: "1.25rem",
3745
+ ...style
3746
+ };
3747
+ const theadStyles = {
3748
+ backgroundColor: "#f9fafb",
3749
+ borderBottom: "2px solid #e5e7eb"
3750
+ };
3751
+ const thStyles = {
3752
+ padding: "0.75rem 1rem",
3753
+ textAlign: "left",
3754
+ fontWeight: "600",
3755
+ color: "#374151",
3756
+ borderBottom: bordered ? "1px solid #e5e7eb" : "none"
3757
+ };
3758
+ const getTdStyles = (rowIndex) => ({
3759
+ padding: "0.75rem 1rem",
3760
+ borderBottom: bordered ? "1px solid #e5e7eb" : "none",
3761
+ backgroundColor: hoverable && hoveredRow === rowIndex ? "#f9fafb" : striped && rowIndex % 2 === 1 ? "#f9fafb" : "#ffffff",
3762
+ transition: "background-color 0.15s ease"
3763
+ });
3764
+ return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", { style: { overflowX: "auto", borderRadius: "0.5rem", border: bordered ? "1px solid #e5e7eb" : "none" }, children: /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("table", { style: tableStyles, children: [
3765
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("thead", { style: theadStyles, children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("tr", { children: columns.map((column) => /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
3766
+ "th",
3767
+ {
3768
+ style: {
3769
+ ...thStyles,
3770
+ width: column.width
3771
+ },
3772
+ children: column.header
3773
+ },
3774
+ column.key
3775
+ )) }) }),
3776
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("tbody", { children: data.map((row, rowIndex) => /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
3777
+ "tr",
3778
+ {
3779
+ onMouseEnter: () => hoverable && setHoveredRow(rowIndex),
3780
+ onMouseLeave: () => hoverable && setHoveredRow(null),
3781
+ children: columns.map((column) => /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("td", { style: getTdStyles(rowIndex), children: column.render ? column.render(row) : row[column.key] }, column.key))
3782
+ },
3783
+ rowIndex
3784
+ )) })
3785
+ ] }) });
3786
+ }
3787
+ Table.displayName = "Table";
3788
+
3789
+ // src/components/shared/Container.tsx
3790
+ var import_react38 = __toESM(require("react"));
3791
+ var import_jsx_runtime49 = require("react/jsx-runtime");
3792
+ var Container = import_react38.default.forwardRef(
3793
+ ({ style, maxWidth = "lg", padding = "md", children, ...props }, ref) => {
3794
+ const maxWidthStyles = {
3795
+ sm: "640px",
3796
+ md: "768px",
3797
+ lg: "1024px",
3798
+ xl: "1280px",
3799
+ "2xl": "1536px",
3800
+ full: "100%"
3801
+ };
3802
+ const paddingStyles = {
3803
+ none: "0",
3804
+ sm: "1rem",
3805
+ md: "1.5rem",
3806
+ lg: "2rem"
3807
+ };
3808
+ const containerStyles = {
3809
+ width: "100%",
3810
+ maxWidth: maxWidthStyles[maxWidth],
3811
+ marginLeft: "auto",
3812
+ marginRight: "auto",
3813
+ paddingLeft: paddingStyles[padding],
3814
+ paddingRight: paddingStyles[padding],
3815
+ ...style
3816
+ };
3817
+ return /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("div", { ref, style: containerStyles, ...props, children });
3818
+ }
3819
+ );
3820
+ Container.displayName = "Container";
3821
+
3822
+ // src/components/shared/Grid.tsx
3823
+ var import_react39 = __toESM(require("react"));
3824
+ var import_jsx_runtime50 = require("react/jsx-runtime");
3825
+ var Grid = import_react39.default.forwardRef(
3826
+ ({ style, columns = 3, rows, gap = "md", width = "100%", height = "auto", responsive = true, children, ...props }, ref) => {
3827
+ const gapStyles = {
3828
+ none: "0",
3829
+ sm: "0.5rem",
3830
+ md: "1rem",
3831
+ lg: "1.5rem",
3832
+ xl: "2rem"
3833
+ };
3834
+ const gridStyles = {
3835
+ display: "grid",
3836
+ gridTemplateColumns: responsive ? `repeat(auto-fit, minmax(${Math.floor(100 / columns)}%, 1fr))` : `repeat(${columns}, 1fr)`,
3837
+ gridTemplateRows: rows ? `repeat(${rows}, 1fr)` : void 0,
3838
+ gap: gapStyles[gap] || gap,
3839
+ width,
3840
+ height,
3841
+ ...style
3842
+ };
3843
+ return /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("div", { ref, style: gridStyles, ...props, children });
3844
+ }
3845
+ );
3846
+ Grid.displayName = "Grid";
3847
+
3848
+ // src/components/shared/Stack.tsx
3849
+ var import_react40 = __toESM(require("react"));
3850
+ var import_jsx_runtime51 = require("react/jsx-runtime");
3851
+ var Stack = import_react40.default.forwardRef(
3852
+ ({ style, direction = "vertical", gap = "md", align = "stretch", justify = "start", children, ...props }, ref) => {
3853
+ const gapStyles = {
3854
+ none: "0",
3855
+ sm: "0.5rem",
3856
+ md: "1rem",
3857
+ lg: "1.5rem",
3858
+ xl: "2rem"
3859
+ };
3860
+ const alignStyles = {
3861
+ start: "flex-start",
3862
+ center: "center",
3863
+ end: "flex-end",
3864
+ stretch: "stretch"
3865
+ };
3866
+ const justifyStyles = {
3867
+ start: "flex-start",
3868
+ center: "center",
3869
+ end: "flex-end",
3870
+ between: "space-between",
3871
+ around: "space-around"
3872
+ };
3873
+ const stackStyles = {
3874
+ display: "flex",
3875
+ flexDirection: direction === "vertical" ? "column" : "row",
3876
+ gap: gapStyles[gap],
3877
+ alignItems: alignStyles[align],
3878
+ justifyContent: justifyStyles[justify],
3879
+ ...style
3880
+ };
3881
+ return /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("div", { ref, style: stackStyles, ...props, children });
3882
+ }
3883
+ );
3884
+ Stack.displayName = "Stack";
3885
+
3886
+ // src/components/shared/Modal.tsx
3887
+ var import_react41 = __toESM(require("react"));
3888
+ var import_jsx_runtime52 = require("react/jsx-runtime");
3889
+ var Modal = ({
3890
+ isOpen,
3891
+ onClose,
3892
+ title,
3893
+ children,
3894
+ size = "md",
3895
+ closeOnOverlayClick = true
3896
+ }) => {
3897
+ import_react41.default.useEffect(() => {
3898
+ if (isOpen) {
3899
+ document.body.style.overflow = "hidden";
3900
+ } else {
3901
+ document.body.style.overflow = "unset";
3902
+ }
3903
+ return () => {
3904
+ document.body.style.overflow = "unset";
3905
+ };
3906
+ }, [isOpen]);
3907
+ if (!isOpen) return null;
3908
+ const sizeStyles = {
3909
+ sm: "400px",
3910
+ md: "600px",
3911
+ lg: "800px",
3912
+ xl: "1000px"
3913
+ };
3914
+ const overlayStyles = {
3915
+ position: "fixed",
3916
+ top: 0,
3917
+ left: 0,
3918
+ right: 0,
3919
+ bottom: 0,
3920
+ backgroundColor: "rgba(0, 0, 0, 0.5)",
3921
+ display: "flex",
3922
+ alignItems: "center",
3923
+ justifyContent: "center",
3924
+ zIndex: 1e3,
3925
+ padding: "1rem"
3926
+ };
3927
+ const modalStyles = {
3928
+ backgroundColor: "#ffffff",
3929
+ borderRadius: "0.5rem",
3930
+ boxShadow: "0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)",
3931
+ width: "100%",
3932
+ maxWidth: sizeStyles[size],
3933
+ maxHeight: "90vh",
3934
+ display: "flex",
3935
+ flexDirection: "column"
3936
+ };
3937
+ const headerStyles = {
3938
+ padding: "1.5rem",
3939
+ borderBottom: "1px solid #e5e7eb",
3940
+ display: "flex",
3941
+ alignItems: "center",
3942
+ justifyContent: "space-between"
3943
+ };
3944
+ const titleStyles = {
3945
+ fontSize: "1.25rem",
3946
+ lineHeight: "1.75rem",
3947
+ fontWeight: "600",
3948
+ color: "#111827"
3949
+ };
3950
+ const closeButtonStyles = {
3951
+ padding: "0.5rem",
3952
+ borderRadius: "0.375rem",
3953
+ border: "none",
3954
+ backgroundColor: "transparent",
3955
+ cursor: "pointer",
3956
+ fontSize: "1.5rem",
3957
+ lineHeight: "1",
3958
+ color: "#6b7280",
3959
+ transition: "background-color 0.2s ease"
3960
+ };
3961
+ const contentStyles = {
3962
+ padding: "1.5rem",
3963
+ overflowY: "auto",
3964
+ flex: 1
3965
+ };
3966
+ return /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
3967
+ "div",
3968
+ {
3969
+ style: overlayStyles,
3970
+ onClick: closeOnOverlayClick ? onClose : void 0,
3971
+ children: /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(
3972
+ "div",
3973
+ {
3974
+ style: modalStyles,
3975
+ onClick: (e) => e.stopPropagation(),
3976
+ children: [
3977
+ title && /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("div", { style: headerStyles, children: [
3978
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("h2", { style: titleStyles, children: title }),
3979
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
3980
+ "button",
3981
+ {
3982
+ style: closeButtonStyles,
3983
+ onClick: onClose,
3984
+ "aria-label": "Close modal",
3985
+ children: "\xD7"
3986
+ }
3987
+ )
3988
+ ] }),
3989
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("div", { style: contentStyles, children })
3990
+ ]
3991
+ }
3992
+ )
3993
+ }
3994
+ );
3995
+ };
3996
+ Modal.displayName = "Modal";
3997
+
3998
+ // src/components/shared/DateRangePicker.tsx
3999
+ var import_react42 = require("react");
4000
+ var import_jsx_runtime53 = require("react/jsx-runtime");
4001
+ var PrimusDateRangePicker = ({
4002
+ startDate = null,
4003
+ endDate = null,
4004
+ ranges = [],
4005
+ min,
4006
+ max,
4007
+ disabled = false,
4008
+ onRangeChange
4009
+ }) => {
4010
+ const [start, setStart] = (0, import_react42.useState)(startDate ?? "");
4011
+ const [end, setEnd] = (0, import_react42.useState)(endDate ?? "");
4012
+ (0, import_react42.useEffect)(() => {
4013
+ setStart(startDate ?? "");
4014
+ }, [startDate]);
4015
+ (0, import_react42.useEffect)(() => {
4016
+ setEnd(endDate ?? "");
4017
+ }, [endDate]);
4018
+ const normalizedRanges = (0, import_react42.useMemo)(() => {
4019
+ return ranges.map((range) => typeof range === "string" ? resolvePreset(range) : range).filter((range) => !!range);
4020
+ }, [ranges]);
4021
+ const handleStartChange = (value) => {
4022
+ setStart(value);
4023
+ onRangeChange?.({ startDate: value || null, endDate: end || null });
4024
+ };
4025
+ const handleEndChange = (value) => {
4026
+ setEnd(value);
4027
+ onRangeChange?.({ startDate: start || null, endDate: value || null });
4028
+ };
4029
+ const applyRange = (range) => {
4030
+ const nextStart = toDateInputValue(range.start);
4031
+ const nextEnd = toDateInputValue(range.end);
4032
+ setStart(nextStart);
4033
+ setEnd(nextEnd);
4034
+ onRangeChange?.({ startDate: nextStart, endDate: nextEnd, label: range.label });
4035
+ };
4036
+ return /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("div", { className: "space-y-3", children: [
4037
+ normalizedRanges.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("div", { className: "flex flex-wrap gap-2", children: normalizedRanges.map((range) => /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
4038
+ "button",
4039
+ {
4040
+ type: "button",
4041
+ disabled,
4042
+ onClick: () => applyRange(range),
4043
+ className: "px-3 py-1.5 rounded-full text-xs font-medium border border-white/10 bg-white/5 text-gray-200 hover:bg-white/10 disabled:opacity-50 disabled:cursor-not-allowed",
4044
+ children: range.label
4045
+ },
4046
+ range.label
4047
+ )) }),
4048
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("div", { className: "flex flex-col md:flex-row gap-3", children: [
4049
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
4050
+ "input",
4051
+ {
4052
+ type: "date",
4053
+ value: start,
4054
+ min,
4055
+ max,
4056
+ disabled,
4057
+ onChange: (e) => handleStartChange(e.target.value),
4058
+ className: "w-full px-3 py-2 rounded-lg border border-white/10 bg-white/5 text-gray-200 text-sm focus:outline-none focus:ring-1 focus:ring-purple-500/50"
4059
+ }
4060
+ ),
4061
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
4062
+ "input",
4063
+ {
4064
+ type: "date",
4065
+ value: end,
4066
+ min,
4067
+ max,
4068
+ disabled,
4069
+ onChange: (e) => handleEndChange(e.target.value),
4070
+ className: "w-full px-3 py-2 rounded-lg border border-white/10 bg-white/5 text-gray-200 text-sm focus:outline-none focus:ring-1 focus:ring-purple-500/50"
4071
+ }
4072
+ )
4073
+ ] })
4074
+ ] });
4075
+ };
4076
+ var resolvePreset = (label) => {
4077
+ const today = /* @__PURE__ */ new Date();
4078
+ const startOfDay = new Date(today.getFullYear(), today.getMonth(), today.getDate());
4079
+ switch (label.toLowerCase()) {
4080
+ case "today":
4081
+ return { label, start: startOfDay, end: startOfDay };
4082
+ case "last 7 days": {
4083
+ const start = new Date(startOfDay);
4084
+ start.setDate(start.getDate() - 6);
4085
+ return { label, start, end: startOfDay };
4086
+ }
4087
+ case "last 30 days": {
4088
+ const start = new Date(startOfDay);
4089
+ start.setDate(start.getDate() - 29);
4090
+ return { label, start, end: startOfDay };
4091
+ }
4092
+ case "this month": {
4093
+ const start = new Date(today.getFullYear(), today.getMonth(), 1);
4094
+ const end = new Date(today.getFullYear(), today.getMonth() + 1, 0);
4095
+ return { label, start, end };
4096
+ }
4097
+ default:
4098
+ return null;
4099
+ }
4100
+ };
4101
+ var toDateInputValue = (value) => {
4102
+ if (typeof value === "string") {
4103
+ return value;
4104
+ }
4105
+ const year = value.getFullYear();
4106
+ const month = String(value.getMonth() + 1).padStart(2, "0");
4107
+ const day = String(value.getDate()).padStart(2, "0");
4108
+ return `${year}-${month}-${day}`;
4109
+ };
4110
+
4111
+ // src/components/shared/FilterBar.tsx
4112
+ var import_jsx_runtime54 = require("react/jsx-runtime");
4113
+ var PrimusFilterBar = ({
4114
+ filters,
4115
+ activeFilters,
4116
+ onChange,
4117
+ children
4118
+ }) => {
4119
+ const updateFilter = (key, value) => {
4120
+ const next = {
4121
+ ...activeFilters,
4122
+ [key]: value
4123
+ };
4124
+ onChange?.(next);
4125
+ };
4126
+ return /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("div", { className: "flex flex-wrap gap-4 items-end", children: [
4127
+ filters.map((filter) => /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("div", { className: "min-w-[220px]", children: [
4128
+ filter.type === "select" && /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
4129
+ Select,
4130
+ {
4131
+ label: filter.label,
4132
+ placeholder: filter.placeholder,
4133
+ options: filter.options ?? [],
4134
+ value: activeFilters[filter.key] ?? "",
4135
+ onChange: (value) => updateFilter(filter.key, value)
4136
+ }
4137
+ ),
4138
+ filter.type === "toggle" && /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
4139
+ Toggle,
4140
+ {
4141
+ label: filter.label,
4142
+ checked: Boolean(activeFilters[filter.key]),
4143
+ onChange: (checked) => updateFilter(filter.key, checked)
4144
+ }
4145
+ ),
4146
+ filter.type === "search" && /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
4147
+ Input,
4148
+ {
4149
+ label: filter.label,
4150
+ placeholder: filter.placeholder ?? "Search...",
4151
+ value: activeFilters[filter.key] ?? "",
4152
+ onChange: (event) => updateFilter(filter.key, event.target.value)
4153
+ }
4154
+ )
4155
+ ] }, filter.key)),
4156
+ children
4157
+ ] });
4158
+ };
4159
+
4160
+ // src/components/shared/ExportMenu.tsx
4161
+ var import_react43 = require("react");
4162
+ var import_jsx_runtime55 = require("react/jsx-runtime");
4163
+ var PrimusExportMenu = ({
4164
+ formats = ["CSV", "PDF", "PNG", "JSON"],
4165
+ includeCharts = true,
4166
+ includeStats = true,
4167
+ includeTables = true,
4168
+ onExport
4169
+ }) => {
4170
+ const [format, setFormat] = (0, import_react43.useState)(formats[0] ?? "CSV");
4171
+ const [charts, setCharts] = (0, import_react43.useState)(includeCharts);
4172
+ const [stats, setStats] = (0, import_react43.useState)(includeStats);
4173
+ const [tables, setTables] = (0, import_react43.useState)(includeTables);
4174
+ (0, import_react43.useEffect)(() => {
4175
+ if (!formats.includes(format)) {
4176
+ setFormat(formats[0] ?? "CSV");
4177
+ }
4178
+ }, [formats, format]);
4179
+ const handleExport = () => {
4180
+ onExport?.({
4181
+ format,
4182
+ includeCharts: charts,
4183
+ includeStats: stats,
4184
+ includeTables: tables
4185
+ });
4186
+ };
4187
+ return /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { className: "flex flex-wrap items-center gap-3", children: [
4188
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
4189
+ "select",
4190
+ {
4191
+ value: format,
4192
+ onChange: (event) => setFormat(event.target.value),
4193
+ className: "px-3 py-2 rounded-lg border border-white/10 bg-white/5 text-gray-200 text-sm",
4194
+ children: formats.map((item) => /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("option", { value: item, children: item }, item))
4195
+ }
4196
+ ),
4197
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("label", { className: "flex items-center gap-2 text-xs text-gray-300", children: [
4198
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("input", { type: "checkbox", checked: charts, onChange: (e) => setCharts(e.target.checked) }),
4199
+ "Charts"
4200
+ ] }),
4201
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("label", { className: "flex items-center gap-2 text-xs text-gray-300", children: [
4202
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("input", { type: "checkbox", checked: stats, onChange: (e) => setStats(e.target.checked) }),
4203
+ "Stats"
4204
+ ] }),
4205
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("label", { className: "flex items-center gap-2 text-xs text-gray-300", children: [
4206
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("input", { type: "checkbox", checked: tables, onChange: (e) => setTables(e.target.checked) }),
4207
+ "Tables"
4208
+ ] }),
4209
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
4210
+ "button",
4211
+ {
4212
+ type: "button",
4213
+ onClick: handleExport,
4214
+ className: "px-4 py-2 rounded-lg bg-purple-600 text-white text-sm font-medium hover:bg-purple-500",
4215
+ children: "Export"
4216
+ }
4217
+ )
4218
+ ] });
4219
+ };
4220
+
4221
+ // src/components/shared/Search.tsx
4222
+ var import_react44 = require("react");
4223
+ var import_jsx_runtime56 = require("react/jsx-runtime");
4224
+ var PrimusSearch = ({
4225
+ placeholder = "Search...",
4226
+ debounce = 300,
4227
+ value = "",
4228
+ showSuggestions = false,
4229
+ suggestions = [],
4230
+ onSearch
4231
+ }) => {
4232
+ const [query, setQuery] = (0, import_react44.useState)(value);
4233
+ (0, import_react44.useEffect)(() => {
4234
+ setQuery(value);
4235
+ }, [value]);
4236
+ (0, import_react44.useEffect)(() => {
4237
+ const handle = window.setTimeout(() => {
4238
+ onSearch?.(query);
4239
+ }, debounce);
4240
+ return () => window.clearTimeout(handle);
4241
+ }, [query, debounce, onSearch]);
4242
+ const visibleSuggestions = (0, import_react44.useMemo)(() => {
4243
+ if (!showSuggestions || !suggestions.length) {
4244
+ return [];
4245
+ }
4246
+ if (!query) {
4247
+ return suggestions.slice(0, 5);
4248
+ }
4249
+ return suggestions.filter((item) => item.toLowerCase().includes(query.toLowerCase())).slice(0, 5);
4250
+ }, [suggestions, query, showSuggestions]);
4251
+ return /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "relative", children: [
4252
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
4253
+ "input",
4254
+ {
4255
+ type: "text",
4256
+ value: query,
4257
+ placeholder,
4258
+ onChange: (event) => setQuery(event.target.value),
4259
+ className: "w-full px-3 py-2 rounded-lg border border-white/10 bg-white/5 text-gray-200 text-sm focus:outline-none focus:ring-1 focus:ring-purple-500/50"
4260
+ }
4261
+ ),
4262
+ visibleSuggestions.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("div", { className: "absolute mt-2 w-full rounded-lg border border-white/10 bg-slate-900/90 backdrop-blur-sm shadow-lg z-10", children: visibleSuggestions.map((item) => /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
4263
+ "button",
4264
+ {
4265
+ type: "button",
4266
+ onClick: () => setQuery(item),
4267
+ className: "w-full text-left px-3 py-2 text-sm text-gray-200 hover:bg-white/10",
4268
+ children: item
4269
+ },
4270
+ item
4271
+ )) })
4272
+ ] });
4273
+ };
2553
4274
  // Annotate the CommonJS export names for ESM import in node:
2554
4275
  0 && (module.exports = {
2555
4276
  AICopilot,
2556
4277
  AccountDashboard,
2557
4278
  AgentDirectory,
4279
+ Badge,
4280
+ Button,
4281
+ Card,
4282
+ Checkbox,
2558
4283
  CheckoutForm,
2559
4284
  ClaimStatusTracker,
4285
+ Container,
2560
4286
  CreditCardVisual,
2561
4287
  CreditScoreCard,
2562
4288
  DashboardGrid,
@@ -2564,29 +4290,64 @@ var DashboardGrid = ({
2564
4290
  FeatureFlagToggle,
2565
4291
  FileUploader,
2566
4292
  FraudDetectionDashboard,
4293
+ Grid,
4294
+ Input,
2567
4295
  KYCVerification,
2568
4296
  LoanCalculator,
2569
4297
  LogViewer,
2570
4298
  LoginPage,
4299
+ Modal,
2571
4300
  NotificationBell,
2572
4301
  NotificationFeed,
2573
4302
  PolicyCard,
2574
4303
  PremiumCalculator,
4304
+ PrimusActivityFeed,
4305
+ PrimusAreaChart,
4306
+ PrimusBadge,
4307
+ PrimusBarChart,
4308
+ PrimusButton,
4309
+ PrimusCard,
4310
+ PrimusChartBase,
4311
+ PrimusCheckbox,
4312
+ PrimusContainer,
2575
4313
  PrimusDashboard,
2576
4314
  PrimusDataTable,
4315
+ PrimusDateRangePicker,
4316
+ PrimusExportMenu,
4317
+ PrimusFilterBar,
4318
+ PrimusGrid,
2577
4319
  PrimusHeader,
4320
+ PrimusInput,
2578
4321
  PrimusLayout,
4322
+ PrimusLineChart,
2579
4323
  PrimusLogin,
2580
4324
  PrimusModal,
4325
+ PrimusModalComponent,
2581
4326
  PrimusNotificationCenter,
4327
+ PrimusNotificationFeed,
2582
4328
  PrimusNotifications,
4329
+ PrimusPieChart,
2583
4330
  PrimusProvider,
4331
+ PrimusRadioGroup,
4332
+ PrimusSearch,
4333
+ PrimusSelect,
2584
4334
  PrimusSidebar,
4335
+ PrimusSparkline,
4336
+ PrimusStack,
2585
4337
  PrimusStatCard,
4338
+ PrimusTable,
4339
+ PrimusTextarea,
2586
4340
  PrimusThemeProvider,
2587
4341
  PrimusThemeToggle,
4342
+ PrimusToggle,
2588
4343
  QuoteComparison,
4344
+ RadioGroup,
2589
4345
  SecurityDashboard,
4346
+ Select,
4347
+ Stack,
4348
+ Table,
4349
+ Textarea,
4350
+ Toggle,
2590
4351
  TransactionHistory,
2591
4352
  UserProfile,
2592
4353
  themeColors,