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/README.md +40 -30
- package/dist/index.d.mts +229 -115
- package/dist/index.d.ts +229 -115
- package/dist/index.js +1290 -611
- package/dist/index.mjs +1190 -534
- package/package.json +2 -2
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
|
|
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/
|
|
987
|
+
// src/context/PrimusProvider.tsx
|
|
988
|
+
var import_react13 = require("react");
|
|
965
989
|
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
966
|
-
var
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
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
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
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
|
-
|
|
988
|
-
|
|
989
|
-
|
|
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
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
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
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
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
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
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
|
|
1028
|
-
const [
|
|
1029
|
-
const [
|
|
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
|
-
|
|
1380
|
+
const base = authEndpoint.replace(/\/+$/, "");
|
|
1381
|
+
window.location.href = `${base}/${provider}`;
|
|
1045
1382
|
}
|
|
1046
1383
|
};
|
|
1047
|
-
const
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
const
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
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,
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
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
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
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
|
-
|
|
1092
|
-
/* @__PURE__ */ (0,
|
|
1093
|
-
|
|
1094
|
-
|
|
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: "
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
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/
|
|
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,
|
|
1384
|
-
const [unreadCount, setUnreadCount] = (0,
|
|
1385
|
-
const [loading, setLoading] = (0,
|
|
1386
|
-
const safeMockData = (0,
|
|
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,
|
|
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
|
|
1444
|
-
var
|
|
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)(
|
|
1462
|
-
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
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
|
-
|
|
1747
|
+
import_react18.Transition,
|
|
1471
1748
|
{
|
|
1472
|
-
as:
|
|
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)(
|
|
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
|
|
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,
|
|
1534
|
-
const [isOpen, setIsOpen] = (0,
|
|
1535
|
-
const [showSendForm, setShowSendForm] = (0,
|
|
1536
|
-
const [unreadCount, setUnreadCount] = (0,
|
|
1537
|
-
const [newTitle, setNewTitle] = (0,
|
|
1538
|
-
const [newMessage, setNewMessage] = (0,
|
|
1539
|
-
const [newType, setNewType] = (0,
|
|
1540
|
-
const [sending, setSending] = (0,
|
|
1541
|
-
const fetchNotifications = (0,
|
|
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,
|
|
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
|
|
2042
|
+
var import_react21 = require("react");
|
|
1766
2043
|
var useRealtimeNotifications = (options) => {
|
|
1767
2044
|
const { apiUrl, pollInterval = 3e3, userId } = options;
|
|
1768
|
-
const [notifications, setNotifications] = (0,
|
|
1769
|
-
const [unreadCount, setUnreadCount] = (0,
|
|
1770
|
-
const [loading, setLoading] = (0,
|
|
1771
|
-
const [error, setError] = (0,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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
|
|
2122
|
+
var import_react23 = require("react");
|
|
1846
2123
|
|
|
1847
2124
|
// src/components/shared/Input.tsx
|
|
1848
|
-
var
|
|
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 =
|
|
1863
|
-
({
|
|
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
|
-
|
|
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
|
-
|
|
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 && !
|
|
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,
|
|
1936
|
-
const [cardholderName, setCardholderName] = (0,
|
|
1937
|
-
const [cardNumber, setCardNumber] = (0,
|
|
1938
|
-
const [expiry, setExpiry] = (0,
|
|
1939
|
-
const [cvc, setCvc] = (0,
|
|
1940
|
-
const [error, setError] = (0,
|
|
1941
|
-
const [success, setSuccess] = (0,
|
|
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
|
|
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,
|
|
2340
|
-
const [loading, setLoading] = (0,
|
|
2341
|
-
(0,
|
|
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
|
|
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,
|
|
2384
|
-
const [filter, setFilter] = (0,
|
|
2385
|
-
const [loading, setLoading] = (0,
|
|
2386
|
-
(0,
|
|
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
|
|
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)(
|
|
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/
|
|
2544
|
-
var import_react26 = require("react");
|
|
2850
|
+
// src/components/layout/PrimusSection.tsx
|
|
2545
2851
|
var import_jsx_runtime31 = require("react/jsx-runtime");
|
|
2546
|
-
|
|
2547
|
-
|
|
2548
|
-
|
|
2549
|
-
|
|
2550
|
-
|
|
2551
|
-
|
|
2552
|
-
|
|
2553
|
-
|
|
2554
|
-
|
|
2555
|
-
|
|
2556
|
-
|
|
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,
|
|
2565
|
-
const [sortKey, setSortKey] = (0,
|
|
2566
|
-
const [sortDir, setSortDir] = (0,
|
|
2567
|
-
const [internalPageIndex, setInternalPageIndex] = (0,
|
|
2568
|
-
const filteredData = (0,
|
|
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,
|
|
2625
|
-
searchable && /* @__PURE__ */ (0,
|
|
2626
|
-
/* @__PURE__ */ (0,
|
|
2627
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
2644
|
-
/* @__PURE__ */ (0,
|
|
2645
|
-
selectable && /* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
2670
|
-
/* @__PURE__ */ (0,
|
|
2671
|
-
/* @__PURE__ */ (0,
|
|
2672
|
-
] }) }) }) : filteredData.length === 0 ? /* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
2692
|
-
actions && /* @__PURE__ */ (0,
|
|
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,
|
|
2699
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
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
|
|
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,
|
|
2747
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
2755
|
-
title && /* @__PURE__ */ (0,
|
|
2756
|
-
/* @__PURE__ */ (0,
|
|
2757
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
2767
|
-
footer && /* @__PURE__ */ (0,
|
|
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
|
|
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,
|
|
2810
|
-
/* @__PURE__ */ (0,
|
|
2811
|
-
/* @__PURE__ */ (0,
|
|
2812
|
-
/* @__PURE__ */ (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,
|
|
2815
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
2819
|
-
/* @__PURE__ */ (0,
|
|
2820
|
-
/* @__PURE__ */ (0,
|
|
2821
|
-
/* @__PURE__ */ (0,
|
|
2822
|
-
/* @__PURE__ */ (0,
|
|
2823
|
-
change && /* @__PURE__ */ (0,
|
|
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,
|
|
2831
|
-
/* @__PURE__ */ (0,
|
|
2832
|
-
/* @__PURE__ */ (0,
|
|
2833
|
-
description && /* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
2847
|
-
(title || actions) && /* @__PURE__ */ (0,
|
|
2848
|
-
/* @__PURE__ */ (0,
|
|
2849
|
-
title && /* @__PURE__ */ (0,
|
|
2850
|
-
subtitle && /* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
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
|
|
2872
|
-
var
|
|
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,
|
|
2887
|
-
const groups = (0,
|
|
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,
|
|
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,
|
|
2904
|
-
group.label && /* @__PURE__ */ (0,
|
|
2905
|
-
/* @__PURE__ */ (0,
|
|
2906
|
-
/* @__PURE__ */ (0,
|
|
2907
|
-
/* @__PURE__ */ (0,
|
|
2908
|
-
/* @__PURE__ */ (0,
|
|
2909
|
-
/* @__PURE__ */ (0,
|
|
2910
|
-
showTimestamps && /* @__PURE__ */ (0,
|
|
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,
|
|
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
|
|
3361
|
+
var import_react30 = require("react");
|
|
2940
3362
|
var import_chart = require("chart.js");
|
|
2941
|
-
var
|
|
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,
|
|
2965
|
-
const chartRef = (0,
|
|
2966
|
-
const builtData = (0,
|
|
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,
|
|
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,
|
|
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,
|
|
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
|
|
3458
|
+
var import_jsx_runtime39 = require("react/jsx-runtime");
|
|
3037
3459
|
var PrimusLineChart = (props) => {
|
|
3038
|
-
return /* @__PURE__ */ (0,
|
|
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
|
|
3478
|
+
var import_jsx_runtime40 = require("react/jsx-runtime");
|
|
3057
3479
|
var PrimusAreaChart = (props) => {
|
|
3058
|
-
return /* @__PURE__ */ (0,
|
|
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
|
|
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,
|
|
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
|
|
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,
|
|
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
|
|
3125
|
-
var
|
|
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,
|
|
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,
|
|
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,
|
|
3170
|
-
/* @__PURE__ */ (0,
|
|
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
|
|
3178
|
-
var
|
|
3179
|
-
var Checkbox =
|
|
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,
|
|
3217
|
-
/* @__PURE__ */ (0,
|
|
3218
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
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
|
|
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,
|
|
3286
|
-
/* @__PURE__ */ (0,
|
|
3287
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
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
|
|
3322
|
-
var
|
|
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
|
|
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,
|
|
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,
|
|
3348
|
-
|
|
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,
|
|
3357
|
-
label && /* @__PURE__ */ (0,
|
|
3358
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
3369
|
-
/* @__PURE__ */ (0,
|
|
3370
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
3383
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
3389
|
-
|
|
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,
|
|
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,
|
|
3407
|
-
|
|
3828
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
3829
|
+
import_react34.Transition,
|
|
3408
3830
|
{
|
|
3409
|
-
as:
|
|
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,
|
|
3415
|
-
|
|
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,
|
|
3424
|
-
/* @__PURE__ */ (0,
|
|
3425
|
-
selected ? /* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
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
|
|
3449
|
-
var
|
|
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] =
|
|
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,
|
|
3505
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
3943
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { style: thumbStyles })
|
|
3522
3944
|
}
|
|
3523
3945
|
),
|
|
3524
|
-
label && /* @__PURE__ */ (0,
|
|
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
|
|
3531
|
-
var
|
|
3532
|
-
var Textarea =
|
|
3533
|
-
({ style, label, error, disabled, resize = "vertical", ...props }, ref) => {
|
|
3534
|
-
const
|
|
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.
|
|
3967
|
+
marginBottom: "0.375rem",
|
|
3543
3968
|
display: "block",
|
|
3544
3969
|
color: "#374151",
|
|
3545
|
-
|
|
3546
|
-
|
|
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: "
|
|
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,
|
|
3573
|
-
label && /* @__PURE__ */ (0,
|
|
3574
|
-
/* @__PURE__ */ (0,
|
|
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
|
-
|
|
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
|
|
3668
|
-
var
|
|
3669
|
-
var Badge =
|
|
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,
|
|
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
|
|
3730
|
-
var
|
|
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] =
|
|
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,
|
|
3765
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
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
|
|
3791
|
-
var
|
|
3792
|
-
var Container =
|
|
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,
|
|
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
|
|
3824
|
-
var
|
|
3825
|
-
var Grid =
|
|
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,
|
|
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
|
|
3850
|
-
var
|
|
3851
|
-
var Stack =
|
|
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,
|
|
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
|
|
3888
|
-
var
|
|
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
|
-
|
|
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,
|
|
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,
|
|
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,
|
|
3978
|
-
/* @__PURE__ */ (0,
|
|
3979
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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
|
|
4000
|
-
var
|
|
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,
|
|
4011
|
-
const [end, setEnd] = (0,
|
|
4012
|
-
(0,
|
|
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,
|
|
4373
|
+
(0, import_react43.useEffect)(() => {
|
|
4016
4374
|
setEnd(endDate ?? "");
|
|
4017
4375
|
}, [endDate]);
|
|
4018
|
-
const normalizedRanges = (0,
|
|
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,
|
|
4037
|
-
normalizedRanges.length > 0 && /* @__PURE__ */ (0,
|
|
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,
|
|
4049
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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
|
|
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,
|
|
4127
|
-
filters.map((filter) => /* @__PURE__ */ (0,
|
|
4128
|
-
filter.type === "select" && /* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
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
|
|
4162
|
-
var
|
|
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,
|
|
4171
|
-
const [charts, setCharts] = (0,
|
|
4172
|
-
const [stats, setStats] = (0,
|
|
4173
|
-
const [tables, setTables] = (0,
|
|
4174
|
-
(0,
|
|
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,
|
|
4188
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
4552
|
+
children: formats.map((item) => /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("option", { value: item, children: item }, item))
|
|
4195
4553
|
}
|
|
4196
4554
|
),
|
|
4197
|
-
/* @__PURE__ */ (0,
|
|
4198
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
4202
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
4206
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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
|
|
4223
|
-
var
|
|
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,
|
|
4233
|
-
(0,
|
|
4590
|
+
const [query, setQuery] = (0, import_react45.useState)(value);
|
|
4591
|
+
(0, import_react45.useEffect)(() => {
|
|
4234
4592
|
setQuery(value);
|
|
4235
4593
|
}, [value]);
|
|
4236
|
-
(0,
|
|
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,
|
|
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,
|
|
4252
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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
|
});
|