primus-react-ui 1.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js ADDED
@@ -0,0 +1,2597 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/index.ts
31
+ var index_exports = {};
32
+ __export(index_exports, {
33
+ AICopilot: () => AICopilot,
34
+ AccountDashboard: () => AccountDashboard,
35
+ AgentDirectory: () => AgentDirectory,
36
+ CheckoutForm: () => CheckoutForm,
37
+ ClaimStatusTracker: () => ClaimStatusTracker,
38
+ CreditCardVisual: () => CreditCardVisual,
39
+ CreditScoreCard: () => CreditScoreCard,
40
+ DashboardGrid: () => DashboardGrid,
41
+ DocumentViewer: () => DocumentViewer,
42
+ FeatureFlagToggle: () => FeatureFlagToggle,
43
+ FileUploader: () => FileUploader,
44
+ FraudDetectionDashboard: () => FraudDetectionDashboard,
45
+ KYCVerification: () => KYCVerification,
46
+ LoanCalculator: () => LoanCalculator,
47
+ LogViewer: () => LogViewer,
48
+ LoginPage: () => LoginPage,
49
+ NotificationBell: () => NotificationBell,
50
+ NotificationFeed: () => NotificationFeed,
51
+ PolicyCard: () => PolicyCard,
52
+ PremiumCalculator: () => PremiumCalculator,
53
+ PrimusDashboard: () => PrimusDashboard,
54
+ PrimusDataTable: () => PrimusDataTable,
55
+ PrimusHeader: () => PrimusHeader,
56
+ PrimusLayout: () => PrimusLayout,
57
+ PrimusLogin: () => PrimusLogin,
58
+ PrimusModal: () => PrimusModal,
59
+ PrimusNotificationCenter: () => PrimusNotificationCenter,
60
+ PrimusNotifications: () => PrimusNotifications,
61
+ PrimusProvider: () => PrimusProvider,
62
+ PrimusSidebar: () => PrimusSidebar,
63
+ PrimusStatCard: () => PrimusStatCard,
64
+ PrimusThemeProvider: () => PrimusThemeProvider,
65
+ PrimusThemeToggle: () => PrimusThemeToggle,
66
+ QuoteComparison: () => QuoteComparison,
67
+ SecurityDashboard: () => SecurityDashboard,
68
+ TransactionHistory: () => TransactionHistory,
69
+ UserProfile: () => UserProfile,
70
+ themeColors: () => themeColors,
71
+ useNotifications: () => useNotifications,
72
+ usePrimusAuth: () => usePrimusAuth,
73
+ usePrimusTheme: () => usePrimusTheme,
74
+ useRealtimeNotifications: () => useRealtimeNotifications
75
+ });
76
+ module.exports = __toCommonJS(index_exports);
77
+
78
+ // src/components/banking/accounts/AccountDashboard.tsx
79
+ var import_react = require("react");
80
+ var import_jsx_runtime = require("react/jsx-runtime");
81
+ var AccountDashboard = ({
82
+ apiUrl = "http://localhost:5221"
83
+ }) => {
84
+ const [accounts, setAccounts] = (0, import_react.useState)([]);
85
+ const [loading, setLoading] = (0, import_react.useState)(true);
86
+ (0, import_react.useEffect)(() => {
87
+ fetchAccounts();
88
+ }, []);
89
+ const fetchAccounts = async () => {
90
+ try {
91
+ const response = await fetch(`${apiUrl}/api/banking/accounts`);
92
+ if (response.ok) {
93
+ const data = await response.json();
94
+ setAccounts(data);
95
+ }
96
+ } catch (error) {
97
+ console.error("Failed to fetch accounts:", error);
98
+ } finally {
99
+ setLoading(false);
100
+ }
101
+ };
102
+ if (loading) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "p-4", children: "Loading accounts..." });
103
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "bg-white p-6 rounded-lg border border-gray-200 shadow-sm", children: [
104
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { className: "text-lg font-medium text-gray-900 mb-4", children: "Bank Accounts" }),
105
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "space-y-4", children: accounts.map((account) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "p-4 bg-gray-50 rounded-lg border border-gray-200", children: [
106
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex justify-between items-start", children: [
107
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
108
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h4", { className: "font-medium text-gray-900", children: account.type }),
109
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-sm text-gray-500", children: account.accountNumber })
110
+ ] }),
111
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "text-right", children: [
112
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "text-2xl font-bold text-gray-900", children: [
113
+ "$",
114
+ account.balance.toLocaleString()
115
+ ] }),
116
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-sm text-gray-500", children: account.currency })
117
+ ] })
118
+ ] }),
119
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "mt-2", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: `px-2 py-1 rounded text-xs font-medium ${account.status === "active" ? "bg-green-100 text-green-800" : "bg-gray-100 text-gray-800"}`, children: account.status }) })
120
+ ] }, account.id)) })
121
+ ] });
122
+ };
123
+
124
+ // src/components/banking/kyc/KYCVerification.tsx
125
+ var import_react2 = require("react");
126
+ var import_jsx_runtime2 = require("react/jsx-runtime");
127
+ var KYCVerification = ({
128
+ userId,
129
+ apiUrl = "http://localhost:5221"
130
+ }) => {
131
+ const [status, setStatus] = (0, import_react2.useState)(null);
132
+ const [loading, setLoading] = (0, import_react2.useState)(true);
133
+ (0, import_react2.useEffect)(() => {
134
+ fetchStatus();
135
+ }, [userId]);
136
+ const fetchStatus = async () => {
137
+ try {
138
+ const response = await fetch(`${apiUrl}/api/banking/kyc/status/${userId}`);
139
+ if (response.ok) {
140
+ const data = await response.json();
141
+ setStatus(data);
142
+ }
143
+ } catch (error) {
144
+ console.error("Failed to fetch KYC status:", error);
145
+ } finally {
146
+ setLoading(false);
147
+ }
148
+ };
149
+ if (loading) return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "p-4", children: "Loading KYC status..." });
150
+ if (!status) return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "p-4", children: "No KYC data found" });
151
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "bg-white p-6 rounded-lg border border-gray-200 shadow-sm", children: [
152
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h3", { className: "text-lg font-medium text-gray-900 mb-4", children: "KYC Verification Status" }),
153
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "mb-6", children: [
154
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "flex items-center gap-2 mb-2", children: [
155
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "text-sm text-gray-600", children: "Status:" }),
156
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: `px-3 py-1 rounded-full text-sm font-medium ${status.status === "verified" ? "bg-green-100 text-green-800" : "bg-yellow-100 text-yellow-800"}`, children: status.status })
157
+ ] }),
158
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "flex items-center gap-2", children: [
159
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "text-sm text-gray-600", children: "Risk Level:" }),
160
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: `px-3 py-1 rounded-full text-sm font-medium ${status.riskLevel === "low" ? "bg-green-100 text-green-800" : "bg-red-100 text-red-800"}`, children: status.riskLevel })
161
+ ] })
162
+ ] }),
163
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { children: [
164
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h4", { className: "font-medium text-gray-900 mb-3", children: "Documents" }),
165
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "space-y-2", children: status.documents.map((doc, index) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "flex justify-between items-center p-3 bg-gray-50 rounded", children: [
166
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "text-sm text-gray-900", children: doc.type }),
167
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: `px-2 py-1 rounded text-xs font-medium ${doc.status === "approved" ? "bg-green-100 text-green-800" : "bg-yellow-100 text-yellow-800"}`, children: doc.status })
168
+ ] }, index)) })
169
+ ] })
170
+ ] });
171
+ };
172
+
173
+ // src/components/banking/loans/LoanCalculator.tsx
174
+ var import_react3 = require("react");
175
+ var import_jsx_runtime3 = require("react/jsx-runtime");
176
+ var LoanCalculator = ({
177
+ apiUrl = "http://localhost:5221"
178
+ }) => {
179
+ const [amount, setAmount] = (0, import_react3.useState)(25e3);
180
+ const [rate, setRate] = (0, import_react3.useState)(5.5);
181
+ const [term, setTerm] = (0, import_react3.useState)(60);
182
+ const [result, setResult] = (0, import_react3.useState)(null);
183
+ const [loading, setLoading] = (0, import_react3.useState)(false);
184
+ const calculate = async () => {
185
+ setLoading(true);
186
+ try {
187
+ const response = await fetch(`${apiUrl}/api/banking/loans/calculate`, {
188
+ method: "POST",
189
+ headers: { "Content-Type": "application/json" },
190
+ body: JSON.stringify({ amount, interestRate: rate, term })
191
+ });
192
+ if (response.ok) {
193
+ const data = await response.json();
194
+ setResult(data);
195
+ }
196
+ } catch (error) {
197
+ console.error("Failed to calculate loan:", error);
198
+ } finally {
199
+ setLoading(false);
200
+ }
201
+ };
202
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "bg-white p-6 rounded-lg border border-gray-200 shadow-sm", children: [
203
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h3", { className: "text-lg font-medium text-gray-900 mb-4", children: "Loan Calculator" }),
204
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "space-y-4 mb-6", children: [
205
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { children: [
206
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("label", { className: "block text-sm font-medium text-gray-700 mb-1", children: [
207
+ "Loan Amount: $",
208
+ amount.toLocaleString()
209
+ ] }),
210
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
211
+ "input",
212
+ {
213
+ type: "range",
214
+ min: "1000",
215
+ max: "100000",
216
+ step: "1000",
217
+ value: amount,
218
+ onChange: (e) => setAmount(Number(e.target.value)),
219
+ className: "w-full"
220
+ }
221
+ )
222
+ ] }),
223
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { children: [
224
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("label", { className: "block text-sm font-medium text-gray-700 mb-1", children: [
225
+ "Interest Rate: ",
226
+ rate,
227
+ "%"
228
+ ] }),
229
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
230
+ "input",
231
+ {
232
+ type: "range",
233
+ min: "1",
234
+ max: "15",
235
+ step: "0.1",
236
+ value: rate,
237
+ onChange: (e) => setRate(Number(e.target.value)),
238
+ className: "w-full"
239
+ }
240
+ )
241
+ ] }),
242
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { children: [
243
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("label", { className: "block text-sm font-medium text-gray-700 mb-1", children: [
244
+ "Term: ",
245
+ term,
246
+ " months"
247
+ ] }),
248
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
249
+ "input",
250
+ {
251
+ type: "range",
252
+ min: "12",
253
+ max: "360",
254
+ step: "12",
255
+ value: term,
256
+ onChange: (e) => setTerm(Number(e.target.value)),
257
+ className: "w-full"
258
+ }
259
+ )
260
+ ] })
261
+ ] }),
262
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
263
+ "button",
264
+ {
265
+ onClick: calculate,
266
+ disabled: loading,
267
+ className: "w-full bg-primus-600 text-white py-2 px-4 rounded hover:bg-primus-700 disabled:opacity-50",
268
+ children: loading ? "Calculating..." : "Calculate"
269
+ }
270
+ ),
271
+ result && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "mt-6 p-4 bg-gray-50 rounded-lg", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "grid grid-cols-2 gap-4", children: [
272
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { children: [
273
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "text-sm text-gray-600", children: "Monthly Payment" }),
274
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("p", { className: "text-2xl font-bold text-gray-900", children: [
275
+ "$",
276
+ result.monthlyPayment
277
+ ] })
278
+ ] }),
279
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { children: [
280
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "text-sm text-gray-600", children: "Total Interest" }),
281
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("p", { className: "text-2xl font-bold text-gray-900", children: [
282
+ "$",
283
+ result.totalInterest
284
+ ] })
285
+ ] })
286
+ ] }) })
287
+ ] });
288
+ };
289
+
290
+ // src/components/banking/credit/CreditScoreCard.tsx
291
+ var import_react4 = require("react");
292
+ var import_jsx_runtime4 = require("react/jsx-runtime");
293
+ var CreditScoreCard = ({
294
+ userId,
295
+ apiUrl = "http://localhost:5221"
296
+ }) => {
297
+ const [score, setScore] = (0, import_react4.useState)(null);
298
+ const [loading, setLoading] = (0, import_react4.useState)(true);
299
+ (0, import_react4.useEffect)(() => {
300
+ fetchScore();
301
+ }, [userId]);
302
+ const fetchScore = async () => {
303
+ try {
304
+ const response = await fetch(`${apiUrl}/api/banking/credit-score/${userId}`);
305
+ if (response.ok) {
306
+ const data = await response.json();
307
+ setScore(data);
308
+ }
309
+ } catch (error) {
310
+ console.error("Failed to fetch credit score:", error);
311
+ } finally {
312
+ setLoading(false);
313
+ }
314
+ };
315
+ if (loading) return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "p-4", children: "Loading credit score..." });
316
+ if (!score) return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "p-4", children: "No credit score data" });
317
+ const getScoreColor = (score2) => {
318
+ if (score2 >= 740) return "text-green-600";
319
+ if (score2 >= 670) return "text-blue-600";
320
+ if (score2 >= 580) return "text-yellow-600";
321
+ return "text-red-600";
322
+ };
323
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "bg-white p-6 rounded-lg border border-gray-200 shadow-sm", children: [
324
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("h3", { className: "text-lg font-medium text-gray-900 mb-4", children: "Credit Score" }),
325
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "text-center mb-6", children: [
326
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: `text-6xl font-bold ${getScoreColor(score.score)}`, children: score.score }),
327
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "text-lg text-gray-600 mt-2", children: score.rating }),
328
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "text-sm text-gray-400 mt-1", children: [
329
+ "Updated: ",
330
+ new Date(score.lastUpdated).toLocaleDateString()
331
+ ] })
332
+ ] }),
333
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { children: [
334
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("h4", { className: "font-medium text-gray-900 mb-3", children: "Score Factors" }),
335
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "space-y-2", children: score.factors.map((factor, index) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "flex justify-between items-center p-2 bg-gray-50 rounded", children: [
336
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "text-sm text-gray-900", children: factor.factor }),
337
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "flex items-center gap-2", children: [
338
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "text-xs text-gray-500", children: [
339
+ factor.weight,
340
+ "%"
341
+ ] }),
342
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: `px-2 py-0.5 rounded text-xs font-medium ${factor.impact === "positive" ? "bg-green-100 text-green-800" : factor.impact === "negative" ? "bg-red-100 text-red-800" : "bg-gray-100 text-gray-800"}`, children: factor.impact })
343
+ ] })
344
+ ] }, index)) })
345
+ ] })
346
+ ] });
347
+ };
348
+
349
+ // src/components/insurance/quotes/QuoteComparison.tsx
350
+ var import_react5 = require("react");
351
+ var import_jsx_runtime5 = require("react/jsx-runtime");
352
+ var QuoteComparison = ({
353
+ apiUrl = "http://localhost:5221"
354
+ }) => {
355
+ const [quotes, setQuotes] = (0, import_react5.useState)([]);
356
+ const [loading, setLoading] = (0, import_react5.useState)(true);
357
+ (0, import_react5.useEffect)(() => {
358
+ fetchQuotes();
359
+ }, []);
360
+ const fetchQuotes = async () => {
361
+ try {
362
+ const response = await fetch(`${apiUrl}/api/insurance/quotes`);
363
+ if (response.ok) {
364
+ const data = await response.json();
365
+ setQuotes(data);
366
+ }
367
+ } catch (error) {
368
+ console.error("Failed to fetch quotes:", error);
369
+ } finally {
370
+ setLoading(false);
371
+ }
372
+ };
373
+ if (loading) return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "p-4", children: "Loading quotes..." });
374
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "bg-white p-6 rounded-lg border border-gray-200 shadow-sm", children: [
375
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("h3", { className: "text-lg font-medium text-gray-900 mb-4", children: "Insurance Quotes" }),
376
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: quotes.map((quote) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "p-4 border-2 border-gray-200 rounded-lg hover:border-primus-500 transition-colors", children: [
377
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "flex justify-between items-start mb-3", children: [
378
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("h4", { className: "font-medium text-gray-900", children: quote.type }),
379
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: `px-2 py-1 rounded text-xs font-medium ${quote.status === "active" ? "bg-green-100 text-green-800" : "bg-blue-100 text-blue-800"}`, children: quote.status })
380
+ ] }),
381
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "mb-3", children: [
382
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "text-3xl font-bold text-gray-900", children: [
383
+ "$",
384
+ quote.monthlyPremium,
385
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "text-sm font-normal text-gray-500", children: "/mo" })
386
+ ] }),
387
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "text-sm text-gray-600", children: [
388
+ "Coverage: $",
389
+ quote.coverageAmount.toLocaleString()
390
+ ] })
391
+ ] }),
392
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "text-xs text-gray-500", children: [
393
+ "Valid until: ",
394
+ new Date(quote.validUntil).toLocaleDateString()
395
+ ] }),
396
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { className: "mt-3 w-full px-4 py-2 bg-primus-600 text-white rounded hover:bg-primus-700", children: "Accept Quote" })
397
+ ] }, quote.id)) })
398
+ ] });
399
+ };
400
+
401
+ // src/components/insurance/agents/AgentDirectory.tsx
402
+ var import_react6 = require("react");
403
+ var import_jsx_runtime6 = require("react/jsx-runtime");
404
+ var AgentDirectory = ({
405
+ apiUrl = "http://localhost:5221"
406
+ }) => {
407
+ const [agents, setAgents] = (0, import_react6.useState)([]);
408
+ const [loading, setLoading] = (0, import_react6.useState)(true);
409
+ (0, import_react6.useEffect)(() => {
410
+ fetchAgents();
411
+ }, []);
412
+ const fetchAgents = async () => {
413
+ try {
414
+ const response = await fetch(`${apiUrl}/api/insurance/agents`);
415
+ if (response.ok) {
416
+ const data = await response.json();
417
+ setAgents(data);
418
+ }
419
+ } catch (error) {
420
+ console.error("Failed to fetch agents:", error);
421
+ } finally {
422
+ setLoading(false);
423
+ }
424
+ };
425
+ if (loading) return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "p-4", children: "Loading agents..." });
426
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "bg-white p-6 rounded-lg border border-gray-200 shadow-sm", children: [
427
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("h3", { className: "text-lg font-medium text-gray-900 mb-4", children: "Insurance Agents" }),
428
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: agents.map((agent) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "p-4 border border-gray-200 rounded-lg", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "flex items-start gap-3", children: [
429
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "w-12 h-12 bg-primus-100 rounded-full flex items-center justify-center text-primus-600 font-bold text-lg", children: agent.name.split(" ").map((n) => n[0]).join("") }),
430
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "flex-1", children: [
431
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("h4", { className: "font-medium text-gray-900", children: agent.name }),
432
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "text-sm text-gray-600", children: agent.specialty }),
433
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "flex items-center gap-2 mt-1", children: [
434
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "flex items-center", children: [
435
+ "\u2B50".repeat(Math.floor(agent.rating)),
436
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "text-xs text-gray-500 ml-1", children: agent.rating })
437
+ ] }),
438
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "text-xs text-gray-400", children: "\u2022" }),
439
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "text-xs text-gray-500", children: [
440
+ agent.yearsExperience,
441
+ " years"
442
+ ] })
443
+ ] }),
444
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "mt-2 space-y-1", children: [
445
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "text-xs text-gray-600", children: agent.email }),
446
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "text-xs text-gray-600", children: agent.phone })
447
+ ] })
448
+ ] })
449
+ ] }) }, agent.id)) })
450
+ ] });
451
+ };
452
+
453
+ // src/components/insurance/fraud/FraudDetectionDashboard.tsx
454
+ var import_react7 = require("react");
455
+ var import_jsx_runtime7 = require("react/jsx-runtime");
456
+ var FraudDetectionDashboard = ({
457
+ apiUrl = "http://localhost:5221"
458
+ }) => {
459
+ const [alerts, setAlerts] = (0, import_react7.useState)([]);
460
+ const [loading, setLoading] = (0, import_react7.useState)(true);
461
+ (0, import_react7.useEffect)(() => {
462
+ fetchAlerts();
463
+ }, []);
464
+ const fetchAlerts = async () => {
465
+ try {
466
+ const response = await fetch(`${apiUrl}/api/insurance/fraud/alerts`);
467
+ if (response.ok) {
468
+ const data = await response.json();
469
+ setAlerts(data);
470
+ }
471
+ } catch (error) {
472
+ console.error("Failed to fetch fraud alerts:", error);
473
+ } finally {
474
+ setLoading(false);
475
+ }
476
+ };
477
+ const getSeverityColor = (severity) => {
478
+ switch (severity.toLowerCase()) {
479
+ case "high":
480
+ return "bg-red-100 text-red-800 border-red-200";
481
+ case "medium":
482
+ return "bg-yellow-100 text-yellow-800 border-yellow-200";
483
+ case "low":
484
+ return "bg-blue-100 text-blue-800 border-blue-200";
485
+ default:
486
+ return "bg-gray-100 text-gray-800 border-gray-200";
487
+ }
488
+ };
489
+ if (loading) return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "p-4", children: "Loading fraud alerts..." });
490
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "bg-white p-6 rounded-lg border border-gray-200 shadow-sm", children: [
491
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex justify-between items-center mb-4", children: [
492
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("h3", { className: "text-lg font-medium text-gray-900", children: "Fraud Detection" }),
493
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className: "px-3 py-1 bg-red-100 text-red-800 rounded-full text-sm font-medium", children: [
494
+ alerts.length,
495
+ " Active Alerts"
496
+ ] })
497
+ ] }),
498
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "space-y-3", children: alerts.map((alert) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: `p-4 border-2 rounded-lg ${getSeverityColor(alert.severity)}`, children: [
499
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex justify-between items-start mb-2", children: [
500
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { children: [
501
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("h4", { className: "font-medium", children: alert.type.replace(/_/g, " ").toUpperCase() }),
502
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { className: "text-sm mt-1", children: alert.description })
503
+ ] }),
504
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "px-2 py-1 bg-white rounded text-xs font-medium", children: alert.severity })
505
+ ] }),
506
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex justify-between items-center mt-3 text-xs", children: [
507
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { children: [
508
+ "Claim: ",
509
+ alert.claimId
510
+ ] }),
511
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: new Date(alert.detectedDate).toLocaleString() })
512
+ ] })
513
+ ] }, alert.id)) })
514
+ ] });
515
+ };
516
+
517
+ // src/components/insurance/premium/PremiumCalculator.tsx
518
+ var import_react8 = require("react");
519
+ var import_jsx_runtime8 = require("react/jsx-runtime");
520
+ var PremiumCalculator = ({
521
+ apiUrl = "http://localhost:5221"
522
+ }) => {
523
+ const [coverageAmount, setCoverageAmount] = (0, import_react8.useState)(1e5);
524
+ const [age, setAge] = (0, import_react8.useState)(35);
525
+ const [riskScore, setRiskScore] = (0, import_react8.useState)(30);
526
+ const [result, setResult] = (0, import_react8.useState)(null);
527
+ const [loading, setLoading] = (0, import_react8.useState)(false);
528
+ const calculate = async () => {
529
+ setLoading(true);
530
+ try {
531
+ const response = await fetch(`${apiUrl}/api/insurance/premium/calculate`, {
532
+ method: "POST",
533
+ headers: { "Content-Type": "application/json" },
534
+ body: JSON.stringify({ coverageAmount, age, riskScore })
535
+ });
536
+ if (response.ok) {
537
+ const data = await response.json();
538
+ setResult(data);
539
+ }
540
+ } catch (error) {
541
+ console.error("Failed to calculate premium:", error);
542
+ } finally {
543
+ setLoading(false);
544
+ }
545
+ };
546
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "bg-white p-6 rounded-lg border border-gray-200 shadow-sm", children: [
547
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("h3", { className: "text-lg font-medium text-gray-900 mb-4", children: "Premium Calculator" }),
548
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "space-y-4 mb-6", children: [
549
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { children: [
550
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("label", { className: "block text-sm font-medium text-gray-700 mb-1", children: [
551
+ "Coverage Amount: $",
552
+ coverageAmount.toLocaleString()
553
+ ] }),
554
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
555
+ "input",
556
+ {
557
+ type: "range",
558
+ min: "10000",
559
+ max: "1000000",
560
+ step: "10000",
561
+ value: coverageAmount,
562
+ onChange: (e) => setCoverageAmount(Number(e.target.value)),
563
+ className: "w-full"
564
+ }
565
+ )
566
+ ] }),
567
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { children: [
568
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("label", { className: "block text-sm font-medium text-gray-700 mb-1", children: [
569
+ "Age: ",
570
+ age
571
+ ] }),
572
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
573
+ "input",
574
+ {
575
+ type: "range",
576
+ min: "18",
577
+ max: "80",
578
+ value: age,
579
+ onChange: (e) => setAge(Number(e.target.value)),
580
+ className: "w-full"
581
+ }
582
+ )
583
+ ] }),
584
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { children: [
585
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("label", { className: "block text-sm font-medium text-gray-700 mb-1", children: [
586
+ "Risk Score: ",
587
+ riskScore
588
+ ] }),
589
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
590
+ "input",
591
+ {
592
+ type: "range",
593
+ min: "0",
594
+ max: "100",
595
+ value: riskScore,
596
+ onChange: (e) => setRiskScore(Number(e.target.value)),
597
+ className: "w-full"
598
+ }
599
+ )
600
+ ] })
601
+ ] }),
602
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
603
+ "button",
604
+ {
605
+ onClick: calculate,
606
+ disabled: loading,
607
+ className: "w-full bg-primus-600 text-white py-2 px-4 rounded hover:bg-primus-700 disabled:opacity-50",
608
+ children: loading ? "Calculating..." : "Calculate Premium"
609
+ }
610
+ ),
611
+ result && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "mt-6 p-4 bg-gray-50 rounded-lg", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "grid grid-cols-2 gap-4", children: [
612
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { children: [
613
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { className: "text-sm text-gray-600", children: "Monthly Premium" }),
614
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("p", { className: "text-2xl font-bold text-gray-900", children: [
615
+ "$",
616
+ result.monthlyPremium
617
+ ] })
618
+ ] }),
619
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { children: [
620
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { className: "text-sm text-gray-600", children: "Annual Premium" }),
621
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("p", { className: "text-2xl font-bold text-gray-900", children: [
622
+ "$",
623
+ result.annualPremium
624
+ ] })
625
+ ] })
626
+ ] }) })
627
+ ] });
628
+ };
629
+
630
+ // src/components/ai/AICopilot.tsx
631
+ var import_react9 = require("react");
632
+ var import_jsx_runtime9 = require("react/jsx-runtime");
633
+ var AICopilot = ({
634
+ apiUrl = "http://localhost:5221"
635
+ }) => {
636
+ const [messages, setMessages] = (0, import_react9.useState)([]);
637
+ const [input, setInput] = (0, import_react9.useState)("");
638
+ const [loading, setLoading] = (0, import_react9.useState)(false);
639
+ const sendMessage = async () => {
640
+ if (!input.trim()) return;
641
+ const userMessage = { role: "user", content: input };
642
+ setMessages((prev) => [...prev, userMessage]);
643
+ setInput("");
644
+ setLoading(true);
645
+ try {
646
+ const response = await fetch(`${apiUrl}/api/ai/chat`, {
647
+ method: "POST",
648
+ headers: { "Content-Type": "application/json" },
649
+ body: JSON.stringify({ message: input })
650
+ });
651
+ if (response.ok) {
652
+ const data = await response.json();
653
+ setMessages((prev) => [...prev, { role: "assistant", content: data.message }]);
654
+ }
655
+ } catch (error) {
656
+ console.error("Failed to send message:", error);
657
+ } finally {
658
+ setLoading(false);
659
+ }
660
+ };
661
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "bg-white rounded-lg border border-gray-200 shadow-sm flex flex-col h-[600px]", children: [
662
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "p-4 border-b border-gray-200", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("h3", { className: "text-lg font-medium text-gray-900", children: "AI Copilot" }) }),
663
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex-1 overflow-y-auto p-4 space-y-4", children: [
664
+ messages.map((msg, index) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: `flex ${msg.role === "user" ? "justify-end" : "justify-start"}`, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: `max-w-[70%] p-3 rounded-lg ${msg.role === "user" ? "bg-primus-600 text-white" : "bg-gray-100 text-gray-900"}`, children: msg.content }) }, index)),
665
+ loading && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "flex justify-start", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "bg-gray-100 p-3 rounded-lg", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex gap-1", children: [
666
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "w-2 h-2 bg-gray-400 rounded-full animate-bounce" }),
667
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "w-2 h-2 bg-gray-400 rounded-full animate-bounce", style: { animationDelay: "0.1s" } }),
668
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "w-2 h-2 bg-gray-400 rounded-full animate-bounce", style: { animationDelay: "0.2s" } })
669
+ ] }) }) })
670
+ ] }),
671
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "p-4 border-t border-gray-200", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex gap-2", children: [
672
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
673
+ "input",
674
+ {
675
+ type: "text",
676
+ value: input,
677
+ onChange: (e) => setInput(e.target.value),
678
+ onKeyPress: (e) => e.key === "Enter" && sendMessage(),
679
+ placeholder: "Ask me anything...",
680
+ className: "flex-1 px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-primus-500",
681
+ disabled: loading
682
+ }
683
+ ),
684
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
685
+ "button",
686
+ {
687
+ onClick: sendMessage,
688
+ disabled: loading || !input.trim(),
689
+ className: "px-4 py-2 bg-primus-600 text-white rounded-lg hover:bg-primus-700 disabled:opacity-50",
690
+ children: "Send"
691
+ }
692
+ )
693
+ ] }) })
694
+ ] });
695
+ };
696
+
697
+ // src/components/storage/FileUploader.tsx
698
+ var import_react10 = require("react");
699
+ var import_jsx_runtime10 = require("react/jsx-runtime");
700
+ var FileUploader = ({
701
+ apiUrl = "http://localhost:5221",
702
+ onUploadComplete
703
+ }) => {
704
+ const [uploading, setUploading] = (0, import_react10.useState)(false);
705
+ const [dragActive, setDragActive] = (0, import_react10.useState)(false);
706
+ const handleUpload = async (file) => {
707
+ setUploading(true);
708
+ const formData = new FormData();
709
+ formData.append("file", file);
710
+ try {
711
+ const response = await fetch(`${apiUrl}/api/storage/upload`, {
712
+ method: "POST",
713
+ body: formData
714
+ });
715
+ if (response.ok) {
716
+ const data = await response.json();
717
+ onUploadComplete?.(data);
718
+ }
719
+ } catch (error) {
720
+ console.error("Upload failed:", error);
721
+ } finally {
722
+ setUploading(false);
723
+ }
724
+ };
725
+ const handleDrop = (e) => {
726
+ e.preventDefault();
727
+ setDragActive(false);
728
+ if (e.dataTransfer.files && e.dataTransfer.files[0]) {
729
+ handleUpload(e.dataTransfer.files[0]);
730
+ }
731
+ };
732
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "bg-white p-6 rounded-lg border border-gray-200 shadow-sm", children: [
733
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("h3", { className: "text-lg font-medium text-gray-900 mb-4", children: "Upload File" }),
734
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
735
+ "div",
736
+ {
737
+ className: `border-2 border-dashed rounded-lg p-8 text-center ${dragActive ? "border-primus-500 bg-primus-50" : "border-gray-300"}`,
738
+ onDragOver: (e) => {
739
+ e.preventDefault();
740
+ setDragActive(true);
741
+ },
742
+ onDragLeave: () => setDragActive(false),
743
+ onDrop: handleDrop,
744
+ children: uploading ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "text-gray-600", children: "Uploading..." }) : /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
745
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("svg", { className: "mx-auto h-12 w-12 text-gray-400", stroke: "currentColor", fill: "none", viewBox: "0 0 48 48", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M28 8H12a4 4 0 00-4 4v20m32-12v8m0 0v8a4 4 0 01-4 4H12a4 4 0 01-4-4v-4m32-4l-3.172-3.172a4 4 0 00-5.656 0L28 28M8 32l9.172-9.172a4 4 0 015.656 0L28 28m0 0l4 4m4-24h8m-4-4v8m-12 4h.02", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round" }) }),
746
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "mt-2 text-sm text-gray-600", children: "Drag and drop a file here, or click to select" }),
747
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
748
+ "input",
749
+ {
750
+ type: "file",
751
+ className: "hidden",
752
+ id: "file-upload",
753
+ onChange: (e) => e.target.files?.[0] && handleUpload(e.target.files[0])
754
+ }
755
+ ),
756
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
757
+ "label",
758
+ {
759
+ htmlFor: "file-upload",
760
+ className: "mt-4 inline-block px-4 py-2 bg-primus-600 text-white rounded cursor-pointer hover:bg-primus-700",
761
+ children: "Select File"
762
+ }
763
+ )
764
+ ] })
765
+ }
766
+ )
767
+ ] });
768
+ };
769
+
770
+ // src/components/security/SecurityDashboard.tsx
771
+ var import_react11 = require("react");
772
+ var import_jsx_runtime11 = require("react/jsx-runtime");
773
+ var SecurityDashboard = ({
774
+ apiUrl = "http://localhost:5221"
775
+ }) => {
776
+ const [vulnerabilities, setVulnerabilities] = (0, import_react11.useState)([]);
777
+ const [loading, setLoading] = (0, import_react11.useState)(true);
778
+ (0, import_react11.useEffect)(() => {
779
+ fetchVulnerabilities();
780
+ }, []);
781
+ const fetchVulnerabilities = async () => {
782
+ try {
783
+ const response = await fetch(`${apiUrl}/api/security/vulnerabilities`);
784
+ if (response.ok) {
785
+ const data = await response.json();
786
+ setVulnerabilities(data);
787
+ }
788
+ } catch (error) {
789
+ console.error("Failed to fetch vulnerabilities:", error);
790
+ } finally {
791
+ setLoading(false);
792
+ }
793
+ };
794
+ const getSeverityColor = (severity) => {
795
+ switch (severity.toLowerCase()) {
796
+ case "critical":
797
+ return "bg-red-100 text-red-800";
798
+ case "high":
799
+ return "bg-orange-100 text-orange-800";
800
+ case "medium":
801
+ return "bg-yellow-100 text-yellow-800";
802
+ case "low":
803
+ return "bg-blue-100 text-blue-800";
804
+ default:
805
+ return "bg-gray-100 text-gray-800";
806
+ }
807
+ };
808
+ if (loading) return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "p-4", children: "Scanning for vulnerabilities..." });
809
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "bg-white p-6 rounded-lg border border-gray-200 shadow-sm", children: [
810
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex justify-between items-center mb-4", children: [
811
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("h3", { className: "text-lg font-medium text-gray-900", children: "Security Dashboard" }),
812
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
813
+ "button",
814
+ {
815
+ onClick: fetchVulnerabilities,
816
+ className: "px-3 py-1 bg-primus-600 text-white rounded text-sm hover:bg-primus-700",
817
+ children: "Rescan"
818
+ }
819
+ )
820
+ ] }),
821
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "space-y-3", children: vulnerabilities.map((vuln) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "p-4 border border-gray-200 rounded-lg", children: [
822
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex justify-between items-start mb-2", children: [
823
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("h4", { className: "font-medium text-gray-900", children: vuln.title }),
824
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: `px-2 py-1 rounded text-xs font-medium ${getSeverityColor(vuln.severity)}`, children: vuln.severity })
825
+ ] }),
826
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "text-sm text-gray-600 mb-2", children: vuln.description }),
827
+ vuln.file && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("p", { className: "text-xs text-gray-500 mb-2", children: [
828
+ vuln.file,
829
+ vuln.line ? `:${vuln.line}` : ""
830
+ ] }),
831
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("p", { className: "text-sm text-primus-600", children: [
832
+ "\u{1F4A1} ",
833
+ vuln.recommendation
834
+ ] })
835
+ ] }, vuln.id)) })
836
+ ] });
837
+ };
838
+
839
+ // src/components/auth/PrimusLogin.tsx
840
+ var import_react13 = require("react");
841
+
842
+ // src/context/PrimusThemeProvider.tsx
843
+ var import_react12 = require("react");
844
+ var import_jsx_runtime12 = require("react/jsx-runtime");
845
+ var themeColors = {
846
+ light: {
847
+ bg: "bg-white",
848
+ bgSecondary: "bg-gray-50",
849
+ bgTertiary: "bg-gray-100",
850
+ bgHover: "hover:bg-gray-100",
851
+ border: "border-gray-200",
852
+ borderSecondary: "border-gray-100",
853
+ text: "text-gray-900",
854
+ textSecondary: "text-gray-600",
855
+ textMuted: "text-gray-400",
856
+ accent: "bg-violet-600",
857
+ accentHover: "hover:bg-violet-500",
858
+ accentText: "text-violet-600",
859
+ badge: "bg-orange-500",
860
+ success: "text-emerald-600",
861
+ warning: "text-amber-600",
862
+ error: "text-rose-600",
863
+ info: "text-blue-600"
864
+ },
865
+ dark: {
866
+ bg: "bg-gray-900",
867
+ bgSecondary: "bg-gray-800",
868
+ bgTertiary: "bg-gray-800/50",
869
+ bgHover: "hover:bg-gray-800",
870
+ border: "border-gray-700",
871
+ borderSecondary: "border-gray-800",
872
+ text: "text-white",
873
+ textSecondary: "text-gray-400",
874
+ textMuted: "text-gray-500",
875
+ accent: "bg-blue-600",
876
+ accentHover: "hover:bg-blue-500",
877
+ accentText: "text-blue-400",
878
+ badge: "bg-rose-500",
879
+ success: "text-emerald-400",
880
+ warning: "text-amber-400",
881
+ error: "text-rose-400",
882
+ info: "text-blue-400"
883
+ }
884
+ };
885
+ var PrimusThemeContext = (0, import_react12.createContext)(void 0);
886
+ function PrimusThemeProvider({ children, defaultTheme = "dark" }) {
887
+ const [theme, setTheme] = (0, import_react12.useState)(defaultTheme);
888
+ const toggleTheme = (0, import_react12.useCallback)(() => {
889
+ setTheme((prev) => prev === "dark" ? "light" : "dark");
890
+ }, []);
891
+ const value = {
892
+ theme,
893
+ colors: themeColors[theme],
894
+ setTheme,
895
+ toggleTheme
896
+ };
897
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(PrimusThemeContext.Provider, { value, children });
898
+ }
899
+ function usePrimusTheme() {
900
+ const context = (0, import_react12.useContext)(PrimusThemeContext);
901
+ if (!context) {
902
+ return {
903
+ theme: "light",
904
+ colors: themeColors.light,
905
+ setTheme: () => console.warn("PrimusThemeProvider not found"),
906
+ toggleTheme: () => console.warn("PrimusThemeProvider not found")
907
+ };
908
+ }
909
+ return context;
910
+ }
911
+ function PrimusThemeToggle() {
912
+ const { theme, toggleTheme, colors } = usePrimusTheme();
913
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
914
+ "button",
915
+ {
916
+ onClick: toggleTheme,
917
+ className: `p-2 rounded-lg ${colors.bgHover} transition-colors`,
918
+ title: `Switch to ${theme === "dark" ? "light" : "dark"} mode`,
919
+ children: theme === "dark" ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("svg", { className: "h-5 w-5 text-yellow-400", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z" }) }) : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("svg", { className: "h-5 w-5 text-gray-600", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M20.354 15.354A9 9 0 018.646 3.646 9.003 9.003 0 0012 21a9.003 9.003 0 008.354-5.646z" }) })
920
+ }
921
+ );
922
+ }
923
+
924
+ // src/components/auth/PrimusLogin.tsx
925
+ var import_jsx_runtime13 = require("react/jsx-runtime");
926
+ var providerConfigs = {
927
+ google: {
928
+ name: "Google",
929
+ icon: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("svg", { className: "h-5 w-5", viewBox: "0 0 24 24", children: [
930
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { fill: "#4285F4", d: "M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z" }),
931
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { fill: "#34A853", d: "M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z" }),
932
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { fill: "#FBBC05", d: "M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z" }),
933
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { fill: "#EA4335", d: "M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z" })
934
+ ] }),
935
+ 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" }
936
+ },
937
+ azure: {
938
+ name: "Microsoft",
939
+ icon: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("svg", { className: "h-5 w-5", viewBox: "0 0 23 23", children: [
940
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { fill: "#f35325", d: "M1 1h10v10H1z" }),
941
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { fill: "#81bc06", d: "M12 1h10v10H12z" }),
942
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { fill: "#05a6f0", d: "M1 12h10v10H1z" }),
943
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { fill: "#ffba08", d: "M12 12h10v10H12z" })
944
+ ] }),
945
+ 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" }
946
+ },
947
+ github: {
948
+ name: "GitHub",
949
+ icon: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("svg", { className: "h-5 w-5", fill: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { fillRule: "evenodd", d: "M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z", clipRule: "evenodd" }) }),
950
+ 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" }
951
+ },
952
+ microsoft: {
953
+ name: "Microsoft",
954
+ icon: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("svg", { className: "h-5 w-5", viewBox: "0 0 24 24", children: [
955
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { fill: "#F25022", d: "M1 1h10v10H1z" }),
956
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { fill: "#00A4EF", d: "M1 13h10v10H1z" }),
957
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { fill: "#7FBA00", d: "M13 1h10v10H13z" }),
958
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { fill: "#FFB900", d: "M13 13h10v10H13z" })
959
+ ] }),
960
+ 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" }
961
+ },
962
+ apple: {
963
+ name: "Apple",
964
+ icon: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("svg", { className: "h-5 w-5", fill: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { d: "M18.71 19.5c-.83 1.24-1.71 2.45-3.05 2.47-1.34.03-1.77-.79-3.29-.79-1.53 0-2 .77-3.27.82-1.31.05-2.3-1.32-3.14-2.53C4.25 17 2.94 12.45 4.7 9.39c.87-1.52 2.43-2.48 4.12-2.51 1.28-.02 2.5.87 3.29.87.78 0 2.26-1.07 3.81-.91.65.03 2.47.26 3.64 1.98-.09.06-2.17 1.28-2.15 3.81.03 3.02 2.65 4.03 2.68 4.04-.03.07-.42 1.44-1.38 2.83M13 3.5c.73-.83 1.94-1.46 2.94-1.5.13 1.17-.34 2.35-1.04 3.19-.69.85-1.83 1.51-2.95 1.42-.15-1.15.41-2.35 1.05-3.11z" }) }),
965
+ colors: { light: "bg-black hover:bg-gray-900 text-white border-black", dark: "bg-white hover:bg-gray-100 text-black border-gray-300" }
966
+ },
967
+ facebook: {
968
+ name: "Facebook",
969
+ icon: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("svg", { className: "h-5 w-5", fill: "white", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { d: "M24 12.073c0-6.627-5.373-12-12-12s-12 5.373-12 12c0 5.99 4.388 10.954 10.125 11.854v-8.385H7.078v-3.47h3.047V9.43c0-3.007 1.792-4.669 4.533-4.669 1.312 0 2.686.235 2.686.235v2.953H15.83c-1.491 0-1.956.925-1.956 1.874v2.25h3.328l-.532 3.47h-2.796v8.385C19.612 23.027 24 18.062 24 12.073z" }) }),
970
+ colors: { light: "bg-[#1877F2] hover:bg-[#166FE5] text-white border-[#1877F2]", dark: "bg-[#1877F2] hover:bg-[#166FE5] text-white border-[#1877F2]" }
971
+ }
972
+ };
973
+ function PrimusLogin({
974
+ onLogin,
975
+ socialProviders = [],
976
+ onSocialLogin,
977
+ authEndpoint = "/api/auth",
978
+ showEmailLogin = true,
979
+ title = "Welcome Back",
980
+ subtitle = "Enter your credentials to continue",
981
+ logo,
982
+ theme: themeOverride
983
+ }) {
984
+ const themeContext = usePrimusTheme();
985
+ const theme = themeOverride || themeContext.theme;
986
+ const isLight = theme === "light";
987
+ const [username, setUsername] = (0, import_react13.useState)("");
988
+ const [password, setPassword] = (0, import_react13.useState)("");
989
+ const [loading, setLoading] = (0, import_react13.useState)(false);
990
+ const handleSubmit = async (e) => {
991
+ e.preventDefault();
992
+ if (!username || !password) return;
993
+ setLoading(true);
994
+ try {
995
+ onLogin?.({ username, password });
996
+ } finally {
997
+ setLoading(false);
998
+ }
999
+ };
1000
+ const handleSocialClick = (provider) => {
1001
+ if (onSocialLogin) {
1002
+ onSocialLogin(provider);
1003
+ } else {
1004
+ window.location.href = `${authEndpoint}/${provider}`;
1005
+ }
1006
+ };
1007
+ const bgGradient = isLight ? "bg-gradient-to-br from-gray-50 via-white to-violet-50" : "bg-gray-950";
1008
+ const cardBg = isLight ? "bg-white border-gray-200 shadow-xl" : "bg-gray-900/50 border-white/10";
1009
+ const headingColor = isLight ? "text-gray-900" : "text-white";
1010
+ const subtextColor = isLight ? "text-gray-500" : "text-slate-400";
1011
+ const labelColor = isLight ? "text-gray-600" : "text-slate-300";
1012
+ const inputClasses = isLight ? "bg-gray-50 border-gray-300 text-gray-900 placeholder:text-gray-400 focus:border-violet-500 focus:ring-violet-500" : "bg-gray-950/50 border-slate-700 text-white placeholder:text-slate-600 focus:border-blue-500 focus:ring-blue-500";
1013
+ const buttonGradient = isLight ? "bg-gradient-to-r from-violet-600 to-purple-600" : "bg-gradient-to-r from-blue-600 to-indigo-600";
1014
+ const logoBg = isLight ? "bg-violet-600 shadow-violet-500/20" : "bg-blue-600 shadow-blue-500/20";
1015
+ const dividerColor = isLight ? "border-gray-200" : "border-slate-700";
1016
+ const hasSocial = socialProviders.length > 0;
1017
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: `min-h-screen ${bgGradient} flex items-center justify-center p-4`, children: [
1018
+ !isLight && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "absolute inset-0 overflow-hidden", children: [
1019
+ /* @__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]" }),
1020
+ /* @__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]" })
1021
+ ] }),
1022
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: `w-full max-w-md ${cardBg} p-8 rounded-2xl border backdrop-blur-xl relative z-10`, children: [
1023
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "text-center mb-8", children: [
1024
+ logo ? typeof logo === "string" ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("img", { src: logo, alt: "Logo", className: "h-12 w-12 mx-auto mb-4 rounded-xl" }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "mb-4", children: logo }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: `h-12 w-12 ${logoBg} rounded-xl mx-auto flex items-center justify-center mb-4 shadow-lg`, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "font-bold text-xl text-white", children: "P" }) }),
1025
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("h1", { className: `text-2xl font-bold ${headingColor} tracking-tight`, children: title }),
1026
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { className: `${subtextColor} text-sm mt-2`, children: subtitle })
1027
+ ] }),
1028
+ hasSocial && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "space-y-3 mb-6", children: socialProviders.map((provider) => {
1029
+ const config = providerConfigs[provider];
1030
+ if (!config) return null;
1031
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
1032
+ "button",
1033
+ {
1034
+ onClick: () => handleSocialClick(provider),
1035
+ className: `w-full flex items-center justify-center gap-3 px-4 py-2.5 border rounded-lg font-medium text-sm transition-all duration-200 ${isLight ? config.colors.light : config.colors.dark}`,
1036
+ children: [
1037
+ config.icon,
1038
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { children: [
1039
+ "Continue with ",
1040
+ config.name
1041
+ ] })
1042
+ ]
1043
+ },
1044
+ provider
1045
+ );
1046
+ }) }),
1047
+ hasSocial && showEmailLogin && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "relative my-6", children: [
1048
+ /* @__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}` }) }),
1049
+ /* @__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" }) })
1050
+ ] }),
1051
+ showEmailLogin && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("form", { onSubmit: handleSubmit, className: "space-y-4", children: [
1052
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "space-y-2", children: [
1053
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("label", { className: `text-xs font-medium ${labelColor} ml-1`, children: "EMAIL" }),
1054
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1055
+ "input",
1056
+ {
1057
+ type: "text",
1058
+ value: username,
1059
+ onChange: (e) => setUsername(e.target.value),
1060
+ className: `w-full px-4 py-2.5 ${inputClasses} border rounded-lg focus:outline-none focus:ring-1 transition-all text-sm`,
1061
+ placeholder: "you@example.com"
1062
+ }
1063
+ )
1064
+ ] }),
1065
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "space-y-2", children: [
1066
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("label", { className: `text-xs font-medium ${labelColor} ml-1`, children: "PASSWORD" }),
1067
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1068
+ "input",
1069
+ {
1070
+ type: "password",
1071
+ value: password,
1072
+ onChange: (e) => setPassword(e.target.value),
1073
+ className: `w-full px-4 py-2.5 ${inputClasses} border rounded-lg focus:outline-none focus:ring-1 transition-all text-sm`,
1074
+ placeholder: "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022"
1075
+ }
1076
+ )
1077
+ ] }),
1078
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1079
+ "button",
1080
+ {
1081
+ type: "submit",
1082
+ disabled: loading,
1083
+ className: `w-full mt-4 py-2.5 ${buttonGradient} text-white font-medium rounded-lg hover:opacity-90 transition-opacity disabled:opacity-50`,
1084
+ children: loading ? "Signing in..." : "Sign In"
1085
+ }
1086
+ )
1087
+ ] })
1088
+ ] })
1089
+ ] });
1090
+ }
1091
+ var LoginPage = PrimusLogin;
1092
+
1093
+ // src/context/PrimusProvider.tsx
1094
+ var import_react14 = require("react");
1095
+ var import_jsx_runtime14 = require("react/jsx-runtime");
1096
+ var PrimusAuthContext = (0, import_react14.createContext)(void 0);
1097
+ var PrimusProvider = ({
1098
+ children,
1099
+ authority,
1100
+ clientId,
1101
+ onLoginSuccess,
1102
+ onLoginError
1103
+ }) => {
1104
+ void clientId;
1105
+ const [isAuthenticated, setIsAuthenticated] = (0, import_react14.useState)(false);
1106
+ const [user, setUser] = (0, import_react14.useState)(null);
1107
+ const [token, setToken] = (0, import_react14.useState)(null);
1108
+ const [isLoading, setIsLoading] = (0, import_react14.useState)(false);
1109
+ (0, import_react14.useEffect)(() => {
1110
+ const storedToken = localStorage.getItem("primus_token");
1111
+ const storedUser = localStorage.getItem("primus_user");
1112
+ if (storedToken && storedUser) {
1113
+ try {
1114
+ setToken(storedToken);
1115
+ setUser(JSON.parse(storedUser));
1116
+ setIsAuthenticated(true);
1117
+ } catch {
1118
+ localStorage.removeItem("primus_token");
1119
+ localStorage.removeItem("primus_user");
1120
+ }
1121
+ }
1122
+ }, []);
1123
+ const login = (0, import_react14.useCallback)(async (credentials) => {
1124
+ setIsLoading(true);
1125
+ try {
1126
+ let endpoint;
1127
+ let body;
1128
+ if ("provider" in credentials) {
1129
+ endpoint = `${authority}/auth/${credentials.provider}`;
1130
+ body = {};
1131
+ } else {
1132
+ endpoint = `${authority}/auth/local`;
1133
+ body = { email: credentials.email, password: credentials.password };
1134
+ }
1135
+ const response = await fetch(endpoint, {
1136
+ method: "POST",
1137
+ headers: { "Content-Type": "application/json" },
1138
+ body: JSON.stringify(body)
1139
+ });
1140
+ if (!response.ok) {
1141
+ const errorData = await response.json().catch(() => ({}));
1142
+ const errorMsg = errorData.message || `Login failed (${response.status})`;
1143
+ onLoginError?.(errorMsg);
1144
+ return { success: false, error: errorMsg };
1145
+ }
1146
+ const data = await response.json();
1147
+ const accessToken = data.access_token || data.token;
1148
+ const userData = data.user || {
1149
+ name: "Authenticated User",
1150
+ email: "provider" in credentials ? `${credentials.provider}@primus.local` : credentials.email
1151
+ };
1152
+ localStorage.setItem("primus_token", accessToken);
1153
+ localStorage.setItem("primus_user", JSON.stringify(userData));
1154
+ setToken(accessToken);
1155
+ setUser(userData);
1156
+ setIsAuthenticated(true);
1157
+ onLoginSuccess?.(userData, accessToken);
1158
+ return { success: true };
1159
+ } catch (err) {
1160
+ const errorMsg = err instanceof Error ? err.message : "Network error";
1161
+ onLoginError?.(errorMsg);
1162
+ return { success: false, error: errorMsg };
1163
+ } finally {
1164
+ setIsLoading(false);
1165
+ }
1166
+ }, [authority, onLoginSuccess, onLoginError]);
1167
+ const logout = (0, import_react14.useCallback)(async () => {
1168
+ localStorage.removeItem("primus_token");
1169
+ localStorage.removeItem("primus_user");
1170
+ setToken(null);
1171
+ setIsAuthenticated(false);
1172
+ setUser(null);
1173
+ }, []);
1174
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(PrimusAuthContext.Provider, { value: { isAuthenticated, user, login, logout, token, isLoading }, children });
1175
+ };
1176
+ var usePrimusAuth = () => {
1177
+ const context = (0, import_react14.useContext)(PrimusAuthContext);
1178
+ if (context === void 0) {
1179
+ return {
1180
+ isAuthenticated: false,
1181
+ user: null,
1182
+ login: async () => ({ success: false, error: "PrimusProvider not configured" }),
1183
+ logout: async () => {
1184
+ },
1185
+ token: null,
1186
+ isLoading: false
1187
+ };
1188
+ }
1189
+ return context;
1190
+ };
1191
+
1192
+ // src/components/shared/Button.tsx
1193
+ var import_react15 = __toESM(require("react"));
1194
+ var import_clsx = require("clsx");
1195
+ var import_tailwind_merge = require("tailwind-merge");
1196
+ var import_jsx_runtime15 = require("react/jsx-runtime");
1197
+ function cn(...inputs) {
1198
+ return (0, import_tailwind_merge.twMerge)((0, import_clsx.clsx)(inputs));
1199
+ }
1200
+ var Button = import_react15.default.forwardRef(
1201
+ ({ className, variant = "primary", size = "md", ...props }, ref) => {
1202
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1203
+ "button",
1204
+ {
1205
+ ref,
1206
+ className: cn(
1207
+ "inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-white transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-gray-950 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
1208
+ {
1209
+ "bg-gray-900 text-gray-50 hover:bg-gray-900/90": variant === "primary",
1210
+ "bg-gray-100 text-gray-900 hover:bg-gray-100/80": variant === "secondary",
1211
+ "border border-gray-200 bg-white hover:bg-gray-100 hover:text-gray-900": variant === "outline",
1212
+ "hover:bg-gray-100 hover:text-gray-900": variant === "ghost",
1213
+ "h-9 px-3": size === "sm",
1214
+ "h-10 px-4 py-2": size === "md",
1215
+ "h-11 px-8": size === "lg"
1216
+ },
1217
+ className
1218
+ ),
1219
+ ...props
1220
+ }
1221
+ );
1222
+ }
1223
+ );
1224
+
1225
+ // src/components/auth/UserProfile.tsx
1226
+ var import_jsx_runtime16 = require("react/jsx-runtime");
1227
+ var UserProfile = () => {
1228
+ const { user, logout, isAuthenticated } = usePrimusAuth();
1229
+ if (!isAuthenticated || !user) {
1230
+ return null;
1231
+ }
1232
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex items-center gap-4 p-4 rounded-lg bg-gray-50 border border-gray-200", children: [
1233
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "h-10 w-10 rounded-full bg-primus-100 flex items-center justify-center text-primus-600 font-bold", children: user.name?.charAt(0) || "U" }),
1234
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex-1", children: [
1235
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { className: "text-sm font-medium text-gray-900", children: user.name }),
1236
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { className: "text-xs text-gray-500", children: user.email })
1237
+ ] }),
1238
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Button, { variant: "outline", size: "sm", onClick: () => logout(), children: "Sign out" })
1239
+ ] });
1240
+ };
1241
+
1242
+ // src/hooks/useNotifications.ts
1243
+ var import_react16 = require("react");
1244
+ var useNotifications = (apiUrl = "http://localhost:5221") => {
1245
+ const [notifications, setNotifications] = (0, import_react16.useState)([]);
1246
+ const [unreadCount, setUnreadCount] = (0, import_react16.useState)(0);
1247
+ const [loading, setLoading] = (0, import_react16.useState)(true);
1248
+ (0, import_react16.useEffect)(() => {
1249
+ fetchNotifications();
1250
+ const interval = setInterval(fetchNotifications, 3e3);
1251
+ return () => clearInterval(interval);
1252
+ }, []);
1253
+ const fetchNotifications = async () => {
1254
+ try {
1255
+ const response = await fetch(`${apiUrl}/notifications`);
1256
+ if (response.ok) {
1257
+ const data = await response.json();
1258
+ setNotifications(data);
1259
+ setUnreadCount(data.filter((n) => !n.read).length);
1260
+ }
1261
+ } catch (error) {
1262
+ console.error("Failed to fetch notifications:", error);
1263
+ } finally {
1264
+ setLoading(false);
1265
+ }
1266
+ };
1267
+ const markAsRead = (id) => {
1268
+ setNotifications((prev) => prev.map((n) => n.id === id ? { ...n, read: true } : n));
1269
+ setUnreadCount((prev) => Math.max(0, prev - 1));
1270
+ };
1271
+ const markAllAsRead = () => {
1272
+ setNotifications((prev) => prev.map((n) => ({ ...n, read: true })));
1273
+ setUnreadCount(0);
1274
+ };
1275
+ return {
1276
+ notifications,
1277
+ unreadCount,
1278
+ loading,
1279
+ markAsRead,
1280
+ markAllAsRead,
1281
+ refresh: fetchNotifications
1282
+ };
1283
+ };
1284
+
1285
+ // src/components/notifications/NotificationFeed.tsx
1286
+ var import_outline = require("@heroicons/react/24/outline");
1287
+ var import_react17 = require("@headlessui/react");
1288
+ var import_react18 = require("react");
1289
+ var import_clsx2 = require("clsx");
1290
+ var import_jsx_runtime17 = require("react/jsx-runtime");
1291
+ var NotificationIcon = ({ type }) => {
1292
+ switch (type) {
1293
+ case "success":
1294
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_outline.CheckCircleIcon, { className: "h-6 w-6 text-green-500" });
1295
+ case "warning":
1296
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_outline.ExclamationTriangleIcon, { className: "h-6 w-6 text-yellow-500" });
1297
+ case "error":
1298
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_outline.XCircleIcon, { className: "h-6 w-6 text-red-500" });
1299
+ default:
1300
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_outline.InformationCircleIcon, { className: "h-6 w-6 text-blue-500" });
1301
+ }
1302
+ };
1303
+ var NotificationFeed = () => {
1304
+ const { notifications, unreadCount, markAsRead, markAllAsRead } = useNotifications();
1305
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_react17.Popover, { className: "relative", children: ({ open }) => /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
1306
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_react17.Popover.Button, { className: (0, import_clsx2.clsx)(
1307
+ "relative p-2 rounded-full hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-primus-500",
1308
+ open && "bg-gray-100"
1309
+ ), children: [
1310
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_outline.BellIcon, { className: "h-6 w-6 text-gray-600", "aria-hidden": "true" }),
1311
+ 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" })
1312
+ ] }),
1313
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1314
+ import_react17.Transition,
1315
+ {
1316
+ as: import_react18.Fragment,
1317
+ enter: "transition ease-out duration-200",
1318
+ enterFrom: "opacity-0 translate-y-1",
1319
+ enterTo: "opacity-100 translate-y-0",
1320
+ leave: "transition ease-in duration-150",
1321
+ leaveFrom: "opacity-100 translate-y-0",
1322
+ leaveTo: "opacity-0 translate-y-1",
1323
+ children: /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_react17.Popover.Panel, { className: "absolute right-0 z-10 mt-2 w-80 origin-top-right rounded-md bg-white py-1 shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none sm:w-96", children: [
1324
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "px-4 py-3 flex items-center justify-between border-b border-gray-100", children: [
1325
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("h3", { className: "text-sm font-semibold text-gray-900", children: "Notifications" }),
1326
+ unreadCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1327
+ "button",
1328
+ {
1329
+ onClick: () => markAllAsRead(),
1330
+ className: "text-xs font-medium text-primus-600 hover:text-primus-500",
1331
+ children: "Mark all as read"
1332
+ }
1333
+ )
1334
+ ] }),
1335
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "max-h-96 overflow-y-auto", children: notifications.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "px-4 py-6 text-center text-sm text-gray-500", children: "No new notifications" }) : /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "divide-y divide-gray-100", children: notifications.map((notification) => /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
1336
+ "div",
1337
+ {
1338
+ className: (0, import_clsx2.clsx)(
1339
+ "flex gap-3 px-4 py-4 hover:bg-gray-50 transition-colors cursor-pointer",
1340
+ !notification.read && "bg-blue-50/50"
1341
+ ),
1342
+ onClick: () => markAsRead(notification.id),
1343
+ children: [
1344
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "flex-shrink-0 mt-0.5", children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(NotificationIcon, { type: notification.type }) }),
1345
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "flex-1 min-w-0", children: [
1346
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { className: "text-sm font-medium text-gray-900", children: notification.title }),
1347
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { className: "text-sm text-gray-500 truncate", children: notification.message }),
1348
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { className: "mt-1 text-xs text-gray-400", children: new Date(notification.timestamp).toLocaleDateString() })
1349
+ ] }),
1350
+ !notification.read && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "flex-shrink-0 self-center", children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "block h-2 w-2 rounded-full bg-primus-500" }) })
1351
+ ]
1352
+ },
1353
+ notification.id
1354
+ )) }) }),
1355
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "border-t border-gray-100 px-4 py-2", children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("a", { href: "#", className: "block text-center text-sm font-medium text-primus-600 hover:text-primus-500", children: "View all notifications" }) })
1356
+ ] })
1357
+ }
1358
+ )
1359
+ ] }) });
1360
+ };
1361
+
1362
+ // src/components/notifications/PrimusNotificationCenter.tsx
1363
+ var import_react19 = require("react");
1364
+ var import_lucide_react = require("lucide-react");
1365
+ var import_jsx_runtime18 = require("react/jsx-runtime");
1366
+ var API_URL = "http://localhost:5222";
1367
+ function PrimusNotificationCenter({ theme: themeOverride, apiUrl = API_URL }) {
1368
+ const themeContext = usePrimusTheme();
1369
+ const theme = themeOverride || themeContext.theme;
1370
+ const t = themeColors[theme];
1371
+ const [notifications, setNotifications] = (0, import_react19.useState)([]);
1372
+ const [isOpen, setIsOpen] = (0, import_react19.useState)(false);
1373
+ const [showSendForm, setShowSendForm] = (0, import_react19.useState)(false);
1374
+ const [unreadCount, setUnreadCount] = (0, import_react19.useState)(0);
1375
+ const [newTitle, setNewTitle] = (0, import_react19.useState)("");
1376
+ const [newMessage, setNewMessage] = (0, import_react19.useState)("");
1377
+ const [newType, setNewType] = (0, import_react19.useState)("info");
1378
+ const [sending, setSending] = (0, import_react19.useState)(false);
1379
+ const fetchNotifications = (0, import_react19.useCallback)(async () => {
1380
+ try {
1381
+ const response = await fetch(`${apiUrl}/api/notifications`);
1382
+ if (response.ok) {
1383
+ const data = await response.json();
1384
+ setNotifications(data);
1385
+ setUnreadCount(data.filter((n) => !n.read).length);
1386
+ }
1387
+ } catch (error) {
1388
+ }
1389
+ }, [apiUrl]);
1390
+ (0, import_react19.useEffect)(() => {
1391
+ fetchNotifications();
1392
+ const interval = setInterval(fetchNotifications, 3e3);
1393
+ return () => clearInterval(interval);
1394
+ }, [fetchNotifications]);
1395
+ const sendNotification = async () => {
1396
+ if (!newTitle.trim() || !newMessage.trim()) return;
1397
+ setSending(true);
1398
+ try {
1399
+ const response = await fetch(`${apiUrl}/api/notifications`, {
1400
+ method: "POST",
1401
+ headers: { "Content-Type": "application/json" },
1402
+ body: JSON.stringify({ title: newTitle, message: newMessage, type: newType })
1403
+ });
1404
+ if (response.ok) {
1405
+ setNewTitle("");
1406
+ setNewMessage("");
1407
+ setNewType("info");
1408
+ setShowSendForm(false);
1409
+ await fetchNotifications();
1410
+ }
1411
+ } catch (error) {
1412
+ console.error("Failed to send notification");
1413
+ }
1414
+ setSending(false);
1415
+ };
1416
+ const markAsRead = async (id) => {
1417
+ try {
1418
+ await fetch(`${apiUrl}/api/notifications/${id}/read`, { method: "PUT" });
1419
+ setNotifications((prev) => prev.map((n) => n.id === id ? { ...n, read: true } : n));
1420
+ setUnreadCount((prev) => Math.max(0, prev - 1));
1421
+ } catch {
1422
+ }
1423
+ };
1424
+ const getTypeIcon = (type) => {
1425
+ const iconClass = "h-4 w-4";
1426
+ switch (type) {
1427
+ case "success":
1428
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_lucide_react.Check, { className: `${iconClass} ${t.success}` });
1429
+ case "warning":
1430
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_lucide_react.AlertTriangle, { className: `${iconClass} ${t.warning}` });
1431
+ case "error":
1432
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_lucide_react.AlertCircle, { className: `${iconClass} ${t.error}` });
1433
+ default:
1434
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_lucide_react.Info, { className: `${iconClass} ${t.info}` });
1435
+ }
1436
+ };
1437
+ const getTypeBg = (type) => {
1438
+ if (theme === "light") {
1439
+ switch (type) {
1440
+ case "success":
1441
+ return "bg-emerald-50 border-emerald-200";
1442
+ case "warning":
1443
+ return "bg-amber-50 border-amber-200";
1444
+ case "error":
1445
+ return "bg-rose-50 border-rose-200";
1446
+ default:
1447
+ return "bg-blue-50 border-blue-200";
1448
+ }
1449
+ } else {
1450
+ switch (type) {
1451
+ case "success":
1452
+ return "bg-emerald-900/20 border-emerald-800";
1453
+ case "warning":
1454
+ return "bg-amber-900/20 border-amber-800";
1455
+ case "error":
1456
+ return "bg-rose-900/20 border-rose-800";
1457
+ default:
1458
+ return "bg-blue-900/20 border-blue-800";
1459
+ }
1460
+ }
1461
+ };
1462
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "relative font-sans", children: [
1463
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
1464
+ "button",
1465
+ {
1466
+ onClick: () => setIsOpen(!isOpen),
1467
+ className: `relative p-2.5 rounded-xl ${t.bgHover} transition-all duration-200 group`,
1468
+ children: [
1469
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_lucide_react.Bell, { className: `h-5 w-5 ${t.textSecondary} group-hover:${t.accentText} transition-colors` }),
1470
+ unreadCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: `absolute -top-0.5 -right-0.5 h-5 w-5 ${t.badge} rounded-full flex items-center justify-center text-white text-xs font-bold shadow-lg animate-pulse`, children: unreadCount > 9 ? "9+" : unreadCount })
1471
+ ]
1472
+ }
1473
+ ),
1474
+ isOpen && /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_jsx_runtime18.Fragment, { children: [
1475
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "fixed inset-0 z-40", onClick: () => setIsOpen(false) }),
1476
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: `absolute right-0 mt-3 w-96 ${t.bg} border ${t.border} rounded-2xl shadow-2xl z-50 overflow-hidden`, children: [
1477
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: `px-5 py-4 border-b ${t.border} flex items-center justify-between`, children: [
1478
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "flex items-center gap-3", children: [
1479
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: `p-2 rounded-xl ${t.bgTertiary}`, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_lucide_react.Bell, { className: `h-5 w-5 ${t.accentText}` }) }),
1480
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { children: [
1481
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("h3", { className: `font-semibold ${t.text}`, children: "Notifications" }),
1482
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("p", { className: `text-xs ${t.textMuted}`, children: unreadCount > 0 ? `${unreadCount} unread` : "All caught up!" })
1483
+ ] })
1484
+ ] }),
1485
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("button", { onClick: () => setIsOpen(false), className: `p-1.5 rounded-lg ${t.bgHover} transition-colors`, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_lucide_react.X, { className: `h-4 w-4 ${t.textSecondary}` }) })
1486
+ ] }),
1487
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: `p-4 border-b ${t.border} ${t.bgSecondary}`, children: [
1488
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
1489
+ "button",
1490
+ {
1491
+ onClick: () => setShowSendForm(!showSendForm),
1492
+ className: `w-full px-4 py-2.5 ${t.accent} ${t.accentHover} rounded-xl text-white text-sm font-medium flex items-center justify-center gap-2 transition-all duration-200 shadow-lg`,
1493
+ children: [
1494
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_lucide_react.Send, { className: "h-4 w-4" }),
1495
+ "Send New Notification"
1496
+ ]
1497
+ }
1498
+ ),
1499
+ showSendForm && /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "mt-4 space-y-3", children: [
1500
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
1501
+ "input",
1502
+ {
1503
+ type: "text",
1504
+ placeholder: "Notification title...",
1505
+ value: newTitle,
1506
+ onChange: (e) => setNewTitle(e.target.value),
1507
+ className: `w-full px-4 py-2.5 ${t.bg} border ${t.border} rounded-xl ${t.text} text-sm focus:outline-none focus:ring-2 focus:ring-blue-500`
1508
+ }
1509
+ ),
1510
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
1511
+ "input",
1512
+ {
1513
+ type: "text",
1514
+ placeholder: "Message content...",
1515
+ value: newMessage,
1516
+ onChange: (e) => setNewMessage(e.target.value),
1517
+ className: `w-full px-4 py-2.5 ${t.bg} border ${t.border} rounded-xl ${t.text} text-sm focus:outline-none focus:ring-2 focus:ring-blue-500`
1518
+ }
1519
+ ),
1520
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "flex gap-2", children: ["info", "success", "warning", "error"].map((type) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
1521
+ "button",
1522
+ {
1523
+ onClick: () => setNewType(type),
1524
+ className: `flex-1 py-2 px-3 rounded-lg text-xs font-medium capitalize transition-all border ${newType === type ? `${getTypeBg(type)} ${t.text}` : `${t.bg} ${t.textSecondary} ${t.border} ${t.bgHover}`}`,
1525
+ children: type
1526
+ },
1527
+ type
1528
+ )) }),
1529
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
1530
+ "button",
1531
+ {
1532
+ onClick: sendNotification,
1533
+ disabled: sending || !newTitle.trim() || !newMessage.trim(),
1534
+ className: `w-full py-2.5 ${t.accent} ${t.accentHover} disabled:opacity-50 rounded-xl text-white text-sm font-medium`,
1535
+ children: sending ? "Sending..." : "Send Notification"
1536
+ }
1537
+ )
1538
+ ] })
1539
+ ] }),
1540
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "max-h-80 overflow-y-auto", children: notifications.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "px-5 py-12 text-center", children: [
1541
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: `mx-auto w-12 h-12 rounded-full ${t.bgSecondary} flex items-center justify-center mb-3`, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_lucide_react.Bell, { className: `h-6 w-6 ${t.textMuted}` }) }),
1542
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("p", { className: `${t.textSecondary} text-sm`, children: "No notifications yet" })
1543
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: `divide-y ${t.borderSecondary}`, children: notifications.map((notification) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
1544
+ "div",
1545
+ {
1546
+ onClick: () => markAsRead(notification.id),
1547
+ className: `px-5 py-4 ${t.bgHover} transition-colors cursor-pointer ${!notification.read ? t.bgTertiary : ""}`,
1548
+ children: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "flex gap-3", children: [
1549
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: `mt-0.5 p-2 rounded-lg border ${getTypeBg(notification.type)}`, children: getTypeIcon(notification.type) }),
1550
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "flex-1 min-w-0", children: [
1551
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "flex items-center gap-2", children: [
1552
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("p", { className: `text-sm font-medium ${t.text}`, children: notification.title }),
1553
+ !notification.read && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: `h-2 w-2 rounded-full ${t.badge}` })
1554
+ ] }),
1555
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("p", { className: `text-sm ${t.textSecondary} mt-0.5 line-clamp-2`, children: notification.message }),
1556
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("p", { className: `text-xs ${t.textMuted} mt-1.5`, children: new Date(notification.timestamp).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" }) })
1557
+ ] })
1558
+ ] })
1559
+ },
1560
+ notification.id
1561
+ )) }) }),
1562
+ notifications.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: `px-5 py-3 border-t ${t.border} ${t.bgSecondary} flex items-center justify-between`, children: [
1563
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("button", { onClick: fetchNotifications, className: `text-sm ${t.accentText} font-medium`, children: "Refresh" }),
1564
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("button", { className: `text-sm ${t.textSecondary}`, children: "View all \u2192" })
1565
+ ] })
1566
+ ] })
1567
+ ] })
1568
+ ] });
1569
+ }
1570
+ var NotificationBell = PrimusNotificationCenter;
1571
+ var PrimusNotifications = PrimusNotificationCenter;
1572
+
1573
+ // src/hooks/useRealtimeNotifications.ts
1574
+ var import_react20 = require("react");
1575
+ var useRealtimeNotifications = (options) => {
1576
+ const { apiUrl, pollInterval = 3e3, userId } = options;
1577
+ const [notifications, setNotifications] = (0, import_react20.useState)([]);
1578
+ const [unreadCount, setUnreadCount] = (0, import_react20.useState)(0);
1579
+ const [loading, setLoading] = (0, import_react20.useState)(true);
1580
+ const [error, setError] = (0, import_react20.useState)(null);
1581
+ const baseUrl = `${apiUrl}/api/notifications`;
1582
+ const fetchNotifications = (0, import_react20.useCallback)(async () => {
1583
+ try {
1584
+ const url = userId ? `${baseUrl}?userId=${userId}` : baseUrl;
1585
+ const response = await fetch(url);
1586
+ if (response.ok) {
1587
+ const data = await response.json();
1588
+ setNotifications(data);
1589
+ setUnreadCount(data.filter((n) => !n.read).length);
1590
+ setError(null);
1591
+ }
1592
+ } catch (err) {
1593
+ setError("Failed to connect to notification service");
1594
+ } finally {
1595
+ setLoading(false);
1596
+ }
1597
+ }, [baseUrl, userId]);
1598
+ const sendNotification = (0, import_react20.useCallback)(async (title, message, type = "info") => {
1599
+ try {
1600
+ const response = await fetch(baseUrl, {
1601
+ method: "POST",
1602
+ headers: { "Content-Type": "application/json" },
1603
+ body: JSON.stringify({ title, message, type, userId })
1604
+ });
1605
+ if (response.ok) {
1606
+ await fetchNotifications();
1607
+ return true;
1608
+ }
1609
+ return false;
1610
+ } catch {
1611
+ return false;
1612
+ }
1613
+ }, [baseUrl, userId, fetchNotifications]);
1614
+ const markAsRead = (0, import_react20.useCallback)(async (id) => {
1615
+ try {
1616
+ await fetch(`${baseUrl}/${id}/read`, { method: "PUT" });
1617
+ setNotifications((prev) => prev.map((n) => n.id === id ? { ...n, read: true } : n));
1618
+ setUnreadCount((prev) => Math.max(0, prev - 1));
1619
+ } catch {
1620
+ }
1621
+ }, [baseUrl]);
1622
+ const markAllAsRead = (0, import_react20.useCallback)(async () => {
1623
+ const unread = notifications.filter((n) => !n.read);
1624
+ await Promise.all(unread.map((n) => fetch(`${baseUrl}/${n.id}/read`, { method: "PUT" })));
1625
+ setNotifications((prev) => prev.map((n) => ({ ...n, read: true })));
1626
+ setUnreadCount(0);
1627
+ }, [notifications, baseUrl]);
1628
+ const deleteNotification = (0, import_react20.useCallback)(async (id) => {
1629
+ try {
1630
+ await fetch(`${baseUrl}/${id}`, { method: "DELETE" });
1631
+ setNotifications((prev) => prev.filter((n) => n.id !== id));
1632
+ } catch {
1633
+ }
1634
+ }, [baseUrl]);
1635
+ (0, import_react20.useEffect)(() => {
1636
+ fetchNotifications();
1637
+ const interval = setInterval(fetchNotifications, pollInterval);
1638
+ return () => clearInterval(interval);
1639
+ }, [fetchNotifications, pollInterval]);
1640
+ return {
1641
+ notifications,
1642
+ unreadCount,
1643
+ loading,
1644
+ error,
1645
+ sendNotification,
1646
+ markAsRead,
1647
+ markAllAsRead,
1648
+ deleteNotification,
1649
+ refresh: fetchNotifications
1650
+ };
1651
+ };
1652
+
1653
+ // src/components/payments/CheckoutForm.tsx
1654
+ var import_react22 = require("react");
1655
+
1656
+ // src/components/shared/Input.tsx
1657
+ var import_react21 = __toESM(require("react"));
1658
+ var import_clsx3 = require("clsx");
1659
+ var import_tailwind_merge2 = require("tailwind-merge");
1660
+ var import_jsx_runtime19 = require("react/jsx-runtime");
1661
+ function cn2(...inputs) {
1662
+ return (0, import_tailwind_merge2.twMerge)((0, import_clsx3.clsx)(inputs));
1663
+ }
1664
+ var Input = import_react21.default.forwardRef(
1665
+ ({ className, label, error, ...props }, ref) => {
1666
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "w-full", children: [
1667
+ label && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("label", { className: "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70 mb-2 block text-gray-700", children: label }),
1668
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
1669
+ "input",
1670
+ {
1671
+ ref,
1672
+ className: cn2(
1673
+ "flex h-10 w-full rounded-md border border-gray-200 bg-white px-3 py-2 text-sm ring-offset-white file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-gray-500 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-gray-950 focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
1674
+ error && "border-red-500 focus-visible:ring-red-500",
1675
+ className
1676
+ ),
1677
+ ...props
1678
+ }
1679
+ ),
1680
+ error && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { className: "text-sm text-red-500 mt-1", children: error })
1681
+ ] });
1682
+ }
1683
+ );
1684
+
1685
+ // src/components/payments/CheckoutForm.tsx
1686
+ var import_solid = require("@heroicons/react/24/solid");
1687
+ var import_jsx_runtime20 = require("react/jsx-runtime");
1688
+ var CheckoutForm = ({
1689
+ amount,
1690
+ currency = "USD",
1691
+ apiUrl = "http://localhost:5221",
1692
+ onSuccess,
1693
+ onError
1694
+ }) => {
1695
+ const [loading, setLoading] = (0, import_react22.useState)(false);
1696
+ const [cardholderName, setCardholderName] = (0, import_react22.useState)("");
1697
+ const [cardNumber, setCardNumber] = (0, import_react22.useState)("");
1698
+ const [expiry, setExpiry] = (0, import_react22.useState)("");
1699
+ const [cvc, setCvc] = (0, import_react22.useState)("");
1700
+ const [error, setError] = (0, import_react22.useState)(null);
1701
+ const [success, setSuccess] = (0, import_react22.useState)(false);
1702
+ const handleSubmit = async (e) => {
1703
+ e.preventDefault();
1704
+ setError(null);
1705
+ setSuccess(false);
1706
+ setLoading(true);
1707
+ try {
1708
+ const response = await fetch(`${apiUrl}/api/payments/charge`, {
1709
+ method: "POST",
1710
+ headers: { "Content-Type": "application/json" },
1711
+ body: JSON.stringify({
1712
+ amount,
1713
+ currency,
1714
+ cardholderName,
1715
+ cardNumber: cardNumber.replace(/\s/g, ""),
1716
+ expiry,
1717
+ cvc
1718
+ })
1719
+ });
1720
+ const data = await response.json();
1721
+ if (!response.ok) {
1722
+ throw new Error(data.error || "Payment failed");
1723
+ }
1724
+ setSuccess(true);
1725
+ onSuccess?.(data);
1726
+ setTimeout(() => {
1727
+ setCardholderName("");
1728
+ setCardNumber("");
1729
+ setExpiry("");
1730
+ setCvc("");
1731
+ setSuccess(false);
1732
+ }, 3e3);
1733
+ } catch (err) {
1734
+ const errorMessage = err.message || "Payment processing failed";
1735
+ setError(errorMessage);
1736
+ onError?.(errorMessage);
1737
+ } finally {
1738
+ setLoading(false);
1739
+ }
1740
+ };
1741
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "bg-white p-6 rounded-lg border border-gray-200 shadow-sm", children: [
1742
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex justify-between items-center mb-6", children: [
1743
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("h3", { className: "text-lg font-medium text-gray-900", children: "Payment Details" }),
1744
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex items-center text-gray-500 text-sm", children: [
1745
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_solid.LockClosedIcon, { className: "h-4 w-4 mr-1" }),
1746
+ "Secure Payment"
1747
+ ] })
1748
+ ] }),
1749
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "mb-6 p-4 bg-gray-50 rounded-lg flex justify-between items-center", children: [
1750
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "text-gray-600", children: "Total to pay" }),
1751
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "text-2xl font-bold text-gray-900", children: new Intl.NumberFormat("en-US", { style: "currency", currency }).format(amount) })
1752
+ ] }),
1753
+ error && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "mb-4 p-3 bg-red-50 border border-red-200 rounded-lg flex items-start gap-2", children: [
1754
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_solid.XCircleIcon, { className: "h-5 w-5 text-red-500 flex-shrink-0 mt-0.5" }),
1755
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("p", { className: "text-sm text-red-700", children: error })
1756
+ ] }),
1757
+ success && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "mb-4 p-3 bg-green-50 border border-green-200 rounded-lg flex items-start gap-2", children: [
1758
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_solid.CheckCircleIcon, { className: "h-5 w-5 text-green-500 flex-shrink-0 mt-0.5" }),
1759
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("p", { className: "text-sm text-green-700", children: "Payment successful!" })
1760
+ ] }),
1761
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("form", { onSubmit: handleSubmit, className: "space-y-4", children: [
1762
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
1763
+ Input,
1764
+ {
1765
+ label: "Cardholder Name",
1766
+ placeholder: "John Doe",
1767
+ value: cardholderName,
1768
+ onChange: (e) => setCardholderName(e.target.value),
1769
+ required: true,
1770
+ disabled: loading
1771
+ }
1772
+ ),
1773
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "relative", children: [
1774
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
1775
+ Input,
1776
+ {
1777
+ label: "Card Number",
1778
+ placeholder: "4242 4242 4242 4242",
1779
+ value: cardNumber,
1780
+ onChange: (e) => setCardNumber(e.target.value),
1781
+ required: true,
1782
+ disabled: loading
1783
+ }
1784
+ ),
1785
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "absolute right-3 top-[34px] flex gap-1", children: [
1786
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "h-5 w-8 bg-gray-200 rounded" }),
1787
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "h-5 w-8 bg-gray-200 rounded" })
1788
+ ] })
1789
+ ] }),
1790
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "grid grid-cols-2 gap-4", children: [
1791
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
1792
+ Input,
1793
+ {
1794
+ label: "Expiry Date",
1795
+ placeholder: "MM/YY",
1796
+ value: expiry,
1797
+ onChange: (e) => setExpiry(e.target.value),
1798
+ maxLength: 5,
1799
+ required: true,
1800
+ disabled: loading
1801
+ }
1802
+ ),
1803
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
1804
+ Input,
1805
+ {
1806
+ label: "CVC",
1807
+ placeholder: "123",
1808
+ value: cvc,
1809
+ onChange: (e) => setCvc(e.target.value),
1810
+ maxLength: 4,
1811
+ required: true,
1812
+ disabled: loading
1813
+ }
1814
+ )
1815
+ ] }),
1816
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "pt-4", children: [
1817
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Button, { type: "submit", className: "w-full bg-primus-600 hover:bg-primus-700", size: "lg", disabled: loading, children: loading ? "Processing..." : `Pay ${new Intl.NumberFormat("en-US", { style: "currency", currency }).format(amount)}` }),
1818
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("p", { className: "text-center text-xs text-gray-400 mt-3", children: "Powered by Primus Payments. Your data is encrypted." }),
1819
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("p", { className: "text-center text-xs text-gray-500 mt-2", children: "Test card: 4242 4242 4242 4242" })
1820
+ ] })
1821
+ ] })
1822
+ ] });
1823
+ };
1824
+
1825
+ // src/components/documents/DocumentViewer.tsx
1826
+ var import_outline2 = require("@heroicons/react/24/outline");
1827
+ var import_jsx_runtime21 = require("react/jsx-runtime");
1828
+ var DocumentViewer = ({
1829
+ document,
1830
+ onClose,
1831
+ onDownload
1832
+ }) => {
1833
+ const renderContent = () => {
1834
+ switch (document.type) {
1835
+ case "image":
1836
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
1837
+ "img",
1838
+ {
1839
+ src: document.url,
1840
+ alt: document.name,
1841
+ className: "max-w-full max-h-[80vh] object-contain mx-auto shadow-lg rounded"
1842
+ }
1843
+ );
1844
+ case "pdf":
1845
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "bg-gray-100 p-8 rounded-lg text-center h-[600px] flex items-center justify-center border-2 border-dashed border-gray-300", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "text-gray-500", children: [
1846
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_outline2.DocumentArrowDownIcon, { className: "h-16 w-16 mx-auto mb-4 text-gray-400" }),
1847
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("p", { className: "font-medium", children: "PDF Preview" }),
1848
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("p", { className: "text-sm mt-2", children: document.name }),
1849
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Button, { variant: "outline", size: "sm", className: "mt-4", onClick: onDownload, children: "Download to view" })
1850
+ ] }) });
1851
+ default:
1852
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "bg-white p-8 rounded shadow border border-gray-200 h-[600px] overflow-auto font-mono text-sm leading-relaxed", children: [
1853
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("p", { children: [
1854
+ "Document Content: ",
1855
+ document.name
1856
+ ] }),
1857
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("p", { className: "mt-4 text-gray-500", children: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua." })
1858
+ ] });
1859
+ }
1860
+ };
1861
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex flex-col h-full bg-gray-50 rounded-lg overflow-hidden border border-gray-200", children: [
1862
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "bg-white border-b border-gray-200 px-4 py-3 flex items-center justify-between shadow-sm", children: [
1863
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex items-center gap-3", children: [
1864
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "h-8 w-8 bg-primus-100 rounded flex items-center justify-center text-primus-700", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "uppercase text-xs font-bold", children: document.type }) }),
1865
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { children: [
1866
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("h3", { className: "text-sm font-semibold text-gray-900", children: document.name }),
1867
+ document.size && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("p", { className: "text-xs text-gray-500", children: [
1868
+ document.size,
1869
+ " \u2022 ",
1870
+ document.date
1871
+ ] })
1872
+ ] })
1873
+ ] }),
1874
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex items-center gap-2", children: [
1875
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Button, { variant: "ghost", size: "sm", onClick: () => window.print(), children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_outline2.PrinterIcon, { className: "h-4 w-4" }) }),
1876
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Button, { variant: "ghost", size: "sm", onClick: onDownload, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_outline2.DocumentArrowDownIcon, { className: "h-4 w-4" }) }),
1877
+ onClose && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "h-6 w-px bg-gray-200 mx-1" }),
1878
+ onClose && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Button, { variant: "ghost", size: "sm", onClick: onClose, className: "text-gray-400 hover:text-red-500", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_outline2.XMarkIcon, { className: "h-5 w-5" }) })
1879
+ ] })
1880
+ ] }),
1881
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "flex-1 overflow-auto p-6 flex flex-col items-center justify-center", children: renderContent() })
1882
+ ] });
1883
+ };
1884
+
1885
+ // src/components/banking/cards/CreditCardVisual.tsx
1886
+ var import_clsx4 = require("clsx");
1887
+ var import_outline3 = require("@heroicons/react/24/outline");
1888
+ var import_jsx_runtime22 = require("react/jsx-runtime");
1889
+ var CreditCardVisual = ({
1890
+ cardHolder,
1891
+ last4,
1892
+ expiry,
1893
+ brand = "visa",
1894
+ variant = "black"
1895
+ }) => {
1896
+ const getBackground = () => {
1897
+ switch (variant) {
1898
+ case "blue":
1899
+ return "bg-gradient-to-br from-blue-600 to-blue-800";
1900
+ case "gold":
1901
+ return "bg-gradient-to-br from-yellow-500 to-yellow-700";
1902
+ case "platinum":
1903
+ return "bg-gradient-to-br from-gray-300 to-gray-500";
1904
+ default:
1905
+ return "bg-gradient-to-br from-gray-900 to-gray-800";
1906
+ }
1907
+ };
1908
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: (0, import_clsx4.clsx)(
1909
+ "w-80 h-48 rounded-2xl p-6 text-white shadow-xl relative overflow-hidden transition-transform hover:scale-105 duration-300",
1910
+ getBackground()
1911
+ ), children: [
1912
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "absolute top-0 right-0 -mr-10 -mt-10 w-40 h-40 bg-white opacity-5 rounded-full blur-xl" }),
1913
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "absolute bottom-0 left-0 -ml-10 -mb-10 w-40 h-40 bg-white opacity-5 rounded-full blur-xl" }),
1914
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "flex justify-between items-start mb-8", children: [
1915
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "w-12 h-9 bg-yellow-400 rounded-md opacity-80 flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "w-8 h-6 border border-yellow-600 rounded opacity-50" }) }),
1916
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_outline3.WifiIcon, { className: "h-6 w-6 rotate-90 opacity-70" })
1917
+ ] }),
1918
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "mb-6", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("p", { className: "font-mono text-xl tracking-widest text-shadow", children: [
1919
+ "\u2022\u2022\u2022\u2022 \u2022\u2022\u2022\u2022 \u2022\u2022\u2022\u2022 ",
1920
+ last4
1921
+ ] }) }),
1922
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "flex justify-between items-end", children: [
1923
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { children: [
1924
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { className: "text-[10px] uppercase text-gray-300 tracking-wider mb-1", children: "Card Holder" }),
1925
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { className: "font-medium tracking-wide uppercase text-sm truncate max-w-[160px]", children: cardHolder })
1926
+ ] }),
1927
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { children: [
1928
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { className: "text-[10px] uppercase text-gray-300 tracking-wider mb-1", children: "Expires" }),
1929
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { className: "font-medium tracking-wide text-sm", children: expiry })
1930
+ ] }),
1931
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "font-bold text-lg italic opacity-90", children: brand.toUpperCase() })
1932
+ ] })
1933
+ ] });
1934
+ };
1935
+
1936
+ // src/components/banking/transactions/TransactionHistory.tsx
1937
+ var import_outline4 = require("@heroicons/react/24/outline");
1938
+ var import_clsx5 = require("clsx");
1939
+ var import_jsx_runtime23 = require("react/jsx-runtime");
1940
+ var TransactionHistory = ({
1941
+ transactions,
1942
+ onTransactionClick
1943
+ }) => {
1944
+ const getIcon = (t) => {
1945
+ if (t.type === "credit") return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_outline4.ArrowDownLeftIcon, { className: "h-5 w-5 text-green-600" });
1946
+ if (t.category === "shopping") return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_outline4.ShoppingBagIcon, { className: "h-5 w-5 text-blue-600" });
1947
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_outline4.ArrowUpRightIcon, { className: "h-5 w-5 text-red-600" });
1948
+ };
1949
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "bg-white rounded-lg border border-gray-200 shadow-sm overflow-hidden", children: [
1950
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "px-6 py-4 border-b border-gray-100 flex justify-between items-center", children: [
1951
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("h3", { className: "font-semibold text-gray-900", children: "Recent Transactions" }),
1952
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("button", { className: "text-sm text-primus-600 hover:text-primus-700 font-medium", children: "View All" })
1953
+ ] }),
1954
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "divide-y divide-gray-100", children: transactions.map((t) => /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
1955
+ "div",
1956
+ {
1957
+ onClick: () => onTransactionClick?.(t.id),
1958
+ className: "px-6 py-4 flex items-center justify-between hover:bg-gray-50 cursor-pointer transition-colors",
1959
+ children: [
1960
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex items-center gap-4", children: [
1961
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: (0, import_clsx5.clsx)(
1962
+ "h-10 w-10 rounded-full flex items-center justify-center",
1963
+ t.type === "credit" ? "bg-green-100" : "bg-gray-100"
1964
+ ), children: getIcon(t) }),
1965
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { children: [
1966
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "text-sm font-medium text-gray-900", children: t.description }),
1967
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "text-xs text-gray-500", children: t.date })
1968
+ ] })
1969
+ ] }),
1970
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "text-right", children: [
1971
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("p", { className: (0, import_clsx5.clsx)(
1972
+ "text-sm font-semibold",
1973
+ t.type === "credit" ? "text-green-600" : "text-gray-900"
1974
+ ), children: [
1975
+ t.type === "credit" ? "+" : "-",
1976
+ new Intl.NumberFormat("en-US", { style: "currency", currency: "USD" }).format(t.amount)
1977
+ ] }),
1978
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "text-xs text-gray-400 capitalize", children: t.status || "completed" })
1979
+ ] })
1980
+ ]
1981
+ },
1982
+ t.id
1983
+ )) })
1984
+ ] });
1985
+ };
1986
+
1987
+ // src/components/insurance/policies/PolicyCard.tsx
1988
+ var import_clsx6 = require("clsx");
1989
+ var import_outline5 = require("@heroicons/react/24/outline");
1990
+ var import_jsx_runtime24 = require("react/jsx-runtime");
1991
+ var PolicyCard = ({
1992
+ policyNumber,
1993
+ type,
1994
+ status,
1995
+ coverageAmount,
1996
+ nextPaymentDate,
1997
+ premiumAmount
1998
+ }) => {
1999
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "bg-white rounded-xl border border-gray-200 shadow-sm overflow-hidden hover:shadow-md transition-shadow", children: [
2000
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "bg-gray-50 px-6 py-4 border-b border-gray-100 flex justify-between items-center", children: [
2001
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex items-center gap-2", children: [
2002
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_outline5.ShieldCheckIcon, { className: "h-5 w-5 text-primus-600" }),
2003
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("span", { className: "font-semibold text-gray-900", children: [
2004
+ type,
2005
+ " Insurance"
2006
+ ] })
2007
+ ] }),
2008
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: (0, import_clsx6.clsx)(
2009
+ "px-2.5 py-0.5 rounded-full text-xs font-medium uppercase tracking-wide",
2010
+ status === "active" ? "bg-green-100 text-green-800" : status === "pending" ? "bg-yellow-100 text-yellow-800" : "bg-gray-100 text-gray-800"
2011
+ ), children: status })
2012
+ ] }),
2013
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "p-6", children: [
2014
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "mb-6", children: [
2015
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { className: "text-xs text-gray-500 uppercase tracking-wider mb-1", children: "Policy Number" }),
2016
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { className: "font-mono text-lg font-medium text-gray-900", children: policyNumber })
2017
+ ] }),
2018
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "grid grid-cols-2 gap-6 mb-6", children: [
2019
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { children: [
2020
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { className: "text-xs text-gray-500 uppercase tracking-wider mb-1", children: "Coverage" }),
2021
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { className: "text-xl font-bold text-gray-900", children: new Intl.NumberFormat("en-US", { style: "currency", currency: "USD", maximumFractionDigits: 0 }).format(coverageAmount) })
2022
+ ] }),
2023
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { children: [
2024
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { className: "text-xs text-gray-500 uppercase tracking-wider mb-1", children: "Premium" }),
2025
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("p", { className: "text-gray-900 font-medium", children: [
2026
+ new Intl.NumberFormat("en-US", { style: "currency", currency: "USD" }).format(premiumAmount),
2027
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "text-xs text-gray-500 font-normal", children: " / month" })
2028
+ ] })
2029
+ ] })
2030
+ ] }),
2031
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "bg-blue-50 rounded-lg p-3 flex items-start gap-3 mb-6", children: [
2032
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_outline5.DocumentTextIcon, { className: "h-5 w-5 text-blue-600 mt-0.5" }),
2033
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { children: [
2034
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { className: "text-sm font-medium text-blue-900", children: "Next Payment due" }),
2035
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { className: "text-sm text-blue-700", children: nextPaymentDate })
2036
+ ] })
2037
+ ] }),
2038
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex gap-3", children: [
2039
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(Button, { variant: "outline", className: "flex-1", children: "View Details" }),
2040
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(Button, { className: "flex-1", children: "File Claim" })
2041
+ ] })
2042
+ ] })
2043
+ ] });
2044
+ };
2045
+
2046
+ // src/components/insurance/claims/ClaimStatusTracker.tsx
2047
+ var import_clsx7 = require("clsx");
2048
+ var import_solid2 = require("@heroicons/react/24/solid");
2049
+ var import_jsx_runtime25 = require("react/jsx-runtime");
2050
+ var ClaimStatusTracker = ({
2051
+ claimId,
2052
+ steps
2053
+ }) => {
2054
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "bg-white rounded-xl border border-gray-200 shadow-sm p-6", children: [
2055
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "mb-8", children: [
2056
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("h3", { className: "text-lg font-semibold text-gray-900", children: "Claim Status" }),
2057
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("p", { className: "text-sm text-gray-500", children: [
2058
+ "Claim ID: #",
2059
+ claimId
2060
+ ] })
2061
+ ] }),
2062
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("nav", { "aria-label": "Progress", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("ol", { role: "list", className: "overflow-hidden", children: steps.map((step, stepIdx) => /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("li", { className: (0, import_clsx7.clsx)(
2063
+ "relative pb-10",
2064
+ stepIdx === steps.length - 1 ? "pb-0" : ""
2065
+ ), children: [
2066
+ stepIdx !== steps.length - 1 ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
2067
+ "div",
2068
+ {
2069
+ className: (0, import_clsx7.clsx)(
2070
+ "absolute top-4 left-4 -ml-px h-full w-0.5",
2071
+ step.status === "completed" ? "bg-primus-600" : "bg-gray-200"
2072
+ ),
2073
+ "aria-hidden": "true"
2074
+ }
2075
+ ) : null,
2076
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "relative flex items-start group", children: [
2077
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "h-9 flex items-center", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: (0, import_clsx7.clsx)(
2078
+ "relative z-10 w-8 h-8 flex items-center justify-center rounded-full ring-1 ring-white",
2079
+ step.status === "completed" ? "bg-primus-600" : step.status === "current" ? "bg-white border-2 border-primus-600" : "bg-white border-2 border-gray-300"
2080
+ ), children: step.status === "completed" ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_solid2.CheckIcon, { className: "w-5 h-5 text-white", "aria-hidden": "true" }) : step.status === "current" ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "h-2.5 w-2.5 bg-primus-600 rounded-full" }) : null }) }),
2081
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("span", { className: "ml-4 min-w-0 flex flex-col", children: [
2082
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: (0, import_clsx7.clsx)(
2083
+ "text-sm font-medium",
2084
+ step.status === "upcoming" ? "text-gray-500" : "text-gray-900"
2085
+ ), children: step.label }),
2086
+ step.date && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "text-xs text-gray-500 mt-1", children: step.date })
2087
+ ] })
2088
+ ] })
2089
+ ] }, step.label)) }) })
2090
+ ] });
2091
+ };
2092
+
2093
+ // src/components/featureflags/FeatureFlagToggle.tsx
2094
+ var import_react23 = require("react");
2095
+ var import_jsx_runtime26 = require("react/jsx-runtime");
2096
+ var FeatureFlagToggle = ({
2097
+ apiUrl = "http://localhost:5221"
2098
+ }) => {
2099
+ const [flags, setFlags] = (0, import_react23.useState)([]);
2100
+ const [loading, setLoading] = (0, import_react23.useState)(true);
2101
+ (0, import_react23.useEffect)(() => {
2102
+ fetchFlags();
2103
+ }, []);
2104
+ const fetchFlags = async () => {
2105
+ try {
2106
+ const response = await fetch(`${apiUrl}/api/featureflags`);
2107
+ if (response.ok) {
2108
+ const data = await response.json();
2109
+ setFlags(data);
2110
+ }
2111
+ } catch (error) {
2112
+ console.error("Failed to fetch feature flags:", error);
2113
+ } finally {
2114
+ setLoading(false);
2115
+ }
2116
+ };
2117
+ if (loading) {
2118
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "p-4", children: "Loading feature flags..." });
2119
+ }
2120
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "bg-white p-6 rounded-lg border border-gray-200 shadow-sm", children: [
2121
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("h3", { className: "text-lg font-medium text-gray-900 mb-4", children: "Feature Flags" }),
2122
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "space-y-4", children: flags.map((flag) => /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex items-center justify-between p-4 bg-gray-50 rounded-lg", children: [
2123
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex-1", children: [
2124
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("h4", { className: "font-medium text-gray-900", children: flag.name }),
2125
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("p", { className: "text-sm text-gray-500", children: flag.description }),
2126
+ flag.rolloutPercentage !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("p", { className: "text-xs text-gray-400 mt-1", children: [
2127
+ "Rollout: ",
2128
+ flag.rolloutPercentage,
2129
+ "%"
2130
+ ] })
2131
+ ] }),
2132
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: `px-3 py-1 rounded-full text-sm font-medium ${flag.enabled ? "bg-green-100 text-green-800" : "bg-gray-100 text-gray-800"}`, children: flag.enabled ? "Enabled" : "Disabled" })
2133
+ ] }, flag.name)) })
2134
+ ] });
2135
+ };
2136
+
2137
+ // src/components/logging/LogViewer.tsx
2138
+ var import_react24 = require("react");
2139
+ var import_jsx_runtime27 = require("react/jsx-runtime");
2140
+ var LogViewer = ({
2141
+ apiUrl = "http://localhost:5221"
2142
+ }) => {
2143
+ const [logs, setLogs] = (0, import_react24.useState)([]);
2144
+ const [filter, setFilter] = (0, import_react24.useState)("");
2145
+ const [loading, setLoading] = (0, import_react24.useState)(true);
2146
+ (0, import_react24.useEffect)(() => {
2147
+ fetchLogs();
2148
+ const interval = setInterval(fetchLogs, 1e4);
2149
+ return () => clearInterval(interval);
2150
+ }, [filter]);
2151
+ const fetchLogs = async () => {
2152
+ try {
2153
+ const url = filter ? `${apiUrl}/api/logs?level=${filter}` : `${apiUrl}/api/logs`;
2154
+ const response = await fetch(url);
2155
+ if (response.ok) {
2156
+ const data = await response.json();
2157
+ setLogs(data);
2158
+ }
2159
+ } catch (error) {
2160
+ console.error("Failed to fetch logs:", error);
2161
+ } finally {
2162
+ setLoading(false);
2163
+ }
2164
+ };
2165
+ const getLevelColor = (level) => {
2166
+ switch (level.toUpperCase()) {
2167
+ case "ERROR":
2168
+ return "text-red-600 bg-red-50";
2169
+ case "WARNING":
2170
+ return "text-yellow-600 bg-yellow-50";
2171
+ case "INFO":
2172
+ return "text-blue-600 bg-blue-50";
2173
+ default:
2174
+ return "text-gray-600 bg-gray-50";
2175
+ }
2176
+ };
2177
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "bg-white p-6 rounded-lg border border-gray-200 shadow-sm", children: [
2178
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex justify-between items-center mb-4", children: [
2179
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("h3", { className: "text-lg font-medium text-gray-900", children: "System Logs" }),
2180
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
2181
+ "select",
2182
+ {
2183
+ value: filter,
2184
+ onChange: (e) => setFilter(e.target.value),
2185
+ className: "px-3 py-1 border border-gray-300 rounded-md text-sm",
2186
+ children: [
2187
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("option", { value: "", children: "All Levels" }),
2188
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("option", { value: "INFO", children: "Info" }),
2189
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("option", { value: "WARNING", children: "Warning" }),
2190
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("option", { value: "ERROR", children: "Error" })
2191
+ ]
2192
+ }
2193
+ )
2194
+ ] }),
2195
+ loading ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "text-center py-8 text-gray-500", children: "Loading logs..." }) : /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "space-y-2 max-h-96 overflow-y-auto", children: logs.map((log) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "p-3 bg-gray-50 rounded border border-gray-200", children: /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex items-start gap-3", children: [
2196
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: `px-2 py-0.5 rounded text-xs font-medium ${getLevelColor(log.level)}`, children: log.level }),
2197
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex-1 min-w-0", children: [
2198
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("p", { className: "text-sm text-gray-900", children: log.message }),
2199
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex gap-4 mt-1 text-xs text-gray-500", children: [
2200
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { children: new Date(log.timestamp).toLocaleString() }),
2201
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { children: log.source })
2202
+ ] })
2203
+ ] })
2204
+ ] }) }, log.id)) })
2205
+ ] });
2206
+ };
2207
+
2208
+ // src/components/layout/PrimusLayout.tsx
2209
+ var import_jsx_runtime28 = require("react/jsx-runtime");
2210
+ var PrimusLayout = ({
2211
+ children,
2212
+ sidebar,
2213
+ header
2214
+ }) => {
2215
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: `min-h-screen flex text-white relative`, children: [
2216
+ sidebar && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("aside", { className: "w-72 flex-shrink-0 flex flex-col fixed inset-y-0 left-0 z-50", children: sidebar }),
2217
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: `flex-1 flex flex-col min-h-screen ${sidebar ? "pl-72" : ""}`, children: [
2218
+ header && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("header", { className: "h-20 flex items-center px-8 fixed top-0 right-0 left-72 z-40 bg-slate-900/10 backdrop-blur-md border-b border-white/5 transition-all duration-300", children: header }),
2219
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("main", { className: "flex-1 p-8 pt-28 overflow-x-hidden", children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "max-w-7xl mx-auto space-y-8 animate-enter", children }) })
2220
+ ] })
2221
+ ] });
2222
+ };
2223
+
2224
+ // src/components/layout/PrimusSidebar.tsx
2225
+ var import_jsx_runtime29 = require("react/jsx-runtime");
2226
+ var PrimusSidebar = ({
2227
+ logo,
2228
+ items,
2229
+ footer,
2230
+ onItemClick,
2231
+ activeId
2232
+ }) => {
2233
+ return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex flex-col h-full bg-slate-900/50 backdrop-blur-xl border-r border-white/10 relative overflow-hidden", children: [
2234
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "absolute top-0 left-0 w-full h-64 bg-purple-500/10 blur-[60px] pointer-events-none" }),
2235
+ logo && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "h-20 flex items-center px-6 relative z-10 border-b border-white/5", children: logo }),
2236
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("nav", { className: "flex-1 py-6 px-3 overflow-y-auto relative z-10", children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("ul", { className: "space-y-1", children: items.map((item) => {
2237
+ const isActive = activeId === item.id || item.active;
2238
+ return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
2239
+ "button",
2240
+ {
2241
+ onClick: () => {
2242
+ item.onClick?.();
2243
+ onItemClick?.(item);
2244
+ },
2245
+ className: `group relative w-full flex items-center gap-3 px-4 py-3 rounded-xl text-sm font-medium transition-all duration-300 ${isActive ? "text-white shadow-lg shadow-purple-500/20 ring-1 ring-white/10" : "text-gray-400 hover:text-white hover:bg-white/5"}`,
2246
+ children: [
2247
+ isActive && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "absolute inset-0 rounded-xl bg-gradient-to-r from-purple-600/90 to-pink-600/90 opacity-100 transition-opacity" }),
2248
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "relative z-10 w-5 h-5 flex items-center justify-center transition-transform group-hover:scale-110 duration-300", children: item.icon }),
2249
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "relative z-10 flex-1 text-left", children: item.label }),
2250
+ item.badge && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: `relative z-10 px-2 py-0.5 text-xs font-semibold rounded-full border ${isActive ? "bg-white/20 border-white/20 text-white" : "bg-gray-800 border-gray-700 text-gray-300 group-hover:bg-gray-700"}`, children: item.badge }),
2251
+ isActive && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "absolute left-0 top-1/2 -translate-y-1/2 w-1 h-8 bg-white rounded-r-full shadow-[0_0_12px_rgba(255,255,255,0.6)] hidden" })
2252
+ ]
2253
+ }
2254
+ ) }, item.id);
2255
+ }) }) }),
2256
+ footer && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "p-4 border-t border-white/5 bg-black/20 backdrop-blur-md relative z-10", children: footer })
2257
+ ] });
2258
+ };
2259
+
2260
+ // src/components/layout/PrimusHeader.tsx
2261
+ var import_react25 = __toESM(require("react"));
2262
+ var import_jsx_runtime30 = require("react/jsx-runtime");
2263
+ var PrimusHeader = ({
2264
+ title,
2265
+ breadcrumbs,
2266
+ actions,
2267
+ user,
2268
+ onUserClick
2269
+ }) => {
2270
+ return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex items-center justify-between w-full", children: [
2271
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex items-center gap-4", children: [
2272
+ breadcrumbs && breadcrumbs.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("nav", { className: "flex items-center gap-2 text-sm", children: breadcrumbs.map((crumb, index) => /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(import_react25.default.Fragment, { children: [
2273
+ index > 0 && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "text-gray-500", children: "/" }),
2274
+ /* @__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 })
2275
+ ] }, index)) }),
2276
+ title && !breadcrumbs && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("h1", { className: "text-xl font-semibold", children: title })
2277
+ ] }),
2278
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex items-center gap-4", children: [
2279
+ actions,
2280
+ user && /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
2281
+ "button",
2282
+ {
2283
+ onClick: onUserClick,
2284
+ className: "flex items-center gap-3 px-3 py-1.5 rounded-lg hover:bg-gray-700/50 transition-colors",
2285
+ children: [
2286
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "text-right hidden sm:block", children: [
2287
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("p", { className: "text-sm font-medium", children: user.name }),
2288
+ user.email && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("p", { className: "text-xs text-gray-400", children: user.email })
2289
+ ] }),
2290
+ user.avatar ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("img", { src: user.avatar, alt: user.name, className: "w-8 h-8 rounded-full" }) : /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "w-8 h-8 rounded-full bg-gradient-to-br from-purple-500 to-pink-500 flex items-center justify-center text-sm font-medium", children: user.name.charAt(0).toUpperCase() })
2291
+ ]
2292
+ }
2293
+ )
2294
+ ] })
2295
+ ] });
2296
+ };
2297
+
2298
+ // src/components/crud/PrimusDataTable.tsx
2299
+ var import_react26 = require("react");
2300
+ var import_jsx_runtime31 = require("react/jsx-runtime");
2301
+ function PrimusDataTable({
2302
+ data,
2303
+ columns,
2304
+ rowKey,
2305
+ loading = false,
2306
+ selectable = false,
2307
+ selectedKeys = [],
2308
+ onSelectionChange,
2309
+ onRowClick,
2310
+ actions,
2311
+ emptyMessage = "No data available",
2312
+ searchPlaceholder = "Filter...",
2313
+ searchable = true
2314
+ }) {
2315
+ const [search, setSearch] = (0, import_react26.useState)("");
2316
+ const [sortKey, setSortKey] = (0, import_react26.useState)(null);
2317
+ const [sortDir, setSortDir] = (0, import_react26.useState)("asc");
2318
+ const filteredData = (0, import_react26.useMemo)(() => {
2319
+ let result = [...data];
2320
+ if (search) {
2321
+ const lowerSearch = search.toLowerCase();
2322
+ result = result.filter(
2323
+ (row) => Object.values(row).some(
2324
+ (val) => String(val).toLowerCase().includes(lowerSearch)
2325
+ )
2326
+ );
2327
+ }
2328
+ if (sortKey) {
2329
+ result.sort((a, b) => {
2330
+ const aVal = a[sortKey];
2331
+ const bVal = b[sortKey];
2332
+ const cmp = aVal < bVal ? -1 : aVal > bVal ? 1 : 0;
2333
+ return sortDir === "asc" ? cmp : -cmp;
2334
+ });
2335
+ }
2336
+ return result;
2337
+ }, [data, search, sortKey, sortDir]);
2338
+ const handleSort = (key) => {
2339
+ if (sortKey === key) {
2340
+ setSortDir(sortDir === "asc" ? "desc" : "asc");
2341
+ } else {
2342
+ setSortKey(key);
2343
+ setSortDir("asc");
2344
+ }
2345
+ };
2346
+ const toggleSelect = (key) => {
2347
+ const newKeys = selectedKeys.includes(key) ? selectedKeys.filter((k) => k !== key) : [...selectedKeys, key];
2348
+ onSelectionChange?.(newKeys);
2349
+ };
2350
+ const toggleSelectAll = () => {
2351
+ if (selectedKeys.length === filteredData.length) {
2352
+ onSelectionChange?.([]);
2353
+ } else {
2354
+ onSelectionChange?.(filteredData.map((row) => row[rowKey]));
2355
+ }
2356
+ };
2357
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: "flex flex-col space-y-4", children: [
2358
+ searchable && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: "flex items-center justify-between px-1", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: "relative group", children: [
2359
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: "absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("svg", { className: "h-4 w-4 text-gray-500 group-focus-within:text-purple-400 transition-colors", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" }) }) }),
2360
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
2361
+ "input",
2362
+ {
2363
+ type: "text",
2364
+ placeholder: searchPlaceholder,
2365
+ value: search,
2366
+ onChange: (e) => setSearch(e.target.value),
2367
+ className: "w-64 pl-10 pr-4 py-2 bg-white/5 border border-white/10 rounded-lg text-sm text-gray-200 placeholder-gray-500 focus:outline-none focus:ring-1 focus:ring-purple-500/50 focus:bg-white/10 transition-all hover:bg-white/10"
2368
+ }
2369
+ )
2370
+ ] }) }),
2371
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: `overflow-hidden rounded-xl border border-white/5 bg-slate-900/40 backdrop-blur-md shadow-xl ring-1 ring-white/5 ${loading ? "opacity-80" : ""}`, children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: "overflow-x-auto", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("table", { className: "w-full text-left border-collapse", children: [
2372
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("thead", { className: "bg-white/5 border-b border-white/5 backdrop-blur-md sticky top-0 z-20", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("tr", { children: [
2373
+ selectable && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("th", { className: "w-12 px-6 py-4", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
2374
+ "input",
2375
+ {
2376
+ type: "checkbox",
2377
+ checked: selectedKeys.length === filteredData.length && filteredData.length > 0,
2378
+ onChange: toggleSelectAll,
2379
+ className: "rounded border-gray-600 bg-gray-800 text-purple-600 focus:ring-offset-gray-900 focus:ring-purple-500 transition-colors cursor-pointer"
2380
+ }
2381
+ ) }),
2382
+ columns.map((col) => /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
2383
+ "th",
2384
+ {
2385
+ className: `px-6 py-4 text-xs font-semibold text-gray-400 uppercase tracking-wider ${col.sortable ? "cursor-pointer hover:text-white group" : ""}`,
2386
+ style: { width: col.width },
2387
+ onClick: () => col.sortable && handleSort(String(col.key)),
2388
+ children: /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: "flex items-center gap-2", children: [
2389
+ col.header,
2390
+ col.sortable && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: `transition-opacity duration-200 ${sortKey === col.key ? "opacity-100 text-purple-400" : "opacity-0 group-hover:opacity-50"}`, children: sortDir === "asc" ? "\u2191" : "\u2193" })
2391
+ ] })
2392
+ },
2393
+ String(col.key)
2394
+ )),
2395
+ actions && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("th", { className: "w-24 px-6 py-4 text-right text-xs font-semibold text-gray-400 uppercase tracking-wider" })
2396
+ ] }) }),
2397
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("tbody", { className: "divide-y divide-white/5", children: loading ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("tr", { children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("td", { colSpan: columns.length + (selectable ? 1 : 0) + (actions ? 1 : 0), className: "px-6 py-24 text-center text-gray-500", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: "flex flex-col items-center justify-center gap-3", children: [
2398
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: "w-6 h-6 border-2 border-purple-500/50 border-t-purple-500 rounded-full animate-spin" }),
2399
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "text-sm font-medium", children: "Loading data..." })
2400
+ ] }) }) }) : filteredData.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("tr", { children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("td", { colSpan: columns.length + (selectable ? 1 : 0) + (actions ? 1 : 0), className: "px-6 py-24 text-center text-gray-500", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("p", { className: "text-sm", children: emptyMessage }) }) }) : filteredData.map((row) => /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(
2401
+ "tr",
2402
+ {
2403
+ onClick: () => onRowClick?.(row),
2404
+ className: `
2405
+ group transition-colors duration-150
2406
+ ${onRowClick ? "cursor-pointer hover:bg-white/5" : ""}
2407
+ ${selectedKeys.includes(row[rowKey]) ? "bg-purple-500/10 hover:bg-purple-500/20" : ""}
2408
+ `,
2409
+ children: [
2410
+ selectable && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("td", { className: "px-6 py-4", onClick: (e) => e.stopPropagation(), children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
2411
+ "input",
2412
+ {
2413
+ type: "checkbox",
2414
+ checked: selectedKeys.includes(row[rowKey]),
2415
+ onChange: () => toggleSelect(row[rowKey]),
2416
+ className: "rounded border-gray-600 bg-gray-800 text-purple-600 focus:ring-offset-gray-900 focus:ring-purple-500 cursor-pointer"
2417
+ }
2418
+ ) }),
2419
+ columns.map((col) => /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("td", { className: "px-6 py-4 text-sm text-gray-300 group-hover:text-white transition-colors", children: col.render ? col.render(row[col.key], row) : String(row[col.key] ?? "") }, String(col.key))),
2420
+ actions && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("td", { className: "px-6 py-4 text-right", onClick: (e) => e.stopPropagation(), children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: "opacity-0 group-hover:opacity-100 transition-opacity transform translate-x-2 group-hover:translate-x-0", children: actions(row) }) })
2421
+ ]
2422
+ },
2423
+ String(row[rowKey])
2424
+ )) })
2425
+ ] }) }) })
2426
+ ] });
2427
+ }
2428
+
2429
+ // src/components/crud/PrimusModal.tsx
2430
+ var import_jsx_runtime32 = require("react/jsx-runtime");
2431
+ var PrimusModal = ({
2432
+ open,
2433
+ onClose,
2434
+ title,
2435
+ children,
2436
+ footer,
2437
+ size = "md"
2438
+ }) => {
2439
+ if (!open) return null;
2440
+ const sizeClasses = {
2441
+ sm: "max-w-sm",
2442
+ md: "max-w-md",
2443
+ lg: "max-w-lg",
2444
+ xl: "max-w-xl"
2445
+ };
2446
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "fixed inset-0 z-50 flex items-center justify-center", children: [
2447
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
2448
+ "div",
2449
+ {
2450
+ className: "absolute inset-0 bg-black/60 backdrop-blur-sm",
2451
+ onClick: onClose
2452
+ }
2453
+ ),
2454
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: `relative w-full ${sizeClasses[size]} mx-4 bg-gray-800 rounded-xl border border-gray-700 shadow-2xl`, children: [
2455
+ title && /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "flex items-center justify-between px-6 py-4 border-b border-gray-700", children: [
2456
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("h2", { className: "text-lg font-semibold text-white", children: title }),
2457
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
2458
+ "button",
2459
+ {
2460
+ onClick: onClose,
2461
+ className: "text-gray-400 hover:text-white transition-colors",
2462
+ children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("svg", { className: "w-5 h-5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) })
2463
+ }
2464
+ )
2465
+ ] }),
2466
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "p-6", children }),
2467
+ footer && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "flex justify-end gap-3 px-6 py-4 border-t border-gray-700 bg-gray-800/50", children: footer })
2468
+ ] })
2469
+ ] });
2470
+ };
2471
+
2472
+ // src/components/dashboard/PrimusDashboard.tsx
2473
+ var import_jsx_runtime33 = require("react/jsx-runtime");
2474
+ var PrimusStatCard = ({
2475
+ title,
2476
+ value,
2477
+ change,
2478
+ icon,
2479
+ description,
2480
+ trend = [40, 35, 50, 45, 60, 55, 70]
2481
+ // Default dummy data
2482
+ }) => {
2483
+ const changeColors = {
2484
+ increase: "text-emerald-400 bg-emerald-400/10",
2485
+ decrease: "text-rose-400 bg-rose-400/10",
2486
+ neutral: "text-gray-400 bg-gray-400/10"
2487
+ };
2488
+ const changeIcons = {
2489
+ increase: "\u2191",
2490
+ decrease: "\u2193",
2491
+ neutral: "\u2192"
2492
+ };
2493
+ const renderSparkline = () => {
2494
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("svg", { className: "w-full h-12 opacity-50 absolute bottom-0 left-0", preserveAspectRatio: "none", "data-trend": trend.join(","), children: [
2495
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("path", { d: "M0 40 Q 20 20 40 40 T 80 40 T 120 40 T 160 30 V 50 H 0 Z", fill: `url(#gradient-${title.replace(/\s/g, "")})`, stroke: "none" }),
2496
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("defs", { children: /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("linearGradient", { id: `gradient-${title.replace(/\s/g, "")}`, x1: "0", y1: "0", x2: "0", y2: "1", children: [
2497
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("stop", { offset: "0%", stopColor: "currentColor", stopOpacity: "0.2" }),
2498
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("stop", { offset: "100%", stopColor: "currentColor", stopOpacity: "0" })
2499
+ ] }) })
2500
+ ] });
2501
+ };
2502
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "relative overflow-hidden bg-slate-900/40 backdrop-blur-md rounded-2xl border border-white/5 hover:border-white/10 transition-all duration-300 group", children: [
2503
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "absolute inset-0 bg-gradient-to-br from-white/5 to-transparent opacity-0 group-hover:opacity-100 transition-opacity pointer-events-none" }),
2504
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "p-6 relative z-10", children: [
2505
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "flex items-start justify-between mb-4", children: [
2506
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "p-2.5 rounded-lg bg-white/5 text-gray-300 ring-1 ring-white/10 group-hover:bg-purple-500/20 group-hover:text-purple-300 transition-colors", children: icon || /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "w-5 h-5 bg-current opacity-20" }) }),
2507
+ change && /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("span", { className: `px-2 py-0.5 text-xs font-medium rounded-full flex items-center gap-1 ${changeColors[change.type]}`, children: [
2508
+ changeIcons[change.type],
2509
+ " ",
2510
+ Math.abs(change.value),
2511
+ "%"
2512
+ ] })
2513
+ ] }),
2514
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { children: [
2515
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("h3", { className: "text-sm font-medium text-gray-400 tracking-wide", children: title }),
2516
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "mt-1 flex items-baseline gap-2", children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "text-3xl font-bold text-transparent bg-clip-text bg-gradient-to-r from-white to-gray-400", children: value }) }),
2517
+ description && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("p", { className: "text-xs text-gray-500 mt-2 font-medium", children: description })
2518
+ ] })
2519
+ ] }),
2520
+ renderSparkline(),
2521
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: `absolute -bottom-2 -right-4 w-32 h-32 blur-2xl opacity-20 rounded-full transition-colors duration-500 ${change?.type === "increase" ? "bg-emerald-500" : change?.type === "decrease" ? "bg-rose-500" : "bg-blue-500"}` })
2522
+ ] });
2523
+ };
2524
+ var PrimusDashboard = ({
2525
+ children,
2526
+ title,
2527
+ subtitle,
2528
+ actions
2529
+ }) => {
2530
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "space-y-8 animate-enter", children: [
2531
+ (title || actions) && /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "flex flex-col md:flex-row md:items-end justify-between gap-4 border-b border-white/5 pb-6", children: [
2532
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { children: [
2533
+ title && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("h1", { className: "text-3xl font-bold bg-clip-text text-transparent bg-gradient-to-r from-white via-gray-200 to-gray-400 tracking-tight", children: title }),
2534
+ subtitle && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("p", { className: "text-gray-400 mt-2 text-lg font-light leading-relaxed", children: subtitle })
2535
+ ] }),
2536
+ actions && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "flex items-center gap-3", children: actions })
2537
+ ] }),
2538
+ children
2539
+ ] });
2540
+ };
2541
+ var DashboardGrid = ({
2542
+ children,
2543
+ columns = 4
2544
+ }) => {
2545
+ const colClasses = {
2546
+ 1: "grid-cols-1",
2547
+ 2: "grid-cols-1 md:grid-cols-2",
2548
+ 3: "grid-cols-1 md:grid-cols-2 lg:grid-cols-3",
2549
+ 4: "grid-cols-1 md:grid-cols-2 lg:grid-cols-4"
2550
+ };
2551
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: `grid gap-6 ${colClasses[columns]}`, children });
2552
+ };
2553
+ // Annotate the CommonJS export names for ESM import in node:
2554
+ 0 && (module.exports = {
2555
+ AICopilot,
2556
+ AccountDashboard,
2557
+ AgentDirectory,
2558
+ CheckoutForm,
2559
+ ClaimStatusTracker,
2560
+ CreditCardVisual,
2561
+ CreditScoreCard,
2562
+ DashboardGrid,
2563
+ DocumentViewer,
2564
+ FeatureFlagToggle,
2565
+ FileUploader,
2566
+ FraudDetectionDashboard,
2567
+ KYCVerification,
2568
+ LoanCalculator,
2569
+ LogViewer,
2570
+ LoginPage,
2571
+ NotificationBell,
2572
+ NotificationFeed,
2573
+ PolicyCard,
2574
+ PremiumCalculator,
2575
+ PrimusDashboard,
2576
+ PrimusDataTable,
2577
+ PrimusHeader,
2578
+ PrimusLayout,
2579
+ PrimusLogin,
2580
+ PrimusModal,
2581
+ PrimusNotificationCenter,
2582
+ PrimusNotifications,
2583
+ PrimusProvider,
2584
+ PrimusSidebar,
2585
+ PrimusStatCard,
2586
+ PrimusThemeProvider,
2587
+ PrimusThemeToggle,
2588
+ QuoteComparison,
2589
+ SecurityDashboard,
2590
+ TransactionHistory,
2591
+ UserProfile,
2592
+ themeColors,
2593
+ useNotifications,
2594
+ usePrimusAuth,
2595
+ usePrimusTheme,
2596
+ useRealtimeNotifications
2597
+ });