@fluid-app/portal-sdk 0.1.159 → 0.1.161

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 (78) hide show
  1. package/README.md +2 -196
  2. package/dist/{FluidProvider-Cqf2kmUc.mjs → FluidProvider-B00jTGTH.mjs} +1510 -1624
  3. package/dist/FluidProvider-B00jTGTH.mjs.map +1 -0
  4. package/dist/{FluidProvider-Bc-3uN7M.cjs → FluidProvider-BtGi2jJt.cjs} +1458 -1614
  5. package/dist/FluidProvider-BtGi2jJt.cjs.map +1 -0
  6. package/dist/{MessagingScreen-BGqIn-c2.cjs → MessagingScreen-BRCUJDDZ.cjs} +2 -2
  7. package/dist/{MessagingScreen-CbmuvlH6.mjs → MessagingScreen-BWpSXB8Q.mjs} +2 -2
  8. package/dist/{MessagingScreen-CbmuvlH6.mjs.map → MessagingScreen-BWpSXB8Q.mjs.map} +1 -1
  9. package/dist/{MessagingScreen-CBPjP4du.cjs → MessagingScreen-C_OLIWCC.cjs} +2 -2
  10. package/dist/{MessagingScreen-CBPjP4du.cjs.map → MessagingScreen-C_OLIWCC.cjs.map} +1 -1
  11. package/dist/{MySiteScreen-DSDLDnCN.cjs → MySiteScreen-B90qzZPe.cjs} +2 -2
  12. package/dist/{MySiteScreen-Cl6nuU99.cjs → MySiteScreen-DLuHDXB1.cjs} +2 -2
  13. package/dist/{MySiteScreen-Cl6nuU99.cjs.map → MySiteScreen-DLuHDXB1.cjs.map} +1 -1
  14. package/dist/{MySiteScreen-BT1PBPsH.mjs → MySiteScreen-VaOB-vWk.mjs} +2 -2
  15. package/dist/{MySiteScreen-BT1PBPsH.mjs.map → MySiteScreen-VaOB-vWk.mjs.map} +1 -1
  16. package/dist/ProductsScreen-B8OynxlP.cjs +13 -0
  17. package/dist/{ProductsScreen-4WRrJcvw.mjs → ProductsScreen-CbVSNv1l.mjs} +3 -5
  18. package/dist/ProductsScreen-CbVSNv1l.mjs.map +1 -0
  19. package/dist/{ProductsScreen-BCs3YKVk.cjs → ProductsScreen-D1bw4ZIH.cjs} +3 -5
  20. package/dist/ProductsScreen-D1bw4ZIH.cjs.map +1 -0
  21. package/dist/ProductsScreen-Pq3j09nI.mjs +11 -0
  22. package/dist/{ProfileScreen-BgyrIQdL.mjs → ProfileScreen-BCHljkWD.mjs} +2 -2
  23. package/dist/{ProfileScreen-BgyrIQdL.mjs.map → ProfileScreen-BCHljkWD.mjs.map} +1 -1
  24. package/dist/{ProfileScreen-B0KNWXpV.cjs → ProfileScreen-Bf-lYNzz.cjs} +2 -2
  25. package/dist/{ProfileScreen-DLLLRNB2.cjs → ProfileScreen-ksdtbydb.cjs} +2 -2
  26. package/dist/{ProfileScreen-DLLLRNB2.cjs.map → ProfileScreen-ksdtbydb.cjs.map} +1 -1
  27. package/dist/{ShareablesScreen-ySSwCVSI.cjs → ShareablesScreen-6wgiwi_9.cjs} +3 -5
  28. package/dist/ShareablesScreen-6wgiwi_9.cjs.map +1 -0
  29. package/dist/{ShareablesScreen-B8cmh8JC.mjs → ShareablesScreen-BLCukNTk.mjs} +3 -5
  30. package/dist/{ShareablesScreen-B8cmh8JC.mjs.map → ShareablesScreen-BLCukNTk.mjs.map} +1 -1
  31. package/dist/ShareablesScreen-CM9OH-Nx.mjs +11 -0
  32. package/dist/ShareablesScreen-rmLcUhbL.cjs +13 -0
  33. package/dist/{ShopScreen-DhMo8bvP.cjs → ShopScreen-8KKwwjka.cjs} +3 -3
  34. package/dist/{ShopScreen-DhMo8bvP.cjs.map → ShopScreen-8KKwwjka.cjs.map} +1 -1
  35. package/dist/{ShopScreen-BkvyW0pE.cjs → ShopScreen-CjEbB3Q7.cjs} +2 -2
  36. package/dist/{ShopScreen-BFFGYwdV.mjs → ShopScreen-Dn5LwwYD.mjs} +3 -3
  37. package/dist/{ShopScreen-BFFGYwdV.mjs.map → ShopScreen-Dn5LwwYD.mjs.map} +1 -1
  38. package/dist/{SubscriptionsScreen-RScBCcY0.cjs → SubscriptionsScreen-B16wPAoA.cjs} +2 -2
  39. package/dist/SubscriptionsScreen-B16wPAoA.cjs.map +1 -0
  40. package/dist/{SubscriptionsScreen-CiNR7JUC.mjs → SubscriptionsScreen-B4cTlgDU.mjs} +2 -2
  41. package/dist/SubscriptionsScreen-B4cTlgDU.mjs.map +1 -0
  42. package/dist/{SubscriptionsScreen-DMh-GE6n.cjs → SubscriptionsScreen-nRUMdnx7.cjs} +1 -1
  43. package/dist/{dist-Bg8UyHyM.cjs → dist-lO2OG0T5.cjs} +1 -1
  44. package/dist/{dist-Bg8UyHyM.cjs.map → dist-lO2OG0T5.cjs.map} +1 -1
  45. package/dist/index.cjs +134 -143
  46. package/dist/index.cjs.map +1 -1
  47. package/dist/index.d.cts +444 -655
  48. package/dist/index.d.cts.map +1 -1
  49. package/dist/index.d.mts +444 -655
  50. package/dist/index.d.mts.map +1 -1
  51. package/dist/index.mjs +127 -130
  52. package/dist/index.mjs.map +1 -1
  53. package/dist/{sortable.esm-Cz-CP2N8.mjs → sortable.esm-DSrWP4x9.mjs} +1 -1
  54. package/dist/{sortable.esm-Cz-CP2N8.mjs.map → sortable.esm-DSrWP4x9.mjs.map} +1 -1
  55. package/dist/{use-portal-products-client-BmlUixy4.cjs → use-portal-products-client-BHSBT64s.cjs} +2 -2
  56. package/dist/use-portal-products-client-BHSBT64s.cjs.map +1 -0
  57. package/dist/{use-portal-products-client-DQK9nFxT.mjs → use-portal-products-client-tbqk6XUq.mjs} +2 -2
  58. package/dist/use-portal-products-client-tbqk6XUq.mjs.map +1 -0
  59. package/dist/{use-portal-shareables-api-KVPj0Jfr.mjs → use-portal-shareables-api-B9B4XTjw.mjs} +107 -201
  60. package/dist/use-portal-shareables-api-B9B4XTjw.mjs.map +1 -0
  61. package/dist/{use-portal-shareables-api-D5D6uIJy.cjs → use-portal-shareables-api-MBl0d0eQ.cjs} +106 -206
  62. package/dist/use-portal-shareables-api-MBl0d0eQ.cjs.map +1 -0
  63. package/package.json +13 -13
  64. package/dist/FluidProvider-Bc-3uN7M.cjs.map +0 -1
  65. package/dist/FluidProvider-Cqf2kmUc.mjs.map +0 -1
  66. package/dist/ProductsScreen-4WRrJcvw.mjs.map +0 -1
  67. package/dist/ProductsScreen-BCs3YKVk.cjs.map +0 -1
  68. package/dist/ProductsScreen-BR9TN4So.cjs +0 -48
  69. package/dist/ProductsScreen-Da6eWJ_c.mjs +0 -46
  70. package/dist/ShareablesScreen-DW0wCYOj.mjs +0 -46
  71. package/dist/ShareablesScreen-DbPJOtCF.cjs +0 -48
  72. package/dist/ShareablesScreen-ySSwCVSI.cjs.map +0 -1
  73. package/dist/SubscriptionsScreen-CiNR7JUC.mjs.map +0 -1
  74. package/dist/SubscriptionsScreen-RScBCcY0.cjs.map +0 -1
  75. package/dist/use-portal-products-client-BmlUixy4.cjs.map +0 -1
  76. package/dist/use-portal-products-client-DQK9nFxT.mjs.map +0 -1
  77. package/dist/use-portal-shareables-api-D5D6uIJy.cjs.map +0 -1
  78. package/dist/use-portal-shareables-api-KVPj0Jfr.mjs.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"SubscriptionsScreen-RScBCcY0.cjs","names":["ToggleGroup","ToggleGroupItem","SearchSort","Skeleton","Table","TableHeader","TableRow","TableColumn","TableBody","TableCell","PaginationFooter","SubscriptionsListScreen","Breadcrumb","BreadcrumbList","BreadcrumbItem","BreadcrumbPage","usePortalTenantClient","useAppNavigation","SubscriptionsListScreenContent","AlertDialog","AlertDialogContent","AlertDialogHeader","AlertDialogTitle","AlertDialogDescription","AlertDialogFooter","AlertDialogCancel","AlertDialogAction","Skeleton","Button","SkipForward","Pause","Play","XCircle","RotateCcw","SubscriptionDetailScreen","Breadcrumb","BreadcrumbList","BreadcrumbItem","BreadcrumbLink","BreadcrumbSeparator","BreadcrumbPage","usePortalTenantClient","useAppNavigation","SubscriptionDetailScreenContent","useAppNavigation","useAccount"],"sources":["../../../subscriptions/core/src/subscriptions-api-context.ts","../../../subscriptions/core/src/provider.tsx","../../../subscriptions/core/src/query-keys.ts","../../../subscriptions/core/src/hooks/use-subscriptions.ts","../../../subscriptions/core/src/hooks/use-subscription.ts","../../../subscriptions/core/src/hooks/use-pause-subscription.ts","../../../subscriptions/core/src/hooks/use-resume-subscription.ts","../../../subscriptions/core/src/hooks/use-skip-subscription.ts","../../../subscriptions/core/src/hooks/use-cancel-subscription.ts","../../../subscriptions/core/src/hooks/use-reactivate-subscription.ts","../../../subscriptions/core/src/utils/subscription-helpers.ts","../../../subscriptions/ui/src/lib/format.ts","../../../subscriptions/ui/src/lib/cn.ts","../../../subscriptions/ui/src/components/status-pill.tsx","../../../subscriptions/ui/src/components/subscriptions-list.tsx","../../../subscriptions/ui/src/screens/SubscriptionsListScreen.tsx","../../../subscriptions/api-client/src/portal-tenant-adapter.ts","../src/screens/SubscriptionsListScreen.tsx","../../../subscriptions/ui/src/components/confirm-dialog.tsx","../../../subscriptions/ui/src/components/subscription-detail.tsx","../../../subscriptions/ui/src/screens/SubscriptionDetailScreen.tsx","../src/screens/SubscriptionDetailScreen.tsx","../src/screens/SubscriptionsScreen.tsx"],"sourcesContent":["import { createContext, useContext } from \"react\";\nimport type { SubscriptionsApi } from \"./subscriptions-api\";\n\nconst SubscriptionsApiContext = createContext<SubscriptionsApi | null>(null);\n\nexport const SubscriptionsApiProvider = SubscriptionsApiContext.Provider;\n\nexport function useSubscriptionsApi(): SubscriptionsApi {\n const api = useContext(SubscriptionsApiContext);\n if (!api) {\n throw new Error(\n \"useSubscriptionsApi must be used within a SubscriptionsCoreProvider\",\n );\n }\n return api;\n}\n","import type { JSX } from \"react\";\nimport type { SubscriptionsApi } from \"./subscriptions-api\";\nimport { SubscriptionsApiProvider } from \"./subscriptions-api-context\";\n\nexport interface SubscriptionsCoreProviderProps {\n api: SubscriptionsApi;\n children: React.ReactNode;\n}\n\nexport function SubscriptionsCoreProvider({\n api,\n children,\n}: SubscriptionsCoreProviderProps): JSX.Element {\n return (\n <SubscriptionsApiProvider value={api}>{children}</SubscriptionsApiProvider>\n );\n}\n","import type { subscriptions } from \"./types\";\n\nexport const subscriptionsKeys = {\n all: [\"subscriptions\"] as const,\n list: (params?: subscriptions.FetchSubscriptionsParams) =>\n [...subscriptionsKeys.all, \"list\", params] as const,\n detail: (token: string) =>\n [...subscriptionsKeys.all, \"detail\", token] as const,\n} as const;\n","import { useQuery } from \"@tanstack/react-query\";\nimport type { subscriptions } from \"../types\";\nimport { subscriptionsKeys } from \"../query-keys\";\nimport { useSubscriptionsApi } from \"../subscriptions-api-context\";\n\nexport function useSubscriptions(\n params: subscriptions.FetchSubscriptionsParams,\n options?: { enabled?: boolean },\n) {\n const api = useSubscriptionsApi();\n return useQuery({\n queryKey: subscriptionsKeys.list(params),\n queryFn: () => api.fetchCustomerSubscriptions(params),\n enabled: options?.enabled ?? !!params.customerId,\n });\n}\n","import { useQuery } from \"@tanstack/react-query\";\nimport { subscriptionsKeys } from \"../query-keys\";\nimport { useSubscriptionsApi } from \"../subscriptions-api-context\";\n\nexport function useSubscription(\n token: string,\n options?: { enabled?: boolean },\n) {\n const api = useSubscriptionsApi();\n return useQuery({\n queryKey: subscriptionsKeys.detail(token),\n queryFn: () => api.fetchSubscription(token),\n enabled: (options?.enabled ?? true) && !!token,\n });\n}\n","import { useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport type { subscriptions } from \"../types\";\nimport { subscriptionsKeys } from \"../query-keys\";\nimport { useSubscriptionsApi } from \"../subscriptions-api-context\";\n\nexport function usePauseSubscription(options?: {\n onSuccess?: () => void;\n onError?: (error: unknown) => void;\n}) {\n const api = useSubscriptionsApi();\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationFn: (params: {\n subscriptionToken: string;\n pauseParams: subscriptions.PauseSubscriptionParams;\n }) => api.pauseSubscription(params.subscriptionToken, params.pauseParams),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: subscriptionsKeys.all });\n options?.onSuccess?.();\n },\n onError: options?.onError,\n });\n}\n","import { useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport type { subscriptions } from \"../types\";\nimport { subscriptionsKeys } from \"../query-keys\";\nimport { useSubscriptionsApi } from \"../subscriptions-api-context\";\n\nexport function useResumeSubscription(options?: {\n onSuccess?: () => void;\n onError?: (error: unknown) => void;\n}) {\n const api = useSubscriptionsApi();\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationFn: (params: {\n subscriptionToken: string;\n resumeParams: subscriptions.ResumeSubscriptionParams;\n }) => api.resumeSubscription(params.subscriptionToken, params.resumeParams),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: subscriptionsKeys.all });\n options?.onSuccess?.();\n },\n onError: options?.onError,\n });\n}\n","import { useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport type { subscriptions } from \"../types\";\nimport { subscriptionsKeys } from \"../query-keys\";\nimport { useSubscriptionsApi } from \"../subscriptions-api-context\";\n\nexport function useSkipSubscription(options?: {\n onSuccess?: () => void;\n onError?: (error: unknown) => void;\n}) {\n const api = useSubscriptionsApi();\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationFn: (params: {\n subscriptionToken: string;\n skipParams: subscriptions.SkipSubscriptionParams;\n }) => api.skipSubscription(params.subscriptionToken, params.skipParams),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: subscriptionsKeys.all });\n options?.onSuccess?.();\n },\n onError: options?.onError,\n });\n}\n","import { useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport { subscriptionsKeys } from \"../query-keys\";\nimport { useSubscriptionsApi } from \"../subscriptions-api-context\";\n\nexport function useCancelSubscription(options?: {\n onSuccess?: () => void;\n onError?: (error: unknown) => void;\n}) {\n const api = useSubscriptionsApi();\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationFn: (params: { subscriptionToken: string; customerId?: number }) =>\n api.cancelSubscription(params.subscriptionToken, params.customerId),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: subscriptionsKeys.all });\n options?.onSuccess?.();\n },\n onError: options?.onError,\n });\n}\n","import { useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport type { subscriptions } from \"../types\";\nimport { subscriptionsKeys } from \"../query-keys\";\nimport { useSubscriptionsApi } from \"../subscriptions-api-context\";\n\nexport function useReactivateSubscription(options?: {\n onSuccess?: () => void;\n onError?: (error: unknown) => void;\n}) {\n const api = useSubscriptionsApi();\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationFn: (params: {\n subscriptionToken: string;\n reactivateParams: subscriptions.ReactivateSubscriptionParams;\n }) =>\n api.reactivateSubscription(\n params.subscriptionToken,\n params.reactivateParams,\n ),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: subscriptionsKeys.all });\n options?.onSuccess?.();\n },\n onError: options?.onError,\n });\n}\n","interface SubscriptionPriceItem {\n allow_subscription: boolean;\n subscription_interval: number | null;\n subscription_price_in_currency: string | null;\n}\n\nexport function getSubscriptionPrice(\n item: SubscriptionPriceItem,\n): string | null {\n if (!item.allow_subscription) return null;\n const intervalText =\n item.subscription_interval === 1\n ? \"month\"\n : `${item.subscription_interval} mo.`;\n return `${item.subscription_price_in_currency}/${intervalText}`;\n}\n\nexport function formatSubscriptionFrequency(frequency: string): string {\n if (frequency === \"day\") return \"Daily\";\n if (frequency === \"week\") return \"Weekly\";\n if (frequency === \"month\") return \"Monthly\";\n if (frequency === \"year\") return \"Yearly\";\n return frequency;\n}\n\nexport function calculateResumeDate(\n billingInterval: number,\n billingIntervalUnit: string,\n orderCount: number,\n fromDate?: string | Date | null,\n): Date {\n let startDate: Date;\n\n if (fromDate) {\n if (typeof fromDate === \"string\") {\n startDate = new Date(\n fromDate + (fromDate.includes(\"T\") ? \"\" : \"T12:00:00.000Z\"),\n );\n } else {\n startDate = new Date(\n Date.UTC(\n fromDate.getUTCFullYear(),\n fromDate.getUTCMonth(),\n fromDate.getUTCDate(),\n 12,\n 0,\n 0,\n 0,\n ),\n );\n }\n } else {\n const now = new Date();\n startDate = new Date(\n Date.UTC(\n now.getUTCFullYear(),\n now.getUTCMonth(),\n now.getUTCDate(),\n 12,\n 0,\n 0,\n 0,\n ),\n );\n }\n\n const baseDate = new Date(startDate.getTime());\n const totalIntervals = billingInterval * orderCount;\n\n switch (billingIntervalUnit.toLowerCase()) {\n case \"day\":\n baseDate.setUTCDate(baseDate.getUTCDate() + totalIntervals);\n break;\n case \"week\":\n baseDate.setUTCDate(baseDate.getUTCDate() + totalIntervals * 7);\n break;\n case \"month\": {\n const currentMonth = baseDate.getUTCMonth();\n const currentDay = baseDate.getUTCDate();\n baseDate.setUTCMonth(currentMonth + totalIntervals);\n if (baseDate.getUTCDate() !== currentDay) {\n baseDate.setUTCDate(0);\n }\n break;\n }\n case \"year\":\n baseDate.setUTCFullYear(baseDate.getUTCFullYear() + totalIntervals);\n break;\n default: {\n const defaultMonth = baseDate.getUTCMonth();\n const defaultDay = baseDate.getUTCDate();\n baseDate.setUTCMonth(defaultMonth + totalIntervals);\n if (baseDate.getUTCDate() !== defaultDay) {\n baseDate.setUTCDate(0);\n }\n }\n }\n\n return baseDate;\n}\n\nexport function calculateNextBillDate(\n billingInterval: number = 1,\n billingIntervalUnit: string = \"month\",\n): string {\n const now = new Date();\n const nextBillDate = new Date(now);\n\n switch (billingIntervalUnit.toLowerCase()) {\n case \"day\":\n nextBillDate.setDate(now.getDate() + billingInterval);\n break;\n case \"week\":\n nextBillDate.setDate(now.getDate() + billingInterval * 7);\n break;\n case \"month\":\n nextBillDate.setMonth(now.getMonth() + billingInterval);\n break;\n case \"year\":\n nextBillDate.setFullYear(now.getFullYear() + billingInterval);\n break;\n default:\n nextBillDate.setMonth(now.getMonth() + billingInterval);\n }\n\n return nextBillDate.toISOString().split(\"T\")[0] || \"\";\n}\n\nexport function formatDate(\n dateString: string,\n isCancelled: boolean = false,\n): string {\n if (isCancelled) return \"Cancelled\";\n if (!dateString) return \"Paused\";\n\n const datePortion = dateString.split(\"T\")[0] ?? dateString;\n const parts = datePortion.split(\"-\");\n if (parts.length !== 3) return \"Invalid date\";\n\n const [year, month, day] = parts.map(Number);\n if (!year || !month || !day) return \"Invalid date\";\n const date = new Date(year, month - 1, day);\n\n const monthNames = [\n \"January\",\n \"February\",\n \"March\",\n \"April\",\n \"May\",\n \"June\",\n \"July\",\n \"August\",\n \"September\",\n \"October\",\n \"November\",\n \"December\",\n ];\n\n const dayNum = date.getDate();\n const monthName = monthNames[date.getMonth()];\n const yearNum = date.getFullYear();\n\n const ordinalSuffix = (d: number) => {\n if (d > 3 && d < 21) return \"th\";\n switch (d % 10) {\n case 1:\n return \"st\";\n case 2:\n return \"nd\";\n case 3:\n return \"rd\";\n default:\n return \"th\";\n }\n };\n\n return `${monthName} ${dayNum}${ordinalSuffix(dayNum)}, ${yearNum}`;\n}\n\nexport function getNextBillDisplay<\n T extends { status?: string; next_bill_date?: string | null },\n>(subscription: T | null | undefined): string {\n if (subscription?.status === \"cancelled\") return \"Cancelled\";\n if (subscription?.next_bill_date)\n return formatDate(subscription.next_bill_date);\n if (subscription?.status === \"paused\") return \"Paused\";\n return \"N/A\";\n}\n\nexport function calculateSubscriptionPrice(\n totalPrice: number,\n subscribeAndSave: string | null | undefined,\n quantity: number,\n): string {\n if (!subscribeAndSave) return totalPrice.toFixed(2);\n\n const unitDiscountAmount = parseFloat(subscribeAndSave);\n if (isNaN(unitDiscountAmount)) return totalPrice.toFixed(2);\n\n const subscriptionAmount = totalPrice - unitDiscountAmount * quantity;\n return subscriptionAmount.toFixed(2);\n}\n","/**\n * Format a number as currency (USD).\n */\nexport function formatCurrency(value: number): string {\n return new Intl.NumberFormat(\"en-US\", {\n style: \"currency\",\n currency: \"USD\",\n }).format(value);\n}\n\n/**\n * Convert a snake_case or lowercase string to Start Case.\n * Replaces lodash startCase for simple status strings.\n */\nexport function startCase(str: string | undefined | null): string {\n if (!str) return \"\";\n return str.replace(/_/g, \" \").replace(/\\b\\w/g, (char) => char.toUpperCase());\n}\n\n/**\n * Format a next bill date string to M/D/YYYY (UTC).\n */\nexport function formatNextBillDate(nextBillDate: string): string {\n if (!nextBillDate) return \"N/A\";\n const date = new Date(nextBillDate);\n if (isNaN(date.getTime())) return \"N/A\";\n const month = date.getUTCMonth() + 1;\n const day = date.getUTCDate();\n const year = date.getUTCFullYear();\n return `${month}/${day}/${year}`;\n}\n","import { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","import type { JSX } from \"react\";\nimport { cn } from \"../lib/cn\";\n\nconst STATUS_COLORS: Record<string, string> = {\n active: \"bg-green-100 text-green-800\",\n paused: \"bg-gray-100 text-gray-800\",\n cancelled: \"bg-red-100 text-red-800\",\n pending: \"bg-yellow-100 text-yellow-800\",\n inactive: \"bg-gray-100 text-gray-800\",\n disabled: \"bg-red-100 text-red-800\",\n past_due: \"bg-gray-100 text-gray-800\",\n};\n\nconst STATUS_DOT_COLORS: Record<string, string> = {\n active: \"bg-green-500\",\n paused: \"bg-gray-400\",\n cancelled: \"bg-red-500\",\n pending: \"bg-yellow-500\",\n inactive: \"bg-gray-400\",\n disabled: \"bg-red-500\",\n past_due: \"bg-gray-400\",\n};\n\nexport interface StatusPillProps {\n status: string | undefined | null;\n children: React.ReactNode;\n}\n\nexport function StatusPill({ status, children }: StatusPillProps): JSX.Element {\n const key = status?.toLowerCase() ?? \"\";\n const pillColor = STATUS_COLORS[key] ?? \"bg-gray-100 text-gray-800\";\n const dotColor = STATUS_DOT_COLORS[key] ?? \"bg-gray-400\";\n\n return (\n <span\n className={cn(\n \"inline-flex items-center gap-1.5 rounded-full px-2.5 py-0.5 text-xs font-medium\",\n pillColor,\n )}\n >\n <span className={cn(\"h-1.5 w-1.5 rounded-full\", dotColor)} />\n {children}\n </span>\n );\n}\n","import { useState, useEffect, type JSX } from \"react\";\nimport type { subscriptions } from \"@fluid-app/subscriptions-core\";\nimport { useSubscriptions } from \"@fluid-app/subscriptions-core\";\nimport { TableColumn, PaginationFooter } from \"@fluid-app/orders-ui\";\nimport {\n Skeleton,\n Table,\n TableBody,\n TableCell,\n TableHeader,\n TableRow,\n ToggleGroup,\n ToggleGroupItem,\n} from \"@fluid-app/ui-primitives\";\nimport { SearchSort } from \"@fluid-app/ui-components/components/SearchSort\";\nimport { formatCurrency, startCase, formatNextBillDate } from \"../lib/format\";\nimport { StatusPill } from \"./status-pill\";\n\nexport interface SubscriptionsListProps {\n customerId: number | undefined;\n onSubscriptionClick: (subscriptionToken: string) => void;\n t: (key: string) => string;\n pageSize?: number;\n}\n\nexport function SubscriptionsList({\n customerId,\n onSubscriptionClick,\n t,\n pageSize = 10,\n}: SubscriptionsListProps): JSX.Element {\n const [currentPage, setCurrentPage] = useState(1);\n const [statusFilter, setStatusFilter] = useState<string | null>(null);\n const [search, setSearch] = useState<string | null>(null);\n const [sortBy, setSortBy] = useState<{\n column: string;\n direction: \"asc\" | \"desc\";\n }>({\n column: \"next_bill_date\",\n direction: \"desc\",\n });\n\n const params: subscriptions.FetchSubscriptionsParams = {\n customerId: customerId ?? 0,\n page: currentPage,\n perPage: pageSize,\n status: statusFilter,\n search,\n sortBy: sortBy.column,\n sortDirection: sortBy.direction,\n };\n\n const { data, isLoading } = useSubscriptions(params, {\n enabled: !!customerId,\n });\n\n // Reset page when filters change\n useEffect(() => {\n setCurrentPage(1);\n }, [statusFilter, search, sortBy]);\n\n const items = data?.subscriptions ?? [];\n const totalItems = data?.meta?.pagination?.total_count ?? 0;\n const totalPages = data?.meta?.pagination?.total_pages ?? 1;\n\n const handleSubscriptionClick = (token: string) => {\n if (token) {\n onSubscriptionClick(token);\n }\n };\n\n return (\n <div className=\"border-border overflow-hidden rounded-lg border shadow-sm\">\n {/* header: filter tabs + search */}\n <div className=\"flex flex-col gap-2 p-3 sm:flex-row sm:items-center sm:justify-between\">\n <ToggleGroup\n type=\"single\"\n value={statusFilter ?? \"all\"}\n onValueChange={(v) => {\n if (v) setStatusFilter(v === \"all\" ? null : v);\n }}\n variant=\"ghost\"\n >\n <ToggleGroupItem value=\"all\">{t(\"all\")}</ToggleGroupItem>\n <ToggleGroupItem value=\"active\">{t(\"active\")}</ToggleGroupItem>\n <ToggleGroupItem value=\"inactive\">{t(\"inactive\")}</ToggleGroupItem>\n </ToggleGroup>\n <div className=\"w-full max-w-sm\">\n <SearchSort\n searchValue={search ?? \"\"}\n onSearchChange={(v) => setSearch(v || null)}\n placeholder={t(\"search_subscriptions\")}\n />\n </div>\n </div>\n\n {/* mobile view */}\n <div className=\"block md:hidden\">\n {isLoading ? (\n Array(5)\n .fill(0)\n .map((_, index) => (\n <div\n key={`skeleton-${index}`}\n className=\"border-border border-b p-4\"\n >\n <div className=\"flex space-x-3\">\n <Skeleton className=\"h-12 w-12 rounded-md\" />\n <div className=\"flex-1 space-y-2\">\n <Skeleton className=\"h-4 w-3/4\" />\n <Skeleton className=\"h-3 w-1/2\" />\n </div>\n </div>\n </div>\n ))\n ) : items.length === 0 ? (\n <div className=\"text-muted-foreground px-3 py-8 text-center text-sm\">\n {t(\"no_subscriptions_found\")}\n </div>\n ) : (\n items.map((subscription) => (\n <div\n key={subscription.subscription_token}\n className=\"border-border hover:bg-accent cursor-pointer border-b p-4 transition-colors duration-200 ease-in-out last:border-b-0\"\n onClick={() =>\n handleSubscriptionClick(subscription.subscription_token)\n }\n >\n <div className=\"flex items-start space-x-3\">\n <img\n src={subscription.variant?.product?.image_url}\n alt={subscription.variant?.product?.title}\n width={48}\n height={48}\n className=\"h-12 w-12 flex-shrink-0 rounded-md object-cover\"\n />\n <div className=\"w-0 min-w-0 flex-1\">\n <p className=\"text-foreground truncate text-sm font-medium\">\n {subscription.variant?.product?.title}\n </p>\n <div className=\"mt-2 grid grid-cols-2 gap-x-4 gap-y-1 text-sm\">\n <div>\n <span className=\"text-muted-foreground block text-xs\">\n {t(\"next_bill_date\")}\n </span>\n <span className=\"text-muted-foreground\">\n {formatNextBillDate(subscription.next_bill_date ?? \"\")}\n </span>\n </div>\n <div>\n <span className=\"text-muted-foreground block text-xs\">\n {t(\"price\")}\n </span>\n <span className=\"text-foreground font-medium\">\n {formatCurrency(\n subscription.price * subscription.quantity,\n )}\n </span>\n </div>\n </div>\n <div className=\"mt-2\">\n <span className=\"text-muted-foreground block text-xs\">\n {t(\"status\")}\n </span>\n <StatusPill status={subscription.status}>\n {startCase(subscription.status) || t(\"unknown_status\")}\n </StatusPill>\n </div>\n </div>\n </div>\n </div>\n ))\n )}\n </div>\n\n {/* desktop view */}\n <div className=\"hidden md:block\">\n <Table className=\"min-w-full table-fixed\">\n <colgroup>\n <col className=\"w-[45%] min-w-[240px]\" />\n <col className=\"w-[20%] min-w-[100px]\" />\n <col className=\"w-[15%] min-w-[100px]\" />\n <col className=\"w-[20%] min-w-[100px]\" />\n </colgroup>\n <TableHeader className=\"bg-muted\">\n <TableRow className=\"hover:bg-muted h-10\">\n <TableColumn label={t(\"product\")} sortable={false} />\n <TableColumn\n label={t(\"next_bill_date\")}\n sortBy=\"next_bill_date\"\n sortData={sortBy}\n onSortClick={(value: string) =>\n setSortBy({\n column: value,\n direction: sortBy.direction === \"asc\" ? \"desc\" : \"asc\",\n })\n }\n />\n <TableColumn label={t(\"price\")} sortable={false} />\n <TableColumn label={t(\"status\")} sortable={false} />\n </TableRow>\n </TableHeader>\n <TableBody className=\"bg-background\">\n {isLoading ? (\n Array(5)\n .fill(0)\n .map((_, index) => (\n <TableRow key={`skeleton-${index}`}>\n <TableCell className=\"px-3 py-4\">\n <div className=\"flex items-center space-x-2\">\n <Skeleton className=\"h-9 w-9 rounded-md\" />\n <Skeleton className=\"h-4 w-32\" />\n </div>\n </TableCell>\n <TableCell className=\"px-3 py-4\">\n <Skeleton className=\"h-4 w-24\" />\n </TableCell>\n <TableCell className=\"px-3 py-4\">\n <Skeleton className=\"h-4 w-24\" />\n </TableCell>\n <TableCell className=\"px-3 py-4\">\n <Skeleton className=\"h-4 w-16\" />\n </TableCell>\n </TableRow>\n ))\n ) : items.length === 0 ? (\n <TableRow>\n <TableCell\n colSpan={4}\n className=\"text-muted-foreground px-3 py-8 text-center text-sm\"\n >\n {t(\"no_subscriptions_found\")}\n </TableCell>\n </TableRow>\n ) : (\n items.map((subscription) => (\n <TableRow\n key={subscription.subscription_token}\n className=\"cursor-pointer\"\n onClick={() =>\n handleSubscriptionClick(subscription.subscription_token)\n }\n >\n <TableCell className=\"text-muted-foreground flex max-w-[280px] items-center space-x-3 py-4 pr-3 pl-3 text-sm\">\n <img\n src={subscription.variant?.product?.image_url}\n alt={subscription.variant?.product?.title}\n width={48}\n height={48}\n className=\"h-12 w-12 flex-shrink-0 rounded-md object-cover\"\n />\n <span className=\"text-foreground truncate text-sm font-medium\">\n {subscription.variant?.product?.title}\n </span>\n </TableCell>\n <TableCell className=\"text-muted-foreground px-3 py-4 text-sm whitespace-nowrap\">\n {formatNextBillDate(subscription.next_bill_date ?? \"\")}\n </TableCell>\n <TableCell className=\"px-3 py-4 text-sm whitespace-nowrap\">\n <span className=\"text-muted-foreground\">\n {formatCurrency(\n subscription.price * subscription.quantity,\n )}\n </span>\n </TableCell>\n <TableCell className=\"px-3 py-4 text-sm whitespace-nowrap\">\n <StatusPill status={subscription.status}>\n {startCase(subscription.status) || t(\"unknown_status\")}\n </StatusPill>\n </TableCell>\n </TableRow>\n ))\n )}\n </TableBody>\n </Table>\n </div>\n\n <PaginationFooter\n currentPage={currentPage}\n totalPages={totalPages}\n pageSize={pageSize}\n totalItems={totalItems}\n onPageChange={setCurrentPage}\n t={t}\n />\n </div>\n );\n}\n","\"use client\";\n\nimport { useMemo } from \"react\";\nimport {\n Breadcrumb,\n BreadcrumbList,\n BreadcrumbItem,\n BreadcrumbPage,\n} from \"@fluid-app/ui-primitives\";\nimport { useScreenHeaderBreadcrumbs } from \"@fluid-app/portal-react/shell/ScreenHeaderContext\";\nimport { SubscriptionsList } from \"../components/subscriptions-list\";\n\nexport interface SubscriptionsListScreenProps {\n customerId: number | undefined;\n onSubscriptionClick: (subscriptionToken: string) => void;\n t: (key: string) => string;\n isLoadingCustomer?: boolean;\n}\n\nexport function SubscriptionsListScreen({\n customerId,\n onSubscriptionClick,\n t,\n isLoadingCustomer,\n}: SubscriptionsListScreenProps) {\n const headerBreadcrumbs = useMemo(\n () => (\n <Breadcrumb>\n <BreadcrumbList className=\"text-lg\">\n <BreadcrumbItem>\n <BreadcrumbPage className=\"font-semibold\">\n Subscriptions\n </BreadcrumbPage>\n </BreadcrumbItem>\n </BreadcrumbList>\n </Breadcrumb>\n ),\n [],\n );\n useScreenHeaderBreadcrumbs(headerBreadcrumbs);\n\n if (isLoadingCustomer) {\n return (\n <div className=\"mx-auto max-w-7xl px-4 py-4 sm:px-6 sm:py-6 lg:px-10 lg:py-8\">\n <div className=\"space-y-3\">\n <div className=\"bg-muted h-10 animate-pulse rounded\" />\n <div className=\"bg-muted h-64 animate-pulse rounded\" />\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"mx-auto max-w-7xl px-4 py-4 sm:px-6 sm:py-6 lg:px-10 lg:py-8\">\n <SubscriptionsList\n customerId={customerId}\n onSubscriptionClick={onSubscriptionClick}\n t={t}\n />\n </div>\n );\n}\n","import type { SubscriptionsApi } from \"@fluid-app/subscriptions-core\";\nimport type { FetchClient } from \"./lib/fetch-client\";\nimport type { subscriptions } from \"./custom/subscriptions\";\nimport { portalTenant } from \"@fluid-app/portal-tenant-api-client\";\n\n/**\n * Maps the BFF meta envelope to the port's expected shape.\n */\nfunction mapMeta(raw: { request_id?: string | null; timestamp?: string }): {\n request_id: string;\n timestamp: string;\n} {\n return {\n request_id: raw.request_id ?? \"\",\n timestamp: raw.timestamp ?? \"\",\n };\n}\n\ntype BffSubscriptionResponse = Awaited<\n ReturnType<typeof portalTenant.subscriptions_show>\n>;\n\ntype BffListResponse = Awaited<\n ReturnType<typeof portalTenant.subscriptions_list>\n>;\n\ntype BffSubscription = NonNullable<BffSubscriptionResponse[\"subscription\"]>;\n\n/**\n * Safely parses a price string to a number, returning the fallback if the\n * result is NaN (e.g. non-numeric strings from a malformed BFF response).\n */\nfunction safeParsePrice(\n value: string | null | undefined,\n fallback = 0,\n): number {\n if (!value) return fallback;\n const parsed = parseFloat(value);\n return Number.isNaN(parsed) ? fallback : parsed;\n}\n\n/**\n * Maps a BFF subscription detail response to the port's SubscriptionDetail.\n *\n * The BFF returns a flat Subscription schema (plan_name, product, etc.) while\n * the port expects richly nested objects (subscription_plan, variant.product).\n * This explicitly maps every field the UI accesses so undefined-property crashes\n * are caught here at the adapter boundary rather than deep in the component tree.\n */\nfunction mapDetailSubscription(\n bff: BffSubscription,\n): subscriptions.SubscriptionDetailSubscription {\n const price = safeParsePrice(bff.total);\n\n return {\n id: bff.id ?? 0,\n subscription_token: bff.token ?? \"\",\n status: bff.status ?? \"\",\n quantity: bff.quantity ?? 1,\n price,\n original_price: safeParsePrice(bff.original_price, price),\n next_bill_date: bff.next_billing_date ?? null,\n last_bill_date: bff.last_billing_date ?? null,\n next_ship_date: null,\n last_ship_date: null,\n disabled: false,\n attempts: 0,\n last_failed_at: null,\n next_retry_at: null,\n skipped_count: 0,\n max_skips: null,\n cancelled_at: null,\n created_at: bff.created_at ?? \"\",\n updated_at: bff.updated_at ?? \"\",\n notes: null,\n subscription_plan: {\n id: bff.plan?.id ?? 0,\n name: bff.plan?.name ?? bff.plan_name ?? \"\",\n billing_interval: bff.plan?.billing_interval ?? 1,\n billing_interval_unit:\n bff.plan?.billing_interval_unit ?? bff.interval ?? \"month\",\n billing_frequency_in_words: bff.plan?.billing_interval_unit\n ? `Every ${bff.plan.billing_interval ?? 1} ${bff.plan.billing_interval_unit}`\n : \"\",\n shipping_interval: 1,\n shipping_interval_unit:\n bff.plan?.billing_interval_unit ?? bff.interval ?? \"month\",\n trial_period: null,\n trial_period_unit: null,\n split_volume: false,\n allow_skipping: bff.plan?.allow_skipping ?? false,\n max_skips: bff.plan?.max_skips ?? null,\n price_adjustment_type: null,\n price_adjustment_amount: null,\n max_quantity: null,\n active: true,\n company_default: null,\n created_at: \"\",\n updated_at: \"\",\n products_count: null,\n subscribers_count: null,\n },\n customer: {\n id: 0,\n account_id: null,\n first_name: null,\n last_name: null,\n full_name: bff.customer_name ?? \"\",\n email: \"\",\n verified_email: null,\n phone: null,\n orders_count: null,\n created_at: \"\",\n display_total_spent: \"0\",\n metadata: {},\n user_company_id: null,\n external_id: null,\n last_order_id: null,\n notes: null,\n active: true,\n total_spent: 0,\n customer_notes: [],\n default_address: null,\n addresses: [],\n active_subscriptions_count: 0,\n inactive_subscriptions_count: 0,\n is_rep: false,\n },\n variant: {\n id: bff.product?.id ?? 0,\n title: bff.product?.variant_name ?? \"\",\n image_url: bff.product?.image_url ?? null,\n image_path: null,\n sku: null,\n primary_image: bff.product?.image_url ?? null,\n price: bff.total ? safeParsePrice(bff.total) : null,\n price_in_currency: bff.total ?? \"0\",\n options: [],\n product: {\n id: bff.product?.id ?? 0,\n title: bff.product?.name ?? \"\",\n image_url: bff.product?.image_url ?? null,\n image_path: null,\n price: bff.total ? safeParsePrice(bff.total) : null,\n cv: null,\n tax: null,\n sku: null,\n price_in_currency: bff.total ?? \"0\",\n tax_in_currency: \"0\",\n cv_in_currency: \"0\",\n },\n },\n address: bff.address\n ? {\n id: bff.address.id ?? 0,\n name: bff.address.name ?? null,\n address1: bff.address.address1 ?? \"\",\n address2: bff.address.address2 ?? null,\n city: bff.address.city ?? \"\",\n state: bff.address.state ?? \"\",\n subdivision_code: null,\n postal_code: bff.address.postal_code ?? \"\",\n country_code: bff.address.country_code ?? null,\n default: false,\n }\n : {\n id: 0,\n name: null,\n address1: \"\",\n address2: null,\n city: \"\",\n state: \"\",\n subdivision_code: null,\n postal_code: \"\",\n country_code: null,\n default: false,\n },\n payment_method: bff.payment_method\n ? {\n id: bff.payment_method.id ?? 0,\n source: bff.payment_method.source ?? \"\",\n payment_type:\n bff.payment_method.payment_type ?? bff.payment_method.source ?? \"\",\n created_at: \"\",\n updated_at: \"\",\n default: false,\n details: {\n card_type: bff.payment_method.details?.card_type ?? undefined,\n last4: bff.payment_method.details?.last4 ?? undefined,\n },\n }\n : {\n id: 0,\n source: \"\",\n payment_type: \"\",\n created_at: \"\",\n updated_at: \"\",\n default: false,\n details: {},\n },\n currency: {\n id: 0,\n name: bff.currency ?? null,\n code: bff.currency ?? \"USD\",\n rate: null,\n active: true,\n symbol: null,\n },\n country: { id: 0, name: \"\", iso: \"\" },\n company: { id: 0, name: \"\" },\n subscription_skips: [],\n orders: [],\n };\n}\n\nfunction mapSubscriptionDetail(\n response: BffSubscriptionResponse,\n): subscriptions.SubscriptionDetail {\n const bff = response.subscription;\n if (!bff) {\n throw new Error(\n \"BFF returned a successful response but subscription data was missing\",\n );\n }\n return {\n subscription: mapDetailSubscription(bff),\n meta: response.meta ? mapMeta(response.meta) : undefined,\n };\n}\n\n/**\n * Maps a BFF list subscription to the port's SubscriptionListItem.\n *\n * The BFF returns a flat shape with `product` and `quantity` while the port\n * expects nested `variant.product` (from the admin API). This bridges the two\n * so the UI layer sees a consistent shape regardless of which API backs it.\n */\nfunction mapListItem(\n bff: NonNullable<BffListResponse[\"subscriptions\"]>[number],\n): subscriptions.SubscriptionListItem {\n return {\n id: bff.id ?? 0,\n subscription_token: bff.token ?? \"\",\n created_at: bff.created_at ?? \"\",\n customer: {\n id: 0,\n account_id: \"\",\n active: true,\n display_total_spent: \"0\",\n email: \"\",\n first_name: \"\",\n full_name: bff.customer_name ?? \"\",\n is_rep: false,\n last_name: \"\",\n orders_count: 0,\n phone: null,\n total_spent: \"0\",\n user_company_id: null,\n },\n last_bill_date: null,\n next_bill_date: bff.next_billing_date ?? null,\n price: safeParsePrice(bff.total),\n quantity: bff.quantity ?? 1,\n status: bff.status ?? \"\",\n subscription_plan: {\n id: 0,\n active: true,\n billing_interval: 1,\n billing_interval_unit: bff.interval ?? \"\",\n shipping_interval: 1,\n shipping_interval_unit: bff.interval ?? \"\",\n },\n variant: {\n id: bff.product?.id ?? 0,\n title: bff.product?.variant_name ?? \"\",\n product: {\n id: bff.product?.id ?? 0,\n title: bff.product?.name ?? \"\",\n image_url: bff.product?.image_url ?? \"\",\n price_in_currency: bff.total ?? \"0\",\n },\n },\n };\n}\n\nfunction mapSubscriptionList(\n response: BffListResponse,\n): subscriptions.SubscriptionsResponse {\n return {\n subscriptions: (response.subscriptions ?? []).map(mapListItem),\n meta: mapMeta(response.meta ?? {}),\n };\n}\n\n/**\n * Creates a SubscriptionsApi-compatible adapter backed by the portal-tenant BFF.\n *\n * Uses async/await with explicit field mapping. The BFF returns simplified\n * subscription types compared to the full admin API; the adapter maps the\n * response envelope and provides runtime defaults for optional fields.\n */\nexport function createPortalSubscriptionsAdapter(\n client: FetchClient,\n): SubscriptionsApi {\n return {\n fetchCustomerSubscriptions: async (\n params: subscriptions.FetchSubscriptionsParams,\n ) => {\n const response = await portalTenant.subscriptions_list(client, {\n \"page[cursor]\": params.cursor,\n \"page[limit]\": params.limit ?? params.perPage,\n });\n return mapSubscriptionList(response);\n },\n\n fetchSubscription: async (subscriptionToken: string) => {\n const response = await portalTenant.subscriptions_show(\n client,\n subscriptionToken,\n );\n return mapSubscriptionDetail(response);\n },\n\n pauseSubscription: async (\n subscriptionToken: string,\n _params: subscriptions.PauseSubscriptionParams,\n ) => {\n const response = await portalTenant.subscriptions_pause(\n client,\n subscriptionToken,\n );\n return mapSubscriptionDetail(response);\n },\n\n resumeSubscription: async (\n subscriptionToken: string,\n _params: subscriptions.ResumeSubscriptionParams,\n ) => {\n const response = await portalTenant.subscriptions_resume(\n client,\n subscriptionToken,\n );\n return mapSubscriptionDetail(response);\n },\n\n skipSubscription: async (\n subscriptionToken: string,\n _params: subscriptions.SkipSubscriptionParams,\n ) => {\n const response = await portalTenant.subscriptions_skip(\n client,\n subscriptionToken,\n );\n return mapSubscriptionDetail(response);\n },\n\n cancelSubscription: async (\n subscriptionToken: string,\n _customerId?: number,\n ) => {\n const response = await portalTenant.subscriptions_cancel(\n client,\n subscriptionToken,\n );\n return mapSubscriptionDetail(response);\n },\n\n reactivateSubscription: async (\n subscriptionToken: string,\n _params: subscriptions.ReactivateSubscriptionParams,\n ) => {\n const response = await portalTenant.subscriptions_reactivate(\n client,\n subscriptionToken,\n );\n return mapSubscriptionDetail(response);\n },\n\n updateSubscriptionInfo: async (\n subscriptionToken: string,\n body: Pick<subscriptions.UpdateSubscriptionInfoBody, \"payment_method_id\">,\n ) => {\n const response = await portalTenant.subscriptions_update(\n client,\n subscriptionToken,\n { subscription: { payment_method_id: body.payment_method_id } },\n );\n return mapSubscriptionDetail(response);\n },\n };\n}\n","import { useMemo } from \"react\";\nimport { SubscriptionsCoreProvider } from \"@fluid-app/subscriptions-core\";\nimport { SubscriptionsListScreen as SubscriptionsListScreenContent } from \"@fluid-app/subscriptions-ui/screens/SubscriptionsListScreen\";\nimport { createPortalSubscriptionsAdapter } from \"@fluid-app/subscriptions-api-client\";\nimport { usePortalTenantClient } from \"../providers/PortalTenantClientProvider\";\nimport { useAppNavigation } from \"../shell/AppNavigationContext\";\n\nconst translations: Record<string, string> = {\n all: \"All\",\n active: \"Active\",\n inactive: \"Inactive\",\n search: \"Search\",\n subscriptions: \"Search subscriptions...\",\n product: \"Product\",\n next_bill_date: \"Next Bill Date\",\n price: \"Price\",\n status: \"Status\",\n no_subscriptions_found: \"No subscriptions found\",\n unknown_status: \"Unknown\",\n total: \"Total\",\n results: \"results\",\n previous: \"Previous\",\n next: \"Next\",\n pagination: \"Pagination\",\n};\n\ninterface SubscriptionsListScreenProps {\n customerId: number | undefined;\n isLoadingCustomer: boolean;\n}\n\nexport function SubscriptionsListScreen({\n customerId,\n isLoadingCustomer,\n}: SubscriptionsListScreenProps): React.JSX.Element {\n const client = usePortalTenantClient();\n const subscriptionsApi = useMemo(\n () => createPortalSubscriptionsAdapter(client),\n [client],\n );\n const { navigate } = useAppNavigation();\n\n return (\n <SubscriptionsCoreProvider api={subscriptionsApi}>\n <SubscriptionsListScreenContent\n customerId={customerId}\n isLoadingCustomer={isLoadingCustomer}\n onSubscriptionClick={(subscriptionToken) =>\n navigate(`subscriptions/${subscriptionToken}`)\n }\n t={(key) => translations[key] ?? key}\n />\n </SubscriptionsCoreProvider>\n );\n}\n","import { useState } from \"react\";\nimport {\n AlertDialog,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n AlertDialogCancel,\n AlertDialogAction,\n} from \"@fluid-app/ui-primitives\";\n\ninterface ConfirmDialogProps {\n title: string;\n description: string;\n actionButtonText?: string;\n cancelButtonText?: string;\n open: boolean;\n setOpen: (open: boolean) => void;\n onConfirm: () => void | Promise<unknown>;\n}\n\nexport function ConfirmDialog({\n title,\n description,\n actionButtonText = \"Delete\",\n cancelButtonText = \"Cancel\",\n open,\n setOpen,\n onConfirm,\n}: ConfirmDialogProps) {\n const [isPending, setIsPending] = useState(false);\n\n const handleConfirm = async () => {\n try {\n const result = onConfirm();\n if (result instanceof Promise) {\n setIsPending(true);\n await result;\n }\n } catch (error) {\n console.error(\"ConfirmDialog: action rejected\", error);\n } finally {\n setIsPending(false);\n setOpen(false);\n }\n };\n\n return (\n <AlertDialog open={open} onOpenChange={(v) => !isPending && setOpen(v)}>\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>{title}</AlertDialogTitle>\n <AlertDialogDescription>{description}</AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel disabled={isPending}>\n {cancelButtonText}\n </AlertDialogCancel>\n <AlertDialogAction\n onClick={handleConfirm}\n disabled={isPending}\n className=\"bg-red-600 text-white hover:bg-red-500\"\n >\n {isPending ? \"...\" : actionButtonText}\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n );\n}\n","import { useState, useEffect, useRef, type JSX } from \"react\";\nimport type { subscriptions } from \"@fluid-app/subscriptions-core\";\nimport {\n useSubscription,\n usePauseSubscription,\n useResumeSubscription,\n useSkipSubscription,\n useCancelSubscription,\n useReactivateSubscription,\n formatSubscriptionFrequency,\n formatDate,\n getNextBillDisplay,\n calculateNextBillDate,\n} from \"@fluid-app/subscriptions-core\";\nimport { SkipForward, Pause, Play, XCircle, RotateCcw } from \"lucide-react\";\nimport { Skeleton, Button } from \"@fluid-app/ui-primitives\";\nimport { ConfirmDialog } from \"./confirm-dialog\";\nimport { StatusPill } from \"./status-pill\";\nimport { startCase, formatCurrency } from \"../lib/format\";\n\nexport interface SubscriptionDetailProps {\n token: string;\n onNotFound?: () => void;\n onError?: (error: Error) => void;\n onSuccess?: (message: string) => void;\n onMutationError?: (message: string, error: unknown) => void;\n}\n\nfunction SubscriptionDetailSkeleton() {\n return (\n <div className=\"flex flex-col lg:grid lg:grid-cols-8\">\n {/* Left: items skeleton */}\n <div className=\"bg-muted flex flex-col items-center px-8 lg:col-span-4\">\n <div className=\"w-full max-w-lg py-6\">\n <Skeleton className=\"mb-4 h-6 w-48\" />\n <div className=\"grid grid-cols-2 gap-4\">\n <Skeleton className=\"h-16 w-full rounded\" />\n <Skeleton className=\"h-16 w-full rounded\" />\n </div>\n <div className=\"mt-6 flex items-center space-x-4\">\n <Skeleton className=\"h-24 w-24 rounded\" />\n <div className=\"flex-1 space-y-2\">\n <Skeleton className=\"h-4 w-3/4\" />\n <Skeleton className=\"h-4 w-1/2\" />\n <Skeleton className=\"h-4 w-1/4\" />\n </div>\n </div>\n <div className=\"mt-6 space-y-2\">\n <Skeleton className=\"h-4 w-full\" />\n <Skeleton className=\"h-4 w-full\" />\n <Skeleton className=\"h-5 w-full\" />\n </div>\n </div>\n </div>\n {/* Right: management skeleton */}\n <div className=\"bg-background col-span-4 px-8 pt-4\">\n <div className=\"mx-auto max-w-lg\">\n <Skeleton className=\"mb-3 h-5 w-32\" />\n <div className=\"grid grid-cols-2 gap-3\">\n <Skeleton className=\"h-10 w-full rounded\" />\n <Skeleton className=\"h-10 w-full rounded\" />\n </div>\n <div className=\"mt-6 space-y-4\">\n <Skeleton className=\"h-5 w-40\" />\n <div className=\"flex gap-4\">\n <Skeleton className=\"h-12 flex-1 rounded\" />\n <Skeleton className=\"h-12 flex-1 rounded\" />\n </div>\n </div>\n <div className=\"mt-6 space-y-4\">\n <Skeleton className=\"h-5 w-40\" />\n <Skeleton className=\"h-16 w-full rounded\" />\n <Skeleton className=\"h-16 w-full rounded\" />\n </div>\n </div>\n </div>\n </div>\n );\n}\n\n/* ── Left column: product & order summary ──────────────────────────── */\n\nfunction SubscriptionItemsSection({\n subscription,\n}: {\n subscription: subscriptions.SubscriptionDetailSubscription;\n}) {\n const variant = subscription.variant;\n const product = variant?.product;\n const quantity = subscription.quantity;\n const totalPrice = formatCurrency(subscription.price * quantity);\n const discount =\n subscription.original_price != null\n ? subscription.original_price - subscription.price\n : 0;\n const subtotal =\n discount > 0\n ? formatCurrency(subscription.original_price * quantity)\n : totalPrice;\n\n return (\n <section className=\"bg-muted flex w-full flex-col items-center px-8 lg:col-span-4\">\n <div className=\"flex w-full max-w-lg flex-col\">\n {/* Upcoming order summary */}\n <div className=\"mt-4\">\n <h2 className=\"text-foreground mb-2 text-lg font-medium\">\n Your Upcoming Order\n </h2>\n <div className=\"text-muted-foreground\">\n <div className=\"grid grid-cols-2 gap-4\">\n <div className=\"border-border border-r pr-4\">\n <div className=\"text-muted-foreground mb-1 text-sm\">\n Next Order Date\n </div>\n <div className=\"text-foreground text-2xl font-bold\">\n {getNextBillDisplay(subscription)}\n </div>\n </div>\n <div className=\"pl-4\">\n <div className=\"text-muted-foreground mb-1 text-sm\">\n Next Bill Amount\n </div>\n <div className=\"text-foreground text-2xl font-bold\">\n {formatCurrency(subscription.price * quantity)}\n </div>\n </div>\n </div>\n <hr className=\"border-border mt-4\" />\n </div>\n </div>\n\n {/* Product row */}\n <div className=\"py-6\">\n <div className=\"flex flex-row items-center space-x-4\">\n <div className=\"flex min-w-0 flex-1 flex-row space-x-4\">\n <div className=\"relative shrink-0\">\n <div className=\"bg-muted h-24 w-24 overflow-hidden rounded\">\n {product?.image_url ? (\n <img\n src={product.image_url}\n alt={variant?.title || \"Product image\"}\n width={96}\n height={96}\n className=\"h-full w-full object-cover\"\n />\n ) : (\n <div className=\"text-muted-foreground flex h-full w-full items-center justify-center\">\n No image\n </div>\n )}\n {quantity > 1 && (\n <span className=\"bg-foreground text-background absolute -top-2 -right-2 z-10 flex h-6 w-6 items-center justify-center rounded-full text-xs font-medium\">\n {quantity}\n </span>\n )}\n </div>\n </div>\n <div className=\"flex min-w-0 flex-col space-y-0.5\">\n <p\n className=\"text-foreground truncate text-sm font-medium\"\n title={product?.title}\n >\n {product?.title}\n </p>\n {variant?.title && product?.title && (\n <p className=\"text-muted-foreground text-sm\">\n {variant.title}\n </p>\n )}\n <div>\n <p className=\"text-foreground text-sm font-medium\">\n {formatCurrency(subscription.price * quantity)}\n </p>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n {/* Pricing summary */}\n <div className=\"mb-4\">\n {discount > 0 && (\n <>\n <div className=\"flex justify-between text-sm\">\n <p className=\"text-muted-foreground text-sm font-medium\">\n Subtotal\n </p>\n <p className=\"text-muted-foreground text-sm font-medium\">\n {subtotal}\n </p>\n </div>\n <div className=\"mt-2 flex justify-between text-sm\">\n <p className=\"text-muted-foreground text-sm font-medium\">\n Discount\n </p>\n <p className=\"text-muted-foreground text-sm font-medium\">\n -{formatCurrency(discount * quantity)}\n </p>\n </div>\n </>\n )}\n <div className=\"mt-4 flex items-center justify-between text-base font-medium\">\n <p className=\"text-muted-foreground text-sm font-medium\">Total</p>\n <p className=\"text-foreground text-base font-bold\">\n {formatCurrency(subscription.price * quantity)}\n </p>\n </div>\n <span className=\"text-muted-foreground text-xs\">\n *Tax and shipping calculated at checkout\n </span>\n </div>\n </div>\n </section>\n );\n}\n\n/* ── Right column: actions & details ───────────────────────────────── */\n\nfunction SubscriptionManagementSection({\n subscription,\n isActive,\n isPaused,\n isCancelled,\n isMutating,\n onSkip,\n onPause,\n onResume,\n onCancel,\n onReactivate,\n}: {\n subscription: subscriptions.SubscriptionDetailSubscription;\n isActive: boolean;\n isPaused: boolean;\n isCancelled: boolean;\n isMutating: boolean;\n onSkip: () => void;\n onPause: () => void;\n onResume: () => void;\n onCancel: () => void;\n onReactivate: () => void;\n}) {\n const plan = subscription.subscription_plan;\n const quantity = subscription.quantity;\n const totalPrice = formatCurrency(subscription.price * quantity);\n\n const paymentMethod = subscription.payment_method;\n const paymentDetails = paymentMethod?.details as {\n last4?: string;\n card_type?: string;\n logo_url?: string;\n } | null;\n\n const actionButtonClass =\n \"flex h-auto flex-row items-center justify-center gap-2 overflow-hidden border border-border bg-muted py-2 text-xs whitespace-nowrap text-foreground hover:bg-accent sm:text-sm\";\n\n return (\n <div className=\"bg-background col-span-4 flex-auto px-8 pt-4\">\n <div className=\"mx-auto max-w-lg lg:mx-0 lg:mr-auto\">\n {/* Action Buttons */}\n <div className=\"border-border mb-6 border-b pb-6\">\n <h2 className=\"text-foreground mb-3 text-sm/6 font-semibold\">\n Order Actions\n </h2>\n <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2\">\n {isActive && plan.allow_skipping && (\n <Button\n variant=\"outline\"\n onClick={onSkip}\n disabled={isMutating || !subscription.next_bill_date}\n className={actionButtonClass}\n >\n <SkipForward className=\"h-3 w-3 shrink-0\" />\n <span className=\"truncate\">Skip Next Order</span>\n </Button>\n )}\n {isActive && (\n <Button\n variant=\"outline\"\n onClick={onPause}\n disabled={isMutating}\n className={actionButtonClass}\n >\n <Pause className=\"h-3 w-3 shrink-0\" />\n <span className=\"truncate\">Pause Subscription</span>\n </Button>\n )}\n {isPaused && (\n <Button\n variant=\"outline\"\n onClick={onResume}\n disabled={isMutating}\n className={actionButtonClass}\n >\n <Play className=\"h-3 w-3 shrink-0\" />\n <span className=\"truncate\">Resume Subscription</span>\n </Button>\n )}\n <Button\n variant=\"outline\"\n onClick={onCancel}\n disabled={isMutating || isCancelled}\n className={actionButtonClass}\n >\n <XCircle className=\"h-3 w-3 shrink-0\" />\n <span className=\"truncate\">\n {isCancelled ? \"Cancelled\" : \"Cancel Subscription\"}\n </span>\n </Button>\n {isCancelled && (\n <Button\n variant=\"outline\"\n onClick={onReactivate}\n disabled={isMutating}\n className={actionButtonClass}\n >\n <RotateCcw className=\"h-3 w-3 shrink-0\" />\n <span className=\"truncate\">Reactivate Subscription</span>\n </Button>\n )}\n </div>\n </div>\n\n {/* Subscription Details */}\n <div className=\"border-border mb-4 border-b\">\n <div className=\"mb-4 flex items-center justify-between\">\n <h3 className=\"text-foreground text-sm/6 font-semibold\">\n Subscription Details\n </h3>\n <StatusPill status={subscription.status}>\n {startCase(subscription.status)}\n </StatusPill>\n </div>\n <div className=\"divide-border mb-4 flex divide-x\">\n <div className=\"flex-1 pr-4\">\n <div className=\"text-muted-foreground text-sm\">\n Order Frequency\n </div>\n <div className=\"text-foreground font-medium\">\n {formatSubscriptionFrequency(plan.billing_interval_unit)}\n </div>\n </div>\n <div className=\"flex-1 px-4\">\n <div className=\"text-muted-foreground text-sm\">Next Payment</div>\n <div className=\"text-foreground font-medium\">{totalPrice}</div>\n </div>\n {subscription.last_bill_date && (\n <div className=\"flex-1 pl-4 text-right\">\n <div className=\"text-muted-foreground text-sm\">Last Billed</div>\n <div className=\"text-foreground font-medium\">\n {formatDate(subscription.last_bill_date)}\n </div>\n </div>\n )}\n </div>\n </div>\n\n {/* Payment & Shipping */}\n <div className=\"pt-2\">\n <h3 className=\"text-foreground text-sm/6 font-semibold\">\n Payment & Shipping\n </h3>\n <div className=\"flex flex-col\">\n {/* Shipping Address */}\n {subscription.address && (\n <div className=\"border-border mb-6 border-b pb-4\">\n <div className=\"text-muted-foreground mt-3 mb-1 text-sm\">\n Shipping Address\n </div>\n <div className=\"text-foreground text-sm\">\n <p className=\"font-medium\">{subscription.address.name}</p>\n <p>{subscription.address.address1}</p>\n {subscription.address.address2 && (\n <p>{subscription.address.address2}</p>\n )}\n <p>\n {[subscription.address.city, subscription.address.state]\n .filter(Boolean)\n .join(\", \")}{\" \"}\n {subscription.address.postal_code}\n </p>\n {subscription.address.country_code && (\n <p>{subscription.address.country_code}</p>\n )}\n </div>\n </div>\n )}\n\n {/* Payment Method */}\n {paymentMethod && (\n <div className=\"border-border mb-6 border-b pb-4\">\n <div className=\"text-muted-foreground mb-1 text-sm\">\n Payment Method\n </div>\n <div className=\"text-foreground flex items-center gap-2 text-sm\">\n {paymentDetails?.logo_url && (\n <img\n src={paymentDetails.logo_url}\n alt={paymentDetails.card_type ?? \"Card\"}\n className=\"h-6\"\n />\n )}\n <span className=\"font-medium\">\n {paymentDetails?.card_type\n ? startCase(paymentDetails.card_type)\n : paymentMethod.payment_type}\n {paymentDetails?.last4\n ? ` ending in ${paymentDetails.last4}`\n : \"\"}\n </span>\n </div>\n </div>\n )}\n </div>\n </div>\n\n {/* Order History */}\n {subscription.orders.length > 0 && (\n <div className=\"border-border mb-4 border-b pb-4\">\n <h3 className=\"text-foreground mb-3 text-sm/6 font-semibold\">\n Order History\n </h3>\n <div className=\"overflow-x-auto\">\n <table className=\"divide-border min-w-full divide-y text-sm\">\n <thead>\n <tr>\n <th className=\"text-muted-foreground py-2 pr-3 text-left font-medium\">\n Order\n </th>\n <th className=\"text-muted-foreground px-3 py-2 text-left font-medium\">\n Date\n </th>\n <th className=\"text-muted-foreground px-3 py-2 text-left font-medium\">\n Status\n </th>\n <th className=\"text-muted-foreground py-2 pl-3 text-right font-medium\">\n Amount\n </th>\n </tr>\n </thead>\n <tbody className=\"divide-border divide-y\">\n {subscription.orders.map((order) => (\n <tr key={order.id}>\n <td className=\"text-foreground py-2 pr-3 font-medium\">\n {order.order_number ?? `#${order.id}`}\n </td>\n <td className=\"text-muted-foreground px-3 py-2\">\n {formatDate(order.created_at.split(\"T\")[0] ?? \"\")}\n </td>\n <td className=\"px-3 py-2\">\n <StatusPill status={order.status}>\n {startCase(order.status)}\n </StatusPill>\n </td>\n <td className=\"text-foreground py-2 pl-3 text-right\">\n {order.amount != null\n ? formatCurrency(Number(order.amount))\n : \"N/A\"}\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n </div>\n )}\n </div>\n </div>\n );\n}\n\n/* ── Main component ────────────────────────────────────────────────── */\n\nexport function SubscriptionDetail({\n token,\n onNotFound,\n onError,\n onSuccess,\n onMutationError,\n}: SubscriptionDetailProps): JSX.Element | null {\n const [showCancelModal, setShowCancelModal] = useState(false);\n\n const { data, isLoading, error } = useSubscription(token);\n const subscription = data?.subscription;\n const customerId = subscription?.customer?.id ?? 0;\n\n const pauseMutation = usePauseSubscription({\n onSuccess: () => onSuccess?.(\"Subscription paused\"),\n onError: (err: unknown) =>\n onMutationError?.(\"Failed to pause subscription\", err),\n });\n\n const resumeMutation = useResumeSubscription({\n onSuccess: () => onSuccess?.(\"Subscription resumed\"),\n onError: (err: unknown) =>\n onMutationError?.(\"Failed to resume subscription\", err),\n });\n\n const skipMutation = useSkipSubscription({\n onSuccess: () => onSuccess?.(\"Next billing skipped\"),\n onError: (err: unknown) => onMutationError?.(\"Failed to skip billing\", err),\n });\n\n const cancelMutation = useCancelSubscription({\n onSuccess: () => {\n onSuccess?.(\"Subscription cancelled\");\n setShowCancelModal(false);\n },\n onError: (err: unknown) =>\n onMutationError?.(\"Failed to cancel subscription\", err),\n });\n\n const reactivateMutation = useReactivateSubscription({\n onSuccess: () => onSuccess?.(\"Subscription reactivated\"),\n onError: (err: unknown) =>\n onMutationError?.(\"Failed to reactivate subscription\", err),\n });\n\n const onErrorRef = useRef(onError);\n onErrorRef.current = onError;\n const onNotFoundRef = useRef(onNotFound);\n onNotFoundRef.current = onNotFound;\n\n useEffect(() => {\n if (!isLoading && error) {\n onErrorRef.current?.(error as Error);\n }\n }, [isLoading, error]);\n\n useEffect(() => {\n if (!isLoading && !error && !subscription) {\n onNotFoundRef.current?.();\n }\n }, [isLoading, error, subscription]);\n\n if (isLoading) {\n return <SubscriptionDetailSkeleton />;\n }\n\n if (!subscription) {\n return null;\n }\n\n const plan = subscription.subscription_plan;\n const isActive = subscription.status === \"active\";\n const isPaused = subscription.status === \"paused\";\n const isCancelled = subscription.status === \"cancelled\";\n const isMutating =\n pauseMutation.isPending ||\n resumeMutation.isPending ||\n skipMutation.isPending ||\n cancelMutation.isPending ||\n reactivateMutation.isPending;\n\n const handlePause = () => {\n pauseMutation.mutate({\n subscriptionToken: token,\n pauseParams: { customerId },\n });\n };\n\n const handleResume = () => {\n const nextBillDate = calculateNextBillDate(\n plan.billing_interval,\n plan.billing_interval_unit,\n );\n resumeMutation.mutate({\n subscriptionToken: token,\n resumeParams: { customerId, nextBillDate },\n });\n };\n\n const handleSkip = () => {\n const nextBillDate = calculateNextBillDate(\n plan.billing_interval,\n plan.billing_interval_unit,\n );\n skipMutation.mutate({\n subscriptionToken: token,\n skipParams: { customerId, nextBillDate },\n });\n };\n\n const handleCancel = () => {\n cancelMutation.mutate({ subscriptionToken: token, customerId });\n };\n\n const handleReactivate = () => {\n reactivateMutation.mutate({\n subscriptionToken: token,\n reactivateParams: {},\n });\n };\n\n return (\n <>\n <div className=\"flex flex-col lg:grid lg:grid-cols-8\">\n <SubscriptionItemsSection subscription={subscription} />\n <SubscriptionManagementSection\n subscription={subscription}\n isActive={isActive}\n isPaused={isPaused}\n isCancelled={isCancelled}\n isMutating={isMutating}\n onSkip={handleSkip}\n onPause={handlePause}\n onResume={handleResume}\n onCancel={() => setShowCancelModal(true)}\n onReactivate={handleReactivate}\n />\n </div>\n <ConfirmDialog\n title=\"Cancel Subscription\"\n actionButtonText=\"Cancel Subscription\"\n description=\"Are you sure you want to cancel this subscription? You can reactivate it later.\"\n open={showCancelModal}\n setOpen={setShowCancelModal}\n onConfirm={handleCancel}\n />\n </>\n );\n}\n\nexport interface SubscriptionActionsProps {\n isActive: boolean;\n isPaused: boolean;\n isCancelled: boolean;\n isMutating: boolean;\n allowSkipping: boolean | null;\n onPause: () => void;\n onResume: () => void;\n onSkip: () => void;\n onCancel: () => void;\n onReactivate: () => void;\n}\n\nexport function SubscriptionActions({\n isActive,\n isPaused,\n isCancelled,\n isMutating,\n allowSkipping,\n onPause,\n onResume,\n onSkip,\n onCancel,\n onReactivate,\n}: SubscriptionActionsProps) {\n const actionButtonClass =\n \"flex h-auto flex-row items-center justify-center gap-2 overflow-hidden border border-border bg-muted py-2 text-xs whitespace-nowrap text-foreground hover:bg-accent sm:text-sm\";\n\n return (\n <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2\">\n {isActive && (\n <>\n {allowSkipping && (\n <Button\n variant=\"outline\"\n onClick={onSkip}\n disabled={isMutating}\n className={actionButtonClass}\n >\n <SkipForward className=\"h-3 w-3 shrink-0\" />\n <span className=\"truncate\">Skip Next</span>\n </Button>\n )}\n <Button\n variant=\"outline\"\n onClick={onPause}\n disabled={isMutating}\n className={actionButtonClass}\n >\n <Pause className=\"h-3 w-3 shrink-0\" />\n <span className=\"truncate\">Pause</span>\n </Button>\n <Button\n variant=\"outline\"\n onClick={onCancel}\n disabled={isMutating}\n className={actionButtonClass}\n >\n <XCircle className=\"h-3 w-3 shrink-0\" />\n <span className=\"truncate\">Cancel</span>\n </Button>\n </>\n )}\n {isPaused && (\n <>\n <Button\n variant=\"outline\"\n onClick={onResume}\n disabled={isMutating}\n className={actionButtonClass}\n >\n <Play className=\"h-3 w-3 shrink-0\" />\n <span className=\"truncate\">Resume</span>\n </Button>\n <Button\n variant=\"outline\"\n onClick={onCancel}\n disabled={isMutating}\n className={actionButtonClass}\n >\n <XCircle className=\"h-3 w-3 shrink-0\" />\n <span className=\"truncate\">Cancel</span>\n </Button>\n </>\n )}\n {isCancelled && (\n <Button\n variant=\"outline\"\n onClick={onReactivate}\n disabled={isMutating}\n className={actionButtonClass}\n >\n <RotateCcw className=\"h-3 w-3 shrink-0\" />\n <span className=\"truncate\">Reactivate</span>\n </Button>\n )}\n </div>\n );\n}\n","\"use client\";\n\nimport { useMemo } from \"react\";\nimport {\n Breadcrumb,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n} from \"@fluid-app/ui-primitives\";\nimport { useScreenHeaderBreadcrumbs } from \"@fluid-app/portal-react/shell/ScreenHeaderContext\";\nimport { SubscriptionDetail } from \"../components/subscription-detail\";\n\nexport interface SubscriptionDetailScreenProps {\n token: string;\n onNavigateToList: () => void;\n onNotFound?: () => void;\n onError?: (error: Error) => void;\n onSuccess?: (message: string) => void;\n onMutationError?: (message: string, error: unknown) => void;\n}\n\nexport function SubscriptionDetailScreen({\n token,\n onNavigateToList,\n onNotFound,\n onError,\n onSuccess,\n onMutationError,\n}: SubscriptionDetailScreenProps) {\n const headerBreadcrumbs = useMemo(\n () => (\n <Breadcrumb>\n <BreadcrumbList className=\"text-lg\">\n <BreadcrumbItem>\n <BreadcrumbLink\n href=\"#\"\n onClick={(e) => {\n e.preventDefault();\n onNavigateToList();\n }}\n >\n Subscriptions\n </BreadcrumbLink>\n </BreadcrumbItem>\n <BreadcrumbSeparator />\n <BreadcrumbItem>\n <BreadcrumbPage className=\"font-semibold\">\n Subscription #{token}\n </BreadcrumbPage>\n </BreadcrumbItem>\n </BreadcrumbList>\n </Breadcrumb>\n ),\n [token, onNavigateToList],\n );\n useScreenHeaderBreadcrumbs(headerBreadcrumbs);\n\n return (\n <div className=\"mx-auto max-w-7xl px-4 py-4 sm:px-6 sm:py-6 lg:px-10 lg:py-8\">\n <SubscriptionDetail\n token={token}\n onNotFound={onNotFound}\n onError={onError}\n onSuccess={onSuccess}\n onMutationError={onMutationError}\n />\n </div>\n );\n}\n","import { useMemo } from \"react\";\nimport { SubscriptionsCoreProvider } from \"@fluid-app/subscriptions-core\";\nimport { SubscriptionDetailScreen as SubscriptionDetailScreenContent } from \"@fluid-app/subscriptions-ui/screens/SubscriptionDetailScreen\";\nimport { createPortalSubscriptionsAdapter } from \"@fluid-app/subscriptions-api-client\";\nimport { usePortalTenantClient } from \"../providers/PortalTenantClientProvider\";\nimport { useAppNavigation } from \"../shell/AppNavigationContext\";\n\ninterface SubscriptionDetailScreenProps {\n token: string;\n onToast: (message: string, type: \"success\" | \"error\" | \"warning\") => void;\n}\n\nexport function SubscriptionDetailScreen({\n token,\n onToast,\n}: SubscriptionDetailScreenProps): React.JSX.Element {\n const client = usePortalTenantClient();\n const subscriptionsApi = useMemo(\n () => createPortalSubscriptionsAdapter(client),\n [client],\n );\n const { navigate } = useAppNavigation();\n\n return (\n <SubscriptionsCoreProvider api={subscriptionsApi}>\n <SubscriptionDetailScreenContent\n token={token}\n onNavigateToList={() => navigate(\"subscriptions\")}\n onNotFound={() => {\n onToast(\"Subscription not found\", \"warning\");\n navigate(\"subscriptions\");\n }}\n onError={(err) => {\n const message =\n err instanceof Error ? err.message : \"An error occurred\";\n onToast(`Failed to load subscription: ${message}`, \"error\");\n }}\n onSuccess={(message) => {\n onToast(message, \"success\");\n }}\n onMutationError={(message, err) => {\n const detail =\n err instanceof Error ? err.message : \"An error occurred\";\n onToast(`${message}: ${detail}`, \"error\");\n }}\n />\n </SubscriptionsCoreProvider>\n );\n}\n","import type { ComponentProps } from \"react\";\nimport type {\n BackgroundValue,\n BorderRadiusOptions,\n ColorOptions,\n PaddingOptions,\n} from \"../types\";\nimport type { WidgetPropertySchema } from \"../registries/property-schema-types\";\nimport { useAppNavigation } from \"../shell/AppNavigationContext\";\nimport { useAccount } from \"../hooks/use-account\";\nimport { SubscriptionsListScreen } from \"./SubscriptionsListScreen\";\nimport { SubscriptionDetailScreen } from \"./SubscriptionDetailScreen\";\n\ntype SubscriptionsScreenProps = ComponentProps<\"div\"> & {\n background?: BackgroundValue;\n textColor?: ColorOptions;\n accentColor?: ColorOptions;\n padding?: PaddingOptions;\n borderRadius?: BorderRadiusOptions;\n onToast?: (message: string, type: \"success\" | \"error\" | \"warning\") => void;\n};\n\nfunction defaultToast(message: string, type: \"success\" | \"error\" | \"warning\") {\n if (type === \"error\" || type === \"warning\") {\n console.warn(\"[Subscriptions]\", message);\n } else {\n console.info(\"[Subscriptions]\", message);\n }\n}\n\nexport function SubscriptionsScreen({\n onToast,\n /* eslint-disable @typescript-eslint/no-unused-vars -- destructured to exclude from divProps spread */\n background,\n textColor,\n accentColor,\n padding,\n borderRadius,\n /* eslint-enable @typescript-eslint/no-unused-vars */\n ...divProps\n}: SubscriptionsScreenProps): React.JSX.Element {\n const { currentSlug } = useAppNavigation();\n const effectiveToast = onToast ?? defaultToast;\n\n // Parse slug: \"subscriptions\" → list, \"subscriptions/{token}\" → detail\n const detailToken = currentSlug.split(\"/\")[1];\n const isDetailView = detailToken !== undefined;\n\n const { data: account } = useAccount();\n const customerId = account?.id;\n const isLoadingCustomer = account === undefined;\n const isCustomerError = false;\n\n if (isDetailView) {\n return (\n <div {...divProps}>\n <SubscriptionDetailScreen\n token={detailToken}\n onToast={effectiveToast}\n />\n </div>\n );\n }\n\n if (isCustomerError && !isLoadingCustomer) {\n return (\n <div {...divProps}>\n <div className=\"text-muted-foreground px-4 py-8 text-center text-sm\">\n Unable to load account data. Please try again later.\n </div>\n </div>\n );\n }\n\n return (\n <div {...divProps}>\n <SubscriptionsListScreen\n customerId={customerId}\n isLoadingCustomer={isLoadingCustomer}\n />\n </div>\n );\n}\n\nexport const subscriptionsScreenPropertySchema: WidgetPropertySchema = {\n widgetType: \"SubscriptionsScreen\",\n displayName: \"Subscriptions Screen\",\n tabsConfig: [{ id: \"styling\", label: \"Styling\" }],\n fields: [],\n} as const satisfies WidgetPropertySchema;\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"use-portal-products-client-BmlUixy4.cjs","names":["usePortalTenantClient"],"sources":["../../../products/api-client/src/portal-tenant-adapter.ts","../src/products/use-portal-products-client.ts"],"sourcesContent":["import type {\n PortalProductsApi,\n portalProducts,\n} from \"@fluid-app/products-core\";\nimport type { FetchClient } from \"./lib/fetch-client\";\nimport { portalTenant } from \"@fluid-app/portal-tenant-api-client\";\n\n/**\n * Creates a PortalProductsApi-compatible adapter from a portal-tenant FetchClient.\n *\n * This bridges the auto-generated portal-tenant API client to the abstract\n * PortalProductsApi interface defined in @fluid-app/products-core, closing\n * over the FetchClient so consumers don't need to pass it per-call.\n *\n * Each method maps the BFF response to the port type at runtime rather than\n * using type assertions, so TypeScript catches schema drift between the\n * generated client and the hand-authored port types at compile time.\n */\nexport function createPortalProductsApiAdapter(\n client: FetchClient,\n): PortalProductsApi {\n return {\n listProducts: async (params) => {\n const response = await portalTenant.products_list(client, {\n \"page[cursor]\": params?.cursor,\n });\n return {\n products: response.products ?? [],\n meta: response.meta,\n } satisfies portalProducts.PortalProductsResponse;\n },\n\n getProduct: async (id) => {\n const response = await portalTenant.products_show(client, id);\n return {\n product: response.product ?? {},\n meta: response.meta,\n } satisfies portalProducts.PortalProductResponse;\n },\n\n searchProducts: async (query, params) => {\n const response = await portalTenant.products_search(client, {\n q: query,\n \"page[cursor]\": params?.cursor,\n });\n return {\n products: response.products ?? [],\n meta: response.meta,\n } satisfies portalProducts.PortalProductsResponse;\n },\n\n getProductMedia: async (productId) => {\n const response = await portalTenant.products_media_list(\n client,\n productId,\n );\n return {\n media: response.media ?? [],\n meta: response.meta,\n } satisfies portalProducts.PortalProductMediaResponse;\n },\n };\n}\n","import { useMemo } from \"react\";\nimport type { PortalProductsApi } from \"@fluid-app/products-core\";\nimport { createPortalProductsApiAdapter } from \"@fluid-app/products-api-client\";\nimport { usePortalTenantClient } from \"../providers/PortalTenantClientProvider\";\n\nexport function usePortalProductsClient(): PortalProductsApi {\n const client = usePortalTenantClient();\n\n return useMemo(() => createPortalProductsApiAdapter(client), [client]);\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAkBA,SAAgB,+BACd,QACmB;AACnB,QAAO;EACL,cAAc,OAAO,WAAW;GAC9B,MAAM,WAAW,MAAA,sBAAA,cAAiC,QAAQ,EACxD,gBAAgB,QAAQ,QACzB,CAAC;AACF,UAAO;IACL,UAAU,SAAS,YAAY,EAAE;IACjC,MAAM,SAAS;IAChB;;EAGH,YAAY,OAAO,OAAO;GACxB,MAAM,WAAW,MAAA,sBAAA,cAAiC,QAAQ,GAAG;AAC7D,UAAO;IACL,SAAS,SAAS,WAAW,EAAE;IAC/B,MAAM,SAAS;IAChB;;EAGH,gBAAgB,OAAO,OAAO,WAAW;GACvC,MAAM,WAAW,MAAA,sBAAA,gBAAmC,QAAQ;IAC1D,GAAG;IACH,gBAAgB,QAAQ;IACzB,CAAC;AACF,UAAO;IACL,UAAU,SAAS,YAAY,EAAE;IACjC,MAAM,SAAS;IAChB;;EAGH,iBAAiB,OAAO,cAAc;GACpC,MAAM,WAAW,MAAA,sBAAA,oBACf,QACA,UACD;AACD,UAAO;IACL,OAAO,SAAS,SAAS,EAAE;IAC3B,MAAM,SAAS;IAChB;;EAEJ;;;;ACxDH,SAAgB,0BAA6C;CAC3D,MAAM,SAASA,mCAAAA,uBAAuB;AAEtC,SAAA,GAAA,MAAA,eAAqB,+BAA+B,OAAO,EAAE,CAAC,OAAO,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"use-portal-products-client-DQK9nFxT.mjs","names":["portalTenant.products_list","portalTenant.products_show","portalTenant.products_search","portalTenant.products_media_list"],"sources":["../../../products/api-client/src/portal-tenant-adapter.ts","../src/products/use-portal-products-client.ts"],"sourcesContent":["import type {\n PortalProductsApi,\n portalProducts,\n} from \"@fluid-app/products-core\";\nimport type { FetchClient } from \"./lib/fetch-client\";\nimport { portalTenant } from \"@fluid-app/portal-tenant-api-client\";\n\n/**\n * Creates a PortalProductsApi-compatible adapter from a portal-tenant FetchClient.\n *\n * This bridges the auto-generated portal-tenant API client to the abstract\n * PortalProductsApi interface defined in @fluid-app/products-core, closing\n * over the FetchClient so consumers don't need to pass it per-call.\n *\n * Each method maps the BFF response to the port type at runtime rather than\n * using type assertions, so TypeScript catches schema drift between the\n * generated client and the hand-authored port types at compile time.\n */\nexport function createPortalProductsApiAdapter(\n client: FetchClient,\n): PortalProductsApi {\n return {\n listProducts: async (params) => {\n const response = await portalTenant.products_list(client, {\n \"page[cursor]\": params?.cursor,\n });\n return {\n products: response.products ?? [],\n meta: response.meta,\n } satisfies portalProducts.PortalProductsResponse;\n },\n\n getProduct: async (id) => {\n const response = await portalTenant.products_show(client, id);\n return {\n product: response.product ?? {},\n meta: response.meta,\n } satisfies portalProducts.PortalProductResponse;\n },\n\n searchProducts: async (query, params) => {\n const response = await portalTenant.products_search(client, {\n q: query,\n \"page[cursor]\": params?.cursor,\n });\n return {\n products: response.products ?? [],\n meta: response.meta,\n } satisfies portalProducts.PortalProductsResponse;\n },\n\n getProductMedia: async (productId) => {\n const response = await portalTenant.products_media_list(\n client,\n productId,\n );\n return {\n media: response.media ?? [],\n meta: response.meta,\n } satisfies portalProducts.PortalProductMediaResponse;\n },\n };\n}\n","import { useMemo } from \"react\";\nimport type { PortalProductsApi } from \"@fluid-app/products-core\";\nimport { createPortalProductsApiAdapter } from \"@fluid-app/products-api-client\";\nimport { usePortalTenantClient } from \"../providers/PortalTenantClientProvider\";\n\nexport function usePortalProductsClient(): PortalProductsApi {\n const client = usePortalTenantClient();\n\n return useMemo(() => createPortalProductsApiAdapter(client), [client]);\n}\n"],"mappings":";;;;;;;;;;;;;;;AAkBA,SAAgB,+BACd,QACmB;AACnB,QAAO;EACL,cAAc,OAAO,WAAW;GAC9B,MAAM,WAAW,MAAMA,cAA2B,QAAQ,EACxD,gBAAgB,QAAQ,QACzB,CAAC;AACF,UAAO;IACL,UAAU,SAAS,YAAY,EAAE;IACjC,MAAM,SAAS;IAChB;;EAGH,YAAY,OAAO,OAAO;GACxB,MAAM,WAAW,MAAMC,cAA2B,QAAQ,GAAG;AAC7D,UAAO;IACL,SAAS,SAAS,WAAW,EAAE;IAC/B,MAAM,SAAS;IAChB;;EAGH,gBAAgB,OAAO,OAAO,WAAW;GACvC,MAAM,WAAW,MAAMC,gBAA6B,QAAQ;IAC1D,GAAG;IACH,gBAAgB,QAAQ;IACzB,CAAC;AACF,UAAO;IACL,UAAU,SAAS,YAAY,EAAE;IACjC,MAAM,SAAS;IAChB;;EAGH,iBAAiB,OAAO,cAAc;GACpC,MAAM,WAAW,MAAMC,oBACrB,QACA,UACD;AACD,UAAO;IACL,OAAO,SAAS,SAAS,EAAE;IAC3B,MAAM,SAAS;IAChB;;EAEJ;;;;ACxDH,SAAgB,0BAA6C;CAC3D,MAAM,SAAS,uBAAuB;AAEtC,QAAO,cAAc,+BAA+B,OAAO,EAAE,CAAC,OAAO,CAAC"}