subos-frontend 1.0.7 → 1.0.8

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.
Files changed (36) hide show
  1. package/dist/index.js +264 -134
  2. package/dist/index.js.map +1 -1
  3. package/dist/index.mjs +193 -68
  4. package/dist/index.mjs.map +1 -1
  5. package/dist/style.css +31 -7
  6. package/dist/types/api/client.d.ts +1 -0
  7. package/dist/types/api/client.d.ts.map +1 -1
  8. package/dist/types/api/config.d.ts +1 -0
  9. package/dist/types/api/config.d.ts.map +1 -1
  10. package/dist/types/components/subscription/SubscriptionDetails.d.ts.map +1 -1
  11. package/dist/types/components/transaction/TransactionExample.d.ts.map +1 -1
  12. package/dist/types/components/transaction/TransactionItem.d.ts +10 -1
  13. package/dist/types/components/transaction/TransactionItem.d.ts.map +1 -1
  14. package/dist/types/components/transaction/TransactionList.d.ts +0 -1
  15. package/dist/types/components/transaction/TransactionList.d.ts.map +1 -1
  16. package/dist/types/components/transaction/TransactionModal.d.ts.map +1 -1
  17. package/dist/types/components/upgrade/UpgradeSummary.d.ts +2 -0
  18. package/dist/types/components/upgrade/UpgradeSummary.d.ts.map +1 -1
  19. package/dist/types/contexts/UpgradeContext.d.ts +14 -0
  20. package/dist/types/contexts/UpgradeContext.d.ts.map +1 -0
  21. package/dist/types/contexts/index.d.ts +3 -0
  22. package/dist/types/contexts/index.d.ts.map +1 -0
  23. package/dist/types/hooks/usePlans.d.ts +1 -0
  24. package/dist/types/hooks/usePlans.d.ts.map +1 -1
  25. package/dist/types/index.d.ts +1 -0
  26. package/dist/types/index.d.ts.map +1 -1
  27. package/dist/types/pages/DashboardPage.d.ts.map +1 -1
  28. package/dist/types/types/index.d.ts +1 -0
  29. package/dist/types/types/index.d.ts.map +1 -1
  30. package/dist/types/utils/index.d.ts +1 -0
  31. package/dist/types/utils/index.d.ts.map +1 -1
  32. package/dist/types/utils/planUtils.d.ts +2 -2
  33. package/dist/types/utils/planUtils.d.ts.map +1 -1
  34. package/dist/types/utils/upgradeUtils.d.ts +18 -0
  35. package/dist/types/utils/upgradeUtils.d.ts.map +1 -0
  36. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1,13 +1,13 @@
1
1
  'use strict';
2
2
 
3
- var React3 = require('react');
3
+ var React4 = require('react');
4
4
  var jsxRuntime = require('react/jsx-runtime');
5
5
  var reactRouterDom = require('react-router-dom');
6
6
 
7
7
  var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
8
8
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
9
9
 
10
- var React3__default = /*#__PURE__*/_interopDefault(React3);
10
+ var React4__default = /*#__PURE__*/_interopDefault(React4);
11
11
 
12
12
  // src/config/envConfig.ts
13
13
  function getEnvVar(key, fallback) {
@@ -107,6 +107,7 @@ var getHeaders = () => {
107
107
  var ENDPOINTS = {
108
108
  PLANS: "/plans",
109
109
  PAYMENTS: "/api/payments",
110
+ CHECKOUT: "/checkout",
110
111
  SUBSCRIPTION: "/subscription",
111
112
  CUSTOMER: "/customer",
112
113
  TRANSACTIONS: "/transaction"
@@ -163,7 +164,7 @@ var plansApi = {
163
164
  if (options == null ? void 0 : options.couponCode) payload.couponCode = options.couponCode;
164
165
  if (typeof amount === "number" && amount > 0) payload.amount = amount;
165
166
  const resp = await apiRequest(
166
- `${ENDPOINTS.PAYMENTS}/checkout`,
167
+ `${ENDPOINTS.CHECKOUT}`,
167
168
  "POST",
168
169
  payload
169
170
  );
@@ -188,6 +189,9 @@ var subscriptionApi = {
188
189
  }
189
190
  }
190
191
  return apiRequest(endpoint, "DELETE");
192
+ },
193
+ checkoutInfo: async (planCode, externalId) => {
194
+ return apiRequest(`${ENDPOINTS.CHECKOUT}/info/${planCode}/${externalId}`);
191
195
  }
192
196
  };
193
197
  var customerApi = {
@@ -212,10 +216,10 @@ var transactionApi = {
212
216
  getInvoice: (transactionId) => apiRequest(`${ENDPOINTS.TRANSACTIONS}/${transactionId}/invoice`)
213
217
  };
214
218
  var useSubscription = () => {
215
- const [subscription, setSubscription] = React3.useState(null);
216
- const [loading, setLoading] = React3.useState(false);
217
- const [error, setError] = React3.useState(null);
218
- const fetchSubscription = React3.useCallback(async (externalId) => {
219
+ const [subscription, setSubscription] = React4.useState(null);
220
+ const [loading, setLoading] = React4.useState(false);
221
+ const [error, setError] = React4.useState(null);
222
+ const fetchSubscription = React4.useCallback(async (externalId) => {
219
223
  if (!externalId || externalId === "undefined" || externalId.trim() === "") {
220
224
  setError("Invalid user ID. Please ensure you are properly authenticated.");
221
225
  setLoading(false);
@@ -240,7 +244,7 @@ var useSubscription = () => {
240
244
  setLoading(false);
241
245
  }
242
246
  }, [loading]);
243
- const clearSubscription = React3.useCallback(() => {
247
+ const clearSubscription = React4.useCallback(() => {
244
248
  setSubscription(null);
245
249
  setError(null);
246
250
  }, []);
@@ -355,8 +359,19 @@ var getPlanDescription = (plan) => {
355
359
  return "Perfect for creators ready to run a full-scale, smart hiring engine with AI and advanced capabilities.";
356
360
  }
357
361
  };
358
- var formatDate = (dateString) => {
362
+ var formatDate = (dateString, format = "date") => {
359
363
  const date = new Date(dateString);
364
+ if (format === "datetime") {
365
+ return new Intl.DateTimeFormat("en-US", {
366
+ year: "numeric",
367
+ month: "short",
368
+ day: "numeric",
369
+ hour: "2-digit",
370
+ minute: "2-digit",
371
+ hour12: false
372
+ // Military time format
373
+ }).format(date);
374
+ }
360
375
  return new Intl.DateTimeFormat("en-US", {
361
376
  year: "numeric",
362
377
  month: "short",
@@ -366,14 +381,14 @@ var formatDate = (dateString) => {
366
381
 
367
382
  // src/hooks/usePlans.ts
368
383
  var usePlans = () => {
369
- const [plans, setPlans] = React3.useState([]);
370
- const [filteredPlans, setFilteredPlans] = React3.useState([]);
371
- const [selectedPlan, setSelectedPlan] = React3.useState(null);
372
- const [tierFilter, setTierFilter] = React3.useState("all");
373
- const [billingCycle, setBillingCycle] = React3.useState("monthly");
374
- const [loading, setLoading] = React3.useState(false);
375
- const [error, setError] = React3.useState(null);
376
- const fetchPlans = React3.useCallback(async () => {
384
+ const [plans, setPlans] = React4.useState([]);
385
+ const [filteredPlans, setFilteredPlans] = React4.useState([]);
386
+ const [selectedPlan, setSelectedPlan] = React4.useState(null);
387
+ const [tierFilter, setTierFilter] = React4.useState("all");
388
+ const [billingCycle, setBillingCycle] = React4.useState("monthly");
389
+ const [loading, setLoading] = React4.useState(false);
390
+ const [error, setError] = React4.useState(null);
391
+ const fetchPlans = React4.useCallback(async () => {
377
392
  if (loading) return;
378
393
  setLoading(true);
379
394
  setError(null);
@@ -395,7 +410,7 @@ var usePlans = () => {
395
410
  setLoading(false);
396
411
  }
397
412
  }, [loading]);
398
- React3.useEffect(() => {
413
+ React4.useEffect(() => {
399
414
  if (plans.length > 0 && tierFilter === "all") {
400
415
  const uniqueUnits = getUniqueCandidateUnits(plans);
401
416
  if (uniqueUnits.length > 0) {
@@ -403,16 +418,16 @@ var usePlans = () => {
403
418
  }
404
419
  }
405
420
  }, [plans, tierFilter]);
406
- React3.useEffect(() => {
421
+ React4.useEffect(() => {
407
422
  let filtered = [...plans];
408
423
  filtered = filterPlansByBillingCycle(filtered, billingCycle);
409
424
  filtered = filterPlansByTier(filtered, tierFilter);
410
425
  setFilteredPlans(filtered);
411
426
  }, [plans, tierFilter, billingCycle]);
412
- const handlePlanSelect = React3.useCallback((plan) => {
427
+ const handlePlanSelect = React4.useCallback((plan) => {
413
428
  setSelectedPlan(plan);
414
429
  }, []);
415
- const handleUpgrade = React3.useCallback(async (externalId) => {
430
+ const handleUpgrade = React4.useCallback(async (externalId) => {
416
431
  var _a;
417
432
  if (!selectedPlan) return;
418
433
  try {
@@ -430,13 +445,16 @@ var usePlans = () => {
430
445
  alert("An error occurred. Please try again.");
431
446
  }
432
447
  }, [selectedPlan]);
433
- const clearPlans = React3.useCallback(() => {
448
+ const clearPlans = React4.useCallback(() => {
434
449
  setPlans([]);
435
450
  setFilteredPlans([]);
436
451
  setSelectedPlan(null);
437
452
  setError(null);
438
453
  setTierFilter("all");
439
454
  }, []);
455
+ const clearSelectedPlan2 = React4.useCallback(() => {
456
+ setSelectedPlan(null);
457
+ }, []);
440
458
  const dropdownOptions = getDropdownOptions(plans);
441
459
  const currentSelectionText = getCurrentSelectionText(tierFilter, plans);
442
460
  return {
@@ -456,6 +474,7 @@ var usePlans = () => {
456
474
  setTierFilter,
457
475
  setBillingCycle,
458
476
  clearPlans,
477
+ clearSelectedPlan: clearSelectedPlan2,
459
478
  // Computed values
460
479
  dropdownOptions,
461
480
  currentSelectionText,
@@ -517,18 +536,18 @@ var useTransactions = ({
517
536
  initialFilters = {},
518
537
  autoFetch = false
519
538
  }) => {
520
- const [transactions, setTransactions] = React3.useState([]);
521
- const [allTransactions, setAllTransactions] = React3.useState([]);
522
- const [loading, setLoading] = React3.useState(false);
523
- const [error, setError] = React3.useState(null);
524
- const [filters, setFilters] = React3.useState({
539
+ const [transactions, setTransactions] = React4.useState([]);
540
+ const [allTransactions, setAllTransactions] = React4.useState([]);
541
+ const [loading, setLoading] = React4.useState(false);
542
+ const [error, setError] = React4.useState(null);
543
+ const [filters, setFilters] = React4.useState({
525
544
  ...DEFAULT_FILTERS,
526
545
  ...initialFilters
527
546
  });
528
- const [meta, setMeta] = React3.useState(null);
529
- const [isBackendPaginated, setIsBackendPaginated] = React3.useState(false);
530
- const hasAutoFetchedRef = React3.useRef(false);
531
- const fetchTransactions = React3.useCallback(async () => {
547
+ const [meta, setMeta] = React4.useState(null);
548
+ const [isBackendPaginated, setIsBackendPaginated] = React4.useState(false);
549
+ const hasAutoFetchedRef = React4.useRef(false);
550
+ const fetchTransactions = React4.useCallback(async () => {
532
551
  if (!externalId) return;
533
552
  setLoading(true);
534
553
  setError(null);
@@ -572,7 +591,7 @@ var useTransactions = ({
572
591
  setLoading(false);
573
592
  }
574
593
  }, [externalId, filters]);
575
- const updateFilters = React3.useCallback((newFilters) => {
594
+ const updateFilters = React4.useCallback((newFilters) => {
576
595
  setFilters((prev) => ({
577
596
  ...prev,
578
597
  ...newFilters,
@@ -580,7 +599,7 @@ var useTransactions = ({
580
599
  page: newFilters.page !== void 0 ? newFilters.page : 1
581
600
  }));
582
601
  }, []);
583
- React3.useEffect(() => {
602
+ React4.useEffect(() => {
584
603
  if (!isBackendPaginated && allTransactions.length > 0) {
585
604
  const filteredTransactions = applyFrontendFilters(allTransactions, filters);
586
605
  const paginatedResult = applyFrontendPagination(filteredTransactions, filters);
@@ -588,19 +607,19 @@ var useTransactions = ({
588
607
  setMeta(paginatedResult.meta);
589
608
  }
590
609
  }, [filters, allTransactions, isBackendPaginated]);
591
- const clearFilters = React3.useCallback(() => {
610
+ const clearFilters = React4.useCallback(() => {
592
611
  setFilters(DEFAULT_FILTERS);
593
612
  }, []);
594
- const refetch = React3.useCallback(async () => {
613
+ const refetch = React4.useCallback(async () => {
595
614
  await fetchTransactions();
596
615
  }, [fetchTransactions]);
597
- React3.useEffect(() => {
616
+ React4.useEffect(() => {
598
617
  if (autoFetch && externalId && !hasAutoFetchedRef.current) {
599
618
  hasAutoFetchedRef.current = true;
600
619
  fetchTransactions();
601
620
  }
602
621
  }, [autoFetch, externalId, fetchTransactions]);
603
- React3.useEffect(() => {
622
+ React4.useEffect(() => {
604
623
  if (!autoFetch) return;
605
624
  const hasNonPaginationFilters = filters.startDate !== void 0 || filters.endDate !== void 0 || filters.status !== void 0;
606
625
  const shouldFetch = isBackendPaginated || allTransactions.length === 0 && hasNonPaginationFilters;
@@ -627,10 +646,10 @@ var usePagination = ({
627
646
  initialPage = 1,
628
647
  initialLimit = 10
629
648
  } = {}) => {
630
- const [currentPage, setCurrentPage] = React3.useState(initialPage);
631
- const [limit, setLimitState] = React3.useState(initialLimit);
632
- const [meta, setMeta] = React3.useState(null);
633
- const goToPage = React3.useCallback((page) => {
649
+ const [currentPage, setCurrentPage] = React4.useState(initialPage);
650
+ const [limit, setLimitState] = React4.useState(initialLimit);
651
+ const [meta, setMeta] = React4.useState(null);
652
+ const goToPage = React4.useCallback((page) => {
634
653
  if (meta) {
635
654
  const validPage = Math.max(1, Math.min(page, meta.totalPages));
636
655
  setCurrentPage(validPage);
@@ -638,29 +657,29 @@ var usePagination = ({
638
657
  setCurrentPage(Math.max(1, page));
639
658
  }
640
659
  }, [meta]);
641
- const goToNextPage = React3.useCallback(() => {
660
+ const goToNextPage = React4.useCallback(() => {
642
661
  if (meta && meta.hasNextPage) {
643
662
  setCurrentPage((prev) => prev + 1);
644
663
  }
645
664
  }, [meta]);
646
- const goToPreviousPage = React3.useCallback(() => {
665
+ const goToPreviousPage = React4.useCallback(() => {
647
666
  if (meta && meta.hasPreviousPage) {
648
667
  setCurrentPage((prev) => prev - 1);
649
668
  }
650
669
  }, [meta]);
651
- const goToFirstPage = React3.useCallback(() => {
670
+ const goToFirstPage = React4.useCallback(() => {
652
671
  setCurrentPage(1);
653
672
  }, []);
654
- const goToLastPage = React3.useCallback(() => {
673
+ const goToLastPage = React4.useCallback(() => {
655
674
  if (meta) {
656
675
  setCurrentPage(meta.totalPages);
657
676
  }
658
677
  }, [meta]);
659
- const setLimit = React3.useCallback((newLimit) => {
678
+ const setLimit = React4.useCallback((newLimit) => {
660
679
  setLimitState(newLimit);
661
680
  setCurrentPage(1);
662
681
  }, []);
663
- const reset = React3.useCallback(() => {
682
+ const reset = React4.useCallback(() => {
664
683
  setCurrentPage(initialPage);
665
684
  setLimitState(initialLimit);
666
685
  setMeta(null);
@@ -683,9 +702,9 @@ var useCancelSubscription = ({
683
702
  onSuccess,
684
703
  onError
685
704
  } = {}) => {
686
- const [loading, setLoading] = React3.useState(false);
687
- const [error, setError] = React3.useState(null);
688
- const cancelSubscription = React3.useCallback(async (externalId, options) => {
705
+ const [loading, setLoading] = React4.useState(false);
706
+ const [error, setError] = React4.useState(null);
707
+ const cancelSubscription = React4.useCallback(async (externalId, options) => {
689
708
  if (!externalId) {
690
709
  const errorMsg = "External ID is required";
691
710
  setError(errorMsg);
@@ -714,7 +733,7 @@ var useCancelSubscription = ({
714
733
  setLoading(false);
715
734
  }
716
735
  }, [onSuccess, onError]);
717
- const reset = React3.useCallback(() => {
736
+ const reset = React4.useCallback(() => {
718
737
  setLoading(false);
719
738
  setError(null);
720
739
  }, []);
@@ -754,9 +773,9 @@ var useCustomerPortal = ({
754
773
  onSuccess,
755
774
  onError
756
775
  } = {}) => {
757
- const [loading, setLoading] = React3.useState(false);
758
- const [error, setError] = React3.useState(null);
759
- const openCustomerPortal = React3.useCallback(async (externalId) => {
776
+ const [loading, setLoading] = React4.useState(false);
777
+ const [error, setError] = React4.useState(null);
778
+ const openCustomerPortal = React4.useCallback(async (externalId) => {
760
779
  var _a;
761
780
  if (!externalId) {
762
781
  const errorMsg = "External ID is required";
@@ -794,7 +813,7 @@ var useCustomerPortal = ({
794
813
  setLoading(false);
795
814
  }
796
815
  }, [onSuccess, onError]);
797
- const reset = React3.useCallback(() => {
816
+ const reset = React4.useCallback(() => {
798
817
  setLoading(false);
799
818
  setError(null);
800
819
  }, []);
@@ -805,6 +824,34 @@ var useCustomerPortal = ({
805
824
  reset
806
825
  };
807
826
  };
827
+ var UpgradeContext = React4.createContext(void 0);
828
+ var UpgradeProvider = ({ children }) => {
829
+ const [isUpgradeSummaryVisible, setIsUpgradeSummaryVisible] = React4.useState(false);
830
+ const setUpgradeSummaryVisible = (visible) => {
831
+ setIsUpgradeSummaryVisible(visible);
832
+ };
833
+ const clearUpgradeSelection = () => {
834
+ setIsUpgradeSummaryVisible(false);
835
+ };
836
+ return /* @__PURE__ */ jsxRuntime.jsx(
837
+ UpgradeContext.Provider,
838
+ {
839
+ value: {
840
+ isUpgradeSummaryVisible,
841
+ setUpgradeSummaryVisible,
842
+ clearUpgradeSelection
843
+ },
844
+ children
845
+ }
846
+ );
847
+ };
848
+ var useUpgrade = () => {
849
+ const context = React4.useContext(UpgradeContext);
850
+ if (context === void 0) {
851
+ throw new Error("useUpgrade must be used within an UpgradeProvider");
852
+ }
853
+ return context;
854
+ };
808
855
  var BillingCycleToggle = ({
809
856
  billingCycle,
810
857
  onBillingCycleChange
@@ -836,8 +883,8 @@ var TierFilterDropdown = ({
836
883
  selectedValue,
837
884
  onSelect
838
885
  }) => {
839
- const dropdownRef = React3.useRef(null);
840
- React3.useEffect(() => {
886
+ const dropdownRef = React4.useRef(null);
887
+ React4.useEffect(() => {
841
888
  const handleClickOutside = (event) => {
842
889
  if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
843
890
  if (isOpen) {
@@ -1014,7 +1061,7 @@ var PlanSelector = ({
1014
1061
  onBillingCycleChange,
1015
1062
  activePlanCode
1016
1063
  }) => {
1017
- const [isDropdownOpen, setIsDropdownOpen] = React3.useState(false);
1064
+ const [isDropdownOpen, setIsDropdownOpen] = React4.useState(false);
1018
1065
  const handleDropdownToggle = () => {
1019
1066
  setIsDropdownOpen(!isDropdownOpen);
1020
1067
  };
@@ -1235,6 +1282,21 @@ var PaymentSuccessView = ({ details }) => {
1235
1282
  ] });
1236
1283
  };
1237
1284
  var PaymentSuccessView_default = PaymentSuccessView;
1285
+
1286
+ // src/utils/upgradeUtils.ts
1287
+ var globalClearSelectedPlan = null;
1288
+ var registerClearSelectedPlan = (clearFn) => {
1289
+ globalClearSelectedPlan = clearFn;
1290
+ };
1291
+ var clearSelectedPlan = () => {
1292
+ if (globalClearSelectedPlan) {
1293
+ globalClearSelectedPlan();
1294
+ }
1295
+ };
1296
+ var unregisterClearSelectedPlan = () => {
1297
+ globalClearSelectedPlan = null;
1298
+ };
1299
+ var DownloadIcon2 = ({ className = "w-4 h-4" }) => /* @__PURE__ */ jsxRuntime.jsx("svg", { className, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 10v6m0 0l-3-3m3 3l3-3m2 8H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" }) });
1238
1300
  var getStatusColor = (status, customColors) => {
1239
1301
  if (customColors && customColors[status.toLowerCase()]) {
1240
1302
  return customColors[status.toLowerCase()];
@@ -1263,38 +1325,60 @@ var formatCurrency = (amount, currency = "USD") => {
1263
1325
  };
1264
1326
  var TransactionItem = ({
1265
1327
  transaction,
1266
- onInvoiceClick,
1267
1328
  className = "",
1268
1329
  showInvoiceButton = true,
1269
- customStatusColors
1330
+ customStatusColors,
1331
+ showFields = {
1332
+ planName: true,
1333
+ transactionDate: true,
1334
+ amount: true,
1335
+ discount: true,
1336
+ status: true,
1337
+ coupon: true,
1338
+ invoice: true
1339
+ },
1340
+ dateFormat = "datetime"
1270
1341
  }) => {
1342
+ const handleInvoiceDownload = (invoiceUrl) => {
1343
+ const link = document.createElement("a");
1344
+ link.href = invoiceUrl;
1345
+ link.download = `invoice-${transaction.id}.pdf`;
1346
+ link.target = "_blank";
1347
+ document.body.appendChild(link);
1348
+ link.click();
1349
+ document.body.removeChild(link);
1350
+ };
1271
1351
  return /* @__PURE__ */ jsxRuntime.jsx("li", { className: `px-6 py-4 hover:bg-gray-50 ${className}`, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-between", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 min-w-0", children: [
1272
1352
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
1273
1353
  /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
1274
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-medium text-gray-900 truncate", children: transaction.planName ? `${transaction.planName} Plan` : `Transaction #${transaction.transactionCode || transaction.id}` }),
1275
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-gray-500", children: formatDate(transaction.transactionDate || transaction.membershipDate) })
1354
+ showFields.planName && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-medium text-gray-900 truncate", children: transaction.planName ? `${transaction.planName} Plan` : `Transaction #${transaction.transactionCode || transaction.id}` }),
1355
+ showFields.transactionDate && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-gray-500", children: formatDate(transaction.transactionDate || transaction.membershipDate, dateFormat) })
1276
1356
  ] }),
1277
1357
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center space-x-4", children: [
1278
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-right", children: [
1358
+ showFields.amount && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-right", children: [
1279
1359
  /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-medium text-gray-900", children: formatCurrency(transaction.amount, transaction.currency) }),
1280
- transaction.discountAmt && parseFloat(transaction.discountAmt.toString()) > 0 && /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-xs text-green-600", children: [
1360
+ showFields.discount && transaction.discountAmt && parseFloat(transaction.discountAmt.toString()) > 0 && /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-xs text-green-600", children: [
1281
1361
  "-",
1282
1362
  formatCurrency(transaction.discountAmt, transaction.currency),
1283
1363
  " discount"
1284
1364
  ] })
1285
1365
  ] }),
1286
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: `inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium ${getStatusColor(transaction.transactionStatus, customStatusColors)}`, children: transaction.transactionStatus }),
1287
- showInvoiceButton && onInvoiceClick && transaction.invoiceUrl && /* @__PURE__ */ jsxRuntime.jsx(
1366
+ showFields.status && /* @__PURE__ */ jsxRuntime.jsx("span", { className: `inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium ${getStatusColor(transaction.transactionStatus, customStatusColors)}`, children: transaction.transactionStatus }),
1367
+ showFields.invoice && showInvoiceButton && transaction.invoice_pdf && /* @__PURE__ */ jsxRuntime.jsx(
1288
1368
  "button",
1289
1369
  {
1290
- onClick: () => onInvoiceClick(transaction.id),
1291
- className: "text-blue-600 hover:text-blue-800 text-sm font-medium",
1292
- children: "Invoice"
1370
+ onClick: () => {
1371
+ handleInvoiceDownload(transaction.invoice_pdf);
1372
+ },
1373
+ className: "inline-flex items-center justify-center p-0 text-blue-600 hover:text-blue-800 transition-colors border-0 bg-transparent focus:outline-none focus:ring-0 focus-visible:outline-none active:outline-none",
1374
+ title: "Download Invoice",
1375
+ "aria-label": "Download Invoice",
1376
+ children: /* @__PURE__ */ jsxRuntime.jsx(DownloadIcon2, { className: "w-4 h-4" })
1293
1377
  }
1294
1378
  )
1295
1379
  ] })
1296
1380
  ] }),
1297
- transaction.coupon && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-2", children: /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex items-center px-2 py-1 rounded-md text-xs font-medium bg-purple-100 text-purple-800", children: [
1381
+ showFields.coupon && transaction.coupon && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-2", children: /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex items-center px-2 py-1 rounded-md text-xs font-medium bg-purple-100 text-purple-800", children: [
1298
1382
  "Coupon: ",
1299
1383
  transaction.coupon
1300
1384
  ] }) })
@@ -1390,7 +1474,6 @@ var TransactionList = ({
1390
1474
  transactions,
1391
1475
  loading = false,
1392
1476
  error = null,
1393
- onInvoiceClick,
1394
1477
  onRetry,
1395
1478
  className = "",
1396
1479
  showInvoiceButton = true,
@@ -1430,7 +1513,6 @@ var TransactionList = ({
1430
1513
  TransactionItem,
1431
1514
  {
1432
1515
  transaction,
1433
- onInvoiceClick,
1434
1516
  showInvoiceButton,
1435
1517
  customStatusColors
1436
1518
  },
@@ -1628,7 +1710,7 @@ var TransactionPagination = ({
1628
1710
  children: "Previous"
1629
1711
  }
1630
1712
  ),
1631
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center space-x-1", children: getVisiblePages().map((page, index) => /* @__PURE__ */ jsxRuntime.jsx(React3__default.default.Fragment, { children: page === "..." ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "px-3 py-2 text-sm text-gray-500", children: "..." }) : /* @__PURE__ */ jsxRuntime.jsx(
1713
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center space-x-1", children: getVisiblePages().map((page, index) => /* @__PURE__ */ jsxRuntime.jsx(React4__default.default.Fragment, { children: page === "..." ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "px-3 py-2 text-sm text-gray-500", children: "..." }) : /* @__PURE__ */ jsxRuntime.jsx(
1632
1714
  "button",
1633
1715
  {
1634
1716
  onClick: () => onPageChange(page),
@@ -1674,7 +1756,7 @@ var TransactionModal = ({
1674
1756
  autoFetch: true
1675
1757
  // Enable auto-fetch so it works when modal opens
1676
1758
  });
1677
- React3.useEffect(() => {
1759
+ React4.useEffect(() => {
1678
1760
  if (isOpen && externalId) {
1679
1761
  fetchTransactions();
1680
1762
  }
@@ -1685,8 +1767,6 @@ var TransactionModal = ({
1685
1767
  const handleLimitChange = (limit) => {
1686
1768
  updateFilters({ limit, page: 1 });
1687
1769
  };
1688
- const handleInvoiceClick = () => {
1689
- };
1690
1770
  const handleFiltersChange = (newFilters) => {
1691
1771
  updateFilters(newFilters);
1692
1772
  };
@@ -1740,7 +1820,6 @@ var TransactionModal = ({
1740
1820
  transactions,
1741
1821
  loading,
1742
1822
  error,
1743
- onInvoiceClick: handleInvoiceClick,
1744
1823
  className: "mb-4"
1745
1824
  }
1746
1825
  ),
@@ -1956,7 +2035,7 @@ var SubscriptionActionButtons = ({
1956
2035
  if (visibleActions.length === 0) {
1957
2036
  return null;
1958
2037
  }
1959
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: `${containerClass} ${className}`, children: visibleActions.map((action) => /* @__PURE__ */ jsxRuntime.jsx(React3__default.default.Fragment, { children: action.component }, action.key)) });
2038
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: `${containerClass} ${className}`, children: visibleActions.map((action) => /* @__PURE__ */ jsxRuntime.jsx(React4__default.default.Fragment, { children: action.component }, action.key)) });
1960
2039
  };
1961
2040
  var SubscriptionCancelModal = ({
1962
2041
  isOpen,
@@ -2038,8 +2117,8 @@ var SubscriptionDetails = ({
2038
2117
  customActions = [],
2039
2118
  className = ""
2040
2119
  }) => {
2041
- const [isTransactionModalOpen, setIsTransactionModalOpen] = React3.useState(false);
2042
- const [showCancelConfirmation, setShowCancelConfirmation] = React3.useState(false);
2120
+ const [isTransactionModalOpen, setIsTransactionModalOpen] = React4.useState(false);
2121
+ const [showCancelConfirmation, setShowCancelConfirmation] = React4.useState(false);
2043
2122
  const { cancelSubscription, loading: cancelLoading } = useCancelSubscription({
2044
2123
  onSuccess: () => {
2045
2124
  setShowCancelConfirmation(false);
@@ -2051,9 +2130,11 @@ var SubscriptionDetails = ({
2051
2130
  }
2052
2131
  });
2053
2132
  const handleTransactionClick = () => {
2133
+ clearSelectedPlan();
2054
2134
  setIsTransactionModalOpen(true);
2055
2135
  };
2056
2136
  const handleCancelClick = () => {
2137
+ clearSelectedPlan();
2057
2138
  setShowCancelConfirmation(true);
2058
2139
  };
2059
2140
  const handleConfirmCancel = async (options) => {
@@ -2089,7 +2170,7 @@ var SubscriptionDetails = ({
2089
2170
  onError: (error) => {
2090
2171
  alert(`Failed to open payment portal: ${error}`);
2091
2172
  },
2092
- children: "Change Card"
2173
+ children: "Manage Billing"
2093
2174
  }
2094
2175
  ),
2095
2176
  show: true
@@ -2103,30 +2184,32 @@ var SubscriptionDetails = ({
2103
2184
  }
2104
2185
  ) })
2105
2186
  ] }),
2106
- /* @__PURE__ */ jsxRuntime.jsx(
2107
- SubscriptionInfoGrid,
2108
- {
2109
- subscription,
2110
- className: "mb-4",
2111
- gridCols: usageMetrics.length > 0 ? 3 : 5
2112
- }
2113
- ),
2114
- usageMetrics.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
2115
- SubscriptionUsageDisplay,
2116
- {
2117
- subscription,
2118
- usageMetrics,
2119
- gridCols: Math.min(usageMetrics.length, 3)
2120
- }
2121
- )
2187
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-5 gap-4", children: [
2188
+ /* @__PURE__ */ jsxRuntime.jsx(
2189
+ SubscriptionInfoGrid,
2190
+ {
2191
+ subscription,
2192
+ className: "!contents",
2193
+ gridCols: usageMetrics.length > 0 ? 3 : 5
2194
+ }
2195
+ ),
2196
+ usageMetrics.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
2197
+ SubscriptionUsageDisplay,
2198
+ {
2199
+ subscription,
2200
+ usageMetrics,
2201
+ gridCols: Math.min(usageMetrics.length, 3),
2202
+ className: "!contents"
2203
+ }
2204
+ )
2205
+ ] })
2122
2206
  ] }),
2123
2207
  /* @__PURE__ */ jsxRuntime.jsx(
2124
2208
  TransactionModal,
2125
2209
  {
2126
2210
  isOpen: isTransactionModalOpen,
2127
2211
  onClose: () => setIsTransactionModalOpen(false),
2128
- externalId,
2129
- title: "Transaction History"
2212
+ externalId
2130
2213
  }
2131
2214
  ),
2132
2215
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -2142,37 +2225,70 @@ var SubscriptionDetails = ({
2142
2225
  };
2143
2226
  var UpgradeSummary = ({
2144
2227
  selectedPlan,
2145
- onUpgrade
2228
+ externalId,
2229
+ onUpgrade,
2230
+ isVisible = true
2146
2231
  }) => {
2147
- if (!selectedPlan || Number(selectedPlan.fixedCost) === 0) {
2232
+ const [checkoutInfo, setCheckoutInfo] = React4.useState(null);
2233
+ const [loading, setLoading] = React4.useState(false);
2234
+ React4.useEffect(() => {
2235
+ if (!selectedPlan || !isVisible || Number(selectedPlan.fixedCost) === 0) {
2236
+ setCheckoutInfo(null);
2237
+ return;
2238
+ }
2239
+ const fetchCheckoutInfo = async () => {
2240
+ setLoading(true);
2241
+ try {
2242
+ const response = await subscriptionApi.checkoutInfo(selectedPlan.code, externalId);
2243
+ const dataWrapper = response == null ? void 0 : response.data;
2244
+ if ((dataWrapper == null ? void 0 : dataWrapper.success) && (dataWrapper == null ? void 0 : dataWrapper.data)) {
2245
+ setCheckoutInfo(dataWrapper.data);
2246
+ }
2247
+ } catch (error) {
2248
+ console.error("Failed to fetch checkout info:", error);
2249
+ } finally {
2250
+ setLoading(false);
2251
+ }
2252
+ };
2253
+ fetchCheckoutInfo();
2254
+ }, [selectedPlan, externalId, isVisible]);
2255
+ if (!selectedPlan || !isVisible || Number(selectedPlan.fixedCost) === 0 || loading || !checkoutInfo) {
2148
2256
  return null;
2149
2257
  }
2150
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "fixed bottom-0 left-0 right-0 w-full z-50", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "max-w-7xl mx-auto w-full px-4", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg-white/40 backdrop-blur-md shadow-xl rounded-tl-md rounded-tr-md border border-gray-200 px-4 py-1.5", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
2258
+ const displayInfo = checkoutInfo;
2259
+ const intervalDisplay = displayInfo.planInterval === "MONTHLY" ? "Mo" : "Yr";
2260
+ const dueToday = displayInfo.proration > 0 ? displayInfo.proration : displayInfo.planPrice;
2261
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "fixed bottom-0 left-0 right-0 w-full z-50", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "max-w-7xl mx-auto w-full", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg-white/40 backdrop-blur-md shadow-xl rounded-tl-md rounded-tr-md border border-gray-200 px-4 py-1.5 mx-4", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
2151
2262
  /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2152
2263
  /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-gray-500", children: "Summary" }),
2153
- /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-base font-semibold", children: selectedPlan.name })
2264
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-sm font-medium", children: displayInfo.planName })
2154
2265
  ] }),
2155
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-5 items-center", children: [
2266
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-6", children: [
2156
2267
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-right", children: /* @__PURE__ */ jsxRuntime.jsxs("h3", { className: "text-2xl font-semibold text-gray-900", children: [
2157
2268
  "$",
2158
- selectedPlan.fixedCost,
2159
- "/Yr"
2269
+ displayInfo.planPrice,
2270
+ "/",
2271
+ intervalDisplay
2160
2272
  ] }) }),
2161
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2162
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-gray-500", children: "Due Today" }),
2163
- /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-xl font-semibold text-gray-900", children: [
2164
- "$",
2165
- selectedPlan.fixedCost
2166
- ] })
2167
- ] }),
2168
- /* @__PURE__ */ jsxRuntime.jsx(
2169
- "button",
2170
- {
2171
- onClick: onUpgrade,
2172
- className: "bg-green-600 text-white px-6 py-2 rounded-md font-medium hover:bg-green-700 transition-colors text-sm",
2173
- children: "Upgrade Now"
2174
- }
2175
- )
2273
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-4", children: [
2274
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-right", children: [
2275
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-gray-500", children: "Due Today" }),
2276
+ /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-xl font-semibold text-gray-900", children: [
2277
+ "$",
2278
+ dueToday
2279
+ ] }),
2280
+ displayInfo.proration > 0 && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-gray-500 mt-1", children: "(Includes prorated discount for unused days of your current plan)" })
2281
+ ] }),
2282
+ /* @__PURE__ */ jsxRuntime.jsx(
2283
+ "button",
2284
+ {
2285
+ onClick: onUpgrade,
2286
+ disabled: loading,
2287
+ className: "bg-green-600 text-white px-6 py-2 rounded-md font-medium hover:bg-green-700 transition-colors text-sm disabled:opacity-50",
2288
+ children: loading ? "Loading..." : "Upgrade Now"
2289
+ }
2290
+ )
2291
+ ] })
2176
2292
  ] })
2177
2293
  ] }) }) }) });
2178
2294
  };
@@ -2276,7 +2392,7 @@ var Pagination = ({
2276
2392
  children: "Previous"
2277
2393
  }
2278
2394
  ),
2279
- pageNumbers.map((page, index) => /* @__PURE__ */ jsxRuntime.jsx(React3__default.default.Fragment, { children: page === "..." ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "px-3 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300", children: "..." }) : /* @__PURE__ */ jsxRuntime.jsx(
2395
+ pageNumbers.map((page, index) => /* @__PURE__ */ jsxRuntime.jsx(React4__default.default.Fragment, { children: page === "..." ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "px-3 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300", children: "..." }) : /* @__PURE__ */ jsxRuntime.jsx(
2280
2396
  "button",
2281
2397
  {
2282
2398
  onClick: () => onPageChange(page),
@@ -2303,18 +2419,24 @@ var DashboardPage = ({
2303
2419
  var _a;
2304
2420
  const subscription = useSubscription();
2305
2421
  const plans = usePlans();
2306
- const lastLoadedIdRef = React3.useRef(null);
2307
- React3.useEffect(() => {
2422
+ const lastLoadedIdRef = React4.useRef(null);
2423
+ React4.useEffect(() => {
2308
2424
  if (lastLoadedIdRef.current !== externalId) {
2309
2425
  subscription.fetchSubscription(externalId);
2310
2426
  plans.fetchPlans();
2311
2427
  lastLoadedIdRef.current = externalId;
2312
2428
  }
2313
2429
  }, [externalId]);
2430
+ React4.useEffect(() => {
2431
+ registerClearSelectedPlan(plans.clearSelectedPlan);
2432
+ return () => {
2433
+ unregisterClearSelectedPlan();
2434
+ };
2435
+ }, [plans.clearSelectedPlan]);
2314
2436
  const handleUpgrade = () => {
2315
2437
  plans.handleUpgrade(externalId);
2316
2438
  };
2317
- return /* @__PURE__ */ jsxRuntime.jsx(Layout, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "max-w-7xl mx-auto w-full h-full py-8 px-4 pb-24", children: [
2439
+ return /* @__PURE__ */ jsxRuntime.jsx(UpgradeProvider, { children: /* @__PURE__ */ jsxRuntime.jsx(Layout, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "max-w-7xl mx-auto w-full h-full py-8 px-4 pb-24", children: [
2318
2440
  /* @__PURE__ */ jsxRuntime.jsx(
2319
2441
  SubscriptionDetails,
2320
2442
  {
@@ -2322,6 +2444,7 @@ var DashboardPage = ({
2322
2444
  externalId,
2323
2445
  onSubscriptionCancelled: () => {
2324
2446
  subscription.fetchSubscription(externalId);
2447
+ plans.clearSelectedPlan();
2325
2448
  }
2326
2449
  }
2327
2450
  ),
@@ -2346,13 +2469,15 @@ var DashboardPage = ({
2346
2469
  UpgradeSummary,
2347
2470
  {
2348
2471
  selectedPlan: plans.selectedPlan,
2349
- onUpgrade: handleUpgrade
2472
+ externalId,
2473
+ onUpgrade: handleUpgrade,
2474
+ isVisible: !!plans.selectedPlan
2350
2475
  }
2351
2476
  )
2352
- ] }) });
2477
+ ] }) }) });
2353
2478
  };
2354
2479
  var usePaymentParams = () => {
2355
- return React3.useMemo(() => {
2480
+ return React4.useMemo(() => {
2356
2481
  const params = new URLSearchParams(window.location.search);
2357
2482
  return {
2358
2483
  gateway: params.get("gateway") || void 0,
@@ -2363,9 +2488,9 @@ var usePaymentParams = () => {
2363
2488
  }, []);
2364
2489
  };
2365
2490
  var useProcessPaymentSuccess = (params) => {
2366
- const [loading, setLoading] = React3.useState(true);
2367
- const [error, setError] = React3.useState(null);
2368
- React3.useEffect(() => {
2491
+ const [loading, setLoading] = React4.useState(true);
2492
+ const [error, setError] = React4.useState(null);
2493
+ React4.useEffect(() => {
2369
2494
  const run = async () => {
2370
2495
  try {
2371
2496
  const qs = new URLSearchParams({
@@ -2435,9 +2560,9 @@ var PaymentSuccessPage = () => {
2435
2560
  };
2436
2561
  var PaymentSuccessPage_default = PaymentSuccessPage;
2437
2562
  var useProcessPaymentCancel = (params) => {
2438
- const [loading, setLoading] = React3.useState(true);
2439
- const [error, setError] = React3.useState(null);
2440
- React3.useEffect(() => {
2563
+ const [loading, setLoading] = React4.useState(true);
2564
+ const [error, setError] = React4.useState(null);
2565
+ React4.useEffect(() => {
2441
2566
  const run = async () => {
2442
2567
  try {
2443
2568
  const qs = new URLSearchParams({
@@ -2528,7 +2653,9 @@ exports.TransactionPagination = TransactionPagination;
2528
2653
  exports.TransactionStatusFilter = TransactionStatusFilter;
2529
2654
  exports.TrendingUpIcon = TrendingUpIcon;
2530
2655
  exports.UpgradeIcon = UpgradeIcon;
2656
+ exports.UpgradeProvider = UpgradeProvider;
2531
2657
  exports.UpgradeSummary = UpgradeSummary;
2658
+ exports.clearSelectedPlan = clearSelectedPlan;
2532
2659
  exports.configureSubOS = configureSubOS;
2533
2660
  exports.customerApi = customerApi;
2534
2661
  exports.ensureSubOSConfig = ensureSubOSConfig;
@@ -2546,14 +2673,17 @@ exports.getStripePublishableKey = getStripePublishableKey;
2546
2673
  exports.getUniqueCandidateUnits = getUniqueCandidateUnits;
2547
2674
  exports.isPlanPopular = isPlanPopular;
2548
2675
  exports.plansApi = plansApi;
2676
+ exports.registerClearSelectedPlan = registerClearSelectedPlan;
2549
2677
  exports.subscriptionApi = subscriptionApi;
2550
2678
  exports.transactionApi = transactionApi;
2679
+ exports.unregisterClearSelectedPlan = unregisterClearSelectedPlan;
2551
2680
  exports.useCancelSubscription = useCancelSubscription;
2552
2681
  exports.useCustomerPortal = useCustomerPortal;
2553
2682
  exports.usePagination = usePagination;
2554
2683
  exports.usePlans = usePlans;
2555
2684
  exports.useSubscription = useSubscription;
2556
2685
  exports.useTransactions = useTransactions;
2686
+ exports.useUpgrade = useUpgrade;
2557
2687
  exports.validateSubOSConfig = validateSubOSConfig;
2558
2688
  //# sourceMappingURL=index.js.map
2559
2689
  //# sourceMappingURL=index.js.map