@retinalabsllc/zairusjs 0.2.4 → 0.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -55,10 +55,14 @@ __export(index_exports, {
55
55
  TextInput: () => TextInput,
56
56
  ThreeDActionButton: () => ThreeDActionButton,
57
57
  ThreeDButton: () => ThreeDButton,
58
+ UniversalAgentConsole: () => UniversalAgentConsole,
59
+ UniversalBillingPage: () => UniversalBillingPage,
60
+ UniversalDashboardPage: () => UniversalDashboardPage,
58
61
  UniversalHeader: () => UniversalHeader,
59
62
  UniversalIdentityPage: () => UniversalIdentityPage,
60
63
  UniversalMembersPage: () => UniversalMembersPage,
61
64
  UniversalOrganizationPage: () => UniversalOrganizationPage,
65
+ UniversalOverviewPage: () => UniversalOverviewPage,
62
66
  UniversalProfileSettings: () => UniversalProfileSettings,
63
67
  UniversalSidebar: () => UniversalSidebar,
64
68
  ZairusAuth: () => ZairusAuth
@@ -1232,11 +1236,12 @@ var TextInput = ({
1232
1236
  maxLength,
1233
1237
  disabled,
1234
1238
  readOnly,
1239
+ type = "text",
1235
1240
  onClick
1236
- }) => /* @__PURE__ */ import_react31.default.createElement("div", { className: "space-y-2 flex-1 w-full", onClick }, /* @__PURE__ */ import_react31.default.createElement("label", { className: "text-[10px] text-neutral-400 tracking-[0.2em] block uppercase" }, label), /* @__PURE__ */ import_react31.default.createElement(
1241
+ }) => /* @__PURE__ */ import_react31.default.createElement("div", { className: "space-y-2 flex-1 w-full", onClick }, label && /* @__PURE__ */ import_react31.default.createElement("label", { className: "text-[10px] text-neutral-400 tracking-[0.2em] block uppercase" }, label), /* @__PURE__ */ import_react31.default.createElement(
1237
1242
  "input",
1238
1243
  {
1239
- type: "text",
1244
+ type,
1240
1245
  value,
1241
1246
  onChange: (e) => onChange(e.target.value.substring(0, maxLength || 100)),
1242
1247
  placeholder,
@@ -1254,7 +1259,7 @@ var NumberInput = ({
1254
1259
  placeholder,
1255
1260
  maxLength,
1256
1261
  disabled
1257
- }) => /* @__PURE__ */ import_react31.default.createElement("div", { className: "space-y-2 flex-1 w-full" }, /* @__PURE__ */ import_react31.default.createElement("label", { className: "text-[10px] text-neutral-400 tracking-[0.2em] block uppercase" }, label), /* @__PURE__ */ import_react31.default.createElement(
1262
+ }) => /* @__PURE__ */ import_react31.default.createElement("div", { className: "space-y-2 flex-1 w-full" }, label && /* @__PURE__ */ import_react31.default.createElement("label", { className: "text-[10px] text-neutral-400 tracking-[0.2em] block uppercase" }, label), /* @__PURE__ */ import_react31.default.createElement(
1258
1263
  "input",
1259
1264
  {
1260
1265
  type: "text",
@@ -2371,6 +2376,376 @@ var UniversalProfileSettings = ({
2371
2376
  "Cancel"
2372
2377
  )))));
2373
2378
  };
2379
+
2380
+ // src/components/UniversalBillingPage.tsx
2381
+ var import_react47 = __toESM(require("react"));
2382
+ var import_react48 = require("@hugeicons/react");
2383
+ var import_core_free_icons13 = require("@hugeicons/core-free-icons");
2384
+ var PageSpinner3 = () => /* @__PURE__ */ import_react47.default.createElement("div", { className: "flex justify-center items-center py-12" }, /* @__PURE__ */ import_react47.default.createElement(import_react48.HugeiconsIcon, { icon: import_core_free_icons13.Loading03Icon, size: 32, className: "animate-spin mb-4 text-neutral-400" }));
2385
+ var ButtonSpinner4 = () => /* @__PURE__ */ import_react47.default.createElement(import_react48.HugeiconsIcon, { icon: import_core_free_icons13.Loading03Icon, size: 16, className: "animate-spin text-neutral-500" });
2386
+ var formatDate = (dateString) => {
2387
+ if (!dateString) return "N/A";
2388
+ return new Date(dateString).toLocaleDateString("en-US", {
2389
+ month: "long",
2390
+ day: "numeric",
2391
+ year: "numeric"
2392
+ });
2393
+ };
2394
+ var formatNaira = (amount) => {
2395
+ return `\u20A6${(amount || 0).toLocaleString("en-NG", { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`;
2396
+ };
2397
+ var UniversalBillingPage = ({
2398
+ headerTitle,
2399
+ headerDescription,
2400
+ isReadOnly = false,
2401
+ isModMode = false,
2402
+ metricPrimaryLabel,
2403
+ metricPrimaryValue,
2404
+ metricPrimarySubtext,
2405
+ metricSecondaryLabel,
2406
+ metricSecondaryValue,
2407
+ metricSecondarySubtext,
2408
+ showBillingOverview = false,
2409
+ billingStatus,
2410
+ nextBillingDate,
2411
+ lastPaidDate,
2412
+ showUsageMetrics = false,
2413
+ usageMetrics = [],
2414
+ showSearchAndFilter = false,
2415
+ searchQuery = "",
2416
+ onSearchChange,
2417
+ timeframe = "ALL",
2418
+ onTimeframeChange,
2419
+ invoices,
2420
+ isLoading,
2421
+ currentPage,
2422
+ totalPages,
2423
+ onPageChange,
2424
+ onPayInvoice,
2425
+ onUpdateInvoiceStatus
2426
+ }) => {
2427
+ const [currentView, setCurrentView] = (0, import_react47.useState)("list");
2428
+ const [selectedInvoice, setSelectedInvoice] = (0, import_react47.useState)(null);
2429
+ const [isTimeframeModalOpen, setIsTimeframeModalOpen] = (0, import_react47.useState)(false);
2430
+ const [isPaying, setIsPaying] = (0, import_react47.useState)(false);
2431
+ const [isActionModalOpen, setIsActionModalOpen] = (0, import_react47.useState)(false);
2432
+ const [isUpdating, setIsUpdating] = (0, import_react47.useState)(false);
2433
+ const [twoFactorCode, setTwoFactorCode] = (0, import_react47.useState)("");
2434
+ const handlePayment = async () => {
2435
+ if (!selectedInvoice || isReadOnly || !onPayInvoice || isPaying) return;
2436
+ setIsPaying(true);
2437
+ try {
2438
+ await onPayInvoice(selectedInvoice.id);
2439
+ setSelectedInvoice({ ...selectedInvoice, status: "PAID" });
2440
+ } finally {
2441
+ setIsPaying(false);
2442
+ }
2443
+ };
2444
+ const handleStatusUpdate = async (newStatus) => {
2445
+ if (!selectedInvoice || !twoFactorCode || isUpdating || !onUpdateInvoiceStatus) return;
2446
+ setIsUpdating(true);
2447
+ try {
2448
+ const res = await onUpdateInvoiceStatus(selectedInvoice.id, newStatus, twoFactorCode);
2449
+ if (res.success) {
2450
+ setIsActionModalOpen(false);
2451
+ setTwoFactorCode("");
2452
+ setSelectedInvoice({ ...selectedInvoice, status: newStatus });
2453
+ }
2454
+ } finally {
2455
+ setIsUpdating(false);
2456
+ }
2457
+ };
2458
+ return /* @__PURE__ */ import_react47.default.createElement("div", { className: "flex max-w-3xl rounded-2xl bg-white p-6 flex-col gap-8 animate-in fade-in duration-300 min-h-full" }, /* @__PURE__ */ import_react47.default.createElement(ManagedToaster, null), /* @__PURE__ */ import_react47.default.createElement("div", { className: "flex flex-col sm:flex-row sm:items-start justify-between gap-3 sm:gap-4" }, currentView === "list" ? /* @__PURE__ */ import_react47.default.createElement("div", { className: "min-w-0 w-full" }, /* @__PURE__ */ import_react47.default.createElement("h1", { className: "text-xl text-black mb-1 truncate tracking-tight" }, headerTitle), /* @__PURE__ */ import_react47.default.createElement("p", { className: "text-xs text-neutral-500 truncate mb-6" }, headerDescription), showSearchAndFilter && onSearchChange && onTimeframeChange && /* @__PURE__ */ import_react47.default.createElement("div", { className: "flex flex-col sm:flex-row gap-4 mb-4" }, /* @__PURE__ */ import_react47.default.createElement(
2459
+ TextInput,
2460
+ {
2461
+ placeholder: "Search by ID or Name...",
2462
+ value: searchQuery,
2463
+ onChange: onSearchChange
2464
+ }
2465
+ ), /* @__PURE__ */ import_react47.default.createElement(
2466
+ "button",
2467
+ {
2468
+ type: "button",
2469
+ onClick: () => setIsTimeframeModalOpen(true),
2470
+ className: "px-4 py-3 text-sm bg-transparent border-b border-neutral-200 text-black outline-none focus:border-black shrink-0 text-left"
2471
+ },
2472
+ timeframe === "ALL" ? "All Time" : timeframe === "24H" ? "Past 24 Hours" : timeframe === "7D" ? "Past 7 Days" : "Past 30 Days"
2473
+ ))) : /* @__PURE__ */ import_react47.default.createElement("div", { className: "flex flex-col items-start gap-3" }, /* @__PURE__ */ import_react47.default.createElement("button", { onClick: () => setCurrentView("list"), className: "text-[10px] text-neutral-400 hover:text-black tracking-[0.2em] flex items-center gap-1.5 transition-colors outline-none" }, /* @__PURE__ */ import_react47.default.createElement(import_react48.HugeiconsIcon, { icon: import_core_free_icons13.ArrowLeft01Icon, size: 12 }), " Back")), isReadOnly && currentView === "list" && /* @__PURE__ */ import_react47.default.createElement("span", { className: "px-3 py-1 bg-neutral-50 text-neutral-500 rounded-full text-[10px] tracking-[0.2em] shrink-0 w-fit" }, "Read Only Access")), currentView === "list" && /* @__PURE__ */ import_react47.default.createElement("div", { className: "w-full max-w-2xl" }, /* @__PURE__ */ import_react47.default.createElement("div", { className: "flex flex-col gap-8 w-full" }, (metricPrimaryLabel || metricSecondaryLabel) && /* @__PURE__ */ import_react47.default.createElement("div", { className: "flex flex-col sm:flex-row sm:justify-between sm:items-start pb-8 border-b border-neutral-100 gap-6 sm:gap-0" }, metricPrimaryLabel && /* @__PURE__ */ import_react47.default.createElement("div", { className: "min-w-0" }, /* @__PURE__ */ import_react47.default.createElement("h3", { className: "text-[10px] text-neutral-400 tracking-[0.2em] mb-2 truncate block uppercase" }, metricPrimaryLabel), /* @__PURE__ */ import_react47.default.createElement("div", { className: "text-xl text-black tracking-tight truncate" }, formatNaira(metricPrimaryValue)), metricPrimarySubtext && /* @__PURE__ */ import_react47.default.createElement("p", { className: "text-[10px] text-neutral-500 mt-1 tracking-widest uppercase" }, metricPrimarySubtext)), metricSecondaryLabel && /* @__PURE__ */ import_react47.default.createElement("div", { className: "min-w-0 sm:text-right" }, /* @__PURE__ */ import_react47.default.createElement("h3", { className: "text-[10px] text-neutral-400 tracking-[0.2em] mb-2 truncate block uppercase" }, metricSecondaryLabel), /* @__PURE__ */ import_react47.default.createElement("div", { className: "text-xl text-emerald-600 tracking-tight truncate" }, formatNaira(metricSecondaryValue)), metricSecondarySubtext && /* @__PURE__ */ import_react47.default.createElement("p", { className: "text-[10px] text-neutral-500 mt-1 tracking-widest uppercase" }, metricSecondarySubtext))), !isReadOnly && showBillingOverview && /* @__PURE__ */ import_react47.default.createElement("div", { className: "grid grid-cols-1 sm:grid-cols-3 gap-8 sm:gap-4" }, /* @__PURE__ */ import_react47.default.createElement("div", { className: "min-w-0" }, /* @__PURE__ */ import_react47.default.createElement("h3", { className: "text-[10px] text-neutral-400 tracking-[0.2em] mb-3 truncate block uppercase" }, "Billing Status"), /* @__PURE__ */ import_react47.default.createElement("div", { className: "flex items-center gap-2 min-w-0" }, /* @__PURE__ */ import_react47.default.createElement("div", { className: `w-2 h-2 rounded-full shrink-0 ${billingStatus === "ACTIVE" ? "bg-green-500" : "bg-neutral-300"}` }), /* @__PURE__ */ import_react47.default.createElement("p", { className: "text-xs text-black tracking-widest truncate" }, billingStatus || "UNKNOWN"))), /* @__PURE__ */ import_react47.default.createElement("div", { className: "min-w-0" }, /* @__PURE__ */ import_react47.default.createElement("h3", { className: "text-[10px] text-neutral-400 tracking-[0.2em] mb-3 truncate block uppercase" }, "Next Billing Date"), /* @__PURE__ */ import_react47.default.createElement("p", { className: "text-sm text-black truncate" }, formatDate(nextBillingDate))), lastPaidDate && /* @__PURE__ */ import_react47.default.createElement("div", { className: "min-w-0" }, /* @__PURE__ */ import_react47.default.createElement("h3", { className: "text-[10px] text-neutral-400 tracking-[0.2em] mb-3 truncate block uppercase" }, "Last Paid Date"), /* @__PURE__ */ import_react47.default.createElement("p", { className: "text-sm text-neutral-600 truncate" }, formatDate(lastPaidDate)))), !isReadOnly && showUsageMetrics && usageMetrics.length > 0 && /* @__PURE__ */ import_react47.default.createElement("div", { className: "pt-8 border-t border-neutral-100" }, /* @__PURE__ */ import_react47.default.createElement("h3", { className: "text-[10px] text-neutral-400 tracking-[0.2em] mb-6 truncate block uppercase" }, "Usage & Limits"), /* @__PURE__ */ import_react47.default.createElement("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-x-8 gap-y-4 text-sm text-black" }, usageMetrics.map((metric, idx) => /* @__PURE__ */ import_react47.default.createElement("div", { key: idx, className: "flex justify-between border-b border-neutral-50 pb-2" }, /* @__PURE__ */ import_react47.default.createElement("span", { className: "text-neutral-500 text-xs" }, metric.label), /* @__PURE__ */ import_react47.default.createElement("span", { className: "text-xs text-black" }, metric.value))))), /* @__PURE__ */ import_react47.default.createElement("div", { className: "pt-8 border-t border-neutral-100" }, /* @__PURE__ */ import_react47.default.createElement("h3", { className: "text-[10px] text-neutral-400 tracking-[0.2em] mb-4 truncate block uppercase" }, "Transaction History"), isLoading ? /* @__PURE__ */ import_react47.default.createElement(PageSpinner3, null) : invoices.length === 0 ? /* @__PURE__ */ import_react47.default.createElement("p", { className: "text-xs text-neutral-500 py-4" }, "No records found.") : /* @__PURE__ */ import_react47.default.createElement("div", { className: "flex flex-col min-w-0" }, /* @__PURE__ */ import_react47.default.createElement("div", { className: "divide-y divide-neutral-100" }, invoices.map((inv) => /* @__PURE__ */ import_react47.default.createElement("div", { key: inv.id, onClick: () => {
2474
+ setSelectedInvoice(inv);
2475
+ setCurrentView("details");
2476
+ }, className: "flex items-center justify-between py-4 hover:bg-neutral-50/50 cursor-pointer group min-w-0 px-2 transition-colors" }, /* @__PURE__ */ import_react47.default.createElement("div", { className: "flex flex-col gap-1 min-w-0 flex-1" }, /* @__PURE__ */ import_react47.default.createElement("p", { className: "text-sm text-black truncate pr-4" }, inv.name), /* @__PURE__ */ import_react47.default.createElement("p", { className: "text-xs text-neutral-500 truncate" }, inv.subtext)), /* @__PURE__ */ import_react47.default.createElement("div", { className: "flex flex-col items-end gap-1 shrink-0 pl-4" }, /* @__PURE__ */ import_react47.default.createElement("p", { className: "text-sm text-black" }, formatNaira(inv.amountDue)), /* @__PURE__ */ import_react47.default.createElement("span", { className: `text-[9px] tracking-widest px-2 py-0.5 rounded-full ${inv.status === "PAID" ? "bg-emerald-50 text-emerald-600" : "bg-neutral-50 text-neutral-600"}` }, inv.status))))), totalPages > 1 && /* @__PURE__ */ import_react47.default.createElement("div", { className: "flex items-center justify-between pt-4 mt-2" }, /* @__PURE__ */ import_react47.default.createElement("span", { className: "text-[10px] text-neutral-400 tracking-[0.2em]" }, "Page ", currentPage, " of ", totalPages), /* @__PURE__ */ import_react47.default.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ import_react47.default.createElement("button", { onClick: () => onPageChange(currentPage - 1), disabled: currentPage === 1 || isLoading, className: "p-2 border border-neutral-200 rounded-full bg-white text-neutral-500 hover:text-black outline-none disabled:opacity-30" }, /* @__PURE__ */ import_react47.default.createElement(import_react48.HugeiconsIcon, { icon: import_core_free_icons13.ArrowLeft01Icon, size: 14 })), /* @__PURE__ */ import_react47.default.createElement("button", { onClick: () => onPageChange(currentPage + 1), disabled: currentPage >= totalPages || isLoading, className: "p-2 border border-neutral-200 rounded-full bg-white text-neutral-500 hover:text-black outline-none disabled:opacity-30" }, /* @__PURE__ */ import_react47.default.createElement(import_react48.HugeiconsIcon, { icon: import_core_free_icons13.ArrowRight01Icon, size: 14 })))))))), currentView === "details" && selectedInvoice && /* @__PURE__ */ import_react47.default.createElement("div", { className: "w-full max-w-2xl animate-in fade-in duration-300" }, /* @__PURE__ */ import_react47.default.createElement("div", { className: "flex flex-col gap-6 w-full" }, /* @__PURE__ */ import_react47.default.createElement("div", null, /* @__PURE__ */ import_react47.default.createElement("span", { className: "text-[10px] tracking-[0.2em] text-neutral-400 block mb-1 uppercase" }, "Breakdown"), /* @__PURE__ */ import_react47.default.createElement("h2", { className: "text-xl text-black mb-1" }, selectedInvoice.name), /* @__PURE__ */ import_react47.default.createElement("p", { className: "text-xs text-neutral-500" }, "Generated on ", formatDate(selectedInvoice.createdAt))), /* @__PURE__ */ import_react47.default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-6 p-6 sm:p-8 rounded-2xl border border-neutral-100" }, /* @__PURE__ */ import_react47.default.createElement("div", null, /* @__PURE__ */ import_react47.default.createElement("span", { className: "text-[10px] tracking-[0.2em] text-neutral-400 block mb-1 uppercase" }, "Amount"), /* @__PURE__ */ import_react47.default.createElement("p", { className: "text-xl text-black" }, formatNaira(selectedInvoice.amountDue))), /* @__PURE__ */ import_react47.default.createElement("div", null, /* @__PURE__ */ import_react47.default.createElement("span", { className: "text-[10px] tracking-[0.2em] text-neutral-400 block mb-1 uppercase" }, "Status"), isModMode ? /* @__PURE__ */ import_react47.default.createElement(
2477
+ "button",
2478
+ {
2479
+ onClick: () => !isUpdating && setIsActionModalOpen(true),
2480
+ disabled: isUpdating,
2481
+ className: `flex items-center gap-3 text-xs text-black px-3 py-1.5 mt-1 border rounded-full transition-colors disabled:opacity-50 outline-none ${isActionModalOpen ? "bg-neutral-50 border-neutral-300" : "bg-white border-neutral-200 hover:bg-neutral-50"}`
2482
+ },
2483
+ selectedInvoice.status,
2484
+ isUpdating ? /* @__PURE__ */ import_react47.default.createElement(ButtonSpinner4, null) : /* @__PURE__ */ import_react47.default.createElement(import_react48.HugeiconsIcon, { icon: import_core_free_icons13.ArrowDown01Icon, size: 14, className: "text-neutral-400" })
2485
+ ) : /* @__PURE__ */ import_react47.default.createElement("span", { className: `text-[10px] tracking-widest px-3 py-1 mt-1 inline-block rounded-full ${selectedInvoice.status === "PAID" ? "bg-emerald-100 text-emerald-700" : "bg-neutral-100 text-neutral-700"}` }, selectedInvoice.status)), /* @__PURE__ */ import_react47.default.createElement("div", { className: "md:col-span-2 pt-4 border-t border-neutral-200/60 mt-2" }, /* @__PURE__ */ import_react47.default.createElement("span", { className: "text-[10px] tracking-[0.2em] text-neutral-400 block mb-1 uppercase" }, "Reference ID"), /* @__PURE__ */ import_react47.default.createElement("p", { className: "text-xs text-neutral-500 bg-white px-3 py-2 rounded-full border border-neutral-200 inline-block" }, selectedInvoice.id))), /* @__PURE__ */ import_react47.default.createElement("div", { className: "flex flex-col sm:flex-row sm:items-center justify-end gap-4 pt-4" }, !isModMode && selectedInvoice.status === "SCHEDULED" && onPayInvoice && /* @__PURE__ */ import_react47.default.createElement("div", { className: "flex flex-col items-end gap-2 w-full sm:w-auto" }, /* @__PURE__ */ import_react47.default.createElement(
2486
+ ThreeDActionButton,
2487
+ {
2488
+ onClick: handlePayment,
2489
+ disabled: isReadOnly || isPaying,
2490
+ isLoading: isPaying,
2491
+ className: "w-full sm:w-auto"
2492
+ },
2493
+ "Pay Invoice"
2494
+ )), !isModMode && selectedInvoice.status === "PAID" && /* @__PURE__ */ import_react47.default.createElement("span", { className: "text-[11px] tracking-widest text-emerald-600 px-6 py-3 bg-emerald-50 rounded-full" }, "Invoice Completed")))), isTimeframeModalOpen && showSearchAndFilter && onTimeframeChange && /* @__PURE__ */ import_react47.default.createElement("div", { className: "fixed inset-0 z-110 flex items-center justify-center p-4" }, /* @__PURE__ */ import_react47.default.createElement("div", { className: "absolute inset-0 bg-black/30", onClick: () => setIsTimeframeModalOpen(false) }), /* @__PURE__ */ import_react47.default.createElement("div", { className: "relative w-80 bg-white shadow-2xl rounded-2xl flex flex-col items-center overflow-hidden animate-in zoom-in-95 duration-200" }, /* @__PURE__ */ import_react47.default.createElement("div", { className: "p-6 text-center w-full" }, /* @__PURE__ */ import_react47.default.createElement("h3", { className: "text-[14px] text-black tracking-tight mb-2" }, "Select Timeframe"), /* @__PURE__ */ import_react47.default.createElement("p", { className: "text-[12px] text-neutral-500" }, "Choose the range of transactions to display.")), /* @__PURE__ */ import_react47.default.createElement("div", { className: "w-full flex flex-col pl-2 pr-2" }, [
2495
+ { value: "ALL", label: "All Time" },
2496
+ { value: "24H", label: "Past 24 Hours" },
2497
+ { value: "7D", label: "Past 7 Days" },
2498
+ { value: "30D", label: "Past 30 Days" }
2499
+ ].map((option) => /* @__PURE__ */ import_react47.default.createElement(
2500
+ "button",
2501
+ {
2502
+ key: option.value,
2503
+ type: "button",
2504
+ onClick: () => {
2505
+ onTimeframeChange(option.value);
2506
+ setIsTimeframeModalOpen(false);
2507
+ },
2508
+ className: `text-left px-4 py-3 text-[12px] tracking-wide transition-colors rounded-full flex items-center justify-between outline-none ${timeframe === option.value ? "bg-neutral-100 text-black" : "text-neutral-500 hover:bg-neutral-50 hover:text-black"}`
2509
+ },
2510
+ /* @__PURE__ */ import_react47.default.createElement("span", { className: "truncate pr-2" }, option.label),
2511
+ timeframe === option.value && /* @__PURE__ */ import_react47.default.createElement("div", { className: "w-1.5 h-1.5 bg-black rounded-full shrink-0" })
2512
+ ))), /* @__PURE__ */ import_react47.default.createElement("div", { className: "w-full flex mt-2" }, /* @__PURE__ */ import_react47.default.createElement("button", { onClick: () => setIsTimeframeModalOpen(false), className: "w-full py-2.5 text-[13px] text-neutral-600 hover:bg-neutral-50 transition-colors outline-none" }, "Cancel")))), isActionModalOpen && isModMode && /* @__PURE__ */ import_react47.default.createElement("div", { className: "fixed inset-0 z-110 flex items-center justify-center p-4" }, /* @__PURE__ */ import_react47.default.createElement("div", { className: "absolute inset-0 bg-black/30", onClick: () => !isUpdating && setIsActionModalOpen(false) }), /* @__PURE__ */ import_react47.default.createElement("div", { className: "relative w-80 bg-white shadow-2xl rounded-2xl flex flex-col items-center overflow-hidden animate-in zoom-in-95 duration-200" }, /* @__PURE__ */ import_react47.default.createElement("div", { className: "p-6 text-center w-full" }, /* @__PURE__ */ import_react47.default.createElement("h3", { className: "text-[14px] text-black tracking-tight mb-2" }, "Update Invoice Status"), /* @__PURE__ */ import_react47.default.createElement(
2513
+ TextInput,
2514
+ {
2515
+ placeholder: "Enter 2FA Code...",
2516
+ value: twoFactorCode,
2517
+ onChange: setTwoFactorCode,
2518
+ type: "password"
2519
+ }
2520
+ )), /* @__PURE__ */ import_react47.default.createElement("div", { className: "w-full flex flex-col pl-2 pr-2" }, ["SCHEDULED", "PAID", "FAILED", "CANCELED"].map((statusOption) => /* @__PURE__ */ import_react47.default.createElement(
2521
+ "button",
2522
+ {
2523
+ key: statusOption,
2524
+ onClick: () => handleStatusUpdate(statusOption),
2525
+ disabled: isUpdating || !twoFactorCode,
2526
+ className: `text-left px-4 py-3 text-[12px] tracking-wide transition-colors rounded-full flex items-center justify-between outline-none ${selectedInvoice?.status === statusOption ? "bg-neutral-100 text-black" : "text-neutral-500 hover:bg-neutral-50 hover:text-black"}`
2527
+ },
2528
+ /* @__PURE__ */ import_react47.default.createElement("span", { className: "truncate pr-2" }, statusOption),
2529
+ selectedInvoice?.status === statusOption && /* @__PURE__ */ import_react47.default.createElement("div", { className: "w-1.5 h-1.5 bg-black rounded-full shrink-0" })
2530
+ ))), /* @__PURE__ */ import_react47.default.createElement("div", { className: "w-full flex mt-2" }, /* @__PURE__ */ import_react47.default.createElement("button", { onClick: () => setIsActionModalOpen(false), disabled: isUpdating, className: "w-full py-2.5 text-[13px] text-neutral-600 hover:bg-neutral-50 transition-colors disabled:opacity-50 outline-none" }, "Cancel")))));
2531
+ };
2532
+
2533
+ // src/components/UniversalDashboardPage.tsx
2534
+ var import_react49 = __toESM(require("react"));
2535
+ var import_react50 = require("@hugeicons/react");
2536
+ var import_core_free_icons14 = require("@hugeicons/core-free-icons");
2537
+ var UniversalDashboardPage = ({
2538
+ headerTitle,
2539
+ headerDescription,
2540
+ timeframes = [],
2541
+ activeTimeframe,
2542
+ onTimeframeChange,
2543
+ stats,
2544
+ lists,
2545
+ isLoading = false
2546
+ }) => {
2547
+ const [isTimeframeModalOpen, setIsTimeframeModalOpen] = (0, import_react49.useState)(false);
2548
+ const selectedTimeframe = timeframes.find((t) => t.id === activeTimeframe) || timeframes[0];
2549
+ if (isLoading) {
2550
+ return /* @__PURE__ */ import_react49.default.createElement("div", { className: "flex justify-center items-center py-12" }, /* @__PURE__ */ import_react49.default.createElement(import_react50.HugeiconsIcon, { icon: import_core_free_icons14.Loading03Icon, size: 32, className: "animate-spin mb-4 text-black" }));
2551
+ }
2552
+ return /* @__PURE__ */ import_react49.default.createElement("div", { className: "flex flex-col gap-8 animate-in fade-in duration-300 min-h-full pb-10" }, /* @__PURE__ */ import_react49.default.createElement(ManagedToaster, null), /* @__PURE__ */ import_react49.default.createElement("div", { className: "flex flex-col sm:flex-row items-start sm:items-center justify-between gap-4" }, /* @__PURE__ */ import_react49.default.createElement("div", null, /* @__PURE__ */ import_react49.default.createElement("h1", { className: "text-xl text-black mb-1 tracking-tight" }, headerTitle), /* @__PURE__ */ import_react49.default.createElement("p", { className: "text-xs text-neutral-500" }, headerDescription)), timeframes.length > 0 && selectedTimeframe && onTimeframeChange && /* @__PURE__ */ import_react49.default.createElement(
2553
+ "button",
2554
+ {
2555
+ onClick: () => setIsTimeframeModalOpen(true),
2556
+ className: "flex items-center gap-3 px-4 py-2 text-xs bg-white text-black outline-none rounded-full transition-colors hover:bg-neutral-50 shrink-0"
2557
+ },
2558
+ /* @__PURE__ */ import_react49.default.createElement("span", null, selectedTimeframe.label),
2559
+ /* @__PURE__ */ import_react49.default.createElement(import_react50.HugeiconsIcon, { icon: import_core_free_icons14.ArrowDown01Icon, size: 14, className: "text-neutral-400" })
2560
+ )), stats.length > 0 && /* @__PURE__ */ import_react49.default.createElement("div", { className: "w-full rounded-2xl overflow-hidden bg-white" }, /* @__PURE__ */ import_react49.default.createElement("div", { className: "grid grid-cols-2 md:grid-cols-5 divide-y md:divide-y-0 md:divide-x divide-neutral-100" }, stats.map((stat, idx) => /* @__PURE__ */ import_react49.default.createElement("div", { key: idx, className: "p-6 flex flex-col gap-1 min-w-0" }, /* @__PURE__ */ import_react49.default.createElement("p", { className: "text-[10px] tracking-[0.2em] text-neutral-400 truncate uppercase" }, stat.label), /* @__PURE__ */ import_react49.default.createElement("p", { className: `text-xl tracking-tight truncate ${stat.valueClass || "text-black"}` }, stat.value))))), lists.length > 0 && /* @__PURE__ */ import_react49.default.createElement("div", { className: "flex flex-col gap-8 w-full max-w-4xl" }, lists.map((list, idx) => /* @__PURE__ */ import_react49.default.createElement("div", { key: idx, className: "bg-white rounded-2xl p-6 flex flex-col min-w-0" }, /* @__PURE__ */ import_react49.default.createElement("div", { className: "flex items-center gap-3 mb-6" }, /* @__PURE__ */ import_react49.default.createElement("div", { className: "text-neutral-400" }, list.icon), /* @__PURE__ */ import_react49.default.createElement("h2", { className: "text-[11px] text-black tracking-[0.2em] uppercase" }, list.title)), /* @__PURE__ */ import_react49.default.createElement("div", { className: "divide-y divide-neutral-100 flex-1 overflow-y-auto" }, list.items.length === 0 ? /* @__PURE__ */ import_react49.default.createElement("p", { className: "text-xs text-neutral-500 py-4" }, list.emptyMessage) : list.items.map((item) => /* @__PURE__ */ import_react49.default.createElement("div", { key: item.id, className: "flex flex-col sm:flex-row sm:items-center justify-between py-4 gap-2 min-w-0 group" }, /* @__PURE__ */ import_react49.default.createElement("div", { className: "min-w-0 flex-1" }, /* @__PURE__ */ import_react49.default.createElement("p", { className: "text-sm text-black truncate pr-4" }, item.primaryText), /* @__PURE__ */ import_react49.default.createElement("p", { className: "text-[10px] text-neutral-500 truncate tracking-widest mt-0.5" }, item.secondaryText)), /* @__PURE__ */ import_react49.default.createElement("div", { className: "flex items-center gap-4 shrink-0 pl-4" }, item.rightText && /* @__PURE__ */ import_react49.default.createElement("p", { className: "text-xs text-black" }, item.rightText), item.rightBadge && /* @__PURE__ */ import_react49.default.createElement("span", { className: `text-[9px] tracking-widest px-2.5 py-1 rounded-full ${item.rightBadgeClass || "bg-neutral-50 text-neutral-600"}` }, item.rightBadge)))))))), isTimeframeModalOpen && timeframes.length > 0 && onTimeframeChange && /* @__PURE__ */ import_react49.default.createElement("div", { className: "fixed inset-0 z-110 flex items-center justify-center p-4" }, /* @__PURE__ */ import_react49.default.createElement("div", { className: "absolute inset-0 bg-black/30", onClick: () => setIsTimeframeModalOpen(false) }), /* @__PURE__ */ import_react49.default.createElement("div", { className: "relative w-72 bg-white shadow-2xl rounded-2xl flex flex-col items-center overflow-hidden animate-in zoom-in-95 duration-200" }, /* @__PURE__ */ import_react49.default.createElement("div", { className: "p-6 text-center w-full" }, /* @__PURE__ */ import_react49.default.createElement("h3", { className: "text-[14px] text-black tracking-tight" }, "Select Timeframe")), /* @__PURE__ */ import_react49.default.createElement("div", { className: "w-full flex flex-col pl-2 pr-2 pb-2" }, timeframes.map((tf) => /* @__PURE__ */ import_react49.default.createElement(
2561
+ "button",
2562
+ {
2563
+ key: tf.id,
2564
+ onClick: () => {
2565
+ onTimeframeChange(tf.id);
2566
+ setIsTimeframeModalOpen(false);
2567
+ },
2568
+ className: `text-left px-4 py-3 text-[12px] tracking-wide transition-colors rounded-full flex items-center justify-between outline-none ${activeTimeframe === tf.id ? "bg-neutral-100 text-black" : "text-neutral-500 hover:bg-neutral-50 hover:text-black"}`
2569
+ },
2570
+ /* @__PURE__ */ import_react49.default.createElement("span", { className: "truncate pr-2" }, tf.label),
2571
+ activeTimeframe === tf.id && /* @__PURE__ */ import_react49.default.createElement("div", { className: "w-1.5 h-1.5 bg-black rounded-full shrink-0" })
2572
+ ))), /* @__PURE__ */ import_react49.default.createElement("div", { className: "w-full flex border-t border-neutral-50" }, /* @__PURE__ */ import_react49.default.createElement(
2573
+ "button",
2574
+ {
2575
+ onClick: () => setIsTimeframeModalOpen(false),
2576
+ className: "w-full py-2.5 text-[13px] text-neutral-600 hover:bg-neutral-50 transition-colors outline-none"
2577
+ },
2578
+ "Cancel"
2579
+ )))));
2580
+ };
2581
+
2582
+ // src/components/UniversalAgentConsole.tsx
2583
+ var import_react51 = __toESM(require("react"));
2584
+ var import_react52 = require("@hugeicons/react");
2585
+ var import_core_free_icons15 = require("@hugeicons/core-free-icons");
2586
+ var formatKeyName = (key) => key.replace(/([A-Z])/g, " $1").replace(/^./, (str) => str.toUpperCase()).trim();
2587
+ var toTitleCaseSafe = (str) => {
2588
+ if (!str) return "";
2589
+ return str.toLowerCase().split(" ").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
2590
+ };
2591
+ var IGNORED_KEYS = ["id", "fileName", "contentType", "fileSizeInBytes", "categoryCode", "specificCode", "iAgree"];
2592
+ var UniversalAgentConsole = ({
2593
+ headerTitle,
2594
+ headerDescription,
2595
+ stats,
2596
+ tabs,
2597
+ activeTab,
2598
+ onTabChange,
2599
+ listData,
2600
+ isLoadingList,
2601
+ currentPage,
2602
+ totalPages,
2603
+ onPageChange,
2604
+ onRowClick,
2605
+ currentView,
2606
+ onBackToList,
2607
+ selectedApp,
2608
+ currentAgentId,
2609
+ onAcceptApplication,
2610
+ onUpdateStatus,
2611
+ onUploadArchives,
2612
+ onDeleteArchive
2613
+ }) => {
2614
+ const archiveRef = (0, import_react51.useRef)(null);
2615
+ const [pendingFiles, setPendingFiles] = (0, import_react51.useState)([]);
2616
+ const [isUploading, setIsUploading] = (0, import_react51.useState)(false);
2617
+ const [isActioning, setIsActioning] = (0, import_react51.useState)(false);
2618
+ const [actionModal, setActionModal] = (0, import_react51.useState)(null);
2619
+ const [actionMessage, setActionMessage] = (0, import_react51.useState)("");
2620
+ const [archiveToDelete, setArchiveToDelete] = (0, import_react51.useState)(null);
2621
+ const handleFileSelect = (e) => {
2622
+ if (e.target.files && e.target.files.length > 0) {
2623
+ setPendingFiles((prev) => [...prev, ...Array.from(e.target.files)]);
2624
+ }
2625
+ setTimeout(() => {
2626
+ if (archiveRef.current) archiveRef.current.value = "";
2627
+ }, 0);
2628
+ };
2629
+ const executeUpload = async () => {
2630
+ if (pendingFiles.length === 0 || !selectedApp) return;
2631
+ setIsUploading(true);
2632
+ try {
2633
+ const payloads = await Promise.all(pendingFiles.map(async (file) => {
2634
+ const base64data = await new Promise((resolve, reject) => {
2635
+ const reader = new FileReader();
2636
+ reader.readAsDataURL(file);
2637
+ reader.onload = () => resolve(reader.result);
2638
+ reader.onerror = (error) => reject(error);
2639
+ });
2640
+ return { imageBase64: base64data, fileName: file.name, fileType: file.type, fileSize: file.size };
2641
+ }));
2642
+ const res = await onUploadArchives(selectedApp.id, payloads);
2643
+ if (res.success) setPendingFiles([]);
2644
+ } finally {
2645
+ setIsUploading(false);
2646
+ }
2647
+ };
2648
+ const DynamicArrayAccordion = ({ items, parentKey }) => {
2649
+ const [activeFAQ, setActiveFAQ] = (0, import_react51.useState)(null);
2650
+ return /* @__PURE__ */ import_react51.default.createElement("div", { className: "flex flex-col relative z-10 bg-transparent w-full mt-2 border-t border-neutral-100" }, items.map((item, index) => {
2651
+ const isOpen = activeFAQ === index;
2652
+ let label = `${parentKey ? formatKeyName(parentKey) : "Item"} ${index + 1}`;
2653
+ if (item.fullName) label = toTitleCaseSafe(item.fullName);
2654
+ else if (item.role) label = item.role;
2655
+ else if (item.proposedName) label = toTitleCaseSafe(item.proposedName);
2656
+ return /* @__PURE__ */ import_react51.default.createElement("div", { key: index, className: `transition-all duration-300 ${index !== items.length - 1 ? "border-b border-neutral-100" : ""}` }, /* @__PURE__ */ import_react51.default.createElement("button", { className: "flex items-center justify-between w-full gap-4 text-left py-5 md:py-6 group outline-none bg-transparent", onClick: () => setActiveFAQ(isOpen ? null : index) }, /* @__PURE__ */ import_react51.default.createElement("span", { className: `text-[13px] md:text-[14px] transition-colors ${isOpen ? "text-black" : "text-neutral-700 group-hover:text-black"}` }, label), /* @__PURE__ */ import_react51.default.createElement("div", { className: `shrink-0 flex items-center justify-center w-8 h-8 rounded-full border transition-all duration-300 ${isOpen ? "rotate-180 border-black text-black" : "border-neutral-300 text-neutral-500"}` }, /* @__PURE__ */ import_react51.default.createElement(import_react52.HugeiconsIcon, { icon: import_core_free_icons15.ArrowDown01Icon, size: 16 }))), /* @__PURE__ */ import_react51.default.createElement("div", { className: `grid transition-all duration-300 ease-in-out ${isOpen ? "grid-rows-[1fr] pb-6 md:pb-8 opacity-100" : "grid-rows-[0fr] opacity-0"}` }, /* @__PURE__ */ import_react51.default.createElement("div", { className: "overflow-hidden" }, /* @__PURE__ */ import_react51.default.createElement("div", { className: "pt-2 flex flex-col gap-3 pr-4 md:pr-12" }, renderDynamicObject(item)))));
2657
+ }));
2658
+ };
2659
+ const renderValue = (key, value) => {
2660
+ if (value === null || value === void 0 || value === "") return null;
2661
+ if (typeof value === "string") {
2662
+ if (value.startsWith("http") || value.startsWith("data:image")) return /* @__PURE__ */ import_react51.default.createElement("a", { href: value, download: true, target: "_blank", rel: "noopener noreferrer", className: "flex items-center gap-2 px-5 py-2 bg-white border border-neutral-200 text-black text-[11px] tracking-widest rounded-full hover:bg-neutral-50 transition-colors w-fit outline-none mt-2" }, /* @__PURE__ */ import_react51.default.createElement(import_react52.HugeiconsIcon, { icon: import_core_free_icons15.Download01Icon, size: 14 }), " Download File");
2663
+ if (key.toLowerCase().includes("name") && !value.includes("@")) return /* @__PURE__ */ import_react51.default.createElement("p", { className: "text-[12px] md:text-[13px] leading-[1.8] text-neutral-600" }, toTitleCaseSafe(value));
2664
+ return /* @__PURE__ */ import_react51.default.createElement("p", { className: "text-[12px] md:text-[13px] leading-[1.8] text-neutral-600" }, value);
2665
+ }
2666
+ if (Array.isArray(value)) {
2667
+ const validItems = value.filter((item) => item !== null && item !== void 0 && item !== "");
2668
+ if (validItems.length === 0) return null;
2669
+ if (typeof validItems[0] === "string") return /* @__PURE__ */ import_react51.default.createElement("ul", { className: "list-disc pl-4 mt-1" }, validItems.map((v, i) => /* @__PURE__ */ import_react51.default.createElement("li", { key: i, className: "text-[12px] md:text-[13px] leading-[1.8] text-neutral-600" }, toTitleCaseSafe(v))));
2670
+ return /* @__PURE__ */ import_react51.default.createElement(DynamicArrayAccordion, { items: validItems, parentKey: key });
2671
+ }
2672
+ if (typeof value === "object") {
2673
+ if (Object.keys(value).length === 0) return null;
2674
+ const renderedObj = renderDynamicObject(value);
2675
+ if (!renderedObj || Array.isArray(renderedObj) && renderedObj.length === 0) return null;
2676
+ return /* @__PURE__ */ import_react51.default.createElement("div", { className: "flex flex-col gap-3 mt-1 w-full border-l border-neutral-100 pl-4 py-2" }, renderedObj);
2677
+ }
2678
+ return /* @__PURE__ */ import_react51.default.createElement("span", { className: "text-sm text-black" }, String(value));
2679
+ };
2680
+ const renderDynamicObject = (obj) => {
2681
+ if (!obj) return null;
2682
+ const entries = Object.entries(obj).filter(([k, v]) => {
2683
+ if (IGNORED_KEYS.includes(k) || v === null || v === "" || v === void 0) return false;
2684
+ if (Array.isArray(v) && v.filter((item) => item !== null && item !== "").length === 0) return false;
2685
+ if (typeof v === "object" && !Array.isArray(v) && Object.keys(v).length === 0) return false;
2686
+ return true;
2687
+ });
2688
+ if (entries.length === 0) return null;
2689
+ return entries.map(([k, v]) => /* @__PURE__ */ import_react51.default.createElement("div", { key: k, className: "flex flex-col items-start min-w-0 wrap-break-word w-full mb-3 last:mb-0" }, /* @__PURE__ */ import_react51.default.createElement("span", { className: "text-[10px] tracking-[0.2em] text-neutral-400 mb-1 uppercase" }, formatKeyName(k)), renderValue(k, v)));
2690
+ };
2691
+ return /* @__PURE__ */ import_react51.default.createElement("div", { className: "flex flex-col gap-8 animate-in fade-in duration-300 min-h-full pb-10" }, /* @__PURE__ */ import_react51.default.createElement(ManagedToaster, null), currentView === "list" && /* @__PURE__ */ import_react51.default.createElement(import_react51.default.Fragment, null, /* @__PURE__ */ import_react51.default.createElement("div", { className: "flex flex-col items-start gap-1" }, /* @__PURE__ */ import_react51.default.createElement("h1", { className: "text-xl text-black tracking-tight" }, headerTitle), /* @__PURE__ */ import_react51.default.createElement("p", { className: "text-sm text-neutral-500" }, headerDescription)), stats.length > 0 && /* @__PURE__ */ import_react51.default.createElement("div", { className: "w-full rounded-2xl max-w-3xl overflow-hidden bg-white" }, /* @__PURE__ */ import_react51.default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-3 divide-y md:divide-y-0 md:divide-x divide-neutral-100" }, stats.map((stat, idx) => /* @__PURE__ */ import_react51.default.createElement("div", { key: idx, className: "p-6 flex items-center gap-4 hover:bg-neutral-50/50 transition-colors min-w-0" }, /* @__PURE__ */ import_react51.default.createElement("div", { className: "w-12 h-12 rounded-full border border-neutral-200 bg-white flex items-center justify-center text-black shrink-0" }, stat.icon), /* @__PURE__ */ import_react51.default.createElement("div", { className: "min-w-0 flex-1" }, /* @__PURE__ */ import_react51.default.createElement("p", { className: "text-[10px] tracking-[0.2em] text-neutral-400 mb-1 truncate uppercase" }, stat.label), /* @__PURE__ */ import_react51.default.createElement("p", { className: "text-xl text-black tracking-tight truncate" }, stat.value)))))), tabs.length > 0 && /* @__PURE__ */ import_react51.default.createElement("div", { className: "flex items-center gap-6" }, tabs.map((tab) => /* @__PURE__ */ import_react51.default.createElement("button", { key: tab.id, onClick: () => onTabChange(tab.id), className: `pb-3 text-sm transition-colors outline-none ${activeTab === tab.id ? "text-black border-b border-black" : "text-neutral-400 hover:text-black"}` }, tab.label))), /* @__PURE__ */ import_react51.default.createElement("div", { className: "w-full bg-white rounded-2xl max-w-3xl overflow-hidden flex flex-col min-h-100" }, isLoadingList ? /* @__PURE__ */ import_react51.default.createElement("div", { className: "flex justify-center items-center py-12" }, /* @__PURE__ */ import_react51.default.createElement(import_react52.HugeiconsIcon, { icon: import_core_free_icons15.Loading03Icon, size: 32, className: "animate-spin text-black" })) : listData.length === 0 ? /* @__PURE__ */ import_react51.default.createElement("div", { className: "flex-1 flex justify-center items-center text-neutral-500 text-sm py-20" }, "No matching applications found.") : /* @__PURE__ */ import_react51.default.createElement(import_react51.default.Fragment, null, /* @__PURE__ */ import_react51.default.createElement("div", { className: "divide-y divide-neutral-100 flex-1" }, listData.map((item) => /* @__PURE__ */ import_react51.default.createElement("div", { key: item.id, onClick: () => onRowClick(item.id), className: "flex items-center justify-between p-5 hover:bg-neutral-50/50 transition-colors cursor-pointer group min-w-0" }, /* @__PURE__ */ import_react51.default.createElement("div", { className: "min-w-0 flex-1" }, /* @__PURE__ */ import_react51.default.createElement("p", { className: "text-sm text-black truncate pr-4" }, item.title), /* @__PURE__ */ import_react51.default.createElement("p", { className: "text-xs text-neutral-500 truncate mt-1" }, item.subtitle)), /* @__PURE__ */ import_react51.default.createElement("div", { className: "flex flex-col items-end gap-1 shrink-0 pl-4" }, /* @__PURE__ */ import_react51.default.createElement("span", { className: `text-[10px] tracking-widest px-3 py-1 rounded-full uppercase ${item.status === "COMPLETED" ? "bg-emerald-50 text-emerald-600" : "bg-neutral-50 text-neutral-600"}` }, item.status.replace(/_/g, " ")), /* @__PURE__ */ import_react51.default.createElement("span", { className: "text-[10px] text-neutral-400 mt-1" }, item.date))))), totalPages > 1 && /* @__PURE__ */ import_react51.default.createElement("div", { className: "flex items-center justify-between p-5 bg-neutral-50/50" }, /* @__PURE__ */ import_react51.default.createElement("span", { className: "text-[10px] text-neutral-400 tracking-[0.2em]" }, "Page ", currentPage, " of ", totalPages), /* @__PURE__ */ import_react51.default.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ import_react51.default.createElement("button", { onClick: () => onPageChange(currentPage - 1), disabled: currentPage === 1, className: "p-2 border border-neutral-200 rounded-full bg-white text-neutral-500 hover:text-black outline-none disabled:opacity-30" }, /* @__PURE__ */ import_react51.default.createElement(import_react52.HugeiconsIcon, { icon: import_core_free_icons15.ArrowLeft01Icon, size: 14 })), /* @__PURE__ */ import_react51.default.createElement("button", { onClick: () => onPageChange(currentPage + 1), disabled: currentPage >= totalPages, className: "p-2 border border-neutral-200 rounded-full bg-white text-neutral-500 hover:text-black outline-none disabled:opacity-30" }, /* @__PURE__ */ import_react51.default.createElement(import_react52.HugeiconsIcon, { icon: import_core_free_icons15.ArrowRight01Icon, size: 14 }))))))), currentView === "details" && selectedApp && /* @__PURE__ */ import_react51.default.createElement("div", { className: "w-full bg-white rounded-2xl p-6 sm:p-10 animate-in fade-in duration-300 max-w-3xl flex flex-col" }, /* @__PURE__ */ import_react51.default.createElement("div", { className: "flex items-center justify-between gap-4 pb-6" }, /* @__PURE__ */ import_react51.default.createElement("button", { onClick: () => {
2692
+ onBackToList();
2693
+ setPendingFiles([]);
2694
+ }, className: "flex items-center gap-2 text-[10px] text-neutral-400 hover:text-black tracking-widest transition-colors outline-none uppercase" }, /* @__PURE__ */ import_react51.default.createElement(import_react52.HugeiconsIcon, { icon: import_core_free_icons15.ArrowLeft01Icon, size: 14 }), " Back to List"), /* @__PURE__ */ import_react51.default.createElement("span", { className: `text-[10px] tracking-widest px-4 py-1.5 rounded-full uppercase ${selectedApp.status === "COMPLETED" ? "bg-emerald-50 text-emerald-600" : "bg-neutral-50 text-neutral-600"}` }, selectedApp.status.replace(/_/g, " "))), /* @__PURE__ */ import_react51.default.createElement("div", { className: "flex flex-col gap-2 mb-8" }, /* @__PURE__ */ import_react51.default.createElement("h2", { className: "text-xl text-black tracking-tight" }, selectedApp.name || selectedApp.title), /* @__PURE__ */ import_react51.default.createElement("p", { className: "text-sm text-neutral-500" }, selectedApp.type ? selectedApp.type.replace(/_/g, " ").toLowerCase().replace(/\b\w/g, (c) => c.toUpperCase()) : selectedApp.subtitle)), selectedApp.agentId === currentAgentId && selectedApp.metadata && Object.keys(selectedApp.metadata).length > 0 ? /* @__PURE__ */ import_react51.default.createElement("div", { className: "flex flex-col gap-5" }, renderDynamicObject(selectedApp.metadata)) : selectedApp.agentId === currentAgentId ? /* @__PURE__ */ import_react51.default.createElement("div", { className: "flex flex-col gap-5" }, /* @__PURE__ */ import_react51.default.createElement("p", { className: "text-sm text-neutral-500" }, "No application data extracted.")) : null, selectedApp.agentId && /* @__PURE__ */ import_react51.default.createElement("div", { className: "flex flex-col gap-4 pt-8 mt-4 border-t border-neutral-100" }, /* @__PURE__ */ import_react51.default.createElement("div", { className: "flex flex-col gap-1 mb-4" }, /* @__PURE__ */ import_react51.default.createElement("h3", { className: "text-sm text-black" }, "Official Archives"), /* @__PURE__ */ import_react51.default.createElement("p", { className: "text-xs text-neutral-500 leading-relaxed" }, "Upload final certificates or documents. Once marked completed, the archive unlocks for the user.")), selectedApp.archives?.map((arch) => /* @__PURE__ */ import_react51.default.createElement("div", { key: arch.id, className: "flex items-center justify-between p-4 bg-emerald-50 rounded-full text-emerald-800 text-sm w-full" }, /* @__PURE__ */ import_react51.default.createElement("div", { className: "flex items-center gap-3 min-w-0" }, /* @__PURE__ */ import_react51.default.createElement(import_react52.HugeiconsIcon, { icon: import_core_free_icons15.File02Icon, size: 18, className: "shrink-0" }), /* @__PURE__ */ import_react51.default.createElement("span", { className: "truncate pr-2" }, arch.name)), /* @__PURE__ */ import_react51.default.createElement("button", { onClick: () => setArchiveToDelete(arch), className: "text-emerald-700 hover:text-red-500 transition-colors p-1 outline-none shrink-0" }, /* @__PURE__ */ import_react51.default.createElement(import_react52.HugeiconsIcon, { icon: import_core_free_icons15.Delete02Icon, size: 16 })))), pendingFiles.map((file, idx) => /* @__PURE__ */ import_react51.default.createElement("div", { key: idx, className: "flex items-center justify-between text-neutral-600 text-sm w-full" }, /* @__PURE__ */ import_react51.default.createElement("div", { className: "flex items-center gap-3 min-w-0" }, /* @__PURE__ */ import_react51.default.createElement(import_react52.HugeiconsIcon, { icon: import_core_free_icons15.AttachmentIcon, size: 18, className: "shrink-0" }), /* @__PURE__ */ import_react51.default.createElement("span", { className: "truncate pr-2" }, file.name)), /* @__PURE__ */ import_react51.default.createElement("button", { onClick: () => setPendingFiles((p) => p.filter((_, i) => i !== idx)), className: "text-neutral-400 hover:text-red-500 transition-colors p-1 outline-none shrink-0" }, /* @__PURE__ */ import_react51.default.createElement(import_react52.HugeiconsIcon, { icon: import_core_free_icons15.Cancel01Icon, size: 16 })))), /* @__PURE__ */ import_react51.default.createElement("input", { type: "file", multiple: true, ref: archiveRef, onChange: handleFileSelect, className: "hidden", accept: "application/pdf,image/*" }), /* @__PURE__ */ import_react51.default.createElement("div", { className: "flex flex-col sm:flex-row items-center gap-3 w-full" }, /* @__PURE__ */ import_react51.default.createElement("button", { onClick: () => archiveRef.current?.click(), disabled: selectedApp.status !== "COMPLETED" || isUploading, className: "flex items-center justify-center gap-3 p-4 border border-neutral-200 rounded-full hover:bg-neutral-50 transition-colors text-black text-sm w-full outline-none disabled:opacity-50" }, /* @__PURE__ */ import_react51.default.createElement(import_react52.HugeiconsIcon, { icon: import_core_free_icons15.Upload01Icon, size: 18, className: "text-neutral-400" }), " Select Files to Upload"), pendingFiles.length > 0 && /* @__PURE__ */ import_react51.default.createElement("div", { className: "flex flex-col sm:flex-row items-center gap-3 w-full sm:w-auto shrink-0" }, /* @__PURE__ */ import_react51.default.createElement("button", { onClick: () => setPendingFiles([]), disabled: isUploading, className: "px-6 py-2 text-neutral-600 text-[11px] tracking-widest rounded-full hover:bg-neutral-200 outline-none w-full sm:w-auto uppercase" }, "Clear All"), /* @__PURE__ */ import_react51.default.createElement(ThreeDActionButton, { onClick: executeUpload, disabled: isUploading, isLoading: isUploading, className: "w-full sm:w-auto" }, "Upload ", pendingFiles.length, " File(s)")))), /* @__PURE__ */ import_react51.default.createElement("div", { className: "flex flex-col sm:flex-row items-center justify-between gap-4 mt-8 pt-6" }, !selectedApp.agentId ? /* @__PURE__ */ import_react51.default.createElement(ThreeDActionButton, { onClick: async () => {
2695
+ setIsActioning(true);
2696
+ await onAcceptApplication(selectedApp.id);
2697
+ setIsActioning(false);
2698
+ }, disabled: isActioning, isLoading: isActioning, className: "w-full sm:w-auto" }, "Accept Application") : selectedApp.agentId !== currentAgentId ? /* @__PURE__ */ import_react51.default.createElement("div", { className: "w-full p-4 border border-red-100 bg-red-50/30 rounded-xl flex items-start gap-3" }, /* @__PURE__ */ import_react51.default.createElement(import_react52.HugeiconsIcon, { icon: import_core_free_icons15.Cancel01Icon, size: 16, className: "text-red-500 shrink-0 mt-0.5" }), /* @__PURE__ */ import_react51.default.createElement("div", null, /* @__PURE__ */ import_react51.default.createElement("p", { className: "text-sm text-red-700" }, "Application Taken"), /* @__PURE__ */ import_react51.default.createElement("p", { className: "text-xs text-red-600 mt-1" }, "Currently handled by ", selectedApp.agentName || "another agent", "."))) : /* @__PURE__ */ import_react51.default.createElement("div", { className: "w-full flex flex-col sm:flex-row items-center gap-4 justify-between" }, /* @__PURE__ */ import_react51.default.createElement("p", { className: "text-xs text-neutral-500" }, "You are the assigned agent."), /* @__PURE__ */ import_react51.default.createElement("div", { className: "flex flex-col sm:flex-row items-center justify-end gap-3 w-full sm:w-auto" }, /* @__PURE__ */ import_react51.default.createElement("button", { onClick: () => setActionModal("query"), disabled: selectedApp.status === "COMPLETED", className: "w-full sm:w-auto px-6 py-2 bg-white border border-neutral-200 text-neutral-600 text-[11px] tracking-widest rounded-full hover:bg-neutral-50 transition-colors outline-none disabled:opacity-30 uppercase" }, "Query"), /* @__PURE__ */ import_react51.default.createElement("button", { onClick: () => setActionModal("reject"), disabled: selectedApp.status === "COMPLETED", className: "w-full sm:w-auto px-6 py-2 bg-white border border-neutral-200 text-neutral-600 text-[11px] tracking-widest rounded-full hover:bg-neutral-50 transition-colors outline-none disabled:opacity-30 uppercase" }, "Reject"), /* @__PURE__ */ import_react51.default.createElement(ThreeDActionButton, { onClick: () => setActionModal("success"), disabled: selectedApp.status === "COMPLETED", className: "w-full sm:w-auto" }, "Mark Success"))))), actionModal && /* @__PURE__ */ import_react51.default.createElement("div", { className: "fixed inset-0 z-110 flex items-center justify-center p-4" }, /* @__PURE__ */ import_react51.default.createElement("div", { className: "absolute inset-0 bg-black/30", onClick: () => !isActioning && setActionModal(null) }), /* @__PURE__ */ import_react51.default.createElement("div", { className: "relative w-full max-w-md bg-white rounded-3xl flex flex-col overflow-hidden animate-in zoom-in-95 duration-200 text-left" }, /* @__PURE__ */ import_react51.default.createElement("div", { className: "p-6" }, /* @__PURE__ */ import_react51.default.createElement("h3", { className: "text-lg text-black tracking-tight capitalize mb-2" }, actionModal === "success" ? "Complete Application" : `${actionModal} Application`), /* @__PURE__ */ import_react51.default.createElement("p", { className: "text-xs text-neutral-500" }, actionModal === "success" ? "Are you sure you want to mark this application as successfully completed?" : `Please provide a clear reason for the user. They will see this message and be asked to fix their application.`)), (actionModal === "query" || actionModal === "reject") && /* @__PURE__ */ import_react51.default.createElement("div", { className: "p-6 pb-2" }, /* @__PURE__ */ import_react51.default.createElement(TextInput, { label: "Reason for Action", value: actionMessage, onChange: setActionMessage, placeholder: "Enter your reason here...", disabled: isActioning })), /* @__PURE__ */ import_react51.default.createElement("div", { className: "flex items-center p-6 pt-4 gap-3" }, /* @__PURE__ */ import_react51.default.createElement("button", { onClick: () => setActionModal(null), disabled: isActioning, className: "flex-1 py-3 text-[11px] tracking-widest uppercase text-neutral-600 rounded-full hover:bg-neutral-50 transition-colors outline-none disabled:opacity-50" }, "Cancel"), /* @__PURE__ */ import_react51.default.createElement(ThreeDActionButton, { onClick: async () => {
2699
+ setIsActioning(true);
2700
+ await onUpdateStatus(selectedApp.id, actionModal === "success" ? "COMPLETED" : actionModal === "reject" ? "REJECTED" : "QUEUED", actionMessage);
2701
+ setIsActioning(false);
2702
+ setActionModal(null);
2703
+ setActionMessage("");
2704
+ }, disabled: isActioning || (actionModal === "query" || actionModal === "reject") && actionMessage.trim().length < 5, isLoading: isActioning, className: "flex-1" }, "Confirm ", actionModal)))), archiveToDelete && /* @__PURE__ */ import_react51.default.createElement("div", { className: "fixed inset-0 z-110 flex items-center justify-center p-4" }, /* @__PURE__ */ import_react51.default.createElement("div", { className: "absolute inset-0 bg-black/30", onClick: () => !isActioning && setArchiveToDelete(null) }), /* @__PURE__ */ import_react51.default.createElement("div", { className: "relative w-full max-w-md bg-white rounded-3xl flex flex-col overflow-hidden animate-in zoom-in-95 duration-200 text-left" }, /* @__PURE__ */ import_react51.default.createElement("div", { className: "p-6" }, /* @__PURE__ */ import_react51.default.createElement("h3", { className: "text-lg text-black tracking-tight mb-2" }, "Delete Document?"), /* @__PURE__ */ import_react51.default.createElement("p", { className: "text-xs text-neutral-500" }, 'Are you sure you want to permanently delete "', archiveToDelete.name, '"?')), /* @__PURE__ */ import_react51.default.createElement("div", { className: "flex items-center p-6 gap-3" }, /* @__PURE__ */ import_react51.default.createElement("button", { onClick: () => setArchiveToDelete(null), disabled: isActioning, className: "flex-1 py-3 text-[11px] tracking-widest uppercase text-neutral-600 rounded-full hover:bg-neutral-50 transition-colors outline-none disabled:opacity-50" }, "Cancel"), /* @__PURE__ */ import_react51.default.createElement(ThreeDActionButton, { onClick: async () => {
2705
+ setIsActioning(true);
2706
+ await onDeleteArchive(selectedApp.id, archiveToDelete.id);
2707
+ setIsActioning(false);
2708
+ setArchiveToDelete(null);
2709
+ }, isLoading: isActioning, className: "flex-1" }, "Delete Document")))));
2710
+ };
2711
+
2712
+ // src/components/UniversalOverviewPage.tsx
2713
+ var import_react53 = __toESM(require("react"));
2714
+ var UniversalOverviewPage = ({
2715
+ headerTitle,
2716
+ headerDescription,
2717
+ quickStats,
2718
+ detailsTitle = "Details",
2719
+ details,
2720
+ primaryAction,
2721
+ alerts = []
2722
+ }) => {
2723
+ return /* @__PURE__ */ import_react53.default.createElement("div", { className: "flex flex-col gap-8 animate-in fade-in duration-300 min-h-full pb-10" }, /* @__PURE__ */ import_react53.default.createElement("div", { className: "flex items-center justify-between gap-4" }, /* @__PURE__ */ import_react53.default.createElement("div", null, /* @__PURE__ */ import_react53.default.createElement("h1", { className: "text-xl text-black mb-1 tracking-tight" }, headerTitle), /* @__PURE__ */ import_react53.default.createElement("p", { className: "text-xs text-neutral-500" }, headerDescription))), quickStats.length > 0 && /* @__PURE__ */ import_react53.default.createElement("div", { className: "w-full rounded-2xl overflow-hidden max-w-3xl bg-white" }, /* @__PURE__ */ import_react53.default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-3 divide-y md:divide-y-0 md:divide-x divide-neutral-100" }, quickStats.map((stat, idx) => /* @__PURE__ */ import_react53.default.createElement("div", { key: idx, className: "p-6 flex items-center gap-4 hover:bg-neutral-50/50 transition-colors min-w-0" }, /* @__PURE__ */ import_react53.default.createElement("div", { className: "w-12 h-12 rounded-full border border-neutral-200 bg-white flex items-center justify-center text-black shrink-0" }, stat.icon), /* @__PURE__ */ import_react53.default.createElement("div", { className: "min-w-0 flex-1" }, /* @__PURE__ */ import_react53.default.createElement("p", { className: "text-[10px] tracking-[0.2em] text-neutral-400 mb-1 truncate uppercase" }, stat.label), /* @__PURE__ */ import_react53.default.createElement("p", { className: "text-lg md:text-xl text-black tracking-tight truncate" }, stat.value)))))), /* @__PURE__ */ import_react53.default.createElement("div", { className: "w-full rounded-2xl max-w-3xl overflow-hidden bg-white min-w-0" }, /* @__PURE__ */ import_react53.default.createElement("div", { className: "p-6 sm:p-8 flex flex-col h-full min-w-0 gap-6" }, /* @__PURE__ */ import_react53.default.createElement("div", { className: "flex flex-wrap items-center justify-between gap-4 border-b border-neutral-100 pb-4" }, /* @__PURE__ */ import_react53.default.createElement("h3", { className: "text-[11px] text-black tracking-[0.2em] uppercase" }, detailsTitle), primaryAction && (primaryAction.href ? /* @__PURE__ */ import_react53.default.createElement(
2724
+ ThreeDButton,
2725
+ {
2726
+ href: primaryAction.href,
2727
+ onClick: primaryAction.onClick,
2728
+ className: "w-fit shrink-0 gap-2"
2729
+ },
2730
+ primaryAction.label,
2731
+ primaryAction.icon
2732
+ ) : /* @__PURE__ */ import_react53.default.createElement(
2733
+ ThreeDActionButton,
2734
+ {
2735
+ onClick: primaryAction.onClick,
2736
+ isLoading: primaryAction.isLoading,
2737
+ className: "w-fit shrink-0 gap-2"
2738
+ },
2739
+ primaryAction.label,
2740
+ primaryAction.icon
2741
+ ))), /* @__PURE__ */ import_react53.default.createElement("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-8" }, details.map((detail, idx) => /* @__PURE__ */ import_react53.default.createElement("div", { key: idx, className: "min-w-0" }, /* @__PURE__ */ import_react53.default.createElement("p", { className: "text-[10px] tracking-[0.2em] text-neutral-400 mb-1.5 uppercase" }, detail.label), /* @__PURE__ */ import_react53.default.createElement("p", { className: "text-[13px] text-black truncate" }, detail.value)))), alerts.map((alert, idx) => {
2742
+ const bgClass = alert.type === "warning" ? "bg-amber-50/50" : alert.type === "info" ? "bg-blue-50/50" : "bg-red-50/50";
2743
+ const textClass = alert.type === "warning" ? "text-amber-600" : alert.type === "info" ? "text-blue-600" : "text-red-600";
2744
+ const valClass = alert.type === "warning" ? "text-amber-700" : alert.type === "info" ? "text-blue-700" : "text-red-700";
2745
+ const lblClass = alert.type === "warning" ? "text-amber-400" : alert.type === "info" ? "text-blue-400" : "text-red-400";
2746
+ return /* @__PURE__ */ import_react53.default.createElement("div", { key: idx, className: `mt-4 p-5 rounded-xl flex flex-col gap-4 ${bgClass}` }, /* @__PURE__ */ import_react53.default.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ import_react53.default.createElement("span", { className: `text-[11px] tracking-widest uppercase ${textClass}` }, alert.title)), alert.items.map((item, itemIdx) => /* @__PURE__ */ import_react53.default.createElement("div", { key: itemIdx }, /* @__PURE__ */ import_react53.default.createElement("span", { className: `text-[10px] tracking-[0.2em] block mb-1 uppercase ${lblClass}` }, item.label), /* @__PURE__ */ import_react53.default.createElement("p", { className: `text-[13px] leading-relaxed ${valClass}` }, item.text))));
2747
+ }))));
2748
+ };
2374
2749
  // Annotate the CommonJS export names for ESM import in node:
2375
2750
  0 && (module.exports = {
2376
2751
  AITranscriptionFeature,
@@ -2397,10 +2772,14 @@ var UniversalProfileSettings = ({
2397
2772
  TextInput,
2398
2773
  ThreeDActionButton,
2399
2774
  ThreeDButton,
2775
+ UniversalAgentConsole,
2776
+ UniversalBillingPage,
2777
+ UniversalDashboardPage,
2400
2778
  UniversalHeader,
2401
2779
  UniversalIdentityPage,
2402
2780
  UniversalMembersPage,
2403
2781
  UniversalOrganizationPage,
2782
+ UniversalOverviewPage,
2404
2783
  UniversalProfileSettings,
2405
2784
  UniversalSidebar,
2406
2785
  ZairusAuth