@retinalabsllc/zairusjs 0.2.4 → 0.2.6

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,17 @@ __export(index_exports, {
55
55
  TextInput: () => TextInput,
56
56
  ThreeDActionButton: () => ThreeDActionButton,
57
57
  ThreeDButton: () => ThreeDButton,
58
+ UniversalAgentConsole: () => UniversalAgentConsole,
59
+ UniversalBillingPage: () => UniversalBillingPage,
60
+ UniversalDashboardPage: () => UniversalDashboardPage,
61
+ UniversalDirectoryPage: () => UniversalDirectoryPage,
62
+ UniversalErrorView: () => UniversalErrorView,
58
63
  UniversalHeader: () => UniversalHeader,
59
64
  UniversalIdentityPage: () => UniversalIdentityPage,
65
+ UniversalLookupPage: () => UniversalLookupPage,
60
66
  UniversalMembersPage: () => UniversalMembersPage,
61
67
  UniversalOrganizationPage: () => UniversalOrganizationPage,
68
+ UniversalOverviewPage: () => UniversalOverviewPage,
62
69
  UniversalProfileSettings: () => UniversalProfileSettings,
63
70
  UniversalSidebar: () => UniversalSidebar,
64
71
  ZairusAuth: () => ZairusAuth
@@ -1232,11 +1239,12 @@ var TextInput = ({
1232
1239
  maxLength,
1233
1240
  disabled,
1234
1241
  readOnly,
1242
+ type = "text",
1235
1243
  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(
1244
+ }) => /* @__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
1245
  "input",
1238
1246
  {
1239
- type: "text",
1247
+ type,
1240
1248
  value,
1241
1249
  onChange: (e) => onChange(e.target.value.substring(0, maxLength || 100)),
1242
1250
  placeholder,
@@ -1254,7 +1262,7 @@ var NumberInput = ({
1254
1262
  placeholder,
1255
1263
  maxLength,
1256
1264
  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(
1265
+ }) => /* @__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
1266
  "input",
1259
1267
  {
1260
1268
  type: "text",
@@ -2371,6 +2379,542 @@ var UniversalProfileSettings = ({
2371
2379
  "Cancel"
2372
2380
  )))));
2373
2381
  };
2382
+
2383
+ // src/components/UniversalBillingPage.tsx
2384
+ var import_react47 = __toESM(require("react"));
2385
+ var import_react48 = require("@hugeicons/react");
2386
+ var import_core_free_icons13 = require("@hugeicons/core-free-icons");
2387
+ 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" }));
2388
+ var ButtonSpinner4 = () => /* @__PURE__ */ import_react47.default.createElement(import_react48.HugeiconsIcon, { icon: import_core_free_icons13.Loading03Icon, size: 16, className: "animate-spin text-neutral-500" });
2389
+ var formatDate = (dateString) => {
2390
+ if (!dateString) return "N/A";
2391
+ return new Date(dateString).toLocaleDateString("en-US", {
2392
+ month: "long",
2393
+ day: "numeric",
2394
+ year: "numeric"
2395
+ });
2396
+ };
2397
+ var formatNaira = (amount) => {
2398
+ return `\u20A6${(amount || 0).toLocaleString("en-NG", { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`;
2399
+ };
2400
+ var UniversalBillingPage = ({
2401
+ headerTitle,
2402
+ headerDescription,
2403
+ isReadOnly = false,
2404
+ isModMode = false,
2405
+ metricPrimaryLabel,
2406
+ metricPrimaryValue,
2407
+ metricPrimarySubtext,
2408
+ metricSecondaryLabel,
2409
+ metricSecondaryValue,
2410
+ metricSecondarySubtext,
2411
+ showBillingOverview = false,
2412
+ billingStatus,
2413
+ nextBillingDate,
2414
+ lastPaidDate,
2415
+ showUsageMetrics = false,
2416
+ usageMetrics = [],
2417
+ showSearchAndFilter = false,
2418
+ searchQuery = "",
2419
+ onSearchChange,
2420
+ timeframe = "ALL",
2421
+ onTimeframeChange,
2422
+ invoices,
2423
+ isLoading,
2424
+ currentPage,
2425
+ totalPages,
2426
+ onPageChange,
2427
+ onPayInvoice,
2428
+ onUpdateInvoiceStatus
2429
+ }) => {
2430
+ const [currentView, setCurrentView] = (0, import_react47.useState)("list");
2431
+ const [selectedInvoice, setSelectedInvoice] = (0, import_react47.useState)(null);
2432
+ const [isTimeframeModalOpen, setIsTimeframeModalOpen] = (0, import_react47.useState)(false);
2433
+ const [isPaying, setIsPaying] = (0, import_react47.useState)(false);
2434
+ const [isActionModalOpen, setIsActionModalOpen] = (0, import_react47.useState)(false);
2435
+ const [isUpdating, setIsUpdating] = (0, import_react47.useState)(false);
2436
+ const [twoFactorCode, setTwoFactorCode] = (0, import_react47.useState)("");
2437
+ const handlePayment = async () => {
2438
+ if (!selectedInvoice || isReadOnly || !onPayInvoice || isPaying) return;
2439
+ setIsPaying(true);
2440
+ try {
2441
+ await onPayInvoice(selectedInvoice.id);
2442
+ setSelectedInvoice({ ...selectedInvoice, status: "PAID" });
2443
+ } finally {
2444
+ setIsPaying(false);
2445
+ }
2446
+ };
2447
+ const handleStatusUpdate = async (newStatus) => {
2448
+ if (!selectedInvoice || !twoFactorCode || isUpdating || !onUpdateInvoiceStatus) return;
2449
+ setIsUpdating(true);
2450
+ try {
2451
+ const res = await onUpdateInvoiceStatus(selectedInvoice.id, newStatus, twoFactorCode);
2452
+ if (res.success) {
2453
+ setIsActionModalOpen(false);
2454
+ setTwoFactorCode("");
2455
+ setSelectedInvoice({ ...selectedInvoice, status: newStatus });
2456
+ }
2457
+ } finally {
2458
+ setIsUpdating(false);
2459
+ }
2460
+ };
2461
+ 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(
2462
+ TextInput,
2463
+ {
2464
+ placeholder: "Search by ID or Name...",
2465
+ value: searchQuery,
2466
+ onChange: onSearchChange
2467
+ }
2468
+ ), /* @__PURE__ */ import_react47.default.createElement(
2469
+ "button",
2470
+ {
2471
+ type: "button",
2472
+ onClick: () => setIsTimeframeModalOpen(true),
2473
+ 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"
2474
+ },
2475
+ timeframe === "ALL" ? "All Time" : timeframe === "24H" ? "Past 24 Hours" : timeframe === "7D" ? "Past 7 Days" : "Past 30 Days"
2476
+ ))) : /* @__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: () => {
2477
+ setSelectedInvoice(inv);
2478
+ setCurrentView("details");
2479
+ }, 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(
2480
+ "button",
2481
+ {
2482
+ onClick: () => !isUpdating && setIsActionModalOpen(true),
2483
+ disabled: isUpdating,
2484
+ 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"}`
2485
+ },
2486
+ selectedInvoice.status,
2487
+ 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" })
2488
+ ) : /* @__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(
2489
+ ThreeDActionButton,
2490
+ {
2491
+ onClick: handlePayment,
2492
+ disabled: isReadOnly || isPaying,
2493
+ isLoading: isPaying,
2494
+ className: "w-full sm:w-auto"
2495
+ },
2496
+ "Pay Invoice"
2497
+ )), !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" }, [
2498
+ { value: "ALL", label: "All Time" },
2499
+ { value: "24H", label: "Past 24 Hours" },
2500
+ { value: "7D", label: "Past 7 Days" },
2501
+ { value: "30D", label: "Past 30 Days" }
2502
+ ].map((option) => /* @__PURE__ */ import_react47.default.createElement(
2503
+ "button",
2504
+ {
2505
+ key: option.value,
2506
+ type: "button",
2507
+ onClick: () => {
2508
+ onTimeframeChange(option.value);
2509
+ setIsTimeframeModalOpen(false);
2510
+ },
2511
+ 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"}`
2512
+ },
2513
+ /* @__PURE__ */ import_react47.default.createElement("span", { className: "truncate pr-2" }, option.label),
2514
+ timeframe === option.value && /* @__PURE__ */ import_react47.default.createElement("div", { className: "w-1.5 h-1.5 bg-black rounded-full shrink-0" })
2515
+ ))), /* @__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(
2516
+ TextInput,
2517
+ {
2518
+ placeholder: "Enter 2FA Code...",
2519
+ value: twoFactorCode,
2520
+ onChange: setTwoFactorCode,
2521
+ type: "password"
2522
+ }
2523
+ )), /* @__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(
2524
+ "button",
2525
+ {
2526
+ key: statusOption,
2527
+ onClick: () => handleStatusUpdate(statusOption),
2528
+ disabled: isUpdating || !twoFactorCode,
2529
+ 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"}`
2530
+ },
2531
+ /* @__PURE__ */ import_react47.default.createElement("span", { className: "truncate pr-2" }, statusOption),
2532
+ selectedInvoice?.status === statusOption && /* @__PURE__ */ import_react47.default.createElement("div", { className: "w-1.5 h-1.5 bg-black rounded-full shrink-0" })
2533
+ ))), /* @__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")))));
2534
+ };
2535
+
2536
+ // src/components/UniversalDashboardPage.tsx
2537
+ var import_react49 = __toESM(require("react"));
2538
+ var import_react50 = require("@hugeicons/react");
2539
+ var import_core_free_icons14 = require("@hugeicons/core-free-icons");
2540
+ var UniversalDashboardPage = ({
2541
+ headerTitle,
2542
+ headerDescription,
2543
+ timeframes = [],
2544
+ activeTimeframe,
2545
+ onTimeframeChange,
2546
+ stats,
2547
+ lists,
2548
+ isLoading = false
2549
+ }) => {
2550
+ const [isTimeframeModalOpen, setIsTimeframeModalOpen] = (0, import_react49.useState)(false);
2551
+ const selectedTimeframe = timeframes.find((t) => t.id === activeTimeframe) || timeframes[0];
2552
+ if (isLoading) {
2553
+ 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" }));
2554
+ }
2555
+ 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(
2556
+ "button",
2557
+ {
2558
+ onClick: () => setIsTimeframeModalOpen(true),
2559
+ 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"
2560
+ },
2561
+ /* @__PURE__ */ import_react49.default.createElement("span", null, selectedTimeframe.label),
2562
+ /* @__PURE__ */ import_react49.default.createElement(import_react50.HugeiconsIcon, { icon: import_core_free_icons14.ArrowDown01Icon, size: 14, className: "text-neutral-400" })
2563
+ )), 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(
2564
+ "button",
2565
+ {
2566
+ key: tf.id,
2567
+ onClick: () => {
2568
+ onTimeframeChange(tf.id);
2569
+ setIsTimeframeModalOpen(false);
2570
+ },
2571
+ 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"}`
2572
+ },
2573
+ /* @__PURE__ */ import_react49.default.createElement("span", { className: "truncate pr-2" }, tf.label),
2574
+ activeTimeframe === tf.id && /* @__PURE__ */ import_react49.default.createElement("div", { className: "w-1.5 h-1.5 bg-black rounded-full shrink-0" })
2575
+ ))), /* @__PURE__ */ import_react49.default.createElement("div", { className: "w-full flex border-t border-neutral-50" }, /* @__PURE__ */ import_react49.default.createElement(
2576
+ "button",
2577
+ {
2578
+ onClick: () => setIsTimeframeModalOpen(false),
2579
+ className: "w-full py-2.5 text-[13px] text-neutral-600 hover:bg-neutral-50 transition-colors outline-none"
2580
+ },
2581
+ "Cancel"
2582
+ )))));
2583
+ };
2584
+
2585
+ // src/components/UniversalAgentConsole.tsx
2586
+ var import_react51 = __toESM(require("react"));
2587
+ var import_react52 = require("@hugeicons/react");
2588
+ var import_core_free_icons15 = require("@hugeicons/core-free-icons");
2589
+ var formatKeyName = (key) => key.replace(/([A-Z])/g, " $1").replace(/^./, (str) => str.toUpperCase()).trim();
2590
+ var toTitleCaseSafe = (str) => {
2591
+ if (!str) return "";
2592
+ return str.toLowerCase().split(" ").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
2593
+ };
2594
+ var IGNORED_KEYS = ["id", "fileName", "contentType", "fileSizeInBytes", "categoryCode", "specificCode", "iAgree"];
2595
+ var UniversalAgentConsole = ({
2596
+ headerTitle,
2597
+ headerDescription,
2598
+ stats,
2599
+ tabs,
2600
+ activeTab,
2601
+ onTabChange,
2602
+ listData,
2603
+ isLoadingList,
2604
+ currentPage,
2605
+ totalPages,
2606
+ onPageChange,
2607
+ onRowClick,
2608
+ currentView,
2609
+ onBackToList,
2610
+ selectedApp,
2611
+ currentAgentId,
2612
+ onAcceptApplication,
2613
+ onUpdateStatus,
2614
+ onUploadArchives,
2615
+ onDeleteArchive
2616
+ }) => {
2617
+ const archiveRef = (0, import_react51.useRef)(null);
2618
+ const [pendingFiles, setPendingFiles] = (0, import_react51.useState)([]);
2619
+ const [isUploading, setIsUploading] = (0, import_react51.useState)(false);
2620
+ const [isActioning, setIsActioning] = (0, import_react51.useState)(false);
2621
+ const [actionModal, setActionModal] = (0, import_react51.useState)(null);
2622
+ const [actionMessage, setActionMessage] = (0, import_react51.useState)("");
2623
+ const [archiveToDelete, setArchiveToDelete] = (0, import_react51.useState)(null);
2624
+ const handleFileSelect = (e) => {
2625
+ if (e.target.files && e.target.files.length > 0) {
2626
+ setPendingFiles((prev) => [...prev, ...Array.from(e.target.files)]);
2627
+ }
2628
+ setTimeout(() => {
2629
+ if (archiveRef.current) archiveRef.current.value = "";
2630
+ }, 0);
2631
+ };
2632
+ const executeUpload = async () => {
2633
+ if (pendingFiles.length === 0 || !selectedApp) return;
2634
+ setIsUploading(true);
2635
+ try {
2636
+ const payloads = await Promise.all(pendingFiles.map(async (file) => {
2637
+ const base64data = await new Promise((resolve, reject) => {
2638
+ const reader = new FileReader();
2639
+ reader.readAsDataURL(file);
2640
+ reader.onload = () => resolve(reader.result);
2641
+ reader.onerror = (error) => reject(error);
2642
+ });
2643
+ return { imageBase64: base64data, fileName: file.name, fileType: file.type, fileSize: file.size };
2644
+ }));
2645
+ const res = await onUploadArchives(selectedApp.id, payloads);
2646
+ if (res.success) setPendingFiles([]);
2647
+ } finally {
2648
+ setIsUploading(false);
2649
+ }
2650
+ };
2651
+ const DynamicArrayAccordion = ({ items, parentKey }) => {
2652
+ const [activeFAQ, setActiveFAQ] = (0, import_react51.useState)(null);
2653
+ 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) => {
2654
+ const isOpen = activeFAQ === index;
2655
+ let label = `${parentKey ? formatKeyName(parentKey) : "Item"} ${index + 1}`;
2656
+ if (item.fullName) label = toTitleCaseSafe(item.fullName);
2657
+ else if (item.role) label = item.role;
2658
+ else if (item.proposedName) label = toTitleCaseSafe(item.proposedName);
2659
+ 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)))));
2660
+ }));
2661
+ };
2662
+ const renderValue = (key, value) => {
2663
+ if (value === null || value === void 0 || value === "") return null;
2664
+ if (typeof value === "string") {
2665
+ 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");
2666
+ 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));
2667
+ return /* @__PURE__ */ import_react51.default.createElement("p", { className: "text-[12px] md:text-[13px] leading-[1.8] text-neutral-600" }, value);
2668
+ }
2669
+ if (Array.isArray(value)) {
2670
+ const validItems = value.filter((item) => item !== null && item !== void 0 && item !== "");
2671
+ if (validItems.length === 0) return null;
2672
+ 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))));
2673
+ return /* @__PURE__ */ import_react51.default.createElement(DynamicArrayAccordion, { items: validItems, parentKey: key });
2674
+ }
2675
+ if (typeof value === "object") {
2676
+ if (Object.keys(value).length === 0) return null;
2677
+ const renderedObj = renderDynamicObject(value);
2678
+ if (!renderedObj || Array.isArray(renderedObj) && renderedObj.length === 0) return null;
2679
+ 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);
2680
+ }
2681
+ return /* @__PURE__ */ import_react51.default.createElement("span", { className: "text-sm text-black" }, String(value));
2682
+ };
2683
+ const renderDynamicObject = (obj) => {
2684
+ if (!obj) return null;
2685
+ const entries = Object.entries(obj).filter(([k, v]) => {
2686
+ if (IGNORED_KEYS.includes(k) || v === null || v === "" || v === void 0) return false;
2687
+ if (Array.isArray(v) && v.filter((item) => item !== null && item !== "").length === 0) return false;
2688
+ if (typeof v === "object" && !Array.isArray(v) && Object.keys(v).length === 0) return false;
2689
+ return true;
2690
+ });
2691
+ if (entries.length === 0) return null;
2692
+ 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)));
2693
+ };
2694
+ 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: () => {
2695
+ onBackToList();
2696
+ setPendingFiles([]);
2697
+ }, 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 () => {
2698
+ setIsActioning(true);
2699
+ await onAcceptApplication(selectedApp.id);
2700
+ setIsActioning(false);
2701
+ }, 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 () => {
2702
+ setIsActioning(true);
2703
+ await onUpdateStatus(selectedApp.id, actionModal === "success" ? "COMPLETED" : actionModal === "reject" ? "REJECTED" : "QUEUED", actionMessage);
2704
+ setIsActioning(false);
2705
+ setActionModal(null);
2706
+ setActionMessage("");
2707
+ }, 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 () => {
2708
+ setIsActioning(true);
2709
+ await onDeleteArchive(selectedApp.id, archiveToDelete.id);
2710
+ setIsActioning(false);
2711
+ setArchiveToDelete(null);
2712
+ }, isLoading: isActioning, className: "flex-1" }, "Delete Document")))));
2713
+ };
2714
+
2715
+ // src/components/UniversalOverviewPage.tsx
2716
+ var import_react53 = __toESM(require("react"));
2717
+ var UniversalOverviewPage = ({
2718
+ headerTitle,
2719
+ headerDescription,
2720
+ quickStats,
2721
+ detailsTitle = "Details",
2722
+ details,
2723
+ primaryAction,
2724
+ alerts = []
2725
+ }) => {
2726
+ 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(
2727
+ ThreeDButton,
2728
+ {
2729
+ href: primaryAction.href,
2730
+ onClick: primaryAction.onClick,
2731
+ className: "w-fit shrink-0 gap-2"
2732
+ },
2733
+ primaryAction.label,
2734
+ primaryAction.icon
2735
+ ) : /* @__PURE__ */ import_react53.default.createElement(
2736
+ ThreeDActionButton,
2737
+ {
2738
+ onClick: primaryAction.onClick,
2739
+ isLoading: primaryAction.isLoading,
2740
+ className: "w-fit shrink-0 gap-2"
2741
+ },
2742
+ primaryAction.label,
2743
+ primaryAction.icon
2744
+ ))), /* @__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) => {
2745
+ const bgClass = alert.type === "warning" ? "bg-amber-50/50" : alert.type === "info" ? "bg-blue-50/50" : "bg-red-50/50";
2746
+ const textClass = alert.type === "warning" ? "text-amber-600" : alert.type === "info" ? "text-blue-600" : "text-red-600";
2747
+ const valClass = alert.type === "warning" ? "text-amber-700" : alert.type === "info" ? "text-blue-700" : "text-red-700";
2748
+ const lblClass = alert.type === "warning" ? "text-amber-400" : alert.type === "info" ? "text-blue-400" : "text-red-400";
2749
+ 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))));
2750
+ }))));
2751
+ };
2752
+
2753
+ // src/components/UniversalErrorView.tsx
2754
+ var import_react54 = __toESM(require("react"));
2755
+ var import_react55 = require("@hugeicons/react");
2756
+ var import_core_free_icons16 = require("@hugeicons/core-free-icons");
2757
+ var UniversalErrorView = ({
2758
+ isBooting,
2759
+ isLoading,
2760
+ activeData,
2761
+ activeError,
2762
+ envName,
2763
+ onRetry,
2764
+ returnUrl = "/app",
2765
+ returnLabel = "Return to Workspace"
2766
+ }) => {
2767
+ if (isBooting || isLoading && !activeData) {
2768
+ return /* @__PURE__ */ import_react54.default.createElement("div", { className: "flex items-center justify-center h-screen w-full bg-transparent" }, /* @__PURE__ */ import_react54.default.createElement(PageSpinner, null));
2769
+ }
2770
+ if (!isLoading && (!activeData || activeError)) {
2771
+ const errorString = typeof activeError === "string" ? activeError : JSON.stringify(activeError || "");
2772
+ const errorMsg = errorString.toLowerCase();
2773
+ const isPermissionError = errorMsg.includes("forbidden") || errorMsg.includes("unauthorized") || errorMsg.includes("permission");
2774
+ const isNetworkError = errorMsg.includes("network") || errorMsg.includes("connection") || errorMsg.includes("fetch");
2775
+ const isNotFoundError = errorMsg.includes("not found") || errorMsg.includes("404") || errorMsg.includes("does not exist") || !activeData && !isPermissionError && !isNetworkError;
2776
+ const apiMessage = typeof activeError === "string" && activeError.trim() !== "" ? activeError : null;
2777
+ let title = "Oops Connection Error";
2778
+ let description = apiMessage || `We could not load your request. Please check your connection and try again.`;
2779
+ let IconComponent = import_core_free_icons16.ConfusedIcon;
2780
+ if (isNotFoundError) {
2781
+ title = "Oops its not your fault";
2782
+ description = apiMessage || `We could not reach the ${envName} you just loaded. Our team has been notified.`;
2783
+ } else if (isPermissionError) {
2784
+ title = "Access Restricted";
2785
+ description = apiMessage || `You have insufficient permissions to view this ${envName}. Please contact your administrator.`;
2786
+ }
2787
+ return /* @__PURE__ */ import_react54.default.createElement("div", { className: "flex flex-col items-center justify-center h-screen w-full px-4 animate-in fade-in duration-500" }, /* @__PURE__ */ import_react54.default.createElement("div", { className: "mb-4 flex justify-center" }, /* @__PURE__ */ import_react54.default.createElement(import_react55.HugeiconsIcon, { icon: IconComponent, size: 48, className: "text-neutral-300" })), /* @__PURE__ */ import_react54.default.createElement("h2", { className: "text-lg text-black tracking-tight " }, title), /* @__PURE__ */ import_react54.default.createElement("p", { className: "text-xs mt-2 mb-8 text-neutral-500 max-w-sm text-center leading-relaxed" }, description), /* @__PURE__ */ import_react54.default.createElement("div", { className: "flex flex-col sm:flex-row items-center gap-3 w-full justify-center sm:w-auto" }, isNotFoundError || isPermissionError ? /* @__PURE__ */ import_react54.default.createElement(
2788
+ "button",
2789
+ {
2790
+ onClick: () => window.location.href = returnUrl,
2791
+ className: "px-6 py-2 bg-neutral-100 hover:bg-neutral-200 text-black rounded-full text-[11px] tracking-widest transition-colors w-full sm:w-auto outline-none"
2792
+ },
2793
+ returnLabel
2794
+ ) : (
2795
+ // Soft errors (Network timeouts) allow them to retry or optionally retreat
2796
+ /* @__PURE__ */ import_react54.default.createElement(import_react54.default.Fragment, null, envName.toLowerCase().includes("application") && /* @__PURE__ */ import_react54.default.createElement(
2797
+ "button",
2798
+ {
2799
+ onClick: () => window.location.href = returnUrl,
2800
+ className: "px-6 py-2 bg-transparent border border-neutral-200 hover:bg-neutral-50 text-neutral-600 hover:text-black rounded-full text-[11px] tracking-widest transition-colors w-full sm:w-auto outline-none"
2801
+ },
2802
+ "Back Home"
2803
+ ), /* @__PURE__ */ import_react54.default.createElement(
2804
+ "button",
2805
+ {
2806
+ onClick: onRetry,
2807
+ className: "px-6 py-2 bg-black hover:bg-neutral-800 text-white rounded-full text-[11px] tracking-widest transition-colors w-full sm:w-auto outline-none capitalize"
2808
+ },
2809
+ "Refresh ",
2810
+ envName
2811
+ ))
2812
+ )));
2813
+ }
2814
+ return null;
2815
+ };
2816
+
2817
+ // src/components/UniversalLookupPage.tsx
2818
+ var import_react56 = __toESM(require("react"));
2819
+ var import_react57 = require("@hugeicons/react");
2820
+ var import_core_free_icons17 = require("@hugeicons/core-free-icons");
2821
+ var UniversalLookupPage = ({
2822
+ headerTitle,
2823
+ headerDescription,
2824
+ searchOptions,
2825
+ selectedSearchType,
2826
+ onSearchTypeChange,
2827
+ searchQuery,
2828
+ onSearchQueryChange,
2829
+ isSearching,
2830
+ onSearch,
2831
+ resultContent,
2832
+ modals
2833
+ }) => {
2834
+ const [isTypeModalOpen, setIsTypeModalOpen] = (0, import_react56.useState)(false);
2835
+ const currentOptionLabel = searchOptions.find((opt) => opt.value === selectedSearchType)?.label || "Select Type";
2836
+ return /* @__PURE__ */ import_react56.default.createElement("div", { className: "flex flex-col max-w-3xl rounded-2xl p-6 bg-white gap-8 animate-in fade-in duration-300 min-h-full pb-20" }, /* @__PURE__ */ import_react56.default.createElement(ManagedToaster, null), /* @__PURE__ */ import_react56.default.createElement("div", { className: "flex flex-col sm:flex-row sm:items-start justify-between gap-3 sm:gap-4" }, /* @__PURE__ */ import_react56.default.createElement("div", { className: "min-w-0" }, /* @__PURE__ */ import_react56.default.createElement("h1", { className: "text-xl text-black mb-1 truncate tracking-tight" }, headerTitle), /* @__PURE__ */ import_react56.default.createElement("p", { className: "text-xs text-neutral-500 truncate" }, headerDescription))), /* @__PURE__ */ import_react56.default.createElement("div", { className: "w-full max-w-2xl pb-8" }, /* @__PURE__ */ import_react56.default.createElement("form", { className: "flex flex-col gap-6", onSubmit: onSearch, autoComplete: "off" }, /* @__PURE__ */ import_react56.default.createElement("div", { className: "flex gap-4" }, /* @__PURE__ */ import_react56.default.createElement(
2837
+ "button",
2838
+ {
2839
+ type: "button",
2840
+ onClick: () => setIsTypeModalOpen(true),
2841
+ className: "mt-2 text-[12px] tracking-widest bg-transparent border-b border-neutral-200 text-black text-left outline-none focus:border-black shrink-0 uppercase"
2842
+ },
2843
+ currentOptionLabel
2844
+ ), /* @__PURE__ */ import_react56.default.createElement("div", { className: "flex-1" }, /* @__PURE__ */ import_react56.default.createElement(
2845
+ TextInput,
2846
+ {
2847
+ placeholder: "Enter Exact ID, Email, or Slug...",
2848
+ value: searchQuery,
2849
+ onChange: onSearchQueryChange,
2850
+ disabled: isSearching
2851
+ }
2852
+ ))), /* @__PURE__ */ import_react56.default.createElement("div", { className: "flex justify-end" }, /* @__PURE__ */ import_react56.default.createElement(
2853
+ ThreeDActionButton,
2854
+ {
2855
+ type: "submit",
2856
+ disabled: isSearching || !searchQuery,
2857
+ isLoading: isSearching,
2858
+ className: "min-w-32"
2859
+ },
2860
+ /* @__PURE__ */ import_react56.default.createElement(import_react57.HugeiconsIcon, { icon: import_core_free_icons17.Search01Icon, size: 14, className: "mr-2" }),
2861
+ " Lookup"
2862
+ )))), resultContent && /* @__PURE__ */ import_react56.default.createElement("div", { className: "w-full max-w-2xl bg-white text-left animate-in fade-in slide-in-from-bottom-4" }, /* @__PURE__ */ import_react56.default.createElement("h3", { className: "text-[10px] text-neutral-400 tracking-[0.2em] mb-6 uppercase" }, "Entity Record Found"), resultContent), isTypeModalOpen && /* @__PURE__ */ import_react56.default.createElement("div", { className: "fixed inset-0 z-110 flex items-center justify-center p-4" }, /* @__PURE__ */ import_react56.default.createElement("div", { className: "absolute inset-0 bg-black/30", onClick: () => setIsTypeModalOpen(false) }), /* @__PURE__ */ import_react56.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_react56.default.createElement("div", { className: "p-6 text-center w-full" }, /* @__PURE__ */ import_react56.default.createElement("h3", { className: "text-[14px] text-black tracking-tight mb-2" }, "Select Entity Type")), /* @__PURE__ */ import_react56.default.createElement("div", { className: "w-full flex flex-col pl-2 pr-2 pb-2" }, searchOptions.map((option) => /* @__PURE__ */ import_react56.default.createElement(
2863
+ "button",
2864
+ {
2865
+ key: option.value,
2866
+ type: "button",
2867
+ onClick: () => {
2868
+ onSearchTypeChange(option.value);
2869
+ setIsTypeModalOpen(false);
2870
+ },
2871
+ className: `text-left px-4 py-3 text-[12px] tracking-wide transition-colors rounded-full flex items-center justify-between outline-none ${selectedSearchType === option.value ? "bg-neutral-100 text-black" : "text-neutral-500 hover:bg-neutral-50 hover:text-black"}`
2872
+ },
2873
+ /* @__PURE__ */ import_react56.default.createElement("span", { className: "truncate pr-2" }, option.label),
2874
+ selectedSearchType === option.value && /* @__PURE__ */ import_react56.default.createElement("div", { className: "w-1.5 h-1.5 bg-black rounded-full shrink-0" })
2875
+ ))), /* @__PURE__ */ import_react56.default.createElement("div", { className: "w-full flex" }, /* @__PURE__ */ import_react56.default.createElement("button", { type: "button", onClick: () => setIsTypeModalOpen(false), className: "w-full py-2.5 text-[13px] text-neutral-600 hover:bg-neutral-50 transition-colors outline-none" }, "Cancel")))), modals);
2876
+ };
2877
+
2878
+ // src/components/UniversalDirectoryPage.tsx
2879
+ var import_react58 = __toESM(require("react"));
2880
+ var import_react59 = require("@hugeicons/react");
2881
+ var import_core_free_icons18 = require("@hugeicons/core-free-icons");
2882
+ var PageSpinner4 = () => /* @__PURE__ */ import_react58.default.createElement("div", { className: "flex justify-center items-center py-12" }, /* @__PURE__ */ import_react58.default.createElement(import_react59.HugeiconsIcon, { icon: import_core_free_icons18.Loading03Icon, size: 32, className: "animate-spin mb-4 text-black" }));
2883
+ var UniversalDirectoryPage = ({
2884
+ headerTitle,
2885
+ headerDescription,
2886
+ searchPlaceholder = "Search...",
2887
+ searchQuery,
2888
+ onSearchChange,
2889
+ currentView,
2890
+ onBackToList,
2891
+ items,
2892
+ isLoading,
2893
+ currentPage,
2894
+ totalPages,
2895
+ onPageChange,
2896
+ onRowClick,
2897
+ detailsContent,
2898
+ modals
2899
+ }) => {
2900
+ return /* @__PURE__ */ import_react58.default.createElement("div", { className: "flex flex-col gap-8 animate-in max-w-3xl fade-in duration-300 p-6 rounded-2xl bg-white min-h-full" }, /* @__PURE__ */ import_react58.default.createElement(ManagedToaster, null), /* @__PURE__ */ import_react58.default.createElement("div", { className: "flex flex-col sm:flex-row sm:items-start justify-between gap-4" }, currentView === "list" ? /* @__PURE__ */ import_react58.default.createElement("div", { className: "w-full" }, /* @__PURE__ */ import_react58.default.createElement("h1", { className: "text-xl text-black mb-1 tracking-tight" }, headerTitle), /* @__PURE__ */ import_react58.default.createElement("p", { className: "text-xs text-neutral-500 mb-6" }, headerDescription), /* @__PURE__ */ import_react58.default.createElement(
2901
+ TextInput,
2902
+ {
2903
+ placeholder: searchPlaceholder,
2904
+ value: searchQuery,
2905
+ onChange: onSearchChange
2906
+ }
2907
+ )) : /* @__PURE__ */ import_react58.default.createElement("div", { className: "flex flex-col items-start gap-3" }, /* @__PURE__ */ import_react58.default.createElement("button", { onClick: onBackToList, className: "text-[10px] text-neutral-400 hover:text-black tracking-[0.2em] flex items-center gap-1.5 transition-colors outline-none uppercase" }, /* @__PURE__ */ import_react58.default.createElement(import_react59.HugeiconsIcon, { icon: import_core_free_icons18.ArrowLeft01Icon, size: 12 }), " Back"))), currentView === "list" && /* @__PURE__ */ import_react58.default.createElement("div", { className: "w-full overflow-hidden pt-2" }, isLoading ? /* @__PURE__ */ import_react58.default.createElement(PageSpinner4, null) : /* @__PURE__ */ import_react58.default.createElement("div", { className: "flex flex-col min-w-0" }, /* @__PURE__ */ import_react58.default.createElement("div", { className: "divide-y divide-neutral-100" }, items.length === 0 ? /* @__PURE__ */ import_react58.default.createElement("p", { className: "text-xs text-neutral-500 py-6 text-center" }, "No records found.") : items.map((item) => /* @__PURE__ */ import_react58.default.createElement(
2908
+ "div",
2909
+ {
2910
+ key: item.id,
2911
+ onClick: () => onRowClick(item.id),
2912
+ className: "flex items-center justify-between p-4 sm:p-5 hover:bg-neutral-50/50 transition-colors cursor-pointer group min-w-0"
2913
+ },
2914
+ /* @__PURE__ */ import_react58.default.createElement("div", { className: "flex items-center gap-3 sm:gap-4 min-w-0 flex-1" }, /* @__PURE__ */ import_react58.default.createElement("div", { className: "w-10 h-10 shrink-0 rounded-full flex items-center justify-center bg-neutral-100 text-black text-xs" }, item.icon), /* @__PURE__ */ import_react58.default.createElement("div", { className: "min-w-0 flex-1" }, /* @__PURE__ */ import_react58.default.createElement("div", { className: "text-sm text-black truncate pr-2" }, item.primaryText), /* @__PURE__ */ import_react58.default.createElement("div", { className: "text-xs text-neutral-500 truncate pr-2 mt-0.5" }, item.secondaryText))),
2915
+ item.rightBadge && /* @__PURE__ */ import_react58.default.createElement("div", { className: "shrink-0 pl-2" }, /* @__PURE__ */ import_react58.default.createElement("span", { className: `text-[10px] tracking-[0.2em] px-3 py-1 rounded-full whitespace-nowrap uppercase ${item.rightBadgeClass || "text-neutral-500 border border-neutral-200 bg-white"}` }, item.rightBadge))
2916
+ ))), totalPages > 1 && /* @__PURE__ */ import_react58.default.createElement("div", { className: "flex items-center justify-between p-4 sm:p-5" }, /* @__PURE__ */ import_react58.default.createElement("span", { className: "text-[10px] text-neutral-400 tracking-[0.2em] uppercase" }, "Page ", currentPage, " of ", totalPages), /* @__PURE__ */ import_react58.default.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ import_react58.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_react58.default.createElement(import_react59.HugeiconsIcon, { icon: import_core_free_icons18.ArrowLeft01Icon, size: 14 })), /* @__PURE__ */ import_react58.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_react58.default.createElement(import_react59.HugeiconsIcon, { icon: import_core_free_icons18.ArrowRight01Icon, size: 14 })))))), currentView === "details" && detailsContent, modals);
2917
+ };
2374
2918
  // Annotate the CommonJS export names for ESM import in node:
2375
2919
  0 && (module.exports = {
2376
2920
  AITranscriptionFeature,
@@ -2397,10 +2941,17 @@ var UniversalProfileSettings = ({
2397
2941
  TextInput,
2398
2942
  ThreeDActionButton,
2399
2943
  ThreeDButton,
2944
+ UniversalAgentConsole,
2945
+ UniversalBillingPage,
2946
+ UniversalDashboardPage,
2947
+ UniversalDirectoryPage,
2948
+ UniversalErrorView,
2400
2949
  UniversalHeader,
2401
2950
  UniversalIdentityPage,
2951
+ UniversalLookupPage,
2402
2952
  UniversalMembersPage,
2403
2953
  UniversalOrganizationPage,
2954
+ UniversalOverviewPage,
2404
2955
  UniversalProfileSettings,
2405
2956
  UniversalSidebar,
2406
2957
  ZairusAuth