primus-react-ui 1.0.14 → 1.1.1

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
@@ -45,17 +45,24 @@ __export(index_exports, {
45
45
  DashboardGrid: () => DashboardGrid,
46
46
  DocumentViewer: () => DocumentViewer,
47
47
  FeatureFlagToggle: () => FeatureFlagToggle,
48
+ Field: () => Field,
49
+ FieldDescription: () => FieldDescription,
50
+ FieldError: () => FieldError,
48
51
  FileUploader: () => FileUploader,
49
52
  FraudDetectionDashboard: () => FraudDetectionDashboard,
50
53
  Grid: () => Grid,
51
54
  Input: () => Input,
55
+ InputAddon: () => InputAddon,
56
+ InputGroup: () => InputGroup,
52
57
  KYCVerification: () => KYCVerification,
58
+ Label: () => Label,
53
59
  LoanCalculator: () => LoanCalculator,
54
60
  LogViewer: () => LogViewer,
55
61
  LoginPage: () => LoginPage,
56
62
  Modal: () => Modal,
57
63
  NotificationBell: () => NotificationBell,
58
64
  NotificationFeed: () => PrimusNotificationFeed,
65
+ PasswordInput: () => PasswordInput,
59
66
  PolicyCard: () => PolicyCard,
60
67
  PremiumCalculator: () => PremiumCalculator,
61
68
  PrimusActivityFeed: () => PrimusActivityFeed,
@@ -71,10 +78,16 @@ __export(index_exports, {
71
78
  PrimusDataTable: () => PrimusDataTable,
72
79
  PrimusDateRangePicker: () => PrimusDateRangePicker,
73
80
  PrimusExportMenu: () => PrimusExportMenu,
81
+ PrimusField: () => Field,
82
+ PrimusFieldDescription: () => FieldDescription,
83
+ PrimusFieldError: () => FieldError,
74
84
  PrimusFilterBar: () => PrimusFilterBar,
75
85
  PrimusGrid: () => Grid,
76
86
  PrimusHeader: () => PrimusHeader,
77
87
  PrimusInput: () => Input,
88
+ PrimusInputAddon: () => InputAddon,
89
+ PrimusInputGroup: () => InputGroup,
90
+ PrimusLabel: () => Label,
78
91
  PrimusLayout: () => PrimusLayout,
79
92
  PrimusLineChart: () => PrimusLineChart,
80
93
  PrimusLogin: () => PrimusLogin,
@@ -83,22 +96,31 @@ __export(index_exports, {
83
96
  PrimusNotificationCenter: () => PrimusNotificationCenter,
84
97
  PrimusNotificationFeed: () => PrimusNotificationFeed,
85
98
  PrimusNotifications: () => PrimusNotifications,
99
+ PrimusPasswordInput: () => PasswordInput,
86
100
  PrimusPieChart: () => PrimusPieChart,
87
101
  PrimusProvider: () => PrimusProvider,
88
102
  PrimusRadioGroup: () => RadioGroup,
89
103
  PrimusSearch: () => PrimusSearch,
104
+ PrimusSearchInput: () => SearchInput,
105
+ PrimusSection: () => PrimusSection,
90
106
  PrimusSelect: () => Select,
91
107
  PrimusSidebar: () => PrimusSidebar,
92
108
  PrimusSparkline: () => PrimusSparkline,
93
109
  PrimusStack: () => Stack,
94
110
  PrimusStatCard: () => PrimusStatCard,
111
+ PrimusStatsCard: () => PrimusStatCard,
112
+ PrimusStep: () => PrimusStep,
113
+ PrimusStepper: () => PrimusStepper,
114
+ PrimusSummaryCard: () => PrimusSummaryCard,
95
115
  PrimusTable: () => Table,
96
116
  PrimusTextarea: () => Textarea,
97
117
  PrimusThemeProvider: () => PrimusThemeProvider,
98
118
  PrimusThemeToggle: () => PrimusThemeToggle,
99
119
  PrimusToggle: () => Toggle,
120
+ PrimusWizard: () => PrimusWizard,
100
121
  QuoteComparison: () => QuoteComparison,
101
122
  RadioGroup: () => RadioGroup,
123
+ SearchInput: () => SearchInput,
102
124
  SecurityDashboard: () => SecurityDashboard,
103
125
  Select: () => Select,
104
126
  Stack: () => Stack,
@@ -110,6 +132,7 @@ __export(index_exports, {
110
132
  themeColors: () => themeColors,
111
133
  useNotifications: () => useNotifications,
112
134
  usePrimusAuth: () => usePrimusAuth,
135
+ usePrimusFetch: () => usePrimusFetch,
113
136
  usePrimusTheme: () => usePrimusTheme,
114
137
  useRealtimeNotifications: () => useRealtimeNotifications
115
138
  });
@@ -877,7 +900,7 @@ var SecurityDashboard = ({
877
900
  };
878
901
 
879
902
  // src/components/auth/PrimusLogin.tsx
880
- var import_react13 = require("react");
903
+ var import_react14 = require("react");
881
904
 
882
905
  // src/context/PrimusThemeProvider.tsx
883
906
  var import_react12 = require("react");
@@ -961,55 +984,343 @@ function PrimusThemeToggle() {
961
984
  );
962
985
  }
963
986
 
964
- // src/components/auth/PrimusLogin.tsx
987
+ // src/context/PrimusProvider.tsx
988
+ var import_react13 = require("react");
965
989
  var import_jsx_runtime13 = require("react/jsx-runtime");
966
- var providerConfigs = {
967
- google: {
968
- name: "Google",
969
- icon: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("svg", { className: "h-5 w-5", viewBox: "0 0 24 24", children: [
970
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { fill: "#4285F4", d: "M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z" }),
971
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { fill: "#34A853", d: "M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z" }),
972
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { fill: "#FBBC05", d: "M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z" }),
973
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { fill: "#EA4335", d: "M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z" })
974
- ] }),
975
- colors: { light: "bg-white hover:bg-gray-50 text-gray-700 border-gray-300", dark: "bg-white hover:bg-gray-100 text-gray-700 border-gray-300" }
990
+ var PrimusAuthContext = (0, import_react13.createContext)(void 0);
991
+ var PrimusProvider = ({
992
+ children,
993
+ authority,
994
+ authBasePath = "/api/auth",
995
+ csrfCookieName = "XSRF-TOKEN",
996
+ csrfHeaderName = "X-Primus-CSRF",
997
+ seedCsrfOnLoad = true,
998
+ clientId,
999
+ onLoginSuccess,
1000
+ onLoginError,
1001
+ heartbeatInterval = 3e5
1002
+ // 5 minutes
1003
+ }) => {
1004
+ void clientId;
1005
+ const [isAuthenticated, setIsAuthenticated] = (0, import_react13.useState)(false);
1006
+ const [user, setUser] = (0, import_react13.useState)(null);
1007
+ const [token, setToken] = (0, import_react13.useState)(null);
1008
+ const [isLoading, setIsLoading] = (0, import_react13.useState)(true);
1009
+ const heartbeatRef = (0, import_react13.useRef)(null);
1010
+ const trimTrailingSlash = (value) => value.replace(/\/+$/, "");
1011
+ const ensureLeadingSlash = (value) => value.startsWith("/") ? value : `/${value}`;
1012
+ const joinUrl = (base, path) => `${trimTrailingSlash(base)}${ensureLeadingSlash(path)}`;
1013
+ const authBaseUrl = trimTrailingSlash(joinUrl(authority, authBasePath));
1014
+ const getCookie = (name) => {
1015
+ if (typeof document === "undefined") return null;
1016
+ const escaped = name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
1017
+ const matches = document.cookie.match(new RegExp(`(?:^|; )${escaped}=([^;]*)`));
1018
+ return matches ? decodeURIComponent(matches[1]) : null;
1019
+ };
1020
+ const fetchSessionUser = (0, import_react13.useCallback)(async () => {
1021
+ const response = await fetch(`${authBaseUrl}/me`, {
1022
+ credentials: "include",
1023
+ headers: {
1024
+ "Accept": "application/json"
1025
+ }
1026
+ });
1027
+ if (!response.ok) return null;
1028
+ const data = await response.json().catch(() => null);
1029
+ if (!data) return null;
1030
+ const resolvedUser = data.user ?? data;
1031
+ return resolvedUser ?? null;
1032
+ }, [authBaseUrl]);
1033
+ const startHeartbeat = (0, import_react13.useCallback)(() => {
1034
+ if (typeof window === "undefined") return;
1035
+ if (heartbeatRef.current) clearInterval(heartbeatRef.current);
1036
+ heartbeatRef.current = setInterval(() => {
1037
+ fetchSessionUser().catch(() => {
1038
+ });
1039
+ }, heartbeatInterval);
1040
+ }, [heartbeatInterval, fetchSessionUser]);
1041
+ const stopHeartbeat = (0, import_react13.useCallback)(() => {
1042
+ if (heartbeatRef.current) {
1043
+ clearInterval(heartbeatRef.current);
1044
+ heartbeatRef.current = null;
1045
+ }
1046
+ }, []);
1047
+ (0, import_react13.useEffect)(() => {
1048
+ return () => stopHeartbeat();
1049
+ }, [stopHeartbeat]);
1050
+ const seedCsrf = (0, import_react13.useCallback)(async () => {
1051
+ try {
1052
+ await fetch(`${authBaseUrl}/providers`, {
1053
+ credentials: "include",
1054
+ headers: { "Accept": "application/json" }
1055
+ });
1056
+ } catch {
1057
+ }
1058
+ }, [authBaseUrl]);
1059
+ (0, import_react13.useEffect)(() => {
1060
+ const checkSession = async () => {
1061
+ setIsLoading(true);
1062
+ try {
1063
+ if (seedCsrfOnLoad) {
1064
+ await seedCsrf();
1065
+ }
1066
+ const userData = await fetchSessionUser();
1067
+ if (userData) {
1068
+ setUser(userData);
1069
+ setIsAuthenticated(true);
1070
+ setToken("session-active");
1071
+ startHeartbeat();
1072
+ } else {
1073
+ stopHeartbeat();
1074
+ }
1075
+ } catch (err) {
1076
+ console.debug("No active session found", err);
1077
+ setIsAuthenticated(false);
1078
+ setUser(null);
1079
+ stopHeartbeat();
1080
+ } finally {
1081
+ setIsLoading(false);
1082
+ }
1083
+ };
1084
+ checkSession();
1085
+ }, [fetchSessionUser, seedCsrf, seedCsrfOnLoad, startHeartbeat, stopHeartbeat]);
1086
+ const login = (0, import_react13.useCallback)(async (credentials) => {
1087
+ setIsLoading(true);
1088
+ try {
1089
+ if ("provider" in credentials) {
1090
+ window.location.href = `${authBaseUrl}/${credentials.provider}`;
1091
+ return { success: true };
1092
+ }
1093
+ const csrfToken = getCookie(csrfCookieName);
1094
+ const headers = {
1095
+ "Content-Type": "application/json"
1096
+ };
1097
+ if (csrfToken) {
1098
+ headers[csrfHeaderName] = csrfToken;
1099
+ }
1100
+ const response = await fetch(`${authBaseUrl}/login`, {
1101
+ method: "POST",
1102
+ headers,
1103
+ credentials: "include",
1104
+ // CRITICAL: Persist HttpOnly Cookie
1105
+ body: JSON.stringify({ email: credentials.email, password: credentials.password })
1106
+ });
1107
+ if (!response.ok) {
1108
+ const errorData = await response.json().catch(() => ({}));
1109
+ const errorMsg = errorData.message || errorData.title || `Login failed (${response.status})`;
1110
+ onLoginError?.(errorMsg);
1111
+ return { success: false, error: errorMsg };
1112
+ }
1113
+ const data = await response.json().catch(() => null);
1114
+ const userData = data ? data.user || data : null;
1115
+ const refreshedUser = userData ?? await fetchSessionUser();
1116
+ setToken("session-active");
1117
+ if (refreshedUser) {
1118
+ setUser(refreshedUser);
1119
+ startHeartbeat();
1120
+ }
1121
+ setIsAuthenticated(true);
1122
+ if (refreshedUser) {
1123
+ onLoginSuccess?.(refreshedUser, "session-active");
1124
+ }
1125
+ return { success: true };
1126
+ } catch (err) {
1127
+ const errorMsg = err instanceof Error ? err.message : "Network error";
1128
+ onLoginError?.(errorMsg);
1129
+ return { success: false, error: errorMsg };
1130
+ } finally {
1131
+ setIsLoading(false);
1132
+ }
1133
+ }, [authBaseUrl, csrfCookieName, csrfHeaderName, fetchSessionUser, onLoginError, onLoginSuccess, startHeartbeat]);
1134
+ const logout = (0, import_react13.useCallback)(async () => {
1135
+ try {
1136
+ stopHeartbeat();
1137
+ const csrfToken = getCookie(csrfCookieName);
1138
+ const headers = {};
1139
+ if (csrfToken) {
1140
+ headers[csrfHeaderName] = csrfToken;
1141
+ }
1142
+ await fetch(`${authBaseUrl}/logout`, {
1143
+ method: "POST",
1144
+ credentials: "include",
1145
+ headers
1146
+ });
1147
+ } catch (e) {
1148
+ console.error("Logout failed", e);
1149
+ } finally {
1150
+ setToken(null);
1151
+ setIsAuthenticated(false);
1152
+ setUser(null);
1153
+ }
1154
+ }, [authBaseUrl, csrfCookieName, csrfHeaderName, stopHeartbeat]);
1155
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(PrimusAuthContext.Provider, { value: {
1156
+ isAuthenticated,
1157
+ user,
1158
+ login,
1159
+ logout,
1160
+ token,
1161
+ isLoading,
1162
+ csrfCookieName,
1163
+ csrfHeaderName
1164
+ }, children });
1165
+ };
1166
+ var usePrimusAuth = () => {
1167
+ const context = (0, import_react13.useContext)(PrimusAuthContext);
1168
+ if (context === void 0) {
1169
+ return {
1170
+ isAuthenticated: false,
1171
+ user: null,
1172
+ login: async () => ({ success: false, error: "PrimusProvider not configured" }),
1173
+ logout: async () => {
1174
+ },
1175
+ token: null,
1176
+ isLoading: false,
1177
+ csrfCookieName: "XSRF-TOKEN",
1178
+ csrfHeaderName: "X-Primus-CSRF"
1179
+ };
1180
+ }
1181
+ return context;
1182
+ };
1183
+
1184
+ // src/components/auth/PrimusLogin.tsx
1185
+ var import_jsx_runtime14 = require("react/jsx-runtime");
1186
+ var styles = {
1187
+ container: {
1188
+ minHeight: "100vh",
1189
+ display: "flex",
1190
+ alignItems: "center",
1191
+ justifyContent: "center",
1192
+ padding: "24px",
1193
+ fontFamily: '"Segoe UI", Arial, sans-serif',
1194
+ transition: "background-color 0.3s, color 0.3s"
976
1195
  },
977
- azure: {
978
- name: "Microsoft",
979
- icon: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("svg", { className: "h-5 w-5", viewBox: "0 0 23 23", children: [
980
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { fill: "#f35325", d: "M1 1h10v10H1z" }),
981
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { fill: "#81bc06", d: "M12 1h10v10H12z" }),
982
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { fill: "#05a6f0", d: "M1 12h10v10H1z" }),
983
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { fill: "#ffba08", d: "M12 12h10v10H12z" })
984
- ] }),
985
- colors: { light: "bg-white hover:bg-gray-50 text-gray-700 border-gray-300", dark: "bg-white hover:bg-gray-100 text-gray-700 border-gray-300" }
1196
+ card: {
1197
+ width: "100%",
1198
+ maxWidth: "420px",
1199
+ borderRadius: "16px",
1200
+ padding: "24px",
1201
+ boxShadow: "0 20px 40px rgba(15, 23, 42, 0.08)",
1202
+ border: "1px solid #e2e8f0",
1203
+ backgroundColor: "#ffffff"
986
1204
  },
987
- github: {
988
- name: "GitHub",
989
- icon: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("svg", { className: "h-5 w-5", fill: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { fillRule: "evenodd", d: "M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z", clipRule: "evenodd" }) }),
990
- colors: { light: "bg-gray-900 hover:bg-gray-800 text-white border-gray-900", dark: "bg-white hover:bg-gray-100 text-gray-900 border-gray-300" }
1205
+ header: {
1206
+ marginBottom: "24px",
1207
+ textAlign: "center"
991
1208
  },
992
- microsoft: {
993
- name: "Microsoft",
994
- icon: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("svg", { className: "h-5 w-5", viewBox: "0 0 24 24", children: [
995
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { fill: "#F25022", d: "M1 1h10v10H1z" }),
996
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { fill: "#00A4EF", d: "M1 13h10v10H1z" }),
997
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { fill: "#7FBA00", d: "M13 1h10v10H13z" }),
998
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { fill: "#FFB900", d: "M13 13h10v10H13z" })
999
- ] }),
1000
- colors: { light: "bg-white hover:bg-gray-50 text-gray-700 border-gray-300", dark: "bg-white hover:bg-gray-100 text-gray-700 border-gray-300" }
1209
+ logoStr: {
1210
+ width: "48px",
1211
+ height: "48px",
1212
+ borderRadius: "12px",
1213
+ marginBottom: "16px",
1214
+ objectFit: "cover"
1215
+ },
1216
+ title: {
1217
+ margin: "12px 0 4px",
1218
+ fontSize: "22px",
1219
+ fontWeight: "600"
1220
+ },
1221
+ subtitle: {
1222
+ margin: 0,
1223
+ fontSize: "13px",
1224
+ color: "#64748b"
1225
+ },
1226
+ socialGrid: {
1227
+ display: "grid",
1228
+ gap: "10px",
1229
+ marginTop: "16px"
1230
+ },
1231
+ socialBtn: {
1232
+ border: "1px solid #cbd5e1",
1233
+ background: "#ffffff",
1234
+ padding: "10px",
1235
+ borderRadius: "10px",
1236
+ fontSize: "13px",
1237
+ cursor: "pointer",
1238
+ color: "#0f172a",
1239
+ display: "flex",
1240
+ alignItems: "center",
1241
+ justifyContent: "center",
1242
+ gap: "8px",
1243
+ width: "100%",
1244
+ fontWeight: 500,
1245
+ transition: "background-color 0.2s"
1246
+ },
1247
+ divider: {
1248
+ margin: "24px 0",
1249
+ textAlign: "center",
1250
+ fontSize: "12px",
1251
+ color: "#94a3b8",
1252
+ position: "relative"
1253
+ },
1254
+ // Form
1255
+ form: {
1256
+ display: "grid",
1257
+ gap: "16px"
1001
1258
  },
1002
- apple: {
1003
- name: "Apple",
1004
- icon: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("svg", { className: "h-5 w-5", fill: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { d: "M18.71 19.5c-.83 1.24-1.71 2.45-3.05 2.47-1.34.03-1.77-.79-3.29-.79-1.53 0-2 .77-3.27.82-1.31.05-2.3-1.32-3.14-2.53C4.25 17 2.94 12.45 4.7 9.39c.87-1.52 2.43-2.48 4.12-2.51 1.28-.02 2.5.87 3.29.87.78 0 2.26-1.07 3.81-.91.65.03 2.47.26 3.64 1.98-.09.06-2.17 1.28-2.15 3.81.03 3.02 2.65 4.03 2.68 4.04-.03.07-.42 1.44-1.38 2.83M13 3.5c.73-.83 1.94-1.46 2.94-1.5.13 1.17-.34 2.35-1.04 3.19-.69.85-1.83 1.51-2.95 1.42-.15-1.15.41-2.35 1.05-3.11z" }) }),
1005
- colors: { light: "bg-black hover:bg-gray-900 text-white border-black", dark: "bg-white hover:bg-gray-100 text-black border-gray-300" }
1259
+ label: {
1260
+ display: "block",
1261
+ fontSize: "12px",
1262
+ color: "#64748b",
1263
+ fontWeight: 400,
1264
+ marginBottom: "6px"
1265
+ },
1266
+ input: {
1267
+ width: "100%",
1268
+ border: "1px solid #cbd5e1",
1269
+ borderRadius: "8px",
1270
+ padding: "10px 12px",
1271
+ background: "#ffffff",
1272
+ color: "#0f172a",
1273
+ fontSize: "14px",
1274
+ outline: "none"
1275
+ },
1276
+ submitBtn: {
1277
+ marginTop: "8px",
1278
+ background: "#8b5cf6",
1279
+ // Purple to match Angular
1280
+ color: "#ffffff",
1281
+ border: "none",
1282
+ borderRadius: "8px",
1283
+ padding: "10px",
1284
+ cursor: "pointer",
1285
+ fontWeight: 500,
1286
+ fontSize: "13px",
1287
+ width: "100%"
1006
1288
  },
1007
- facebook: {
1008
- name: "Facebook",
1009
- icon: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("svg", { className: "h-5 w-5", fill: "white", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { d: "M24 12.073c0-6.627-5.373-12-12-12s-12 5.373-12 12c0 5.99 4.388 10.954 10.125 11.854v-8.385H7.078v-3.47h3.047V9.43c0-3.007 1.792-4.669 4.533-4.669 1.312 0 2.686.235 2.686.235v2.953H15.83c-1.491 0-1.956.925-1.956 1.874v2.25h3.328l-.532 3.47h-2.796v8.385C19.612 23.027 24 18.062 24 12.073z" }) }),
1010
- colors: { light: "bg-[#1877F2] hover:bg-[#166FE5] text-white border-[#1877F2]", dark: "bg-[#1877F2] hover:bg-[#166FE5] text-white border-[#1877F2]" }
1289
+ error: {
1290
+ marginTop: "12px",
1291
+ color: "#dc2626",
1292
+ fontSize: "12px",
1293
+ textAlign: "center"
1011
1294
  }
1012
1295
  };
1296
+ var darkStyles = {
1297
+ container: { backgroundColor: "#0f172a", color: "#f8fafc" },
1298
+ card: { backgroundColor: "#1e293b", borderColor: "#334155", boxShadow: "none" },
1299
+ subtitle: { color: "#94a3b8" },
1300
+ socialBtn: { backgroundColor: "#1e293b", borderColor: "#334155", color: "#f8fafc" },
1301
+ label: { color: "#94a3b8" },
1302
+ input: { backgroundColor: "#0f172a", borderColor: "#334155", color: "#f8fafc" },
1303
+ submitBtn: { backgroundColor: "#8b5cf6" }
1304
+ // Purple to match Angular
1305
+ };
1306
+ var Icons = {
1307
+ google: /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("svg", { width: "18", height: "18", viewBox: "0 0 18 18", children: [
1308
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("path", { d: "M17.64 9.2c0-.637-.057-1.251-.164-1.84H9v3.481h4.844c-.209 1.125-.843 2.078-1.796 2.717v2.258h2.908c1.702-1.567 2.684-3.874 2.684-6.615z", fill: "#4285F4" }),
1309
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("path", { d: "M9 18c2.43 0 4.467-.806 5.956-2.184l-2.908-2.258c-.806.54-1.837.86-3.048.86-2.344 0-4.328-1.584-5.036-3.711H.957v2.332C2.438 15.983 5.482 18 9 18z", fill: "#34A853" }),
1310
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("path", { d: "M3.964 10.707c-.18-.54-.282-1.117-.282-1.707 0-.593.102-1.17.282-1.709V4.958H.957C.347 6.173 0 7.548 0 9c0 1.452.348 2.827.957 4.042l3.007-2.335z", fill: "#FBBC05" }),
1311
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("path", { d: "M9 3.58c1.321 0 2.508.454 3.44 1.345l2.582-2.58C13.463.891 11.426 0 9 0 5.482 0 2.438 2.017.957 4.958L3.964 7.29C4.672 5.163 6.656 3.58 9 3.58z", fill: "#EA4335" })
1312
+ ] }),
1313
+ microsoft: /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("svg", { width: "18", height: "18", viewBox: "0 0 18 18", children: [
1314
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("path", { d: "M0 0h8.571v8.571H0V0z", fill: "#F25022" }),
1315
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("path", { d: "M9.429 0H18v8.571H9.429V0z", fill: "#7FBA00" }),
1316
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("path", { d: "M0 9.429h8.571V18H0V9.429z", fill: "#00A4EF" }),
1317
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("path", { d: "M9.429 9.429H18V18H9.429V9.429z", fill: "#FFB900" })
1318
+ ] }),
1319
+ github: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("svg", { width: "18", height: "18", viewBox: "0 0 18 18", fill: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("path", { d: "M9 0C4.029 0 0 4.029 0 9c0 3.977 2.578 7.348 6.155 8.537.45.082.615-.195.615-.433 0-.213-.008-.923-.012-1.674-2.505.544-3.034-1.073-3.034-1.073-.41-1.04-1-1.316-1-1.316-.817-.558.062-.547.062-.547.903.064 1.378.927 1.378.927.803 1.376 2.107.978 2.62.748.082-.582.314-.978.572-1.203-2-.227-4.1-1-4.1-4.448 0-.983.35-1.786.927-2.416-.093-.228-.402-1.144.088-2.383 0 0 .756-.242 2.475.923A8.63 8.63 0 019 4.347c.765.004 1.535.103 2.254.303 1.718-1.165 2.473-.923 2.473-.923.491 1.239.182 2.155.089 2.383.578.63.926 1.433.926 2.416 0 3.457-2.104 4.218-4.109 4.44.323.278.611.827.611 1.667 0 1.203-.011 2.173-.011 2.469 0 .24.163.52.619.432C15.424 16.345 18 12.976 18 9c0-4.971-4.029-9-9-9z" }) }),
1320
+ apple: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("svg", { width: "18", height: "18", viewBox: "0 0 18 18", fill: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("path", { d: "M14.94 13.52c-.36.77-.54 1.12-1.01 1.8-.66.95-1.59 2.13-2.74 2.14-1.02.01-1.29-.66-2.68-.65-1.39.01-1.69.66-2.71.65-1.15-.01-2.01-1.07-2.67-2.02-1.85-2.66-2.04-5.78-.9-7.44.81-1.18 2.09-1.87 3.29-1.87 1.22 0 1.99.67 3 .67.98 0 1.58-.67 2.99-.67 1.07 0 2.2.58 3.01 1.58-2.64 1.45-2.21 5.23.42 6.81zM11.53 3.96c.52-.67.92-1.61.77-2.56-.84.04-1.84.59-2.43 1.29-.52.62-.96 1.58-.79 2.5.94.02 1.91-.53 2.45-1.23z" }) }),
1321
+ auth0: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("svg", { width: "18", height: "18", viewBox: "0 0 18 18", fill: "#EB5424", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("path", { d: "M13.98 0L9 7.83 4.02 0H0l9 15.59L18 0h-4.02zM9 10.41L4.02 18h9.96L9 10.41z" }) }),
1322
+ facebook: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("svg", { width: "18", height: "18", viewBox: "0 0 18 18", fill: "#1877F2", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("path", { d: "M18 9.05C18 4.05 13.97 0 9 0S0 4.05 0 9.05C0 13.58 3.29 17.34 7.59 18v-6.28H5.31V9.05h2.28V7.05c0-2.25 1.34-3.49 3.39-3.49.98 0 2.01.18 2.01.18v2.21h-1.13c-1.11 0-1.46.69-1.46 1.4v1.68h2.49l-.4 2.67h-2.09V18C14.71 17.34 18 13.58 18 9.05z" }) })
1323
+ };
1013
1324
  function PrimusLogin({
1014
1325
  onLogin,
1015
1326
  socialProviders = [],
@@ -1019,20 +1330,45 @@ function PrimusLogin({
1019
1330
  title = "Welcome Back",
1020
1331
  subtitle = "Enter your credentials to continue",
1021
1332
  logo,
1022
- theme: themeOverride
1333
+ theme: themeOverride,
1334
+ variant = "standalone",
1335
+ useAuth = false
1023
1336
  }) {
1024
1337
  const themeContext = usePrimusTheme();
1338
+ const auth = usePrimusAuth();
1025
1339
  const theme = themeOverride || themeContext.theme;
1026
1340
  const isLight = theme === "light";
1027
- const [username, setUsername] = (0, import_react13.useState)("");
1028
- const [password, setPassword] = (0, import_react13.useState)("");
1029
- const [loading, setLoading] = (0, import_react13.useState)(false);
1341
+ const isDark = !isLight;
1342
+ const [username, setUsername] = (0, import_react14.useState)("");
1343
+ const [password, setPassword] = (0, import_react14.useState)("");
1344
+ const [loading, setLoading] = (0, import_react14.useState)(false);
1345
+ const [errorMessage, setErrorMessage] = (0, import_react14.useState)("");
1346
+ const currentStyles = {
1347
+ container: { ...styles.container, ...isDark ? darkStyles.container : {} },
1348
+ card: { ...styles.card, ...isDark ? darkStyles.card : {} },
1349
+ title: { ...styles.title, color: isLight ? "#0f172a" : "#f8fafc" },
1350
+ subtitle: { ...styles.subtitle, ...isDark ? darkStyles.subtitle : {} },
1351
+ input: { ...styles.input, ...isDark ? darkStyles.input : {} },
1352
+ socialBtn: { ...styles.socialBtn, ...isDark ? darkStyles.socialBtn : {} },
1353
+ label: { ...styles.label, ...isDark ? darkStyles.label : {} },
1354
+ submitBtn: { ...styles.submitBtn, ...isDark ? darkStyles.submitBtn : {} }
1355
+ };
1030
1356
  const handleSubmit = async (e) => {
1031
1357
  e.preventDefault();
1032
1358
  if (!username || !password) return;
1033
1359
  setLoading(true);
1360
+ setErrorMessage("");
1034
1361
  try {
1362
+ if (useAuth) {
1363
+ const result = await auth.login({ email: username, password });
1364
+ if (!result.success) {
1365
+ setErrorMessage(result.error || "Login failed");
1366
+ return;
1367
+ }
1368
+ }
1035
1369
  onLogin?.({ username, password });
1370
+ } catch (err) {
1371
+ setErrorMessage("Login failed. Please try again.");
1036
1372
  } finally {
1037
1373
  setLoading(false);
1038
1374
  }
@@ -1041,194 +1377,90 @@ function PrimusLogin({
1041
1377
  if (onSocialLogin) {
1042
1378
  onSocialLogin(provider);
1043
1379
  } else {
1044
- window.location.href = `${authEndpoint}/${provider}`;
1380
+ const base = authEndpoint.replace(/\/+$/, "");
1381
+ window.location.href = `${base}/${provider}`;
1045
1382
  }
1046
1383
  };
1047
- const bgGradient = isLight ? "bg-gradient-to-br from-gray-50 via-white to-violet-50" : "bg-gray-950";
1048
- const cardBg = isLight ? "bg-white border-gray-200 shadow-xl" : "bg-gray-900/50 border-white/10";
1049
- const headingColor = isLight ? "text-gray-900" : "text-white";
1050
- const subtextColor = isLight ? "text-gray-500" : "text-slate-400";
1051
- const labelColor = isLight ? "text-gray-600" : "text-slate-300";
1052
- const inputClasses = isLight ? "bg-gray-50 border-gray-300 text-gray-900 placeholder:text-gray-400 focus:border-violet-500 focus:ring-violet-500" : "bg-gray-950/50 border-slate-700 text-white placeholder:text-slate-600 focus:border-blue-500 focus:ring-blue-500";
1053
- const buttonGradient = isLight ? "bg-gradient-to-r from-violet-600 to-purple-600" : "bg-gradient-to-r from-blue-600 to-indigo-600";
1054
- const logoBg = isLight ? "bg-violet-600 shadow-violet-500/20" : "bg-blue-600 shadow-blue-500/20";
1055
- const dividerColor = isLight ? "border-gray-200" : "border-slate-700";
1056
- const hasSocial = socialProviders.length > 0;
1057
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: `min-h-screen ${bgGradient} flex items-center justify-center p-4`, children: [
1058
- !isLight && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "absolute inset-0 overflow-hidden", children: [
1059
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "absolute -top-[20%] -left-[10%] w-[50%] h-[50%] bg-blue-600/20 rounded-full blur-[120px]" }),
1060
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "absolute -bottom-[20%] -right-[10%] w-[50%] h-[50%] bg-purple-600/20 rounded-full blur-[120px]" })
1384
+ const renderSocialIcon = (p) => {
1385
+ const key = p === "azure" ? "microsoft" : p;
1386
+ return Icons[key] || null;
1387
+ };
1388
+ const content = /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { style: currentStyles.card, className: "primus-login-card", children: [
1389
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { style: styles.header, className: "primus-login-header", children: [
1390
+ logo && (typeof logo === "string" ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("img", { src: logo, alt: "Logo", style: styles.logoStr }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { style: { marginBottom: "16px", display: "flex", justifyContent: "center" }, children: logo })),
1391
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("h2", { style: currentStyles.title, children: title }),
1392
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { style: currentStyles.subtitle, children: subtitle })
1061
1393
  ] }),
1062
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: `w-full max-w-md ${cardBg} p-8 rounded-2xl border backdrop-blur-xl relative z-10`, children: [
1063
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "text-center mb-8", children: [
1064
- logo ? typeof logo === "string" ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("img", { src: logo, alt: "Logo", className: "h-12 w-12 mx-auto mb-4 rounded-xl" }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "mb-4", children: logo }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: `h-12 w-12 ${logoBg} rounded-xl mx-auto flex items-center justify-center mb-4 shadow-lg`, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "font-bold text-xl text-white", children: "P" }) }),
1065
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("h1", { className: `text-2xl font-bold ${headingColor} tracking-tight`, children: title }),
1066
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { className: `${subtextColor} text-sm mt-2`, children: subtitle })
1067
- ] }),
1068
- hasSocial && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "space-y-3 mb-6", children: socialProviders.map((provider) => {
1069
- const config = providerConfigs[provider];
1070
- if (!config) return null;
1071
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
1072
- "button",
1394
+ socialProviders.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { style: styles.socialGrid, className: "primus-social", children: socialProviders.map((provider) => /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
1395
+ "button",
1396
+ {
1397
+ type: "button",
1398
+ onClick: () => handleSocialClick(provider),
1399
+ style: currentStyles.socialBtn,
1400
+ onMouseOver: (e) => {
1401
+ if (isLight) e.currentTarget.style.backgroundColor = "#f1f5f9";
1402
+ else e.currentTarget.style.backgroundColor = "#334155";
1403
+ },
1404
+ onMouseOut: (e) => {
1405
+ if (isLight) e.currentTarget.style.backgroundColor = "#ffffff";
1406
+ else e.currentTarget.style.backgroundColor = "#1e293b";
1407
+ },
1408
+ children: [
1409
+ renderSocialIcon(provider),
1410
+ "Continue with ",
1411
+ provider === "azure" ? "Microsoft" : provider.charAt(0).toUpperCase() + provider.slice(1)
1412
+ ]
1413
+ },
1414
+ provider
1415
+ )) }),
1416
+ socialProviders.length > 0 && showEmailLogin && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { style: styles.divider, className: "primus-divider", children: [
1417
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { style: { backgroundColor: isLight ? "#fff" : "#1e293b", padding: "0 8px", position: "relative", zIndex: 1 }, children: "Or continue with email" }),
1418
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { style: { position: "absolute", top: "50%", left: 0, right: 0, borderTop: isLight ? "1px solid #e2e8f0" : "1px solid #334155", zIndex: 0 } })
1419
+ ] }),
1420
+ showEmailLogin && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("form", { onSubmit: handleSubmit, style: styles.form, className: "primus-form", children: [
1421
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { children: [
1422
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("label", { style: currentStyles.label, children: "Email" }),
1423
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1424
+ "input",
1073
1425
  {
1074
- onClick: () => handleSocialClick(provider),
1075
- className: `w-full flex items-center justify-center gap-3 px-4 py-2.5 border rounded-lg font-medium text-sm transition-all duration-200 ${isLight ? config.colors.light : config.colors.dark}`,
1076
- children: [
1077
- config.icon,
1078
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { children: [
1079
- "Continue with ",
1080
- config.name
1081
- ] })
1082
- ]
1083
- },
1084
- provider
1085
- );
1086
- }) }),
1087
- hasSocial && showEmailLogin && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "relative my-6", children: [
1088
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "absolute inset-0 flex items-center", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: `w-full border-t ${dividerColor}` }) }),
1089
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "relative flex justify-center text-xs uppercase", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: `${isLight ? "bg-white" : "bg-gray-900/50"} px-2 ${subtextColor}`, children: "Or continue with email" }) })
1426
+ type: "email",
1427
+ value: username,
1428
+ onChange: (e) => setUsername(e.target.value),
1429
+ style: currentStyles.input
1430
+ }
1431
+ )
1090
1432
  ] }),
1091
- showEmailLogin && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("form", { onSubmit: handleSubmit, className: "space-y-4", children: [
1092
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "space-y-2", children: [
1093
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("label", { className: `text-xs font-medium ${labelColor} ml-1`, children: "EMAIL" }),
1094
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1095
- "input",
1096
- {
1097
- type: "text",
1098
- value: username,
1099
- onChange: (e) => setUsername(e.target.value),
1100
- className: `w-full px-4 py-2.5 ${inputClasses} border rounded-lg focus:outline-none focus:ring-1 transition-all text-sm`,
1101
- placeholder: "you@example.com"
1102
- }
1103
- )
1104
- ] }),
1105
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "space-y-2", children: [
1106
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("label", { className: `text-xs font-medium ${labelColor} ml-1`, children: "PASSWORD" }),
1107
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1108
- "input",
1109
- {
1110
- type: "password",
1111
- value: password,
1112
- onChange: (e) => setPassword(e.target.value),
1113
- className: `w-full px-4 py-2.5 ${inputClasses} border rounded-lg focus:outline-none focus:ring-1 transition-all text-sm`,
1114
- placeholder: "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022"
1115
- }
1116
- )
1117
- ] }),
1118
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1119
- "button",
1433
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { children: [
1434
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("label", { style: currentStyles.label, children: "Password" }),
1435
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1436
+ "input",
1120
1437
  {
1121
- type: "submit",
1122
- disabled: loading,
1123
- className: `w-full mt-4 py-2.5 ${buttonGradient} text-white font-medium rounded-lg hover:opacity-90 transition-opacity disabled:opacity-50`,
1124
- children: loading ? "Signing in..." : "Sign In"
1438
+ type: "password",
1439
+ value: password,
1440
+ onChange: (e) => setPassword(e.target.value),
1441
+ style: currentStyles.input
1125
1442
  }
1126
1443
  )
1127
- ] })
1128
- ] })
1444
+ ] }),
1445
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1446
+ "button",
1447
+ {
1448
+ type: "submit",
1449
+ disabled: loading,
1450
+ style: { ...currentStyles.submitBtn, opacity: loading ? 0.7 : 1 },
1451
+ children: loading ? "Signing in..." : "Sign In"
1452
+ }
1453
+ )
1454
+ ] }),
1455
+ errorMessage && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { style: styles.error, children: errorMessage })
1129
1456
  ] });
1457
+ if (variant === "embedded") {
1458
+ return content;
1459
+ }
1460
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { style: { ...currentStyles.container, background: isLight ? "#f8fafc" : "#0f172a" }, className: `primus-login ${isDark ? "dark" : ""}`, children: content });
1130
1461
  }
1131
1462
  var LoginPage = PrimusLogin;
1132
1463
 
1133
- // src/context/PrimusProvider.tsx
1134
- var import_react14 = require("react");
1135
- var import_jsx_runtime14 = require("react/jsx-runtime");
1136
- var PrimusAuthContext = (0, import_react14.createContext)(void 0);
1137
- var PrimusProvider = ({
1138
- children,
1139
- authority,
1140
- clientId,
1141
- onLoginSuccess,
1142
- onLoginError
1143
- }) => {
1144
- void clientId;
1145
- const [isAuthenticated, setIsAuthenticated] = (0, import_react14.useState)(false);
1146
- const [user, setUser] = (0, import_react14.useState)(null);
1147
- const [token, setToken] = (0, import_react14.useState)(null);
1148
- const [isLoading, setIsLoading] = (0, import_react14.useState)(false);
1149
- (0, import_react14.useEffect)(() => {
1150
- const storedToken = localStorage.getItem("primus_token");
1151
- const storedUser = localStorage.getItem("primus_user");
1152
- if (storedToken && storedUser) {
1153
- try {
1154
- setToken(storedToken);
1155
- setUser(JSON.parse(storedUser));
1156
- setIsAuthenticated(true);
1157
- } catch {
1158
- localStorage.removeItem("primus_token");
1159
- localStorage.removeItem("primus_user");
1160
- }
1161
- }
1162
- }, []);
1163
- const login = (0, import_react14.useCallback)(async (credentials) => {
1164
- setIsLoading(true);
1165
- try {
1166
- let endpoint;
1167
- let body;
1168
- if ("provider" in credentials) {
1169
- endpoint = `${authority}/auth/${credentials.provider}`;
1170
- body = {};
1171
- } else {
1172
- endpoint = `${authority}/auth/local`;
1173
- body = { email: credentials.email, password: credentials.password };
1174
- }
1175
- const response = await fetch(endpoint, {
1176
- method: "POST",
1177
- headers: { "Content-Type": "application/json" },
1178
- body: JSON.stringify(body)
1179
- });
1180
- if (!response.ok) {
1181
- const errorData = await response.json().catch(() => ({}));
1182
- const errorMsg = errorData.message || `Login failed (${response.status})`;
1183
- onLoginError?.(errorMsg);
1184
- return { success: false, error: errorMsg };
1185
- }
1186
- const data = await response.json();
1187
- const accessToken = data.access_token || data.token;
1188
- const userData = data.user || {
1189
- name: "Authenticated User",
1190
- email: "provider" in credentials ? `${credentials.provider}@primus.local` : credentials.email
1191
- };
1192
- localStorage.setItem("primus_token", accessToken);
1193
- localStorage.setItem("primus_user", JSON.stringify(userData));
1194
- setToken(accessToken);
1195
- setUser(userData);
1196
- setIsAuthenticated(true);
1197
- onLoginSuccess?.(userData, accessToken);
1198
- return { success: true };
1199
- } catch (err) {
1200
- const errorMsg = err instanceof Error ? err.message : "Network error";
1201
- onLoginError?.(errorMsg);
1202
- return { success: false, error: errorMsg };
1203
- } finally {
1204
- setIsLoading(false);
1205
- }
1206
- }, [authority, onLoginSuccess, onLoginError]);
1207
- const logout = (0, import_react14.useCallback)(async () => {
1208
- localStorage.removeItem("primus_token");
1209
- localStorage.removeItem("primus_user");
1210
- setToken(null);
1211
- setIsAuthenticated(false);
1212
- setUser(null);
1213
- }, []);
1214
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(PrimusAuthContext.Provider, { value: { isAuthenticated, user, login, logout, token, isLoading }, children });
1215
- };
1216
- var usePrimusAuth = () => {
1217
- const context = (0, import_react14.useContext)(PrimusAuthContext);
1218
- if (context === void 0) {
1219
- return {
1220
- isAuthenticated: false,
1221
- user: null,
1222
- login: async () => ({ success: false, error: "PrimusProvider not configured" }),
1223
- logout: async () => {
1224
- },
1225
- token: null,
1226
- isLoading: false
1227
- };
1228
- }
1229
- return context;
1230
- };
1231
-
1232
1464
  // src/components/shared/Button.tsx
1233
1465
  var import_react15 = __toESM(require("react"));
1234
1466
  var import_jsx_runtime15 = require("react/jsx-runtime");
@@ -1373,23 +1605,68 @@ var UserProfile = ({
1373
1605
  ] });
1374
1606
  };
1375
1607
 
1376
- // src/hooks/useNotifications.ts
1608
+ // src/hooks/usePrimusFetch.ts
1377
1609
  var import_react16 = require("react");
1610
+ function usePrimusFetch() {
1611
+ const { logout, csrfCookieName = "XSRF-TOKEN", csrfHeaderName = "X-Primus-CSRF" } = usePrimusAuth();
1612
+ const getCookie = (0, import_react16.useCallback)((name) => {
1613
+ if (typeof document === "undefined") return null;
1614
+ try {
1615
+ const matches = document.cookie.match(new RegExp("(?:^|; )" + name.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g, "\\$1") + "=([^;]*)"));
1616
+ return matches ? decodeURIComponent(matches[1]) : null;
1617
+ } catch {
1618
+ return null;
1619
+ }
1620
+ }, []);
1621
+ const primusFetch = (0, import_react16.useCallback)(async (input, init) => {
1622
+ const { skipAuth, ...fetchInit } = init || {};
1623
+ const config = {
1624
+ ...fetchInit,
1625
+ headers: new Headers(fetchInit.headers)
1626
+ };
1627
+ if (!skipAuth) {
1628
+ config.credentials = "include";
1629
+ }
1630
+ const method = (config.method || "GET").toUpperCase();
1631
+ if (!["GET", "HEAD", "OPTIONS"].includes(method)) {
1632
+ const csrfToken = getCookie(csrfCookieName);
1633
+ if (csrfToken) {
1634
+ config.headers.set(csrfHeaderName, csrfToken);
1635
+ }
1636
+ }
1637
+ try {
1638
+ const response = await window.fetch(input, config);
1639
+ if (response.status === 401 && !skipAuth) {
1640
+ console.debug("[PrimusFetch] 401 Unauthorized detected. triggering logout.");
1641
+ logout();
1642
+ }
1643
+ return response;
1644
+ } catch (error) {
1645
+ throw error;
1646
+ }
1647
+ }, [getCookie, logout, csrfCookieName, csrfHeaderName]);
1648
+ return {
1649
+ fetch: primusFetch
1650
+ };
1651
+ }
1652
+
1653
+ // src/hooks/useNotifications.ts
1654
+ var import_react17 = require("react");
1378
1655
  var useNotifications = ({
1379
1656
  apiUrl = "http://localhost:5221",
1380
1657
  useMock = false,
1381
1658
  mockData = []
1382
1659
  } = {}) => {
1383
- const [notifications, setNotifications] = (0, import_react16.useState)([]);
1384
- const [unreadCount, setUnreadCount] = (0, import_react16.useState)(0);
1385
- const [loading, setLoading] = (0, import_react16.useState)(true);
1386
- const safeMockData = (0, import_react16.useMemo)(() => mockData || [], [JSON.stringify(mockData)]);
1660
+ const [notifications, setNotifications] = (0, import_react17.useState)([]);
1661
+ const [unreadCount, setUnreadCount] = (0, import_react17.useState)(0);
1662
+ const [loading, setLoading] = (0, import_react17.useState)(true);
1663
+ const safeMockData = (0, import_react17.useMemo)(() => mockData || [], [JSON.stringify(mockData)]);
1387
1664
  const DEFAULT_MOCK_DATA = [
1388
1665
  { id: "1", title: "Welcome", message: "Welcome to Primus UI", type: "info", timestamp: (/* @__PURE__ */ new Date()).toISOString(), read: false },
1389
1666
  { id: "2", title: "System Update", message: "Maintenance scheduled", type: "warning", timestamp: (/* @__PURE__ */ new Date()).toISOString(), read: false },
1390
1667
  { id: "3", title: "Payment Success", message: "Your payment was processed", type: "success", timestamp: (/* @__PURE__ */ new Date()).toISOString(), read: false }
1391
1668
  ];
1392
- (0, import_react16.useEffect)(() => {
1669
+ (0, import_react17.useEffect)(() => {
1393
1670
  if (useMock) {
1394
1671
  const data = safeMockData.length > 0 ? safeMockData : DEFAULT_MOCK_DATA;
1395
1672
  setNotifications(data);
@@ -1440,8 +1717,8 @@ var useNotifications = ({
1440
1717
 
1441
1718
  // src/components/notifications/NotificationFeed.tsx
1442
1719
  var import_outline = require("@heroicons/react/24/outline");
1443
- var import_react17 = require("@headlessui/react");
1444
- var import_react18 = require("react");
1720
+ var import_react18 = require("@headlessui/react");
1721
+ var import_react19 = require("react");
1445
1722
  var import_clsx = require("clsx");
1446
1723
  var import_jsx_runtime17 = require("react/jsx-runtime");
1447
1724
  var NotificationIcon = ({ type }) => {
@@ -1458,8 +1735,8 @@ var NotificationIcon = ({ type }) => {
1458
1735
  };
1459
1736
  var PrimusNotificationFeed = ({ useMock, mockData, apiUrl, className }) => {
1460
1737
  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)(
1738
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_react18.Popover, { className: (0, import_clsx.clsx)("relative", className), children: ({ open }) => /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
1739
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_react18.Popover.Button, { className: (0, import_clsx.clsx)(
1463
1740
  "relative p-2 rounded-full hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-primus-500",
1464
1741
  open && "bg-gray-100"
1465
1742
  ), children: [
@@ -1467,16 +1744,16 @@ var PrimusNotificationFeed = ({ useMock, mockData, apiUrl, className }) => {
1467
1744
  unreadCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "absolute top-1 right-1 block h-2.5 w-2.5 rounded-full bg-red-500 ring-2 ring-white" })
1468
1745
  ] }),
1469
1746
  /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1470
- import_react17.Transition,
1747
+ import_react18.Transition,
1471
1748
  {
1472
- as: import_react18.Fragment,
1749
+ as: import_react19.Fragment,
1473
1750
  enter: "transition ease-out duration-200",
1474
1751
  enterFrom: "opacity-0 translate-y-1",
1475
1752
  enterTo: "opacity-100 translate-y-0",
1476
1753
  leave: "transition ease-in duration-150",
1477
1754
  leaveFrom: "opacity-100 translate-y-0",
1478
1755
  leaveTo: "opacity-0 translate-y-1",
1479
- children: /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_react17.Popover.Panel, { className: "absolute right-0 z-10 mt-2 w-80 origin-top-right rounded-md bg-white py-1 shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none sm:w-96", children: [
1756
+ children: /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_react18.Popover.Panel, { className: "absolute right-0 z-10 mt-2 w-80 origin-top-right rounded-md bg-white py-1 shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none sm:w-96", children: [
1480
1757
  /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "px-4 py-3 flex items-center justify-between border-b border-gray-100", children: [
1481
1758
  /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("h3", { className: "text-sm font-semibold text-gray-900", children: "Notifications" }),
1482
1759
  unreadCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
@@ -1516,7 +1793,7 @@ var PrimusNotificationFeed = ({ useMock, mockData, apiUrl, className }) => {
1516
1793
  };
1517
1794
 
1518
1795
  // src/components/notifications/PrimusNotificationCenter.tsx
1519
- var import_react19 = require("react");
1796
+ var import_react20 = require("react");
1520
1797
  var import_lucide_react = require("lucide-react");
1521
1798
  var import_jsx_runtime18 = require("react/jsx-runtime");
1522
1799
  var API_URL = "http://localhost:5222";
@@ -1530,15 +1807,15 @@ function PrimusNotificationCenter({
1530
1807
  const themeContext = usePrimusTheme();
1531
1808
  const theme = themeOverride || themeContext.theme;
1532
1809
  const t = themeColors[theme];
1533
- const [notifications, setNotifications] = (0, import_react19.useState)([]);
1534
- const [isOpen, setIsOpen] = (0, import_react19.useState)(false);
1535
- const [showSendForm, setShowSendForm] = (0, import_react19.useState)(false);
1536
- const [unreadCount, setUnreadCount] = (0, import_react19.useState)(0);
1537
- const [newTitle, setNewTitle] = (0, import_react19.useState)("");
1538
- const [newMessage, setNewMessage] = (0, import_react19.useState)("");
1539
- const [newType, setNewType] = (0, import_react19.useState)("info");
1540
- const [sending, setSending] = (0, import_react19.useState)(false);
1541
- const fetchNotifications = (0, import_react19.useCallback)(async () => {
1810
+ const [notifications, setNotifications] = (0, import_react20.useState)([]);
1811
+ const [isOpen, setIsOpen] = (0, import_react20.useState)(false);
1812
+ const [showSendForm, setShowSendForm] = (0, import_react20.useState)(false);
1813
+ const [unreadCount, setUnreadCount] = (0, import_react20.useState)(0);
1814
+ const [newTitle, setNewTitle] = (0, import_react20.useState)("");
1815
+ const [newMessage, setNewMessage] = (0, import_react20.useState)("");
1816
+ const [newType, setNewType] = (0, import_react20.useState)("info");
1817
+ const [sending, setSending] = (0, import_react20.useState)(false);
1818
+ const fetchNotifications = (0, import_react20.useCallback)(async () => {
1542
1819
  try {
1543
1820
  const response = await fetch(`${apiUrl}/api/notifications`);
1544
1821
  if (response.ok) {
@@ -1549,7 +1826,7 @@ function PrimusNotificationCenter({
1549
1826
  } catch (error) {
1550
1827
  }
1551
1828
  }, [apiUrl]);
1552
- (0, import_react19.useEffect)(() => {
1829
+ (0, import_react20.useEffect)(() => {
1553
1830
  if (useMock || mockData) {
1554
1831
  const next = mockData ?? [];
1555
1832
  setNotifications(next);
@@ -1762,15 +2039,15 @@ var NotificationBell = PrimusNotificationCenter;
1762
2039
  var PrimusNotifications = PrimusNotificationCenter;
1763
2040
 
1764
2041
  // src/hooks/useRealtimeNotifications.ts
1765
- var import_react20 = require("react");
2042
+ var import_react21 = require("react");
1766
2043
  var useRealtimeNotifications = (options) => {
1767
2044
  const { apiUrl, pollInterval = 3e3, userId } = options;
1768
- const [notifications, setNotifications] = (0, import_react20.useState)([]);
1769
- const [unreadCount, setUnreadCount] = (0, import_react20.useState)(0);
1770
- const [loading, setLoading] = (0, import_react20.useState)(true);
1771
- const [error, setError] = (0, import_react20.useState)(null);
2045
+ const [notifications, setNotifications] = (0, import_react21.useState)([]);
2046
+ const [unreadCount, setUnreadCount] = (0, import_react21.useState)(0);
2047
+ const [loading, setLoading] = (0, import_react21.useState)(true);
2048
+ const [error, setError] = (0, import_react21.useState)(null);
1772
2049
  const baseUrl = `${apiUrl}/api/notifications`;
1773
- const fetchNotifications = (0, import_react20.useCallback)(async () => {
2050
+ const fetchNotifications = (0, import_react21.useCallback)(async () => {
1774
2051
  try {
1775
2052
  const url = userId ? `${baseUrl}?userId=${userId}` : baseUrl;
1776
2053
  const response = await fetch(url);
@@ -1786,7 +2063,7 @@ var useRealtimeNotifications = (options) => {
1786
2063
  setLoading(false);
1787
2064
  }
1788
2065
  }, [baseUrl, userId]);
1789
- const sendNotification = (0, import_react20.useCallback)(async (title, message, type = "info") => {
2066
+ const sendNotification = (0, import_react21.useCallback)(async (title, message, type = "info") => {
1790
2067
  try {
1791
2068
  const response = await fetch(baseUrl, {
1792
2069
  method: "POST",
@@ -1802,7 +2079,7 @@ var useRealtimeNotifications = (options) => {
1802
2079
  return false;
1803
2080
  }
1804
2081
  }, [baseUrl, userId, fetchNotifications]);
1805
- const markAsRead = (0, import_react20.useCallback)(async (id) => {
2082
+ const markAsRead = (0, import_react21.useCallback)(async (id) => {
1806
2083
  try {
1807
2084
  await fetch(`${baseUrl}/${id}/read`, { method: "PUT" });
1808
2085
  setNotifications((prev) => prev.map((n) => n.id === id ? { ...n, read: true } : n));
@@ -1810,20 +2087,20 @@ var useRealtimeNotifications = (options) => {
1810
2087
  } catch {
1811
2088
  }
1812
2089
  }, [baseUrl]);
1813
- const markAllAsRead = (0, import_react20.useCallback)(async () => {
2090
+ const markAllAsRead = (0, import_react21.useCallback)(async () => {
1814
2091
  const unread = notifications.filter((n) => !n.read);
1815
2092
  await Promise.all(unread.map((n) => fetch(`${baseUrl}/${n.id}/read`, { method: "PUT" })));
1816
2093
  setNotifications((prev) => prev.map((n) => ({ ...n, read: true })));
1817
2094
  setUnreadCount(0);
1818
2095
  }, [notifications, baseUrl]);
1819
- const deleteNotification = (0, import_react20.useCallback)(async (id) => {
2096
+ const deleteNotification = (0, import_react21.useCallback)(async (id) => {
1820
2097
  try {
1821
2098
  await fetch(`${baseUrl}/${id}`, { method: "DELETE" });
1822
2099
  setNotifications((prev) => prev.filter((n) => n.id !== id));
1823
2100
  } catch {
1824
2101
  }
1825
2102
  }, [baseUrl]);
1826
- (0, import_react20.useEffect)(() => {
2103
+ (0, import_react21.useEffect)(() => {
1827
2104
  fetchNotifications();
1828
2105
  const interval = setInterval(fetchNotifications, pollInterval);
1829
2106
  return () => clearInterval(interval);
@@ -1842,10 +2119,10 @@ var useRealtimeNotifications = (options) => {
1842
2119
  };
1843
2120
 
1844
2121
  // src/components/payments/CheckoutForm.tsx
1845
- var import_react22 = require("react");
2122
+ var import_react23 = require("react");
1846
2123
 
1847
2124
  // src/components/shared/Input.tsx
1848
- var import_react21 = __toESM(require("react"));
2125
+ var import_react22 = __toESM(require("react"));
1849
2126
  var import_clsx2 = require("clsx");
1850
2127
  var import_solid = require("@heroicons/react/20/solid");
1851
2128
  var import_jsx_runtime19 = require("react/jsx-runtime");
@@ -1859,20 +2136,48 @@ var iconSizeClasses = {
1859
2136
  md: "w-5 h-5 [&>*]:w-full [&>*]:h-full",
1860
2137
  lg: "w-6 h-6 [&>*]:w-full [&>*]:h-full"
1861
2138
  };
1862
- var Input = import_react21.default.forwardRef(
1863
- ({ className, style, label, error, disabled, startIcon, endIcon, onClear, value, onChange, size = "md", loading = false, ...props }, ref) => {
2139
+ var Input = import_react22.default.forwardRef(
2140
+ ({
2141
+ className,
2142
+ style,
2143
+ label,
2144
+ error,
2145
+ disabled,
2146
+ startIcon,
2147
+ endIcon,
2148
+ onClear,
2149
+ value,
2150
+ onChange,
2151
+ onValueChange,
2152
+ size = "md",
2153
+ loading = false,
2154
+ autoSelect = false,
2155
+ onFocus,
2156
+ ...props
2157
+ }, ref) => {
2158
+ const handleFocus = (e) => {
2159
+ if (autoSelect) {
2160
+ e.target.select();
2161
+ }
2162
+ onFocus?.(e);
2163
+ };
2164
+ const handleChange = (e) => {
2165
+ onChange?.(e);
2166
+ onValueChange?.(e.target.value);
2167
+ };
1864
2168
  const hasValue = value !== void 0 && value !== "" && value !== null;
2169
+ const isDisabled = disabled || loading;
1865
2170
  return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: (0, import_clsx2.clsx)("w-full", className), style, children: [
1866
2171
  label && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("label", { className: (0, import_clsx2.clsx)(
1867
2172
  "block font-medium mb-1.5",
1868
2173
  size === "sm" ? "text-xs" : "text-sm",
1869
- disabled ? "text-gray-400 opacity-70" : "text-gray-700"
2174
+ isDisabled ? "text-gray-400 opacity-70" : "text-gray-700"
1870
2175
  ), children: label }),
1871
2176
  /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: (0, import_clsx2.clsx)(
1872
2177
  "relative flex items-center w-full rounded-lg transition-all duration-200 ease-in-out bg-white overflow-hidden",
1873
2178
  "border",
1874
2179
  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"
2180
+ isDisabled && "bg-gray-50 opacity-60 cursor-not-allowed"
1876
2181
  ), children: [
1877
2182
  startIcon && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: (0, import_clsx2.clsx)(
1878
2183
  "flex-shrink-0 pl-3 pr-2 text-gray-400 select-none pointer-events-none flex items-center justify-center",
@@ -1882,9 +2187,10 @@ var Input = import_react21.default.forwardRef(
1882
2187
  "input",
1883
2188
  {
1884
2189
  ref,
1885
- disabled,
2190
+ disabled: isDisabled,
1886
2191
  value,
1887
- onChange,
2192
+ onChange: handleChange,
2193
+ onFocus: handleFocus,
1888
2194
  className: (0, import_clsx2.clsx)(
1889
2195
  "flex-1 w-full border-none bg-transparent p-0 placeholder:text-gray-400 focus:ring-0 outline-none",
1890
2196
  sizeClasses[size],
@@ -1895,7 +2201,7 @@ var Input = import_react21.default.forwardRef(
1895
2201
  ...props
1896
2202
  }
1897
2203
  ),
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)(
2204
+ onClear && hasValue && !isDisabled && /* @__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
2205
  "button",
1900
2206
  {
1901
2207
  type: "button",
@@ -1903,7 +2209,8 @@ var Input = import_react21.default.forwardRef(
1903
2209
  e.stopPropagation();
1904
2210
  onClear();
1905
2211
  },
1906
- className: "p-1 rounded-full text-gray-400 hover:text-gray-600 hover:bg-gray-100 transition-colors",
2212
+ className: "p-1 rounded-full text-gray-400 hover:text-gray-600 hover:bg-gray-100 transition-colors focus:outline-none focus:ring-2 focus:ring-offset-1 focus:ring-primus-500",
2213
+ tabIndex: 0,
1907
2214
  children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_solid.XMarkIcon, { className: "h-4 w-4" })
1908
2215
  }
1909
2216
  ) }),
@@ -1932,13 +2239,13 @@ var CheckoutForm = ({
1932
2239
  onSuccess,
1933
2240
  onError
1934
2241
  }) => {
1935
- const [loading, setLoading] = (0, import_react22.useState)(false);
1936
- const [cardholderName, setCardholderName] = (0, import_react22.useState)("");
1937
- const [cardNumber, setCardNumber] = (0, import_react22.useState)("");
1938
- const [expiry, setExpiry] = (0, import_react22.useState)("");
1939
- const [cvc, setCvc] = (0, import_react22.useState)("");
1940
- const [error, setError] = (0, import_react22.useState)(null);
1941
- const [success, setSuccess] = (0, import_react22.useState)(false);
2242
+ const [loading, setLoading] = (0, import_react23.useState)(false);
2243
+ const [cardholderName, setCardholderName] = (0, import_react23.useState)("");
2244
+ const [cardNumber, setCardNumber] = (0, import_react23.useState)("");
2245
+ const [expiry, setExpiry] = (0, import_react23.useState)("");
2246
+ const [cvc, setCvc] = (0, import_react23.useState)("");
2247
+ const [error, setError] = (0, import_react23.useState)(null);
2248
+ const [success, setSuccess] = (0, import_react23.useState)(false);
1942
2249
  const handleSubmit = async (e) => {
1943
2250
  e.preventDefault();
1944
2251
  setError(null);
@@ -2331,14 +2638,14 @@ var ClaimStatusTracker = ({
2331
2638
  };
2332
2639
 
2333
2640
  // src/components/featureflags/FeatureFlagToggle.tsx
2334
- var import_react23 = require("react");
2641
+ var import_react24 = require("react");
2335
2642
  var import_jsx_runtime26 = require("react/jsx-runtime");
2336
2643
  var FeatureFlagToggle = ({
2337
2644
  apiUrl = "http://localhost:5221"
2338
2645
  }) => {
2339
- const [flags, setFlags] = (0, import_react23.useState)([]);
2340
- const [loading, setLoading] = (0, import_react23.useState)(true);
2341
- (0, import_react23.useEffect)(() => {
2646
+ const [flags, setFlags] = (0, import_react24.useState)([]);
2647
+ const [loading, setLoading] = (0, import_react24.useState)(true);
2648
+ (0, import_react24.useEffect)(() => {
2342
2649
  fetchFlags();
2343
2650
  }, []);
2344
2651
  const fetchFlags = async () => {
@@ -2375,15 +2682,15 @@ var FeatureFlagToggle = ({
2375
2682
  };
2376
2683
 
2377
2684
  // src/components/logging/LogViewer.tsx
2378
- var import_react24 = require("react");
2685
+ var import_react25 = require("react");
2379
2686
  var import_jsx_runtime27 = require("react/jsx-runtime");
2380
2687
  var LogViewer = ({
2381
2688
  apiUrl = "http://localhost:5221"
2382
2689
  }) => {
2383
- const [logs, setLogs] = (0, import_react24.useState)([]);
2384
- const [filter, setFilter] = (0, import_react24.useState)("");
2385
- const [loading, setLoading] = (0, import_react24.useState)(true);
2386
- (0, import_react24.useEffect)(() => {
2690
+ const [logs, setLogs] = (0, import_react25.useState)([]);
2691
+ const [filter, setFilter] = (0, import_react25.useState)("");
2692
+ const [loading, setLoading] = (0, import_react25.useState)(true);
2693
+ (0, import_react25.useEffect)(() => {
2387
2694
  fetchLogs();
2388
2695
  const interval = setInterval(fetchLogs, 1e4);
2389
2696
  return () => clearInterval(interval);
@@ -2503,7 +2810,7 @@ var PrimusSidebar = ({
2503
2810
  };
2504
2811
 
2505
2812
  // src/components/layout/PrimusHeader.tsx
2506
- var import_react25 = __toESM(require("react"));
2813
+ var import_react26 = __toESM(require("react"));
2507
2814
  var import_jsx_runtime30 = require("react/jsx-runtime");
2508
2815
  var PrimusHeader = ({
2509
2816
  title,
@@ -2514,7 +2821,7 @@ var PrimusHeader = ({
2514
2821
  }) => {
2515
2822
  return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex items-center justify-between w-full", children: [
2516
2823
  /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex items-center gap-4", children: [
2517
- breadcrumbs && breadcrumbs.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("nav", { className: "flex items-center gap-2 text-sm", children: breadcrumbs.map((crumb, index) => /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(import_react25.default.Fragment, { children: [
2824
+ breadcrumbs && breadcrumbs.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("nav", { className: "flex items-center gap-2 text-sm", children: breadcrumbs.map((crumb, index) => /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(import_react26.default.Fragment, { children: [
2518
2825
  index > 0 && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "text-gray-500", children: "/" }),
2519
2826
  /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: index === breadcrumbs.length - 1 ? "text-white" : "text-gray-400 hover:text-white cursor-pointer", children: crumb.label })
2520
2827
  ] }, index)) }),
@@ -2540,20 +2847,41 @@ var PrimusHeader = ({
2540
2847
  ] });
2541
2848
  };
2542
2849
 
2543
- // src/components/crud/PrimusDataTable.tsx
2544
- var import_react26 = require("react");
2850
+ // src/components/layout/PrimusSection.tsx
2545
2851
  var import_jsx_runtime31 = require("react/jsx-runtime");
2546
- function PrimusDataTable({
2547
- data,
2548
- columns,
2549
- rowKey,
2550
- loading = false,
2551
- selectable = false,
2552
- selectedKeys = [],
2553
- onSelectionChange,
2554
- onRowClick,
2555
- actions,
2556
- emptyMessage = "No data available",
2852
+ var PrimusSection = ({
2853
+ title,
2854
+ subtitle,
2855
+ children,
2856
+ className = "",
2857
+ actions
2858
+ }) => {
2859
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("section", { className: `py-6 ${className}`, children: [
2860
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: "flex items-end justify-between mb-6 border-b border-gray-200 dark:border-gray-800 pb-4", children: [
2861
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { children: [
2862
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("h2", { className: "text-2xl font-bold tracking-tight text-gray-900 dark:text-white", children: title }),
2863
+ subtitle && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("p", { className: "mt-1 text-base text-gray-500 dark:text-gray-400", children: subtitle })
2864
+ ] }),
2865
+ actions && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: "flex items-center gap-2", children: actions })
2866
+ ] }),
2867
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { children })
2868
+ ] });
2869
+ };
2870
+
2871
+ // src/components/crud/PrimusDataTable.tsx
2872
+ var import_react27 = require("react");
2873
+ var import_jsx_runtime32 = require("react/jsx-runtime");
2874
+ function PrimusDataTable({
2875
+ data,
2876
+ columns,
2877
+ rowKey,
2878
+ loading = false,
2879
+ selectable = false,
2880
+ selectedKeys = [],
2881
+ onSelectionChange,
2882
+ onRowClick,
2883
+ actions,
2884
+ emptyMessage = "No data available",
2557
2885
  searchPlaceholder = "Filter...",
2558
2886
  searchable = true,
2559
2887
  paginated = false,
@@ -2561,11 +2889,11 @@ function PrimusDataTable({
2561
2889
  pageIndex,
2562
2890
  onPageChange
2563
2891
  }) {
2564
- const [search, setSearch] = (0, import_react26.useState)("");
2565
- const [sortKey, setSortKey] = (0, import_react26.useState)(null);
2566
- const [sortDir, setSortDir] = (0, import_react26.useState)("asc");
2567
- const [internalPageIndex, setInternalPageIndex] = (0, import_react26.useState)(0);
2568
- const filteredData = (0, import_react26.useMemo)(() => {
2892
+ const [search, setSearch] = (0, import_react27.useState)("");
2893
+ const [sortKey, setSortKey] = (0, import_react27.useState)(null);
2894
+ const [sortDir, setSortDir] = (0, import_react27.useState)("asc");
2895
+ const [internalPageIndex, setInternalPageIndex] = (0, import_react27.useState)(0);
2896
+ const filteredData = (0, import_react27.useMemo)(() => {
2569
2897
  let result = [...data];
2570
2898
  if (search) {
2571
2899
  const lowerSearch = search.toLowerCase();
@@ -2621,10 +2949,10 @@ function PrimusDataTable({
2621
2949
  onSelectionChange?.(scopeKeys);
2622
2950
  }
2623
2951
  };
2624
- return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: "flex flex-col space-y-4", children: [
2625
- searchable && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: "flex items-center justify-between px-1", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: "relative group", children: [
2626
- /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: "absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("svg", { className: "h-4 w-4 text-gray-500 group-focus-within:text-purple-400 transition-colors", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" }) }) }),
2627
- /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
2952
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "flex flex-col space-y-4", children: [
2953
+ searchable && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "flex items-center justify-between px-1", children: /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "relative group", children: [
2954
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none", children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("svg", { className: "h-4 w-4 text-gray-500 group-focus-within:text-purple-400 transition-colors", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" }) }) }),
2955
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
2628
2956
  "input",
2629
2957
  {
2630
2958
  type: "text",
@@ -2640,9 +2968,9 @@ function PrimusDataTable({
2640
2968
  }
2641
2969
  )
2642
2970
  ] }) }),
2643
- /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: `overflow-hidden rounded-xl border border-white/5 bg-slate-900/40 backdrop-blur-md shadow-xl ring-1 ring-white/5 ${loading ? "opacity-80" : ""}`, children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: "overflow-x-auto", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("table", { className: "w-full text-left border-collapse", children: [
2644
- /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("thead", { className: "bg-white/5 border-b border-white/5 backdrop-blur-md sticky top-0 z-20", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("tr", { children: [
2645
- selectable && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("th", { className: "w-12 px-6 py-4", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
2971
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: `overflow-hidden rounded-xl border border-white/5 bg-slate-900/40 backdrop-blur-md shadow-xl ring-1 ring-white/5 ${loading ? "opacity-80" : ""}`, children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "overflow-x-auto", children: /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("table", { className: "w-full text-left border-collapse", children: [
2972
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("thead", { className: "bg-white/5 border-b border-white/5 backdrop-blur-md sticky top-0 z-20", children: /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("tr", { children: [
2973
+ selectable && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("th", { className: "w-12 px-6 py-4", children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
2646
2974
  "input",
2647
2975
  {
2648
2976
  type: "checkbox",
@@ -2651,25 +2979,25 @@ function PrimusDataTable({
2651
2979
  className: "rounded border-gray-600 bg-gray-800 text-purple-600 focus:ring-offset-gray-900 focus:ring-purple-500 transition-colors cursor-pointer"
2652
2980
  }
2653
2981
  ) }),
2654
- columns.map((col) => /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
2982
+ columns.map((col) => /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
2655
2983
  "th",
2656
2984
  {
2657
2985
  className: `px-6 py-4 text-xs font-semibold text-gray-400 uppercase tracking-wider ${col.sortable ? "cursor-pointer hover:text-white group" : ""}`,
2658
2986
  style: { width: col.width },
2659
2987
  onClick: () => col.sortable && handleSort(String(col.key)),
2660
- children: /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: "flex items-center gap-2", children: [
2988
+ children: /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "flex items-center gap-2", children: [
2661
2989
  col.header,
2662
- col.sortable && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: `transition-opacity duration-200 ${sortKey === col.key ? "opacity-100 text-purple-400" : "opacity-0 group-hover:opacity-50"}`, children: sortDir === "asc" ? "\u2191" : "\u2193" })
2990
+ col.sortable && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: `transition-opacity duration-200 ${sortKey === col.key ? "opacity-100 text-purple-400" : "opacity-0 group-hover:opacity-50"}`, children: sortDir === "asc" ? "\u2191" : "\u2193" })
2663
2991
  ] })
2664
2992
  },
2665
2993
  String(col.key)
2666
2994
  )),
2667
- actions && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("th", { className: "w-24 px-6 py-4 text-right text-xs font-semibold text-gray-400 uppercase tracking-wider" })
2995
+ actions && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("th", { className: "w-24 px-6 py-4 text-right text-xs font-semibold text-gray-400 uppercase tracking-wider" })
2668
2996
  ] }) }),
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: [
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" }),
2671
- /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "text-sm font-medium", children: "Loading data..." })
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)(
2997
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("tbody", { className: "divide-y divide-white/5", children: loading ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("tr", { children: /* @__PURE__ */ (0, import_jsx_runtime32.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_runtime32.jsxs)("div", { className: "flex flex-col items-center justify-center gap-3", children: [
2998
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "w-6 h-6 border-2 border-purple-500/50 border-t-purple-500 rounded-full animate-spin" }),
2999
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "text-sm font-medium", children: "Loading data..." })
3000
+ ] }) }) }) : filteredData.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("tr", { children: /* @__PURE__ */ (0, import_jsx_runtime32.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_runtime32.jsx)("p", { className: "text-sm", children: emptyMessage }) }) }) : pageData.map((row) => /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
2673
3001
  "tr",
2674
3002
  {
2675
3003
  onClick: () => onRowClick?.(row),
@@ -2679,7 +3007,7 @@ function PrimusDataTable({
2679
3007
  ${selectedKeys.includes(row[rowKey]) ? "bg-purple-500/10 hover:bg-purple-500/20" : ""}
2680
3008
  `,
2681
3009
  children: [
2682
- selectable && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("td", { className: "px-6 py-4", onClick: (e) => e.stopPropagation(), children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
3010
+ selectable && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("td", { className: "px-6 py-4", onClick: (e) => e.stopPropagation(), children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
2683
3011
  "input",
2684
3012
  {
2685
3013
  type: "checkbox",
@@ -2688,15 +3016,15 @@ function PrimusDataTable({
2688
3016
  className: "rounded border-gray-600 bg-gray-800 text-purple-600 focus:ring-offset-gray-900 focus:ring-purple-500 cursor-pointer"
2689
3017
  }
2690
3018
  ) }),
2691
- columns.map((col) => /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("td", { className: "px-6 py-4 text-sm text-gray-300 group-hover:text-white transition-colors", children: col.render ? col.render(row[col.key], row) : String(row[col.key] ?? "") }, String(col.key))),
2692
- actions && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("td", { className: "px-6 py-4 text-right", onClick: (e) => e.stopPropagation(), children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: "opacity-0 group-hover:opacity-100 transition-opacity transform translate-x-2 group-hover:translate-x-0", children: actions(row) }) })
3019
+ columns.map((col) => /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("td", { className: "px-6 py-4 text-sm text-gray-300 group-hover:text-white transition-colors", children: col.render ? col.render(row[col.key], row) : String(row[col.key] ?? "") }, String(col.key))),
3020
+ actions && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("td", { className: "px-6 py-4 text-right", onClick: (e) => e.stopPropagation(), children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "opacity-0 group-hover:opacity-100 transition-opacity transform translate-x-2 group-hover:translate-x-0", children: actions(row) }) })
2693
3021
  ]
2694
3022
  },
2695
3023
  String(row[rowKey])
2696
3024
  )) })
2697
3025
  ] }) }) }),
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)(
3026
+ paginated && totalPages > 1 && /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "flex items-center justify-between text-sm text-gray-400 px-2", children: [
3027
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
2700
3028
  "button",
2701
3029
  {
2702
3030
  type: "button",
@@ -2706,13 +3034,13 @@ function PrimusDataTable({
2706
3034
  children: "Previous"
2707
3035
  }
2708
3036
  ),
2709
- /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("span", { children: [
3037
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("span", { children: [
2710
3038
  "Page ",
2711
3039
  currentPageIndex + 1,
2712
3040
  " of ",
2713
3041
  totalPages
2714
3042
  ] }),
2715
- /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
3043
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
2716
3044
  "button",
2717
3045
  {
2718
3046
  type: "button",
@@ -2727,7 +3055,7 @@ function PrimusDataTable({
2727
3055
  }
2728
3056
 
2729
3057
  // src/components/crud/PrimusModal.tsx
2730
- var import_jsx_runtime32 = require("react/jsx-runtime");
3058
+ var import_jsx_runtime33 = require("react/jsx-runtime");
2731
3059
  var PrimusModal = ({
2732
3060
  open,
2733
3061
  onClose,
@@ -2743,34 +3071,34 @@ var PrimusModal = ({
2743
3071
  lg: "max-w-lg",
2744
3072
  xl: "max-w-xl"
2745
3073
  };
2746
- return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "fixed inset-0 z-50 flex items-center justify-center", children: [
2747
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
3074
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "fixed inset-0 z-50 flex items-center justify-center", children: [
3075
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
2748
3076
  "div",
2749
3077
  {
2750
3078
  className: "absolute inset-0 bg-black/60 backdrop-blur-sm",
2751
3079
  onClick: onClose
2752
3080
  }
2753
3081
  ),
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: [
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: [
2756
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("h2", { className: "text-lg font-semibold text-white", children: title }),
2757
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
3082
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: `relative w-full ${sizeClasses2[size]} mx-4 bg-gray-800 rounded-xl border border-gray-700 shadow-2xl`, children: [
3083
+ title && /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "flex items-center justify-between px-6 py-4 border-b border-gray-700", children: [
3084
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("h2", { className: "text-lg font-semibold text-white", children: title }),
3085
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
2758
3086
  "button",
2759
3087
  {
2760
3088
  onClick: onClose,
2761
3089
  className: "text-gray-400 hover:text-white transition-colors",
2762
- children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("svg", { className: "w-5 h-5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) })
3090
+ children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("svg", { className: "w-5 h-5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) })
2763
3091
  }
2764
3092
  )
2765
3093
  ] }),
2766
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "p-6", children }),
2767
- footer && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "flex justify-end gap-3 px-6 py-4 border-t border-gray-700 bg-gray-800/50", children: footer })
3094
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "p-6", children }),
3095
+ footer && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "flex justify-end gap-3 px-6 py-4 border-t border-gray-700 bg-gray-800/50", children: footer })
2768
3096
  ] })
2769
3097
  ] });
2770
3098
  };
2771
3099
 
2772
3100
  // src/components/dashboard/PrimusDashboard.tsx
2773
- var import_jsx_runtime33 = require("react/jsx-runtime");
3101
+ var import_jsx_runtime34 = require("react/jsx-runtime");
2774
3102
  var PrimusStatCard = ({
2775
3103
  title,
2776
3104
  value,
@@ -2806,35 +3134,35 @@ var PrimusStatCard = ({
2806
3134
  const linePath = points.map((point, index) => `${index === 0 ? "M" : "L"} ${point.x} ${point.y}`).join(" ");
2807
3135
  const areaPath = `${linePath} L 100 100 L 0 100 Z`;
2808
3136
  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" }),
2812
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("stop", { offset: "100%", stopColor: "currentColor", stopOpacity: "0" })
3137
+ return /* @__PURE__ */ (0, import_jsx_runtime34.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: [
3138
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("defs", { children: /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("linearGradient", { id: gradientId, x1: "0", y1: "0", x2: "0", y2: "1", children: [
3139
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("stop", { offset: "0%", stopColor: "currentColor", stopOpacity: "0.25" }),
3140
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("stop", { offset: "100%", stopColor: "currentColor", stopOpacity: "0" })
2813
3141
  ] }) }),
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" })
3142
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("path", { d: areaPath, fill: `url(#${gradientId})`, stroke: "none" }),
3143
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("path", { d: linePath, fill: "none", stroke: "currentColor", strokeWidth: "1.8", opacity: "0.6" })
2816
3144
  ] });
2817
3145
  };
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: [
2819
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "absolute inset-0 bg-gradient-to-br from-white/5 to-transparent opacity-0 group-hover:opacity-100 transition-opacity pointer-events-none" }),
2820
- /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "p-6 relative z-10", children: [
2821
- /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "flex items-start justify-between mb-4", children: [
2822
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "p-2.5 rounded-lg bg-white/5 text-gray-300 ring-1 ring-white/10 group-hover:bg-purple-500/20 group-hover:text-purple-300 transition-colors", children: icon || /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "w-5 h-5 bg-current opacity-20" }) }),
2823
- change && /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("span", { className: `px-2 py-0.5 text-xs font-medium rounded-full flex items-center gap-1 ${changeColors[change.type]}`, children: [
3146
+ return /* @__PURE__ */ (0, import_jsx_runtime34.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: [
3147
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "absolute inset-0 bg-gradient-to-br from-white/5 to-transparent opacity-0 group-hover:opacity-100 transition-opacity pointer-events-none" }),
3148
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "p-6 relative z-10", children: [
3149
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "flex items-start justify-between mb-4", children: [
3150
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "p-2.5 rounded-lg bg-white/5 text-gray-300 ring-1 ring-white/10 group-hover:bg-purple-500/20 group-hover:text-purple-300 transition-colors", children: icon || /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "w-5 h-5 bg-current opacity-20" }) }),
3151
+ change && /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("span", { className: `px-2 py-0.5 text-xs font-medium rounded-full flex items-center gap-1 ${changeColors[change.type]}`, children: [
2824
3152
  changeIcons[change.type],
2825
3153
  " ",
2826
3154
  Math.abs(change.value),
2827
3155
  "%"
2828
3156
  ] })
2829
3157
  ] }),
2830
- /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { children: [
2831
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("h3", { className: "text-sm font-medium text-gray-400 tracking-wide", children: title }),
2832
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "mt-1 flex items-baseline gap-2", children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "text-3xl font-bold text-transparent bg-clip-text bg-gradient-to-r from-white to-gray-400", children: value }) }),
2833
- description && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("p", { className: "text-xs text-gray-500 mt-2 font-medium", children: description })
3158
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { children: [
3159
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("h3", { className: "text-sm font-medium text-gray-400 tracking-wide", children: title }),
3160
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "mt-1 flex items-baseline gap-2", children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { className: "text-3xl font-bold text-transparent bg-clip-text bg-gradient-to-r from-white to-gray-400", children: value }) }),
3161
+ description && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("p", { className: "text-xs text-gray-500 mt-2 font-medium", children: description })
2834
3162
  ] })
2835
3163
  ] }),
2836
3164
  renderSparkline(),
2837
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: `absolute -bottom-2 -right-4 w-32 h-32 blur-2xl opacity-20 rounded-full transition-colors duration-500 ${change?.type === "increase" ? "bg-emerald-500" : change?.type === "decrease" ? "bg-rose-500" : "bg-blue-500"}` })
3165
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: `absolute -bottom-2 -right-4 w-32 h-32 blur-2xl opacity-20 rounded-full transition-colors duration-500 ${change?.type === "increase" ? "bg-emerald-500" : change?.type === "decrease" ? "bg-rose-500" : "bg-blue-500"}` })
2838
3166
  ] });
2839
3167
  };
2840
3168
  var PrimusDashboard = ({
@@ -2843,13 +3171,13 @@ var PrimusDashboard = ({
2843
3171
  subtitle,
2844
3172
  actions
2845
3173
  }) => {
2846
- return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "space-y-8 animate-enter", children: [
2847
- (title || actions) && /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "flex flex-col md:flex-row md:items-end justify-between gap-4 border-b border-white/5 pb-6", children: [
2848
- /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { children: [
2849
- title && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("h1", { className: "text-3xl font-bold bg-clip-text text-transparent bg-gradient-to-r from-white via-gray-200 to-gray-400 tracking-tight", children: title }),
2850
- subtitle && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("p", { className: "text-gray-400 mt-2 text-lg font-light leading-relaxed", children: subtitle })
3174
+ return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "space-y-8 animate-enter", children: [
3175
+ (title || actions) && /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "flex flex-col md:flex-row md:items-end justify-between gap-4 border-b border-white/5 pb-6", children: [
3176
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { children: [
3177
+ title && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("h1", { className: "text-3xl font-bold bg-clip-text text-transparent bg-gradient-to-r from-white via-gray-200 to-gray-400 tracking-tight", children: title }),
3178
+ subtitle && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("p", { className: "text-gray-400 mt-2 text-lg font-light leading-relaxed", children: subtitle })
2851
3179
  ] }),
2852
- actions && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "flex items-center gap-3", children: actions })
3180
+ actions && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "flex items-center gap-3", children: actions })
2853
3181
  ] }),
2854
3182
  children
2855
3183
  ] });
@@ -2864,12 +3192,106 @@ var DashboardGrid = ({
2864
3192
  3: "grid-cols-1 md:grid-cols-2 lg:grid-cols-3",
2865
3193
  4: "grid-cols-1 md:grid-cols-2 lg:grid-cols-4"
2866
3194
  };
2867
- return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: `grid gap-6 ${colClasses[columns]}`, children });
3195
+ return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: `grid gap-6 ${colClasses[columns]}`, children });
3196
+ };
3197
+
3198
+ // src/components/shared/Card.tsx
3199
+ var import_react28 = __toESM(require("react"));
3200
+ var import_jsx_runtime35 = require("react/jsx-runtime");
3201
+ var Card = import_react28.default.forwardRef(
3202
+ ({ style, variant = "default", padding = "md", children, ...props }, ref) => {
3203
+ const [isHovered, setIsHovered] = import_react28.default.useState(false);
3204
+ const paddingStyles = {
3205
+ none: "0",
3206
+ sm: "0.75rem",
3207
+ md: "1.5rem",
3208
+ lg: "2rem"
3209
+ };
3210
+ const variantStyles = {
3211
+ default: {
3212
+ normal: {
3213
+ backgroundColor: "#ffffff",
3214
+ border: "1px solid #e5e7eb",
3215
+ boxShadow: "0 1px 2px rgba(0, 0, 0, 0.05)"
3216
+ },
3217
+ hover: {
3218
+ boxShadow: "0 4px 6px rgba(0, 0, 0, 0.1)"
3219
+ }
3220
+ },
3221
+ outlined: {
3222
+ normal: {
3223
+ backgroundColor: "#ffffff",
3224
+ border: "2px solid #e5e7eb",
3225
+ boxShadow: "none"
3226
+ },
3227
+ hover: {
3228
+ borderColor: "#d1d5db"
3229
+ }
3230
+ },
3231
+ elevated: {
3232
+ normal: {
3233
+ backgroundColor: "#ffffff",
3234
+ border: "none",
3235
+ boxShadow: "0 4px 6px rgba(0, 0, 0, 0.1)"
3236
+ },
3237
+ hover: {
3238
+ boxShadow: "0 10px 15px rgba(0, 0, 0, 0.15)",
3239
+ transform: "translateY(-2px)"
3240
+ }
3241
+ }
3242
+ };
3243
+ const baseStyles = {
3244
+ borderRadius: "0.5rem",
3245
+ padding: paddingStyles[padding],
3246
+ transition: "all 0.2s ease"
3247
+ };
3248
+ const currentVariant = variantStyles[variant];
3249
+ const combinedStyles = {
3250
+ ...baseStyles,
3251
+ ...currentVariant.normal,
3252
+ ...isHovered ? currentVariant.hover : {},
3253
+ ...style
3254
+ };
3255
+ return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
3256
+ "div",
3257
+ {
3258
+ ref,
3259
+ style: combinedStyles,
3260
+ onMouseEnter: () => setIsHovered(true),
3261
+ onMouseLeave: () => setIsHovered(false),
3262
+ ...props,
3263
+ children
3264
+ }
3265
+ );
3266
+ }
3267
+ );
3268
+ Card.displayName = "Card";
3269
+
3270
+ // src/components/dashboard/PrimusSummaryCard.tsx
3271
+ var import_jsx_runtime36 = require("react/jsx-runtime");
3272
+ var PrimusSummaryCard = ({
3273
+ title,
3274
+ subtitle,
3275
+ actionLabel,
3276
+ onAction,
3277
+ children,
3278
+ className
3279
+ }) => {
3280
+ return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(Card, { className, children: /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: "p-6", children: [
3281
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: "flex items-center justify-between mb-4", children: [
3282
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { children: [
3283
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("h3", { className: "text-lg font-semibold text-gray-900 dark:text-white", children: title }),
3284
+ subtitle && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("p", { className: "text-sm text-gray-500 dark:text-gray-400 mt-1", children: subtitle })
3285
+ ] }),
3286
+ actionLabel && onAction && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(Button, { variant: "outline", size: "sm", onClick: onAction, children: actionLabel })
3287
+ ] }),
3288
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "mt-4", children })
3289
+ ] }) });
2868
3290
  };
2869
3291
 
2870
3292
  // src/components/dashboard/PrimusActivityFeed.tsx
2871
- var import_react27 = require("react");
2872
- var import_jsx_runtime34 = require("react/jsx-runtime");
3293
+ var import_react29 = require("react");
3294
+ var import_jsx_runtime37 = require("react/jsx-runtime");
2873
3295
  var statusClasses = {
2874
3296
  success: "bg-emerald-500/10 text-emerald-300 border-emerald-500/30",
2875
3297
  warning: "bg-amber-500/10 text-amber-300 border-amber-500/30",
@@ -2883,8 +3305,8 @@ var PrimusActivityFeed = ({
2883
3305
  groupByDate = false,
2884
3306
  loading = false
2885
3307
  }) => {
2886
- const visibleItems = (0, import_react27.useMemo)(() => items.slice(0, maxItems), [items, maxItems]);
2887
- const groups = (0, import_react27.useMemo)(() => {
3308
+ const visibleItems = (0, import_react29.useMemo)(() => items.slice(0, maxItems), [items, maxItems]);
3309
+ const groups = (0, import_react29.useMemo)(() => {
2888
3310
  if (!groupByDate) {
2889
3311
  return [{ label: "", items: visibleItems }];
2890
3312
  }
@@ -2898,18 +3320,18 @@ var PrimusActivityFeed = ({
2898
3320
  return Array.from(map.entries()).map(([label, groupItems]) => ({ label, items: groupItems }));
2899
3321
  }, [groupByDate, visibleItems]);
2900
3322
  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..." });
3323
+ return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: "rounded-xl border border-white/10 bg-slate-900/40 p-6 text-sm text-gray-400", children: "Loading activity..." });
2902
3324
  }
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) })
3325
+ return /* @__PURE__ */ (0, import_jsx_runtime37.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_runtime37.jsxs)("div", { children: [
3326
+ group.label && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: "text-xs uppercase tracking-wide text-gray-500 mb-3", children: group.label }),
3327
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: "space-y-4", children: group.items.map((item, itemIndex) => /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "flex items-start gap-4", children: [
3328
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: `mt-1 h-2.5 w-2.5 rounded-full border ${statusClasses[item.status ?? "info"]}` }),
3329
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "flex-1", children: [
3330
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "flex items-center justify-between gap-4", children: [
3331
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: "text-sm font-medium text-gray-100", children: item.title }),
3332
+ showTimestamps && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: "text-xs text-gray-500", children: formatTime(item.timestamp) })
2911
3333
  ] }),
2912
- item.description && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "text-xs text-gray-400 mt-1", children: item.description })
3334
+ item.description && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: "text-xs text-gray-400 mt-1", children: item.description })
2913
3335
  ] })
2914
3336
  ] }, item.id ?? `${itemIndex}-${item.title}`)) })
2915
3337
  ] }, `${group.label}-${index}`)) });
@@ -2936,9 +3358,9 @@ var formatTime = (value) => {
2936
3358
  };
2937
3359
 
2938
3360
  // src/components/charts/PrimusChartBase.tsx
2939
- var import_react28 = require("react");
3361
+ var import_react30 = require("react");
2940
3362
  var import_chart = require("chart.js");
2941
- var import_jsx_runtime35 = require("react/jsx-runtime");
3363
+ var import_jsx_runtime38 = require("react/jsx-runtime");
2942
3364
  var registered = false;
2943
3365
  var ensureRegistered = () => {
2944
3366
  if (!registered) {
@@ -2961,9 +3383,9 @@ var PrimusChartBase = ({
2961
3383
  className,
2962
3384
  datasetTransform
2963
3385
  }) => {
2964
- const canvasRef = (0, import_react28.useRef)(null);
2965
- const chartRef = (0, import_react28.useRef)(null);
2966
- const builtData = (0, import_react28.useMemo)(() => {
3386
+ const canvasRef = (0, import_react30.useRef)(null);
3387
+ const chartRef = (0, import_react30.useRef)(null);
3388
+ const builtData = (0, import_react30.useMemo)(() => {
2967
3389
  if (data) {
2968
3390
  return data;
2969
3391
  }
@@ -2987,7 +3409,7 @@ var PrimusChartBase = ({
2987
3409
  datasets
2988
3410
  };
2989
3411
  }, [data, labels, series, datasetTransform]);
2990
- const builtOptions = (0, import_react28.useMemo)(() => {
3412
+ const builtOptions = (0, import_react30.useMemo)(() => {
2991
3413
  const mergedPlugins = {
2992
3414
  ...options?.plugins ?? {},
2993
3415
  legend: {
@@ -3005,7 +3427,7 @@ var PrimusChartBase = ({
3005
3427
  }
3006
3428
  };
3007
3429
  }, [options, responsive, maintainAspectRatio, legend]);
3008
- (0, import_react28.useEffect)(() => {
3430
+ (0, import_react30.useEffect)(() => {
3009
3431
  ensureRegistered();
3010
3432
  const canvas = canvasRef.current;
3011
3433
  if (!canvas) {
@@ -3029,13 +3451,13 @@ var PrimusChartBase = ({
3029
3451
  chartRef.current = null;
3030
3452
  };
3031
3453
  }, [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" }) });
3454
+ return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className, style: { height, width }, children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("canvas", { ref: canvasRef, "aria-label": ariaLabel, role: "img" }) });
3033
3455
  };
3034
3456
 
3035
3457
  // src/components/charts/PrimusLineChart.tsx
3036
- var import_jsx_runtime36 = require("react/jsx-runtime");
3458
+ var import_jsx_runtime39 = require("react/jsx-runtime");
3037
3459
  var PrimusLineChart = (props) => {
3038
- return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
3460
+ return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
3039
3461
  PrimusChartBase,
3040
3462
  {
3041
3463
  ...props,
@@ -3053,9 +3475,9 @@ var PrimusLineChart = (props) => {
3053
3475
  };
3054
3476
 
3055
3477
  // src/components/charts/PrimusAreaChart.tsx
3056
- var import_jsx_runtime37 = require("react/jsx-runtime");
3478
+ var import_jsx_runtime40 = require("react/jsx-runtime");
3057
3479
  var PrimusAreaChart = (props) => {
3058
- return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
3480
+ return /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
3059
3481
  PrimusChartBase,
3060
3482
  {
3061
3483
  ...props,
@@ -3073,7 +3495,7 @@ var PrimusAreaChart = (props) => {
3073
3495
  };
3074
3496
 
3075
3497
  // src/components/charts/PrimusBarChart.tsx
3076
- var import_jsx_runtime38 = require("react/jsx-runtime");
3498
+ var import_jsx_runtime41 = require("react/jsx-runtime");
3077
3499
  var PrimusBarChart = ({ stacked = false, options, ...props }) => {
3078
3500
  const mergedOptions = {
3079
3501
  ...options,
@@ -3083,7 +3505,7 @@ var PrimusBarChart = ({ stacked = false, options, ...props }) => {
3083
3505
  ...options?.scales ?? {}
3084
3506
  }
3085
3507
  };
3086
- return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
3508
+ return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
3087
3509
  PrimusChartBase,
3088
3510
  {
3089
3511
  ...props,
@@ -3099,13 +3521,13 @@ var PrimusBarChart = ({ stacked = false, options, ...props }) => {
3099
3521
  };
3100
3522
 
3101
3523
  // src/components/charts/PrimusPieChart.tsx
3102
- var import_jsx_runtime39 = require("react/jsx-runtime");
3524
+ var import_jsx_runtime42 = require("react/jsx-runtime");
3103
3525
  var PrimusPieChart = ({ donut = false, cutout = "55%", options, ...props }) => {
3104
3526
  const mergedOptions = {
3105
3527
  ...options,
3106
3528
  cutout: donut ? cutout : void 0
3107
3529
  };
3108
- return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
3530
+ return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
3109
3531
  PrimusChartBase,
3110
3532
  {
3111
3533
  ...props,
@@ -3121,8 +3543,8 @@ var PrimusPieChart = ({ donut = false, cutout = "55%", options, ...props }) => {
3121
3543
  };
3122
3544
 
3123
3545
  // src/components/charts/PrimusSparkline.tsx
3124
- var import_react29 = require("react");
3125
- var import_jsx_runtime40 = require("react/jsx-runtime");
3546
+ var import_react31 = require("react");
3547
+ var import_jsx_runtime43 = require("react/jsx-runtime");
3126
3548
  var PrimusSparkline = ({
3127
3549
  series = [],
3128
3550
  data,
@@ -3135,7 +3557,7 @@ var PrimusSparkline = ({
3135
3557
  }) => {
3136
3558
  const values = data ?? series[0]?.data ?? [];
3137
3559
  const color = series[0]?.color ?? series[0]?.borderColor ?? "#3b82f6";
3138
- const { linePath, areaPath } = (0, import_react29.useMemo)(() => {
3560
+ const { linePath, areaPath } = (0, import_react31.useMemo)(() => {
3139
3561
  if (!values.length) {
3140
3562
  return { linePath: "", areaPath: "" };
3141
3563
  }
@@ -3155,7 +3577,7 @@ var PrimusSparkline = ({
3155
3577
  if (!values.length) {
3156
3578
  return null;
3157
3579
  }
3158
- return /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(
3580
+ return /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(
3159
3581
  "svg",
3160
3582
  {
3161
3583
  className,
@@ -3166,17 +3588,17 @@ var PrimusSparkline = ({
3166
3588
  "aria-label": ariaLabel,
3167
3589
  role: "img",
3168
3590
  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 })
3591
+ type === "area" && /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("path", { d: areaPath, fill: color, opacity: 0.2, stroke: "none" }),
3592
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("path", { d: linePath, fill: "none", stroke: color, strokeWidth })
3171
3593
  ]
3172
3594
  }
3173
3595
  );
3174
3596
  };
3175
3597
 
3176
3598
  // 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(
3599
+ var import_react32 = __toESM(require("react"));
3600
+ var import_jsx_runtime44 = require("react/jsx-runtime");
3601
+ var Checkbox = import_react32.default.forwardRef(
3180
3602
  ({ style, label, error, disabled, className, ...props }, ref) => {
3181
3603
  const containerStyles = {
3182
3604
  display: "flex",
@@ -3213,9 +3635,9 @@ var Checkbox = import_react30.default.forwardRef(
3213
3635
  marginTop: "0.25rem",
3214
3636
  marginLeft: "1.75rem"
3215
3637
  };
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)(
3638
+ return /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { children: [
3639
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { style: containerStyles, children: [
3640
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", { style: checkboxWrapperStyles, children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
3219
3641
  "input",
3220
3642
  {
3221
3643
  ref,
@@ -3228,21 +3650,21 @@ var Checkbox = import_react30.default.forwardRef(
3228
3650
  ...props
3229
3651
  }
3230
3652
  ) }),
3231
- label && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("label", { style: labelStyles, onClick: (e) => {
3653
+ label && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("label", { style: labelStyles, onClick: (e) => {
3232
3654
  if (!disabled) {
3233
3655
  const input = e.currentTarget.previousElementSibling?.querySelector("input");
3234
3656
  input?.click();
3235
3657
  }
3236
3658
  }, children: label })
3237
3659
  ] }),
3238
- error && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("p", { style: errorTextStyles, children: error })
3660
+ error && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("p", { style: errorTextStyles, children: error })
3239
3661
  ] });
3240
3662
  }
3241
3663
  );
3242
3664
  Checkbox.displayName = "Checkbox";
3243
3665
 
3244
3666
  // src/components/shared/RadioGroup.tsx
3245
- var import_jsx_runtime42 = require("react/jsx-runtime");
3667
+ var import_jsx_runtime45 = require("react/jsx-runtime");
3246
3668
  var RadioGroup = ({
3247
3669
  name,
3248
3670
  options,
@@ -3282,9 +3704,9 @@ var RadioGroup = ({
3282
3704
  color: "#ef4444",
3283
3705
  marginTop: "0.5rem"
3284
3706
  };
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)(
3707
+ return /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { children: [
3708
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { style: containerStyles, children: options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { style: optionStyles, children: [
3709
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
3288
3710
  "input",
3289
3711
  {
3290
3712
  type: "radio",
@@ -3296,7 +3718,7 @@ var RadioGroup = ({
3296
3718
  style: radioStyles
3297
3719
  }
3298
3720
  ),
3299
- /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
3721
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
3300
3722
  "label",
3301
3723
  {
3302
3724
  style: {
@@ -3312,17 +3734,17 @@ var RadioGroup = ({
3312
3734
  }
3313
3735
  )
3314
3736
  ] }, option.value)) }),
3315
- error && /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("p", { style: errorTextStyles, children: error })
3737
+ error && /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("p", { style: errorTextStyles, children: error })
3316
3738
  ] });
3317
3739
  };
3318
3740
  RadioGroup.displayName = "RadioGroup";
3319
3741
 
3320
3742
  // src/components/shared/Select.tsx
3321
- var import_react31 = __toESM(require("react"));
3322
- var import_react32 = require("@headlessui/react");
3743
+ var import_react33 = __toESM(require("react"));
3744
+ var import_react34 = require("@headlessui/react");
3323
3745
  var import_solid4 = require("@heroicons/react/20/solid");
3324
3746
  var import_clsx7 = require("clsx");
3325
- var import_jsx_runtime43 = require("react/jsx-runtime");
3747
+ var import_jsx_runtime46 = require("react/jsx-runtime");
3326
3748
  var Select = ({
3327
3749
  label,
3328
3750
  error,
@@ -3334,7 +3756,7 @@ var Select = ({
3334
3756
  disabled = false,
3335
3757
  className
3336
3758
  }) => {
3337
- const [query, setQuery] = (0, import_react31.useState)("");
3759
+ const [query, setQuery] = (0, import_react33.useState)("");
3338
3760
  const filteredOptions = query === "" ? options : options.filter(
3339
3761
  (option) => option.label.toLowerCase().replace(/\s+/g, "").includes(query.toLowerCase().replace(/\s+/g, ""))
3340
3762
  );
@@ -3344,8 +3766,8 @@ var Select = ({
3344
3766
  onChange?.(value.filter((v) => v !== valToRemove));
3345
3767
  }
3346
3768
  };
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,
3769
+ return /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("div", { className: (0, import_clsx7.clsx)("w-full", className), children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
3770
+ import_react34.Combobox,
3349
3771
  {
3350
3772
  value,
3351
3773
  onChange: (val) => {
@@ -3353,21 +3775,21 @@ var Select = ({
3353
3775
  },
3354
3776
  multiple,
3355
3777
  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)(
3778
+ children: ({}) => /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "relative", children: [
3779
+ label && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_react34.Combobox.Label, { className: "block text-sm font-medium text-gray-700 mb-1", children: label }),
3780
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: (0, import_clsx7.clsx)(
3359
3781
  "relative w-full cursor-default overflow-hidden rounded-lg bg-white text-left focus-within:ring-2 focus-within:ring-primus-500",
3360
3782
  "border transition-all duration-200 ease-in-out",
3361
3783
  error ? "border-red-500 focus-within:ring-red-500" : "border-gray-300",
3362
3784
  disabled && "opacity-50 cursor-not-allowed bg-gray-50"
3363
3785
  ), children: [
3364
- /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: (0, import_clsx7.clsx)(
3786
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: (0, import_clsx7.clsx)(
3365
3787
  "flex flex-wrap items-center gap-1.5 w-full py-1.5 pl-3 pr-10 text-sm",
3366
3788
  "min-h-[2.5rem]"
3367
3789
  ), 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)(
3790
+ multiple && Array.isArray(value) && value.map((val) => /* @__PURE__ */ (0, import_jsx_runtime46.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: [
3791
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: "truncate", children: getLabel(val) }),
3792
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(
3371
3793
  "button",
3372
3794
  {
3373
3795
  type: "button",
@@ -3379,14 +3801,14 @@ var Select = ({
3379
3801
  },
3380
3802
  onMouseDown: (e) => e.preventDefault(),
3381
3803
  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" })
3804
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: "sr-only", children: "Remove" }),
3805
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_solid4.XMarkIcon, { className: "h-3.5 w-3.5", "aria-hidden": "true" })
3384
3806
  ]
3385
3807
  }
3386
3808
  )
3387
3809
  ] }, val)),
3388
- /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
3389
- import_react32.Combobox.Input,
3810
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
3811
+ import_react34.Combobox.Input,
3390
3812
  {
3391
3813
  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
3814
  displayValue: (val) => !multiple && val ? getLabel(val) : query,
@@ -3395,7 +3817,7 @@ var Select = ({
3395
3817
  }
3396
3818
  )
3397
3819
  ] }),
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)(
3820
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_react34.Combobox.Button, { className: "absolute inset-y-0 right-0 flex items-center pr-2", children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
3399
3821
  import_solid4.ChevronUpDownIcon,
3400
3822
  {
3401
3823
  className: "h-5 w-5 text-gray-400",
@@ -3403,16 +3825,16 @@ var Select = ({
3403
3825
  }
3404
3826
  ) })
3405
3827
  ] }),
3406
- /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
3407
- import_react32.Transition,
3828
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
3829
+ import_react34.Transition,
3408
3830
  {
3409
- as: import_react31.default.Fragment,
3831
+ as: import_react33.default.Fragment,
3410
3832
  leave: "transition ease-in duration-100",
3411
3833
  leaveFrom: "opacity-100",
3412
3834
  leaveTo: "opacity-0",
3413
3835
  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,
3836
+ children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_react34.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_runtime46.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_runtime46.jsx)(
3837
+ import_react34.Combobox.Option,
3416
3838
  {
3417
3839
  className: ({ active }) => (0, import_clsx7.clsx)(
3418
3840
  "relative cursor-default select-none py-2 pl-10 pr-4",
@@ -3420,16 +3842,16 @@ var Select = ({
3420
3842
  ),
3421
3843
  value: option.value,
3422
3844
  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)(
3845
+ children: ({ selected, active }) => /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(import_jsx_runtime46.Fragment, { children: [
3846
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: (0, import_clsx7.clsx)("block truncate", selected ? "font-medium" : "font-normal"), children: option.label }),
3847
+ selected ? /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
3426
3848
  "span",
3427
3849
  {
3428
3850
  className: (0, import_clsx7.clsx)(
3429
3851
  "absolute inset-y-0 left-0 flex items-center pl-3",
3430
3852
  active ? "text-white" : "text-primus-600"
3431
3853
  ),
3432
- children: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_solid4.CheckIcon, { className: "h-5 w-5", "aria-hidden": "true" })
3854
+ children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_solid4.CheckIcon, { className: "h-5 w-5", "aria-hidden": "true" })
3433
3855
  }
3434
3856
  ) : null
3435
3857
  ] })
@@ -3438,15 +3860,15 @@ var Select = ({
3438
3860
  )) })
3439
3861
  }
3440
3862
  ),
3441
- error && /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("p", { className: "mt-1 text-sm text-red-500", children: error })
3863
+ error && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("p", { className: "mt-1 text-sm text-red-500", children: error })
3442
3864
  ] })
3443
3865
  }
3444
3866
  ) });
3445
3867
  };
3446
3868
 
3447
3869
  // src/components/shared/Toggle.tsx
3448
- var import_react33 = __toESM(require("react"));
3449
- var import_jsx_runtime44 = require("react/jsx-runtime");
3870
+ var import_react35 = __toESM(require("react"));
3871
+ var import_jsx_runtime47 = require("react/jsx-runtime");
3450
3872
  var Toggle = ({
3451
3873
  checked = false,
3452
3874
  onChange,
@@ -3454,7 +3876,7 @@ var Toggle = ({
3454
3876
  label,
3455
3877
  size = "md"
3456
3878
  }) => {
3457
- const [isHovered, setIsHovered] = import_react33.default.useState(false);
3879
+ const [isHovered, setIsHovered] = import_react35.default.useState(false);
3458
3880
  const sizes = {
3459
3881
  sm: { width: "2.25rem", height: "1.25rem", thumbSize: "0.875rem" },
3460
3882
  md: { width: "2.75rem", height: "1.5rem", thumbSize: "1.125rem" },
@@ -3501,8 +3923,8 @@ var Toggle = ({
3501
3923
  onChange?.(!checked);
3502
3924
  }
3503
3925
  };
3504
- return /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { style: containerStyles, children: [
3505
- /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
3926
+ return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { style: containerStyles, children: [
3927
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
3506
3928
  "div",
3507
3929
  {
3508
3930
  style: switchStyles,
@@ -3518,20 +3940,23 @@ var Toggle = ({
3518
3940
  handleClick();
3519
3941
  }
3520
3942
  },
3521
- children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", { style: thumbStyles })
3943
+ children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { style: thumbStyles })
3522
3944
  }
3523
3945
  ),
3524
- label && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("label", { style: labelStyles, onClick: handleClick, children: label })
3946
+ label && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("label", { style: labelStyles, onClick: handleClick, children: label })
3525
3947
  ] });
3526
3948
  };
3527
3949
  Toggle.displayName = "Toggle";
3528
3950
 
3529
3951
  // 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);
3952
+ var import_react36 = __toESM(require("react"));
3953
+ var import_jsx_runtime48 = require("react/jsx-runtime");
3954
+ var Textarea = import_react36.default.forwardRef(
3955
+ ({ style, label, error, disabled, resize = "vertical", onChange, onValueChange, className, ...props }, ref) => {
3956
+ const handleChange = (e) => {
3957
+ onChange?.(e);
3958
+ onValueChange?.(e.target.value);
3959
+ };
3535
3960
  const containerStyles = {
3536
3961
  width: "100%"
3537
3962
  };
@@ -3539,11 +3964,11 @@ var Textarea = import_react34.default.forwardRef(
3539
3964
  fontSize: "0.875rem",
3540
3965
  lineHeight: "1.25rem",
3541
3966
  fontWeight: "500",
3542
- marginBottom: "0.5rem",
3967
+ marginBottom: "0.375rem",
3543
3968
  display: "block",
3544
3969
  color: "#374151",
3545
- cursor: disabled ? "not-allowed" : "default",
3546
- opacity: disabled ? 0.7 : 1
3970
+ opacity: disabled ? 0.7 : 1,
3971
+ cursor: disabled ? "not-allowed" : "default"
3547
3972
  };
3548
3973
  const textareaStyles = {
3549
3974
  display: "flex",
@@ -3556,12 +3981,11 @@ var Textarea = import_react34.default.forwardRef(
3556
3981
  fontSize: "0.875rem",
3557
3982
  lineHeight: "1.5rem",
3558
3983
  outline: "none",
3559
- transition: "all 0.2s ease",
3560
- cursor: disabled ? "not-allowed" : "text",
3984
+ transition: "border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out",
3561
3985
  opacity: disabled ? 0.5 : 1,
3986
+ cursor: disabled ? "not-allowed" : "text",
3562
3987
  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"
3988
+ fontFamily: "inherit"
3565
3989
  };
3566
3990
  const errorTextStyles = {
3567
3991
  fontSize: "0.875rem",
@@ -3569,9 +3993,9 @@ var Textarea = import_react34.default.forwardRef(
3569
3993
  color: "#ef4444",
3570
3994
  marginTop: "0.25rem"
3571
3995
  };
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)(
3996
+ return /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { style: containerStyles, className, children: [
3997
+ label && /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("label", { style: labelStyles, children: label }),
3998
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
3575
3999
  "textarea",
3576
4000
  {
3577
4001
  ref,
@@ -3579,94 +4003,28 @@ var Textarea = import_react34.default.forwardRef(
3579
4003
  ...textareaStyles,
3580
4004
  ...style
3581
4005
  },
3582
- onFocus: () => setIsFocused(true),
3583
- onBlur: () => setIsFocused(false),
3584
4006
  disabled,
4007
+ onChange: handleChange,
4008
+ className: `primus-textarea ${error ? "error" : ""}`,
3585
4009
  ...props
3586
4010
  }
3587
4011
  ),
3588
- error && /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("p", { style: errorTextStyles, children: error })
4012
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("style", { children: `
4013
+ .primus-textarea:focus {
4014
+ border-color: ${error ? "#ef4444" : "#6366f1"};
4015
+ box-shadow: 0 0 0 1px ${error ? "#ef4444" : "#6366f1"};
4016
+ }
4017
+ ` }),
4018
+ error && /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("p", { style: errorTextStyles, children: error })
3589
4019
  ] });
3590
4020
  }
3591
4021
  );
3592
4022
  Textarea.displayName = "Textarea";
3593
4023
 
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
4024
  // 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(
4025
+ var import_react37 = __toESM(require("react"));
4026
+ var import_jsx_runtime49 = require("react/jsx-runtime");
4027
+ var Badge = import_react37.default.forwardRef(
3670
4028
  ({ style, variant = "default", size = "md", children, ...props }, ref) => {
3671
4029
  const variantStyles = {
3672
4030
  default: {
@@ -3720,14 +4078,14 @@ var Badge = import_react36.default.forwardRef(
3720
4078
  ...sizeStyles[size],
3721
4079
  ...style
3722
4080
  };
3723
- return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { ref, style: combinedStyles, ...props, children });
4081
+ return /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { ref, style: combinedStyles, ...props, children });
3724
4082
  }
3725
4083
  );
3726
4084
  Badge.displayName = "Badge";
3727
4085
 
3728
4086
  // src/components/shared/Table.tsx
3729
- var import_react37 = __toESM(require("react"));
3730
- var import_jsx_runtime48 = require("react/jsx-runtime");
4087
+ var import_react38 = __toESM(require("react"));
4088
+ var import_jsx_runtime50 = require("react/jsx-runtime");
3731
4089
  function Table({
3732
4090
  columns,
3733
4091
  data,
@@ -3736,7 +4094,7 @@ function Table({
3736
4094
  bordered = true,
3737
4095
  style
3738
4096
  }) {
3739
- const [hoveredRow, setHoveredRow] = import_react37.default.useState(null);
4097
+ const [hoveredRow, setHoveredRow] = import_react38.default.useState(null);
3740
4098
  const tableStyles = {
3741
4099
  width: "100%",
3742
4100
  borderCollapse: "collapse",
@@ -3761,8 +4119,8 @@ function Table({
3761
4119
  backgroundColor: hoverable && hoveredRow === rowIndex ? "#f9fafb" : striped && rowIndex % 2 === 1 ? "#f9fafb" : "#ffffff",
3762
4120
  transition: "background-color 0.15s ease"
3763
4121
  });
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)(
4122
+ return /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("div", { style: { overflowX: "auto", borderRadius: "0.5rem", border: bordered ? "1px solid #e5e7eb" : "none" }, children: /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)("table", { style: tableStyles, children: [
4123
+ /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("thead", { style: theadStyles, children: /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("tr", { children: columns.map((column) => /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
3766
4124
  "th",
3767
4125
  {
3768
4126
  style: {
@@ -3773,12 +4131,12 @@ function Table({
3773
4131
  },
3774
4132
  column.key
3775
4133
  )) }) }),
3776
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("tbody", { children: data.map((row, rowIndex) => /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
4134
+ /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("tbody", { children: data.map((row, rowIndex) => /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
3777
4135
  "tr",
3778
4136
  {
3779
4137
  onMouseEnter: () => hoverable && setHoveredRow(rowIndex),
3780
4138
  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))
4139
+ children: columns.map((column) => /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("td", { style: getTdStyles(rowIndex), children: column.render ? column.render(row) : row[column.key] }, column.key))
3782
4140
  },
3783
4141
  rowIndex
3784
4142
  )) })
@@ -3787,9 +4145,9 @@ function Table({
3787
4145
  Table.displayName = "Table";
3788
4146
 
3789
4147
  // 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(
4148
+ var import_react39 = __toESM(require("react"));
4149
+ var import_jsx_runtime51 = require("react/jsx-runtime");
4150
+ var Container = import_react39.default.forwardRef(
3793
4151
  ({ style, maxWidth = "lg", padding = "md", children, ...props }, ref) => {
3794
4152
  const maxWidthStyles = {
3795
4153
  sm: "640px",
@@ -3814,15 +4172,15 @@ var Container = import_react38.default.forwardRef(
3814
4172
  paddingRight: paddingStyles[padding],
3815
4173
  ...style
3816
4174
  };
3817
- return /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("div", { ref, style: containerStyles, ...props, children });
4175
+ return /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("div", { ref, style: containerStyles, ...props, children });
3818
4176
  }
3819
4177
  );
3820
4178
  Container.displayName = "Container";
3821
4179
 
3822
4180
  // 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(
4181
+ var import_react40 = __toESM(require("react"));
4182
+ var import_jsx_runtime52 = require("react/jsx-runtime");
4183
+ var Grid = import_react40.default.forwardRef(
3826
4184
  ({ style, columns = 3, rows, gap = "md", width = "100%", height = "auto", responsive = true, children, ...props }, ref) => {
3827
4185
  const gapStyles = {
3828
4186
  none: "0",
@@ -3840,15 +4198,15 @@ var Grid = import_react39.default.forwardRef(
3840
4198
  height,
3841
4199
  ...style
3842
4200
  };
3843
- return /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("div", { ref, style: gridStyles, ...props, children });
4201
+ return /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("div", { ref, style: gridStyles, ...props, children });
3844
4202
  }
3845
4203
  );
3846
4204
  Grid.displayName = "Grid";
3847
4205
 
3848
4206
  // 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(
4207
+ var import_react41 = __toESM(require("react"));
4208
+ var import_jsx_runtime53 = require("react/jsx-runtime");
4209
+ var Stack = import_react41.default.forwardRef(
3852
4210
  ({ style, direction = "vertical", gap = "md", align = "stretch", justify = "start", children, ...props }, ref) => {
3853
4211
  const gapStyles = {
3854
4212
  none: "0",
@@ -3878,14 +4236,14 @@ var Stack = import_react40.default.forwardRef(
3878
4236
  justifyContent: justifyStyles[justify],
3879
4237
  ...style
3880
4238
  };
3881
- return /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("div", { ref, style: stackStyles, ...props, children });
4239
+ return /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("div", { ref, style: stackStyles, ...props, children });
3882
4240
  }
3883
4241
  );
3884
4242
  Stack.displayName = "Stack";
3885
4243
 
3886
4244
  // src/components/shared/Modal.tsx
3887
- var import_react41 = __toESM(require("react"));
3888
- var import_jsx_runtime52 = require("react/jsx-runtime");
4245
+ var import_react42 = __toESM(require("react"));
4246
+ var import_jsx_runtime54 = require("react/jsx-runtime");
3889
4247
  var Modal = ({
3890
4248
  isOpen,
3891
4249
  onClose,
@@ -3894,7 +4252,7 @@ var Modal = ({
3894
4252
  size = "md",
3895
4253
  closeOnOverlayClick = true
3896
4254
  }) => {
3897
- import_react41.default.useEffect(() => {
4255
+ import_react42.default.useEffect(() => {
3898
4256
  if (isOpen) {
3899
4257
  document.body.style.overflow = "hidden";
3900
4258
  } else {
@@ -3963,20 +4321,20 @@ var Modal = ({
3963
4321
  overflowY: "auto",
3964
4322
  flex: 1
3965
4323
  };
3966
- return /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
4324
+ return /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
3967
4325
  "div",
3968
4326
  {
3969
4327
  style: overlayStyles,
3970
4328
  onClick: closeOnOverlayClick ? onClose : void 0,
3971
- children: /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(
4329
+ children: /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(
3972
4330
  "div",
3973
4331
  {
3974
4332
  style: modalStyles,
3975
4333
  onClick: (e) => e.stopPropagation(),
3976
4334
  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)(
4335
+ title && /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("div", { style: headerStyles, children: [
4336
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("h2", { style: titleStyles, children: title }),
4337
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
3980
4338
  "button",
3981
4339
  {
3982
4340
  style: closeButtonStyles,
@@ -3986,7 +4344,7 @@ var Modal = ({
3986
4344
  }
3987
4345
  )
3988
4346
  ] }),
3989
- /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("div", { style: contentStyles, children })
4347
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("div", { style: contentStyles, children })
3990
4348
  ]
3991
4349
  }
3992
4350
  )
@@ -3996,8 +4354,8 @@ var Modal = ({
3996
4354
  Modal.displayName = "Modal";
3997
4355
 
3998
4356
  // src/components/shared/DateRangePicker.tsx
3999
- var import_react42 = require("react");
4000
- var import_jsx_runtime53 = require("react/jsx-runtime");
4357
+ var import_react43 = require("react");
4358
+ var import_jsx_runtime55 = require("react/jsx-runtime");
4001
4359
  var PrimusDateRangePicker = ({
4002
4360
  startDate = null,
4003
4361
  endDate = null,
@@ -4007,15 +4365,15 @@ var PrimusDateRangePicker = ({
4007
4365
  disabled = false,
4008
4366
  onRangeChange
4009
4367
  }) => {
4010
- const [start, setStart] = (0, import_react42.useState)(startDate ?? "");
4011
- const [end, setEnd] = (0, import_react42.useState)(endDate ?? "");
4012
- (0, import_react42.useEffect)(() => {
4368
+ const [start, setStart] = (0, import_react43.useState)(startDate ?? "");
4369
+ const [end, setEnd] = (0, import_react43.useState)(endDate ?? "");
4370
+ (0, import_react43.useEffect)(() => {
4013
4371
  setStart(startDate ?? "");
4014
4372
  }, [startDate]);
4015
- (0, import_react42.useEffect)(() => {
4373
+ (0, import_react43.useEffect)(() => {
4016
4374
  setEnd(endDate ?? "");
4017
4375
  }, [endDate]);
4018
- const normalizedRanges = (0, import_react42.useMemo)(() => {
4376
+ const normalizedRanges = (0, import_react43.useMemo)(() => {
4019
4377
  return ranges.map((range) => typeof range === "string" ? resolvePreset(range) : range).filter((range) => !!range);
4020
4378
  }, [ranges]);
4021
4379
  const handleStartChange = (value) => {
@@ -4033,8 +4391,8 @@ var PrimusDateRangePicker = ({
4033
4391
  setEnd(nextEnd);
4034
4392
  onRangeChange?.({ startDate: nextStart, endDate: nextEnd, label: range.label });
4035
4393
  };
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)(
4394
+ return /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { className: "space-y-3", children: [
4395
+ normalizedRanges.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { className: "flex flex-wrap gap-2", children: normalizedRanges.map((range) => /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
4038
4396
  "button",
4039
4397
  {
4040
4398
  type: "button",
@@ -4045,8 +4403,8 @@ var PrimusDateRangePicker = ({
4045
4403
  },
4046
4404
  range.label
4047
4405
  )) }),
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)(
4406
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { className: "flex flex-col md:flex-row gap-3", children: [
4407
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
4050
4408
  "input",
4051
4409
  {
4052
4410
  type: "date",
@@ -4058,7 +4416,7 @@ var PrimusDateRangePicker = ({
4058
4416
  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
4417
  }
4060
4418
  ),
4061
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
4419
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
4062
4420
  "input",
4063
4421
  {
4064
4422
  type: "date",
@@ -4109,7 +4467,7 @@ var toDateInputValue = (value) => {
4109
4467
  };
4110
4468
 
4111
4469
  // src/components/shared/FilterBar.tsx
4112
- var import_jsx_runtime54 = require("react/jsx-runtime");
4470
+ var import_jsx_runtime56 = require("react/jsx-runtime");
4113
4471
  var PrimusFilterBar = ({
4114
4472
  filters,
4115
4473
  activeFilters,
@@ -4123,9 +4481,9 @@ var PrimusFilterBar = ({
4123
4481
  };
4124
4482
  onChange?.(next);
4125
4483
  };
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)(
4484
+ return /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "flex flex-wrap gap-4 items-end", children: [
4485
+ filters.map((filter) => /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "min-w-[220px]", children: [
4486
+ filter.type === "select" && /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
4129
4487
  Select,
4130
4488
  {
4131
4489
  label: filter.label,
@@ -4135,7 +4493,7 @@ var PrimusFilterBar = ({
4135
4493
  onChange: (value) => updateFilter(filter.key, value)
4136
4494
  }
4137
4495
  ),
4138
- filter.type === "toggle" && /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
4496
+ filter.type === "toggle" && /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
4139
4497
  Toggle,
4140
4498
  {
4141
4499
  label: filter.label,
@@ -4143,7 +4501,7 @@ var PrimusFilterBar = ({
4143
4501
  onChange: (checked) => updateFilter(filter.key, checked)
4144
4502
  }
4145
4503
  ),
4146
- filter.type === "search" && /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
4504
+ filter.type === "search" && /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
4147
4505
  Input,
4148
4506
  {
4149
4507
  label: filter.label,
@@ -4158,8 +4516,8 @@ var PrimusFilterBar = ({
4158
4516
  };
4159
4517
 
4160
4518
  // src/components/shared/ExportMenu.tsx
4161
- var import_react43 = require("react");
4162
- var import_jsx_runtime55 = require("react/jsx-runtime");
4519
+ var import_react44 = require("react");
4520
+ var import_jsx_runtime57 = require("react/jsx-runtime");
4163
4521
  var PrimusExportMenu = ({
4164
4522
  formats = ["CSV", "PDF", "PNG", "JSON"],
4165
4523
  includeCharts = true,
@@ -4167,11 +4525,11 @@ var PrimusExportMenu = ({
4167
4525
  includeTables = true,
4168
4526
  onExport
4169
4527
  }) => {
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)(() => {
4528
+ const [format, setFormat] = (0, import_react44.useState)(formats[0] ?? "CSV");
4529
+ const [charts, setCharts] = (0, import_react44.useState)(includeCharts);
4530
+ const [stats, setStats] = (0, import_react44.useState)(includeStats);
4531
+ const [tables, setTables] = (0, import_react44.useState)(includeTables);
4532
+ (0, import_react44.useEffect)(() => {
4175
4533
  if (!formats.includes(format)) {
4176
4534
  setFormat(formats[0] ?? "CSV");
4177
4535
  }
@@ -4184,29 +4542,29 @@ var PrimusExportMenu = ({
4184
4542
  includeTables: tables
4185
4543
  });
4186
4544
  };
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)(
4545
+ return /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { className: "flex flex-wrap items-center gap-3", children: [
4546
+ /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
4189
4547
  "select",
4190
4548
  {
4191
4549
  value: format,
4192
4550
  onChange: (event) => setFormat(event.target.value),
4193
4551
  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))
4552
+ children: formats.map((item) => /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("option", { value: item, children: item }, item))
4195
4553
  }
4196
4554
  ),
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) }),
4555
+ /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("label", { className: "flex items-center gap-2 text-xs text-gray-300", children: [
4556
+ /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("input", { type: "checkbox", checked: charts, onChange: (e) => setCharts(e.target.checked) }),
4199
4557
  "Charts"
4200
4558
  ] }),
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) }),
4559
+ /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("label", { className: "flex items-center gap-2 text-xs text-gray-300", children: [
4560
+ /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("input", { type: "checkbox", checked: stats, onChange: (e) => setStats(e.target.checked) }),
4203
4561
  "Stats"
4204
4562
  ] }),
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) }),
4563
+ /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("label", { className: "flex items-center gap-2 text-xs text-gray-300", children: [
4564
+ /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("input", { type: "checkbox", checked: tables, onChange: (e) => setTables(e.target.checked) }),
4207
4565
  "Tables"
4208
4566
  ] }),
4209
- /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
4567
+ /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
4210
4568
  "button",
4211
4569
  {
4212
4570
  type: "button",
@@ -4219,8 +4577,8 @@ var PrimusExportMenu = ({
4219
4577
  };
4220
4578
 
4221
4579
  // src/components/shared/Search.tsx
4222
- var import_react44 = require("react");
4223
- var import_jsx_runtime56 = require("react/jsx-runtime");
4580
+ var import_react45 = require("react");
4581
+ var import_jsx_runtime58 = require("react/jsx-runtime");
4224
4582
  var PrimusSearch = ({
4225
4583
  placeholder = "Search...",
4226
4584
  debounce = 300,
@@ -4229,17 +4587,17 @@ var PrimusSearch = ({
4229
4587
  suggestions = [],
4230
4588
  onSearch
4231
4589
  }) => {
4232
- const [query, setQuery] = (0, import_react44.useState)(value);
4233
- (0, import_react44.useEffect)(() => {
4590
+ const [query, setQuery] = (0, import_react45.useState)(value);
4591
+ (0, import_react45.useEffect)(() => {
4234
4592
  setQuery(value);
4235
4593
  }, [value]);
4236
- (0, import_react44.useEffect)(() => {
4594
+ (0, import_react45.useEffect)(() => {
4237
4595
  const handle = window.setTimeout(() => {
4238
4596
  onSearch?.(query);
4239
4597
  }, debounce);
4240
4598
  return () => window.clearTimeout(handle);
4241
4599
  }, [query, debounce, onSearch]);
4242
- const visibleSuggestions = (0, import_react44.useMemo)(() => {
4600
+ const visibleSuggestions = (0, import_react45.useMemo)(() => {
4243
4601
  if (!showSuggestions || !suggestions.length) {
4244
4602
  return [];
4245
4603
  }
@@ -4248,8 +4606,8 @@ var PrimusSearch = ({
4248
4606
  }
4249
4607
  return suggestions.filter((item) => item.toLowerCase().includes(query.toLowerCase())).slice(0, 5);
4250
4608
  }, [suggestions, query, showSuggestions]);
4251
- return /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "relative", children: [
4252
- /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
4609
+ return /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("div", { className: "relative", children: [
4610
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(
4253
4611
  "input",
4254
4612
  {
4255
4613
  type: "text",
@@ -4259,7 +4617,7 @@ var PrimusSearch = ({
4259
4617
  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
4618
  }
4261
4619
  ),
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)(
4620
+ visibleSuggestions.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime58.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_runtime58.jsx)(
4263
4621
  "button",
4264
4622
  {
4265
4623
  type: "button",
@@ -4271,6 +4629,304 @@ var PrimusSearch = ({
4271
4629
  )) })
4272
4630
  ] });
4273
4631
  };
4632
+
4633
+ // src/components/shared/PrimusWizard.tsx
4634
+ var import_react46 = __toESM(require("react"));
4635
+ var import_jsx_runtime59 = require("react/jsx-runtime");
4636
+ var PrimusStep = ({ children }) => {
4637
+ return /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(import_jsx_runtime59.Fragment, { children });
4638
+ };
4639
+ var PrimusStepper = ({ steps, currentStep }) => {
4640
+ return /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("nav", { "aria-label": "Progress", className: "mb-8", children: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("ol", { role: "list", className: "overflow-hidden rounded-md items-center flex md:border md:border-gray-200 dark:md:border-gray-800", children: steps.map((step, stepIdx) => /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("li", { className: "relative md:flex-1 md:flex", children: stepIdx < currentStep ? /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("div", { className: "group flex flex-1 items-center md:border-b-0 md:border-r border-gray-200 dark:border-gray-800 py-2 pl-4 md:py-3 md:pl-6 bg-white dark:bg-gray-900", children: /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("span", { className: "flex items-center text-sm font-medium text-purple-600 dark:text-purple-400", children: [
4641
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("span", { className: "flex h-8 w-8 flex-shrink-0 items-center justify-center rounded-full bg-purple-600 hover:bg-purple-800 text-white dark:bg-purple-500 dark:text-white", children: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("svg", { className: "h-5 w-5", viewBox: "0 0 20 20", fill: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("path", { fillRule: "evenodd", d: "M16.704 4.153a.75.75 0 01.143 1.052l-8 10.5a.75.75 0 01-1.127.075l-4.5-4.5a.75.75 0 011.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 011.05-.143z", clipRule: "evenodd" }) }) }),
4642
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("span", { className: "ml-4 text-sm font-medium", children: step.label })
4643
+ ] }) }) : stepIdx === currentStep ? /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("div", { className: "flex flex-1 items-center md:border-b-0 md:border-r border-gray-200 dark:border-gray-800 py-2 pl-4 md:py-3 md:pl-6 bg-white dark:bg-gray-900", "aria-current": "step", children: /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("span", { className: "flex items-center text-sm font-medium text-purple-600 dark:text-purple-400", children: [
4644
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("span", { className: "flex h-8 w-8 flex-shrink-0 items-center justify-center rounded-full border-2 border-purple-600 dark:border-purple-500", children: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("span", { className: "text-purple-600 dark:text-purple-500 font-bold", children: stepIdx + 1 }) }),
4645
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("span", { className: "ml-4 text-sm font-medium text-gray-900 dark:text-white", children: step.label })
4646
+ ] }) }) : /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("div", { className: "group flex flex-1 items-center md:border-b-0 md:border-r border-gray-200 dark:border-gray-800 py-2 pl-4 md:py-3 md:pl-6 bg-gray-50 dark:bg-gray-800/50", children: /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("span", { className: "flex items-center text-sm font-medium text-gray-500 dark:text-gray-400", children: [
4647
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("span", { className: "flex h-8 w-8 flex-shrink-0 items-center justify-center rounded-full border-2 border-gray-300 dark:border-gray-700", children: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("span", { className: "text-gray-500 dark:text-gray-400 font-medium", children: stepIdx + 1 }) }),
4648
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("span", { className: "ml-4", children: step.label })
4649
+ ] }) }) }, step.label)) }) });
4650
+ };
4651
+ var PrimusWizard = ({
4652
+ title,
4653
+ subtitle,
4654
+ children,
4655
+ onComplete,
4656
+ className,
4657
+ startStep = 0
4658
+ }) => {
4659
+ const [currentStep, setCurrentStep] = (0, import_react46.useState)(startStep);
4660
+ const steps = import_react46.default.Children.toArray(children).filter(
4661
+ (child) => import_react46.default.isValidElement(child) && (child.type === PrimusStep || child.type.name === "PrimusStep")
4662
+ );
4663
+ const totalSteps = steps.length;
4664
+ const isFirstStep = currentStep === 0;
4665
+ const isLastStep = currentStep === totalSteps - 1;
4666
+ const handleNext = () => {
4667
+ if (isLastStep) {
4668
+ onComplete?.();
4669
+ } else {
4670
+ setCurrentStep((prev) => prev + 1);
4671
+ }
4672
+ };
4673
+ const handleBack = () => {
4674
+ if (!isFirstStep) {
4675
+ setCurrentStep((prev) => prev - 1);
4676
+ }
4677
+ };
4678
+ if (totalSteps === 0) {
4679
+ return /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("div", { className: "text-red-500", children: "Error: PrimusWizard requires PrimusStep children" });
4680
+ }
4681
+ const currentStepConfig = steps[currentStep].props;
4682
+ return /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("div", { className: `space-y-6 ${className}`, children: [
4683
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("div", { children: [
4684
+ title && /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("h2", { className: "text-2xl font-bold text-gray-900 dark:text-white", children: title }),
4685
+ subtitle && /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("p", { className: "mt-1 text-gray-500 dark:text-gray-400", children: subtitle })
4686
+ ] }),
4687
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
4688
+ PrimusStepper,
4689
+ {
4690
+ steps: steps.map((s) => ({ label: s.props.label, description: s.props.description })),
4691
+ currentStep
4692
+ }
4693
+ ),
4694
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)(Card, { className: "p-6 min-h-[300px]", children: [
4695
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("div", { className: "mb-8", children: steps[currentStep] }),
4696
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("div", { className: "flex justify-between pt-6 border-t border-gray-100 dark:border-gray-800", children: [
4697
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
4698
+ Button,
4699
+ {
4700
+ variant: "ghost",
4701
+ onClick: handleBack,
4702
+ disabled: isFirstStep,
4703
+ children: "Back"
4704
+ }
4705
+ ),
4706
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
4707
+ Button,
4708
+ {
4709
+ onClick: handleNext,
4710
+ disabled: currentStepConfig.isValid === false,
4711
+ children: isLastStep ? "Complete" : "Next"
4712
+ }
4713
+ )
4714
+ ] })
4715
+ ] })
4716
+ ] });
4717
+ };
4718
+
4719
+ // src/components/shared/Field.tsx
4720
+ var import_react47 = __toESM(require("react"));
4721
+ var import_clsx8 = require("clsx");
4722
+ var import_solid5 = require("@heroicons/react/20/solid");
4723
+ var import_jsx_runtime60 = require("react/jsx-runtime");
4724
+ var FieldContext = import_react47.default.createContext(void 0);
4725
+ var useFieldContext = () => import_react47.default.useContext(FieldContext);
4726
+ var Field = ({ children, error, disabled, dense, className, ...props }) => {
4727
+ const id = import_react47.default.useId();
4728
+ return /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(FieldContext.Provider, { value: { id, error, disabled }, children: /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
4729
+ "div",
4730
+ {
4731
+ className: (0, import_clsx8.clsx)(
4732
+ "flex flex-col w-full",
4733
+ dense ? "gap-1" : "gap-1.5",
4734
+ className
4735
+ ),
4736
+ ...props,
4737
+ children
4738
+ }
4739
+ ) });
4740
+ };
4741
+ var Label = ({ className, children, required, indicator, ...props }) => {
4742
+ const context = useFieldContext();
4743
+ return /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)(
4744
+ "label",
4745
+ {
4746
+ htmlFor: context?.id,
4747
+ className: (0, import_clsx8.clsx)(
4748
+ "block text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70",
4749
+ context?.disabled ? "text-gray-400 opacity-70" : "text-gray-700",
4750
+ props.onClick ? "cursor-pointer" : "cursor-default",
4751
+ className
4752
+ ),
4753
+ ...props,
4754
+ children: [
4755
+ children,
4756
+ required && /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("span", { className: "ml-0.5 text-red-500", children: "*" }),
4757
+ indicator
4758
+ ]
4759
+ }
4760
+ );
4761
+ };
4762
+ var FieldDescription = ({ className, children, ...props }) => {
4763
+ const context = useFieldContext();
4764
+ return /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
4765
+ "p",
4766
+ {
4767
+ className: (0, import_clsx8.clsx)(
4768
+ "text-[0.8rem] text-muted-foreground text-gray-500",
4769
+ context?.disabled && "opacity-70",
4770
+ className
4771
+ ),
4772
+ ...props,
4773
+ children
4774
+ }
4775
+ );
4776
+ };
4777
+ var FieldError = ({ className, children, forceVisible, ...props }) => {
4778
+ const context = useFieldContext();
4779
+ const error = context?.error || children;
4780
+ if (!error && !forceVisible) return null;
4781
+ return /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)(
4782
+ "p",
4783
+ {
4784
+ className: (0, import_clsx8.clsx)(
4785
+ "text-[0.8rem] font-medium text-red-500 flex items-center gap-1.5 animate-in slide-in-from-top-1 fade-in-50",
4786
+ className
4787
+ ),
4788
+ ...props,
4789
+ children: [
4790
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(import_solid5.ExclamationCircleIcon, { className: "h-4 w-4 shrink-0" }),
4791
+ error
4792
+ ]
4793
+ }
4794
+ );
4795
+ };
4796
+
4797
+ // src/components/shared/InputGroup.tsx
4798
+ var import_react48 = __toESM(require("react"));
4799
+ var import_clsx9 = require("clsx");
4800
+ var import_jsx_runtime61 = require("react/jsx-runtime");
4801
+ var InputGroup = ({ className, children, size = "md", ...props }) => {
4802
+ return /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(
4803
+ "div",
4804
+ {
4805
+ className: (0, import_clsx9.clsx)(
4806
+ "flex items-stretch w-full rounded-lg shadow-sm",
4807
+ // Target direct children to remove borders and rounded corners where they touch
4808
+ "[&>*:first-child]:rounded-r-none",
4809
+ "[&>*:last-child]:rounded-l-none",
4810
+ "[&>*:not(:first-child):not(:last-child)]:rounded-none",
4811
+ // Handle borders to prevent double borders
4812
+ "[&>*:not(:first-child)]:-ml-px",
4813
+ // Ensure z-index handling for focus rings
4814
+ "[&>*:focus-within]:z-10",
4815
+ className
4816
+ ),
4817
+ ...props,
4818
+ children: import_react48.default.Children.map(children, (child) => {
4819
+ if (import_react48.default.isValidElement(child)) {
4820
+ return import_react48.default.cloneElement(child, { size });
4821
+ }
4822
+ return child;
4823
+ })
4824
+ }
4825
+ );
4826
+ };
4827
+ var InputAddon = ({ className, children, ...props }) => {
4828
+ return /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(
4829
+ "div",
4830
+ {
4831
+ className: (0, import_clsx9.clsx)(
4832
+ "flex items-center px-3 border border-gray-200 bg-gray-50 text-gray-500 text-sm whitespace-nowrap",
4833
+ // These will be overridden by the group's first/last child selectors usually, but good defaults:
4834
+ "first:rounded-l-lg last:rounded-r-lg",
4835
+ className
4836
+ ),
4837
+ ...props,
4838
+ children
4839
+ }
4840
+ );
4841
+ };
4842
+
4843
+ // src/components/shared/PasswordInput.tsx
4844
+ var import_react49 = __toESM(require("react"));
4845
+ var import_solid6 = require("@heroicons/react/20/solid");
4846
+ var import_jsx_runtime62 = require("react/jsx-runtime");
4847
+ var PasswordInput = import_react49.default.forwardRef(
4848
+ (props, ref) => {
4849
+ const [showPassword, setShowPassword] = (0, import_react49.useState)(false);
4850
+ const toggleVisibility = () => {
4851
+ setShowPassword(!showPassword);
4852
+ };
4853
+ return /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(
4854
+ Input,
4855
+ {
4856
+ ref,
4857
+ type: showPassword ? "text" : "password",
4858
+ endIcon: /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)(
4859
+ "button",
4860
+ {
4861
+ type: "button",
4862
+ onClick: toggleVisibility,
4863
+ className: "text-gray-400 hover:text-gray-600 focus:outline-none focus:text-primus-600 transition-colors pointer-events-auto cursor-pointer p-0.5 rounded",
4864
+ tabIndex: -1,
4865
+ children: [
4866
+ showPassword ? /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(import_solid6.EyeSlashIcon, { className: "h-4 w-4", "aria-hidden": "true" }) : /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(import_solid6.EyeIcon, { className: "h-4 w-4", "aria-hidden": "true" }),
4867
+ /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("span", { className: "sr-only", children: showPassword ? "Hide password" : "Show password" })
4868
+ ]
4869
+ }
4870
+ ),
4871
+ ...props
4872
+ }
4873
+ );
4874
+ }
4875
+ );
4876
+ PasswordInput.displayName = "PasswordInput";
4877
+
4878
+ // src/components/shared/SearchInput.tsx
4879
+ var import_react50 = __toESM(require("react"));
4880
+ var import_solid7 = require("@heroicons/react/20/solid");
4881
+ var import_jsx_runtime63 = require("react/jsx-runtime");
4882
+ var SearchInput = import_react50.default.forwardRef(
4883
+ ({ value, onSearch, debounceMs = 300, className, ...props }, ref) => {
4884
+ const [localValue, setLocalValue] = (0, import_react50.useState)(value || "");
4885
+ const [isDebouncing, setIsDebouncing] = (0, import_react50.useState)(false);
4886
+ (0, import_react50.useEffect)(() => {
4887
+ if (value !== void 0) {
4888
+ setLocalValue(value);
4889
+ }
4890
+ }, [value]);
4891
+ (0, import_react50.useEffect)(() => {
4892
+ if (debounceMs === 0) {
4893
+ onSearch?.(localValue);
4894
+ return;
4895
+ }
4896
+ const handler = setTimeout(() => {
4897
+ onSearch?.(localValue);
4898
+ setIsDebouncing(false);
4899
+ }, debounceMs);
4900
+ return () => {
4901
+ clearTimeout(handler);
4902
+ };
4903
+ }, [localValue, debounceMs]);
4904
+ const handleChange = (e) => {
4905
+ const newVal = e.target.value;
4906
+ setLocalValue(newVal);
4907
+ if (debounceMs > 0) setIsDebouncing(true);
4908
+ };
4909
+ const handleClear = () => {
4910
+ setLocalValue("");
4911
+ props.onClear?.();
4912
+ };
4913
+ return /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
4914
+ Input,
4915
+ {
4916
+ ref,
4917
+ type: "text",
4918
+ startIcon: /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(import_solid7.MagnifyingGlassIcon, { className: "h-4 w-4" }),
4919
+ value: localValue,
4920
+ onChange: handleChange,
4921
+ onClear: handleClear,
4922
+ loading: props.loading || props.loading === void 0 && isDebouncing,
4923
+ className,
4924
+ ...props
4925
+ }
4926
+ );
4927
+ }
4928
+ );
4929
+ SearchInput.displayName = "SearchInput";
4274
4930
  // Annotate the CommonJS export names for ESM import in node:
4275
4931
  0 && (module.exports = {
4276
4932
  AICopilot,
@@ -4288,17 +4944,24 @@ var PrimusSearch = ({
4288
4944
  DashboardGrid,
4289
4945
  DocumentViewer,
4290
4946
  FeatureFlagToggle,
4947
+ Field,
4948
+ FieldDescription,
4949
+ FieldError,
4291
4950
  FileUploader,
4292
4951
  FraudDetectionDashboard,
4293
4952
  Grid,
4294
4953
  Input,
4954
+ InputAddon,
4955
+ InputGroup,
4295
4956
  KYCVerification,
4957
+ Label,
4296
4958
  LoanCalculator,
4297
4959
  LogViewer,
4298
4960
  LoginPage,
4299
4961
  Modal,
4300
4962
  NotificationBell,
4301
4963
  NotificationFeed,
4964
+ PasswordInput,
4302
4965
  PolicyCard,
4303
4966
  PremiumCalculator,
4304
4967
  PrimusActivityFeed,
@@ -4314,10 +4977,16 @@ var PrimusSearch = ({
4314
4977
  PrimusDataTable,
4315
4978
  PrimusDateRangePicker,
4316
4979
  PrimusExportMenu,
4980
+ PrimusField,
4981
+ PrimusFieldDescription,
4982
+ PrimusFieldError,
4317
4983
  PrimusFilterBar,
4318
4984
  PrimusGrid,
4319
4985
  PrimusHeader,
4320
4986
  PrimusInput,
4987
+ PrimusInputAddon,
4988
+ PrimusInputGroup,
4989
+ PrimusLabel,
4321
4990
  PrimusLayout,
4322
4991
  PrimusLineChart,
4323
4992
  PrimusLogin,
@@ -4326,22 +4995,31 @@ var PrimusSearch = ({
4326
4995
  PrimusNotificationCenter,
4327
4996
  PrimusNotificationFeed,
4328
4997
  PrimusNotifications,
4998
+ PrimusPasswordInput,
4329
4999
  PrimusPieChart,
4330
5000
  PrimusProvider,
4331
5001
  PrimusRadioGroup,
4332
5002
  PrimusSearch,
5003
+ PrimusSearchInput,
5004
+ PrimusSection,
4333
5005
  PrimusSelect,
4334
5006
  PrimusSidebar,
4335
5007
  PrimusSparkline,
4336
5008
  PrimusStack,
4337
5009
  PrimusStatCard,
5010
+ PrimusStatsCard,
5011
+ PrimusStep,
5012
+ PrimusStepper,
5013
+ PrimusSummaryCard,
4338
5014
  PrimusTable,
4339
5015
  PrimusTextarea,
4340
5016
  PrimusThemeProvider,
4341
5017
  PrimusThemeToggle,
4342
5018
  PrimusToggle,
5019
+ PrimusWizard,
4343
5020
  QuoteComparison,
4344
5021
  RadioGroup,
5022
+ SearchInput,
4345
5023
  SecurityDashboard,
4346
5024
  Select,
4347
5025
  Stack,
@@ -4353,6 +5031,7 @@ var PrimusSearch = ({
4353
5031
  themeColors,
4354
5032
  useNotifications,
4355
5033
  usePrimusAuth,
5034
+ usePrimusFetch,
4356
5035
  usePrimusTheme,
4357
5036
  useRealtimeNotifications
4358
5037
  });