@fluid-app/portal-sdk 0.1.162 → 0.1.164
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{MySiteScreen-g8Esyofu.mjs → MySiteScreen-CG2DnzQH.mjs} +2 -2
- package/dist/{MySiteScreen-g8Esyofu.mjs.map → MySiteScreen-CG2DnzQH.mjs.map} +1 -1
- package/dist/{MySiteScreen-Cos0jTa_.cjs → MySiteScreen-DRMrEMEI.cjs} +2 -2
- package/dist/{MySiteScreen-Xcg07a3M.cjs → MySiteScreen-Lr2SbrXz.cjs} +2 -2
- package/dist/{MySiteScreen-Xcg07a3M.cjs.map → MySiteScreen-Lr2SbrXz.cjs.map} +1 -1
- package/dist/{OrdersScreen-DZyOBKmU.cjs → OrdersScreen-B6n41CbG.cjs} +1 -1
- package/dist/{OrdersScreen-ZGUm8buk.cjs → OrdersScreen-BKCQdz5A.cjs} +55 -56
- package/dist/OrdersScreen-BKCQdz5A.cjs.map +1 -0
- package/dist/{OrdersScreen-DeLoyVGI.mjs → OrdersScreen-CFRVfzez.mjs} +55 -56
- package/dist/OrdersScreen-CFRVfzez.mjs.map +1 -0
- package/dist/{use-portal-shareables-api-DRK9Y5dp.mjs → PortalContentApiProvider-CW0ADhPi.mjs} +285 -94
- package/dist/PortalContentApiProvider-CW0ADhPi.mjs.map +1 -0
- package/dist/{use-portal-shareables-api-DcjYlAOy.cjs → PortalContentApiProvider-Di5emtYd.cjs} +290 -129
- package/dist/PortalContentApiProvider-Di5emtYd.cjs.map +1 -0
- package/dist/PortalProductsApiProvider-BCXX9NGK.mjs +780 -0
- package/dist/PortalProductsApiProvider-BCXX9NGK.mjs.map +1 -0
- package/dist/PortalProductsApiProvider-BquMHwvt.cjs +816 -0
- package/dist/PortalProductsApiProvider-BquMHwvt.cjs.map +1 -0
- package/dist/{ProductsScreen-B2SKzTE4.cjs → ProductsScreen-C6eNgxjP.cjs} +4 -3
- package/dist/{ProductsScreen-D6eoU86k.mjs → ProductsScreen-CVNJudq9.mjs} +39 -44
- package/dist/ProductsScreen-CVNJudq9.mjs.map +1 -0
- package/dist/{ProductsScreen-DbwSCY7G.cjs → ProductsScreen-KjjhlDGo.cjs} +39 -44
- package/dist/ProductsScreen-KjjhlDGo.cjs.map +1 -0
- package/dist/{ProductsScreen-BGah2tcD.mjs → ProductsScreen-nHmUftQn.mjs} +4 -3
- package/dist/{ShareablesScreen-DRUT-yoi.mjs → ShareablesScreen-CdTyyDRO.mjs} +4 -3
- package/dist/{ShareablesScreen-Dy04EXe5.cjs → ShareablesScreen-DUzo8kRi.cjs} +4 -3
- package/dist/ShareablesScreen-DpEP_6u0.mjs +132 -0
- package/dist/ShareablesScreen-DpEP_6u0.mjs.map +1 -0
- package/dist/ShareablesScreen-Dz8w2l3e.cjs +144 -0
- package/dist/ShareablesScreen-Dz8w2l3e.cjs.map +1 -0
- package/dist/{ShopScreen-CQ48b1c8.mjs → ShopScreen-BH6zQndJ.mjs} +10 -724
- package/dist/ShopScreen-BH6zQndJ.mjs.map +1 -0
- package/dist/{ShopScreen-CFqoT4IC.cjs → ShopScreen-BUXUtEuj.cjs} +13 -727
- package/dist/ShopScreen-BUXUtEuj.cjs.map +1 -0
- package/dist/{ShopScreen-B7faQx84.cjs → ShopScreen-BbucUNI7.cjs} +2 -1
- package/dist/{SubscriptionsScreen-C2iORyT_.cjs → SubscriptionsScreen-BdGF5OLE.cjs} +408 -409
- package/dist/SubscriptionsScreen-BdGF5OLE.cjs.map +1 -0
- package/dist/{SubscriptionsScreen-ClWrrqPK.cjs → SubscriptionsScreen-Cwa2lR1D.cjs} +1 -1
- package/dist/{SubscriptionsScreen-BfdK8067.mjs → SubscriptionsScreen-Dn3AEUJi.mjs} +408 -409
- package/dist/SubscriptionsScreen-Dn3AEUJi.mjs.map +1 -0
- package/dist/{dist-lO2OG0T5.cjs → dist-BF_4vk1z.cjs} +1 -1
- package/dist/{dist-lO2OG0T5.cjs.map → dist-BF_4vk1z.cjs.map} +1 -1
- package/dist/index.cjs +21 -20
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +21 -20
- package/dist/index.mjs.map +1 -1
- package/dist/{sortable.esm-DSrWP4x9.mjs → sortable.esm-E6JdQn7I.mjs} +1 -1
- package/dist/{sortable.esm-DSrWP4x9.mjs.map → sortable.esm-E6JdQn7I.mjs.map} +1 -1
- package/package.json +17 -17
- package/dist/OrdersScreen-DeLoyVGI.mjs.map +0 -1
- package/dist/OrdersScreen-ZGUm8buk.cjs.map +0 -1
- package/dist/ProductsScreen-D6eoU86k.mjs.map +0 -1
- package/dist/ProductsScreen-DbwSCY7G.cjs.map +0 -1
- package/dist/ShareablesScreen-DPHZMh-V.cjs +0 -391
- package/dist/ShareablesScreen-DPHZMh-V.cjs.map +0 -1
- package/dist/ShareablesScreen-DrQDQ1-U.mjs +0 -379
- package/dist/ShareablesScreen-DrQDQ1-U.mjs.map +0 -1
- package/dist/ShopScreen-CFqoT4IC.cjs.map +0 -1
- package/dist/ShopScreen-CQ48b1c8.mjs.map +0 -1
- package/dist/SubscriptionsScreen-BfdK8067.mjs.map +0 -1
- package/dist/SubscriptionsScreen-C2iORyT_.cjs.map +0 -1
- package/dist/use-portal-products-client-BUFD20ZY.mjs +0 -65
- package/dist/use-portal-products-client-BUFD20ZY.mjs.map +0 -1
- package/dist/use-portal-products-client-DTkFvOal.cjs +0 -71
- package/dist/use-portal-products-client-DTkFvOal.cjs.map +0 -1
- package/dist/use-portal-shareables-api-DRK9Y5dp.mjs.map +0 -1
- package/dist/use-portal-shareables-api-DcjYlAOy.cjs.map +0 -1
|
@@ -206,342 +206,6 @@ function getNextBillDisplay(subscription) {
|
|
|
206
206
|
return "N/A";
|
|
207
207
|
}
|
|
208
208
|
//#endregion
|
|
209
|
-
//#region ../../subscriptions/ui/src/lib/format.ts
|
|
210
|
-
/**
|
|
211
|
-
* Format a number as currency (USD).
|
|
212
|
-
*/
|
|
213
|
-
function formatCurrency(value) {
|
|
214
|
-
return new Intl.NumberFormat("en-US", {
|
|
215
|
-
style: "currency",
|
|
216
|
-
currency: "USD"
|
|
217
|
-
}).format(value);
|
|
218
|
-
}
|
|
219
|
-
/**
|
|
220
|
-
* Convert a snake_case or lowercase string to Start Case.
|
|
221
|
-
* Replaces lodash startCase for simple status strings.
|
|
222
|
-
*/
|
|
223
|
-
function startCase(str) {
|
|
224
|
-
if (!str) return "";
|
|
225
|
-
return str.replace(/_/g, " ").replace(/\b\w/g, (char) => char.toUpperCase());
|
|
226
|
-
}
|
|
227
|
-
/**
|
|
228
|
-
* Format a next bill date string to M/D/YYYY (UTC).
|
|
229
|
-
*/
|
|
230
|
-
function formatNextBillDate(nextBillDate) {
|
|
231
|
-
if (!nextBillDate) return "N/A";
|
|
232
|
-
const date = new Date(nextBillDate);
|
|
233
|
-
if (isNaN(date.getTime())) return "N/A";
|
|
234
|
-
return `${date.getUTCMonth() + 1}/${date.getUTCDate()}/${date.getUTCFullYear()}`;
|
|
235
|
-
}
|
|
236
|
-
//#endregion
|
|
237
|
-
//#region ../../subscriptions/ui/src/lib/cn.ts
|
|
238
|
-
function cn(...inputs) {
|
|
239
|
-
return twMerge(clsx(inputs));
|
|
240
|
-
}
|
|
241
|
-
//#endregion
|
|
242
|
-
//#region ../../subscriptions/ui/src/components/status-pill.tsx
|
|
243
|
-
const STATUS_COLORS = {
|
|
244
|
-
active: "bg-green-100 text-green-800",
|
|
245
|
-
paused: "bg-gray-100 text-gray-800",
|
|
246
|
-
cancelled: "bg-red-100 text-red-800",
|
|
247
|
-
pending: "bg-yellow-100 text-yellow-800",
|
|
248
|
-
inactive: "bg-gray-100 text-gray-800",
|
|
249
|
-
disabled: "bg-red-100 text-red-800",
|
|
250
|
-
past_due: "bg-gray-100 text-gray-800"
|
|
251
|
-
};
|
|
252
|
-
const STATUS_DOT_COLORS = {
|
|
253
|
-
active: "bg-green-500",
|
|
254
|
-
paused: "bg-gray-400",
|
|
255
|
-
cancelled: "bg-red-500",
|
|
256
|
-
pending: "bg-yellow-500",
|
|
257
|
-
inactive: "bg-gray-400",
|
|
258
|
-
disabled: "bg-red-500",
|
|
259
|
-
past_due: "bg-gray-400"
|
|
260
|
-
};
|
|
261
|
-
function StatusPill({ status, children }) {
|
|
262
|
-
const key = status?.toLowerCase() ?? "";
|
|
263
|
-
const pillColor = STATUS_COLORS[key] ?? "bg-gray-100 text-gray-800";
|
|
264
|
-
const dotColor = STATUS_DOT_COLORS[key] ?? "bg-gray-400";
|
|
265
|
-
return /* @__PURE__ */ jsxs("span", {
|
|
266
|
-
className: cn("inline-flex items-center gap-1.5 rounded-full px-2.5 py-0.5 text-xs font-medium", pillColor),
|
|
267
|
-
children: [/* @__PURE__ */ jsx("span", { className: cn("h-1.5 w-1.5 rounded-full", dotColor) }), children]
|
|
268
|
-
});
|
|
269
|
-
}
|
|
270
|
-
//#endregion
|
|
271
|
-
//#region ../../subscriptions/ui/src/components/subscriptions-list.tsx
|
|
272
|
-
function SubscriptionsList({ customerId, onSubscriptionClick, t, pageSize = 10 }) {
|
|
273
|
-
const [currentPage, setCurrentPage] = useState(1);
|
|
274
|
-
const [statusFilter, setStatusFilter] = useState(null);
|
|
275
|
-
const [search, setSearch] = useState(null);
|
|
276
|
-
const [sortBy, setSortBy] = useState({
|
|
277
|
-
column: "next_bill_date",
|
|
278
|
-
direction: "desc"
|
|
279
|
-
});
|
|
280
|
-
const { data, isLoading } = useSubscriptions({
|
|
281
|
-
customerId: customerId ?? 0,
|
|
282
|
-
page: currentPage,
|
|
283
|
-
perPage: pageSize,
|
|
284
|
-
status: statusFilter,
|
|
285
|
-
search,
|
|
286
|
-
sortBy: sortBy.column,
|
|
287
|
-
sortDirection: sortBy.direction
|
|
288
|
-
}, { enabled: !!customerId });
|
|
289
|
-
useEffect(() => {
|
|
290
|
-
setCurrentPage(1);
|
|
291
|
-
}, [
|
|
292
|
-
statusFilter,
|
|
293
|
-
search,
|
|
294
|
-
sortBy
|
|
295
|
-
]);
|
|
296
|
-
const items = data?.subscriptions ?? [];
|
|
297
|
-
const totalItems = data?.meta?.pagination?.total_count ?? 0;
|
|
298
|
-
const totalPages = data?.meta?.pagination?.total_pages ?? 1;
|
|
299
|
-
const handleSubscriptionClick = (token) => {
|
|
300
|
-
if (token) onSubscriptionClick(token);
|
|
301
|
-
};
|
|
302
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
303
|
-
className: "border-border overflow-hidden rounded-lg border shadow-sm",
|
|
304
|
-
children: [
|
|
305
|
-
/* @__PURE__ */ jsxs("div", {
|
|
306
|
-
className: "flex flex-col gap-2 p-3 sm:flex-row sm:items-center sm:justify-between",
|
|
307
|
-
children: [/* @__PURE__ */ jsxs(ToggleGroup, {
|
|
308
|
-
type: "single",
|
|
309
|
-
value: statusFilter ?? "all",
|
|
310
|
-
onValueChange: (v) => {
|
|
311
|
-
if (v) setStatusFilter(v === "all" ? null : v);
|
|
312
|
-
},
|
|
313
|
-
variant: "ghost",
|
|
314
|
-
children: [
|
|
315
|
-
/* @__PURE__ */ jsx(ToggleGroupItem, {
|
|
316
|
-
value: "all",
|
|
317
|
-
children: t("all")
|
|
318
|
-
}),
|
|
319
|
-
/* @__PURE__ */ jsx(ToggleGroupItem, {
|
|
320
|
-
value: "active",
|
|
321
|
-
children: t("active")
|
|
322
|
-
}),
|
|
323
|
-
/* @__PURE__ */ jsx(ToggleGroupItem, {
|
|
324
|
-
value: "inactive",
|
|
325
|
-
children: t("inactive")
|
|
326
|
-
})
|
|
327
|
-
]
|
|
328
|
-
}), /* @__PURE__ */ jsx("div", {
|
|
329
|
-
className: "w-full max-w-sm",
|
|
330
|
-
children: /* @__PURE__ */ jsx(SearchSort, {
|
|
331
|
-
searchValue: search ?? "",
|
|
332
|
-
onSearchChange: (v) => setSearch(v || null),
|
|
333
|
-
placeholder: t("search_subscriptions")
|
|
334
|
-
})
|
|
335
|
-
})]
|
|
336
|
-
}),
|
|
337
|
-
/* @__PURE__ */ jsx("div", {
|
|
338
|
-
className: "block md:hidden",
|
|
339
|
-
children: isLoading ? Array(5).fill(0).map((_, index) => /* @__PURE__ */ jsx("div", {
|
|
340
|
-
className: "border-border border-b p-4",
|
|
341
|
-
children: /* @__PURE__ */ jsxs("div", {
|
|
342
|
-
className: "flex space-x-3",
|
|
343
|
-
children: [/* @__PURE__ */ jsx(Skeleton, { className: "h-12 w-12 rounded-md" }), /* @__PURE__ */ jsxs("div", {
|
|
344
|
-
className: "flex-1 space-y-2",
|
|
345
|
-
children: [/* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-3/4" }), /* @__PURE__ */ jsx(Skeleton, { className: "h-3 w-1/2" })]
|
|
346
|
-
})]
|
|
347
|
-
})
|
|
348
|
-
}, `skeleton-${index}`)) : items.length === 0 ? /* @__PURE__ */ jsx("div", {
|
|
349
|
-
className: "text-muted-foreground px-3 py-8 text-center text-sm",
|
|
350
|
-
children: t("no_subscriptions_found")
|
|
351
|
-
}) : items.map((subscription) => /* @__PURE__ */ jsx("div", {
|
|
352
|
-
className: "border-border hover:bg-accent cursor-pointer border-b p-4 transition-colors duration-200 ease-in-out last:border-b-0",
|
|
353
|
-
onClick: () => handleSubscriptionClick(subscription.subscription_token),
|
|
354
|
-
children: /* @__PURE__ */ jsxs("div", {
|
|
355
|
-
className: "flex items-start space-x-3",
|
|
356
|
-
children: [/* @__PURE__ */ jsx("img", {
|
|
357
|
-
src: subscription.variant?.product?.image_url,
|
|
358
|
-
alt: subscription.variant?.product?.title,
|
|
359
|
-
width: 48,
|
|
360
|
-
height: 48,
|
|
361
|
-
className: "h-12 w-12 flex-shrink-0 rounded-md object-cover"
|
|
362
|
-
}), /* @__PURE__ */ jsxs("div", {
|
|
363
|
-
className: "w-0 min-w-0 flex-1",
|
|
364
|
-
children: [
|
|
365
|
-
/* @__PURE__ */ jsx("p", {
|
|
366
|
-
className: "text-foreground truncate text-sm font-medium",
|
|
367
|
-
children: subscription.variant?.product?.title
|
|
368
|
-
}),
|
|
369
|
-
/* @__PURE__ */ jsxs("div", {
|
|
370
|
-
className: "mt-2 grid grid-cols-2 gap-x-4 gap-y-1 text-sm",
|
|
371
|
-
children: [/* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("span", {
|
|
372
|
-
className: "text-muted-foreground block text-xs",
|
|
373
|
-
children: t("next_bill_date")
|
|
374
|
-
}), /* @__PURE__ */ jsx("span", {
|
|
375
|
-
className: "text-muted-foreground",
|
|
376
|
-
children: formatNextBillDate(subscription.next_bill_date ?? "")
|
|
377
|
-
})] }), /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("span", {
|
|
378
|
-
className: "text-muted-foreground block text-xs",
|
|
379
|
-
children: t("price")
|
|
380
|
-
}), /* @__PURE__ */ jsx("span", {
|
|
381
|
-
className: "text-foreground font-medium",
|
|
382
|
-
children: formatCurrency(subscription.price * subscription.quantity)
|
|
383
|
-
})] })]
|
|
384
|
-
}),
|
|
385
|
-
/* @__PURE__ */ jsxs("div", {
|
|
386
|
-
className: "mt-2",
|
|
387
|
-
children: [/* @__PURE__ */ jsx("span", {
|
|
388
|
-
className: "text-muted-foreground block text-xs",
|
|
389
|
-
children: t("status")
|
|
390
|
-
}), /* @__PURE__ */ jsx(StatusPill, {
|
|
391
|
-
status: subscription.status,
|
|
392
|
-
children: startCase(subscription.status) || t("unknown_status")
|
|
393
|
-
})]
|
|
394
|
-
})
|
|
395
|
-
]
|
|
396
|
-
})]
|
|
397
|
-
})
|
|
398
|
-
}, subscription.subscription_token))
|
|
399
|
-
}),
|
|
400
|
-
/* @__PURE__ */ jsx("div", {
|
|
401
|
-
className: "hidden md:block",
|
|
402
|
-
children: /* @__PURE__ */ jsxs(Table$1, {
|
|
403
|
-
className: "min-w-full table-fixed",
|
|
404
|
-
children: [
|
|
405
|
-
/* @__PURE__ */ jsxs("colgroup", { children: [
|
|
406
|
-
/* @__PURE__ */ jsx("col", { className: "w-[45%] min-w-[240px]" }),
|
|
407
|
-
/* @__PURE__ */ jsx("col", { className: "w-[20%] min-w-[100px]" }),
|
|
408
|
-
/* @__PURE__ */ jsx("col", { className: "w-[15%] min-w-[100px]" }),
|
|
409
|
-
/* @__PURE__ */ jsx("col", { className: "w-[20%] min-w-[100px]" })
|
|
410
|
-
] }),
|
|
411
|
-
/* @__PURE__ */ jsx(TableHeader, {
|
|
412
|
-
className: "bg-muted",
|
|
413
|
-
children: /* @__PURE__ */ jsxs(TableRow, {
|
|
414
|
-
className: "hover:bg-muted h-10",
|
|
415
|
-
children: [
|
|
416
|
-
/* @__PURE__ */ jsx(TableColumn, {
|
|
417
|
-
label: t("product"),
|
|
418
|
-
sortable: false
|
|
419
|
-
}),
|
|
420
|
-
/* @__PURE__ */ jsx(TableColumn, {
|
|
421
|
-
label: t("next_bill_date"),
|
|
422
|
-
sortBy: "next_bill_date",
|
|
423
|
-
sortData: sortBy,
|
|
424
|
-
onSortClick: (value) => setSortBy({
|
|
425
|
-
column: value,
|
|
426
|
-
direction: sortBy.direction === "asc" ? "desc" : "asc"
|
|
427
|
-
})
|
|
428
|
-
}),
|
|
429
|
-
/* @__PURE__ */ jsx(TableColumn, {
|
|
430
|
-
label: t("price"),
|
|
431
|
-
sortable: false
|
|
432
|
-
}),
|
|
433
|
-
/* @__PURE__ */ jsx(TableColumn, {
|
|
434
|
-
label: t("status"),
|
|
435
|
-
sortable: false
|
|
436
|
-
})
|
|
437
|
-
]
|
|
438
|
-
})
|
|
439
|
-
}),
|
|
440
|
-
/* @__PURE__ */ jsx(TableBody, {
|
|
441
|
-
className: "bg-background",
|
|
442
|
-
children: isLoading ? Array(5).fill(0).map((_, index) => /* @__PURE__ */ jsxs(TableRow, { children: [
|
|
443
|
-
/* @__PURE__ */ jsx(TableCell, {
|
|
444
|
-
className: "px-3 py-4",
|
|
445
|
-
children: /* @__PURE__ */ jsxs("div", {
|
|
446
|
-
className: "flex items-center space-x-2",
|
|
447
|
-
children: [/* @__PURE__ */ jsx(Skeleton, { className: "h-9 w-9 rounded-md" }), /* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-32" })]
|
|
448
|
-
})
|
|
449
|
-
}),
|
|
450
|
-
/* @__PURE__ */ jsx(TableCell, {
|
|
451
|
-
className: "px-3 py-4",
|
|
452
|
-
children: /* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-24" })
|
|
453
|
-
}),
|
|
454
|
-
/* @__PURE__ */ jsx(TableCell, {
|
|
455
|
-
className: "px-3 py-4",
|
|
456
|
-
children: /* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-24" })
|
|
457
|
-
}),
|
|
458
|
-
/* @__PURE__ */ jsx(TableCell, {
|
|
459
|
-
className: "px-3 py-4",
|
|
460
|
-
children: /* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-16" })
|
|
461
|
-
})
|
|
462
|
-
] }, `skeleton-${index}`)) : items.length === 0 ? /* @__PURE__ */ jsx(TableRow, { children: /* @__PURE__ */ jsx(TableCell, {
|
|
463
|
-
colSpan: 4,
|
|
464
|
-
className: "text-muted-foreground px-3 py-8 text-center text-sm",
|
|
465
|
-
children: t("no_subscriptions_found")
|
|
466
|
-
}) }) : items.map((subscription) => /* @__PURE__ */ jsxs(TableRow, {
|
|
467
|
-
className: "cursor-pointer",
|
|
468
|
-
onClick: () => handleSubscriptionClick(subscription.subscription_token),
|
|
469
|
-
children: [
|
|
470
|
-
/* @__PURE__ */ jsxs(TableCell, {
|
|
471
|
-
className: "text-muted-foreground flex max-w-[280px] items-center space-x-3 py-4 pr-3 pl-3 text-sm",
|
|
472
|
-
children: [/* @__PURE__ */ jsx("img", {
|
|
473
|
-
src: subscription.variant?.product?.image_url,
|
|
474
|
-
alt: subscription.variant?.product?.title,
|
|
475
|
-
width: 48,
|
|
476
|
-
height: 48,
|
|
477
|
-
className: "h-12 w-12 flex-shrink-0 rounded-md object-cover"
|
|
478
|
-
}), /* @__PURE__ */ jsx("span", {
|
|
479
|
-
className: "text-foreground truncate text-sm font-medium",
|
|
480
|
-
children: subscription.variant?.product?.title
|
|
481
|
-
})]
|
|
482
|
-
}),
|
|
483
|
-
/* @__PURE__ */ jsx(TableCell, {
|
|
484
|
-
className: "text-muted-foreground px-3 py-4 text-sm whitespace-nowrap",
|
|
485
|
-
children: formatNextBillDate(subscription.next_bill_date ?? "")
|
|
486
|
-
}),
|
|
487
|
-
/* @__PURE__ */ jsx(TableCell, {
|
|
488
|
-
className: "px-3 py-4 text-sm whitespace-nowrap",
|
|
489
|
-
children: /* @__PURE__ */ jsx("span", {
|
|
490
|
-
className: "text-muted-foreground",
|
|
491
|
-
children: formatCurrency(subscription.price * subscription.quantity)
|
|
492
|
-
})
|
|
493
|
-
}),
|
|
494
|
-
/* @__PURE__ */ jsx(TableCell, {
|
|
495
|
-
className: "px-3 py-4 text-sm whitespace-nowrap",
|
|
496
|
-
children: /* @__PURE__ */ jsx(StatusPill, {
|
|
497
|
-
status: subscription.status,
|
|
498
|
-
children: startCase(subscription.status) || t("unknown_status")
|
|
499
|
-
})
|
|
500
|
-
})
|
|
501
|
-
]
|
|
502
|
-
}, subscription.subscription_token))
|
|
503
|
-
})
|
|
504
|
-
]
|
|
505
|
-
})
|
|
506
|
-
}),
|
|
507
|
-
/* @__PURE__ */ jsx(PaginationFooter, {
|
|
508
|
-
currentPage,
|
|
509
|
-
totalPages,
|
|
510
|
-
pageSize,
|
|
511
|
-
totalItems,
|
|
512
|
-
onPageChange: setCurrentPage,
|
|
513
|
-
t
|
|
514
|
-
})
|
|
515
|
-
]
|
|
516
|
-
});
|
|
517
|
-
}
|
|
518
|
-
//#endregion
|
|
519
|
-
//#region ../../subscriptions/ui/src/screens/SubscriptionsListScreen.tsx
|
|
520
|
-
function SubscriptionsListScreen$1({ customerId, onSubscriptionClick, t, isLoadingCustomer }) {
|
|
521
|
-
useScreenHeaderBreadcrumbs(useMemo(() => /* @__PURE__ */ jsx(Breadcrumb, { children: /* @__PURE__ */ jsx(BreadcrumbList, {
|
|
522
|
-
className: "text-lg",
|
|
523
|
-
children: /* @__PURE__ */ jsx(BreadcrumbItem, { children: /* @__PURE__ */ jsx(BreadcrumbPage, {
|
|
524
|
-
className: "font-semibold",
|
|
525
|
-
children: "Subscriptions"
|
|
526
|
-
}) })
|
|
527
|
-
}) }), []));
|
|
528
|
-
if (isLoadingCustomer) return /* @__PURE__ */ jsx("div", {
|
|
529
|
-
className: "mx-auto max-w-7xl px-4 py-4 sm:px-6 sm:py-6 lg:px-10 lg:py-8",
|
|
530
|
-
children: /* @__PURE__ */ jsxs("div", {
|
|
531
|
-
className: "space-y-3",
|
|
532
|
-
children: [/* @__PURE__ */ jsx("div", { className: "bg-muted h-10 animate-pulse rounded" }), /* @__PURE__ */ jsx("div", { className: "bg-muted h-64 animate-pulse rounded" })]
|
|
533
|
-
})
|
|
534
|
-
});
|
|
535
|
-
return /* @__PURE__ */ jsx("div", {
|
|
536
|
-
className: "mx-auto max-w-7xl px-4 py-4 sm:px-6 sm:py-6 lg:px-10 lg:py-8",
|
|
537
|
-
children: /* @__PURE__ */ jsx(SubscriptionsList, {
|
|
538
|
-
customerId,
|
|
539
|
-
onSubscriptionClick,
|
|
540
|
-
t
|
|
541
|
-
})
|
|
542
|
-
});
|
|
543
|
-
}
|
|
544
|
-
//#endregion
|
|
545
209
|
//#region src/adapters/subscriptions-api-adapter.ts
|
|
546
210
|
/**
|
|
547
211
|
* Maps the BFF meta envelope to the port's expected shape.
|
|
@@ -795,43 +459,388 @@ function mapSubscriptionList(response) {
|
|
|
795
459
|
meta: mapMeta(response.meta ?? {})
|
|
796
460
|
};
|
|
797
461
|
}
|
|
798
|
-
/**
|
|
799
|
-
* Creates a SubscriptionsApi-compatible adapter backed by the portal-tenant BFF.
|
|
800
|
-
*
|
|
801
|
-
* Uses async/await with explicit field mapping. The BFF returns simplified
|
|
802
|
-
* subscription types compared to the full admin API; the adapter maps the
|
|
803
|
-
* response envelope and provides runtime defaults for optional fields.
|
|
804
|
-
*/
|
|
805
|
-
function createPortalSubscriptionsAdapter(client) {
|
|
806
|
-
return {
|
|
807
|
-
fetchCustomerSubscriptions: async (params) => {
|
|
808
|
-
return mapSubscriptionList(await subscriptions_list(client, {
|
|
809
|
-
"page[cursor]": params.cursor,
|
|
810
|
-
"page[limit]": params.limit ?? params.perPage
|
|
811
|
-
}));
|
|
812
|
-
},
|
|
813
|
-
fetchSubscription: async (subscriptionToken) => {
|
|
814
|
-
return mapSubscriptionDetail(await subscriptions_show(client, subscriptionToken));
|
|
815
|
-
},
|
|
816
|
-
pauseSubscription: async (subscriptionToken, _params) => {
|
|
817
|
-
return mapSubscriptionDetail(await subscriptions_pause(client, subscriptionToken));
|
|
818
|
-
},
|
|
819
|
-
resumeSubscription: async (subscriptionToken, _params) => {
|
|
820
|
-
return mapSubscriptionDetail(await subscriptions_resume(client, subscriptionToken));
|
|
821
|
-
},
|
|
822
|
-
skipSubscription: async (subscriptionToken, _params) => {
|
|
823
|
-
return mapSubscriptionDetail(await subscriptions_skip(client, subscriptionToken));
|
|
824
|
-
},
|
|
825
|
-
cancelSubscription: async (subscriptionToken, _customerId) => {
|
|
826
|
-
return mapSubscriptionDetail(await subscriptions_cancel(client, subscriptionToken));
|
|
827
|
-
},
|
|
828
|
-
reactivateSubscription: async (subscriptionToken, _params) => {
|
|
829
|
-
return mapSubscriptionDetail(await subscriptions_reactivate(client, subscriptionToken));
|
|
830
|
-
},
|
|
831
|
-
updateSubscriptionInfo: async (subscriptionToken, body) => {
|
|
832
|
-
return mapSubscriptionDetail(await subscriptions_update(client, subscriptionToken, { subscription: { payment_method_id: body.payment_method_id } }));
|
|
833
|
-
}
|
|
834
|
-
};
|
|
462
|
+
/**
|
|
463
|
+
* Creates a SubscriptionsApi-compatible adapter backed by the portal-tenant BFF.
|
|
464
|
+
*
|
|
465
|
+
* Uses async/await with explicit field mapping. The BFF returns simplified
|
|
466
|
+
* subscription types compared to the full admin API; the adapter maps the
|
|
467
|
+
* response envelope and provides runtime defaults for optional fields.
|
|
468
|
+
*/
|
|
469
|
+
function createPortalSubscriptionsAdapter(client) {
|
|
470
|
+
return {
|
|
471
|
+
fetchCustomerSubscriptions: async (params) => {
|
|
472
|
+
return mapSubscriptionList(await subscriptions_list(client, {
|
|
473
|
+
"page[cursor]": params.cursor,
|
|
474
|
+
"page[limit]": params.limit ?? params.perPage
|
|
475
|
+
}));
|
|
476
|
+
},
|
|
477
|
+
fetchSubscription: async (subscriptionToken) => {
|
|
478
|
+
return mapSubscriptionDetail(await subscriptions_show(client, subscriptionToken));
|
|
479
|
+
},
|
|
480
|
+
pauseSubscription: async (subscriptionToken, _params) => {
|
|
481
|
+
return mapSubscriptionDetail(await subscriptions_pause(client, subscriptionToken));
|
|
482
|
+
},
|
|
483
|
+
resumeSubscription: async (subscriptionToken, _params) => {
|
|
484
|
+
return mapSubscriptionDetail(await subscriptions_resume(client, subscriptionToken));
|
|
485
|
+
},
|
|
486
|
+
skipSubscription: async (subscriptionToken, _params) => {
|
|
487
|
+
return mapSubscriptionDetail(await subscriptions_skip(client, subscriptionToken));
|
|
488
|
+
},
|
|
489
|
+
cancelSubscription: async (subscriptionToken, _customerId) => {
|
|
490
|
+
return mapSubscriptionDetail(await subscriptions_cancel(client, subscriptionToken));
|
|
491
|
+
},
|
|
492
|
+
reactivateSubscription: async (subscriptionToken, _params) => {
|
|
493
|
+
return mapSubscriptionDetail(await subscriptions_reactivate(client, subscriptionToken));
|
|
494
|
+
},
|
|
495
|
+
updateSubscriptionInfo: async (subscriptionToken, body) => {
|
|
496
|
+
return mapSubscriptionDetail(await subscriptions_update(client, subscriptionToken, { subscription: { payment_method_id: body.payment_method_id } }));
|
|
497
|
+
}
|
|
498
|
+
};
|
|
499
|
+
}
|
|
500
|
+
//#endregion
|
|
501
|
+
//#region src/subscriptions/PortalSubscriptionsApiProvider.tsx
|
|
502
|
+
function PortalSubscriptionsApiProvider({ children }) {
|
|
503
|
+
const client = usePortalTenantClient();
|
|
504
|
+
return /* @__PURE__ */ jsx(SubscriptionsCoreProvider, {
|
|
505
|
+
api: useMemo(() => createPortalSubscriptionsAdapter(client), [client]),
|
|
506
|
+
children
|
|
507
|
+
});
|
|
508
|
+
}
|
|
509
|
+
//#endregion
|
|
510
|
+
//#region ../../subscriptions/ui/src/lib/format.ts
|
|
511
|
+
/**
|
|
512
|
+
* Format a number as currency (USD).
|
|
513
|
+
*/
|
|
514
|
+
function formatCurrency(value) {
|
|
515
|
+
return new Intl.NumberFormat("en-US", {
|
|
516
|
+
style: "currency",
|
|
517
|
+
currency: "USD"
|
|
518
|
+
}).format(value);
|
|
519
|
+
}
|
|
520
|
+
/**
|
|
521
|
+
* Convert a snake_case or lowercase string to Start Case.
|
|
522
|
+
* Replaces lodash startCase for simple status strings.
|
|
523
|
+
*/
|
|
524
|
+
function startCase(str) {
|
|
525
|
+
if (!str) return "";
|
|
526
|
+
return str.replace(/_/g, " ").replace(/\b\w/g, (char) => char.toUpperCase());
|
|
527
|
+
}
|
|
528
|
+
/**
|
|
529
|
+
* Format a next bill date string to M/D/YYYY (UTC).
|
|
530
|
+
*/
|
|
531
|
+
function formatNextBillDate(nextBillDate) {
|
|
532
|
+
if (!nextBillDate) return "N/A";
|
|
533
|
+
const date = new Date(nextBillDate);
|
|
534
|
+
if (isNaN(date.getTime())) return "N/A";
|
|
535
|
+
return `${date.getUTCMonth() + 1}/${date.getUTCDate()}/${date.getUTCFullYear()}`;
|
|
536
|
+
}
|
|
537
|
+
//#endregion
|
|
538
|
+
//#region ../../subscriptions/ui/src/lib/cn.ts
|
|
539
|
+
function cn(...inputs) {
|
|
540
|
+
return twMerge(clsx(inputs));
|
|
541
|
+
}
|
|
542
|
+
//#endregion
|
|
543
|
+
//#region ../../subscriptions/ui/src/components/status-pill.tsx
|
|
544
|
+
const STATUS_COLORS = {
|
|
545
|
+
active: "bg-green-100 text-green-800",
|
|
546
|
+
paused: "bg-gray-100 text-gray-800",
|
|
547
|
+
cancelled: "bg-red-100 text-red-800",
|
|
548
|
+
pending: "bg-yellow-100 text-yellow-800",
|
|
549
|
+
inactive: "bg-gray-100 text-gray-800",
|
|
550
|
+
disabled: "bg-red-100 text-red-800",
|
|
551
|
+
past_due: "bg-gray-100 text-gray-800"
|
|
552
|
+
};
|
|
553
|
+
const STATUS_DOT_COLORS = {
|
|
554
|
+
active: "bg-green-500",
|
|
555
|
+
paused: "bg-gray-400",
|
|
556
|
+
cancelled: "bg-red-500",
|
|
557
|
+
pending: "bg-yellow-500",
|
|
558
|
+
inactive: "bg-gray-400",
|
|
559
|
+
disabled: "bg-red-500",
|
|
560
|
+
past_due: "bg-gray-400"
|
|
561
|
+
};
|
|
562
|
+
function StatusPill({ status, children }) {
|
|
563
|
+
const key = status?.toLowerCase() ?? "";
|
|
564
|
+
const pillColor = STATUS_COLORS[key] ?? "bg-gray-100 text-gray-800";
|
|
565
|
+
const dotColor = STATUS_DOT_COLORS[key] ?? "bg-gray-400";
|
|
566
|
+
return /* @__PURE__ */ jsxs("span", {
|
|
567
|
+
className: cn("inline-flex items-center gap-1.5 rounded-full px-2.5 py-0.5 text-xs font-medium", pillColor),
|
|
568
|
+
children: [/* @__PURE__ */ jsx("span", { className: cn("h-1.5 w-1.5 rounded-full", dotColor) }), children]
|
|
569
|
+
});
|
|
570
|
+
}
|
|
571
|
+
//#endregion
|
|
572
|
+
//#region ../../subscriptions/ui/src/components/subscriptions-list.tsx
|
|
573
|
+
function SubscriptionsList({ customerId, onSubscriptionClick, t, pageSize = 10 }) {
|
|
574
|
+
const [currentPage, setCurrentPage] = useState(1);
|
|
575
|
+
const [statusFilter, setStatusFilter] = useState(null);
|
|
576
|
+
const [search, setSearch] = useState(null);
|
|
577
|
+
const [sortBy, setSortBy] = useState({
|
|
578
|
+
column: "next_bill_date",
|
|
579
|
+
direction: "desc"
|
|
580
|
+
});
|
|
581
|
+
const { data, isLoading } = useSubscriptions({
|
|
582
|
+
customerId: customerId ?? 0,
|
|
583
|
+
page: currentPage,
|
|
584
|
+
perPage: pageSize,
|
|
585
|
+
status: statusFilter,
|
|
586
|
+
search,
|
|
587
|
+
sortBy: sortBy.column,
|
|
588
|
+
sortDirection: sortBy.direction
|
|
589
|
+
}, { enabled: !!customerId });
|
|
590
|
+
useEffect(() => {
|
|
591
|
+
setCurrentPage(1);
|
|
592
|
+
}, [
|
|
593
|
+
statusFilter,
|
|
594
|
+
search,
|
|
595
|
+
sortBy
|
|
596
|
+
]);
|
|
597
|
+
const items = data?.subscriptions ?? [];
|
|
598
|
+
const totalItems = data?.meta?.pagination?.total_count ?? 0;
|
|
599
|
+
const totalPages = data?.meta?.pagination?.total_pages ?? 1;
|
|
600
|
+
const handleSubscriptionClick = (token) => {
|
|
601
|
+
if (token) onSubscriptionClick(token);
|
|
602
|
+
};
|
|
603
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
604
|
+
className: "border-border overflow-hidden rounded-lg border shadow-sm",
|
|
605
|
+
children: [
|
|
606
|
+
/* @__PURE__ */ jsxs("div", {
|
|
607
|
+
className: "flex flex-col gap-2 p-3 sm:flex-row sm:items-center sm:justify-between",
|
|
608
|
+
children: [/* @__PURE__ */ jsxs(ToggleGroup, {
|
|
609
|
+
type: "single",
|
|
610
|
+
value: statusFilter ?? "all",
|
|
611
|
+
onValueChange: (v) => {
|
|
612
|
+
if (v) setStatusFilter(v === "all" ? null : v);
|
|
613
|
+
},
|
|
614
|
+
variant: "ghost",
|
|
615
|
+
children: [
|
|
616
|
+
/* @__PURE__ */ jsx(ToggleGroupItem, {
|
|
617
|
+
value: "all",
|
|
618
|
+
children: t("all")
|
|
619
|
+
}),
|
|
620
|
+
/* @__PURE__ */ jsx(ToggleGroupItem, {
|
|
621
|
+
value: "active",
|
|
622
|
+
children: t("active")
|
|
623
|
+
}),
|
|
624
|
+
/* @__PURE__ */ jsx(ToggleGroupItem, {
|
|
625
|
+
value: "inactive",
|
|
626
|
+
children: t("inactive")
|
|
627
|
+
})
|
|
628
|
+
]
|
|
629
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
630
|
+
className: "w-full max-w-sm",
|
|
631
|
+
children: /* @__PURE__ */ jsx(SearchSort, {
|
|
632
|
+
searchValue: search ?? "",
|
|
633
|
+
onSearchChange: (v) => setSearch(v || null),
|
|
634
|
+
placeholder: t("search_subscriptions")
|
|
635
|
+
})
|
|
636
|
+
})]
|
|
637
|
+
}),
|
|
638
|
+
/* @__PURE__ */ jsx("div", {
|
|
639
|
+
className: "block md:hidden",
|
|
640
|
+
children: isLoading ? Array(5).fill(0).map((_, index) => /* @__PURE__ */ jsx("div", {
|
|
641
|
+
className: "border-border border-b p-4",
|
|
642
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
643
|
+
className: "flex space-x-3",
|
|
644
|
+
children: [/* @__PURE__ */ jsx(Skeleton, { className: "h-12 w-12 rounded-md" }), /* @__PURE__ */ jsxs("div", {
|
|
645
|
+
className: "flex-1 space-y-2",
|
|
646
|
+
children: [/* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-3/4" }), /* @__PURE__ */ jsx(Skeleton, { className: "h-3 w-1/2" })]
|
|
647
|
+
})]
|
|
648
|
+
})
|
|
649
|
+
}, `skeleton-${index}`)) : items.length === 0 ? /* @__PURE__ */ jsx("div", {
|
|
650
|
+
className: "text-muted-foreground px-3 py-8 text-center text-sm",
|
|
651
|
+
children: t("no_subscriptions_found")
|
|
652
|
+
}) : items.map((subscription) => /* @__PURE__ */ jsx("div", {
|
|
653
|
+
className: "border-border hover:bg-accent cursor-pointer border-b p-4 transition-colors duration-200 ease-in-out last:border-b-0",
|
|
654
|
+
onClick: () => handleSubscriptionClick(subscription.subscription_token),
|
|
655
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
656
|
+
className: "flex items-start space-x-3",
|
|
657
|
+
children: [/* @__PURE__ */ jsx("img", {
|
|
658
|
+
src: subscription.variant?.product?.image_url,
|
|
659
|
+
alt: subscription.variant?.product?.title,
|
|
660
|
+
width: 48,
|
|
661
|
+
height: 48,
|
|
662
|
+
className: "h-12 w-12 flex-shrink-0 rounded-md object-cover"
|
|
663
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
664
|
+
className: "w-0 min-w-0 flex-1",
|
|
665
|
+
children: [
|
|
666
|
+
/* @__PURE__ */ jsx("p", {
|
|
667
|
+
className: "text-foreground truncate text-sm font-medium",
|
|
668
|
+
children: subscription.variant?.product?.title
|
|
669
|
+
}),
|
|
670
|
+
/* @__PURE__ */ jsxs("div", {
|
|
671
|
+
className: "mt-2 grid grid-cols-2 gap-x-4 gap-y-1 text-sm",
|
|
672
|
+
children: [/* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("span", {
|
|
673
|
+
className: "text-muted-foreground block text-xs",
|
|
674
|
+
children: t("next_bill_date")
|
|
675
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
676
|
+
className: "text-muted-foreground",
|
|
677
|
+
children: formatNextBillDate(subscription.next_bill_date ?? "")
|
|
678
|
+
})] }), /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("span", {
|
|
679
|
+
className: "text-muted-foreground block text-xs",
|
|
680
|
+
children: t("price")
|
|
681
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
682
|
+
className: "text-foreground font-medium",
|
|
683
|
+
children: formatCurrency(subscription.price * subscription.quantity)
|
|
684
|
+
})] })]
|
|
685
|
+
}),
|
|
686
|
+
/* @__PURE__ */ jsxs("div", {
|
|
687
|
+
className: "mt-2",
|
|
688
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
689
|
+
className: "text-muted-foreground block text-xs",
|
|
690
|
+
children: t("status")
|
|
691
|
+
}), /* @__PURE__ */ jsx(StatusPill, {
|
|
692
|
+
status: subscription.status,
|
|
693
|
+
children: startCase(subscription.status) || t("unknown_status")
|
|
694
|
+
})]
|
|
695
|
+
})
|
|
696
|
+
]
|
|
697
|
+
})]
|
|
698
|
+
})
|
|
699
|
+
}, subscription.subscription_token))
|
|
700
|
+
}),
|
|
701
|
+
/* @__PURE__ */ jsx("div", {
|
|
702
|
+
className: "hidden md:block",
|
|
703
|
+
children: /* @__PURE__ */ jsxs(Table$1, {
|
|
704
|
+
className: "min-w-full table-fixed",
|
|
705
|
+
children: [
|
|
706
|
+
/* @__PURE__ */ jsxs("colgroup", { children: [
|
|
707
|
+
/* @__PURE__ */ jsx("col", { className: "w-[45%] min-w-[240px]" }),
|
|
708
|
+
/* @__PURE__ */ jsx("col", { className: "w-[20%] min-w-[100px]" }),
|
|
709
|
+
/* @__PURE__ */ jsx("col", { className: "w-[15%] min-w-[100px]" }),
|
|
710
|
+
/* @__PURE__ */ jsx("col", { className: "w-[20%] min-w-[100px]" })
|
|
711
|
+
] }),
|
|
712
|
+
/* @__PURE__ */ jsx(TableHeader, {
|
|
713
|
+
className: "bg-muted",
|
|
714
|
+
children: /* @__PURE__ */ jsxs(TableRow, {
|
|
715
|
+
className: "hover:bg-muted h-10",
|
|
716
|
+
children: [
|
|
717
|
+
/* @__PURE__ */ jsx(TableColumn, {
|
|
718
|
+
label: t("product"),
|
|
719
|
+
sortable: false
|
|
720
|
+
}),
|
|
721
|
+
/* @__PURE__ */ jsx(TableColumn, {
|
|
722
|
+
label: t("next_bill_date"),
|
|
723
|
+
sortBy: "next_bill_date",
|
|
724
|
+
sortData: sortBy,
|
|
725
|
+
onSortClick: (value) => setSortBy({
|
|
726
|
+
column: value,
|
|
727
|
+
direction: sortBy.direction === "asc" ? "desc" : "asc"
|
|
728
|
+
})
|
|
729
|
+
}),
|
|
730
|
+
/* @__PURE__ */ jsx(TableColumn, {
|
|
731
|
+
label: t("price"),
|
|
732
|
+
sortable: false
|
|
733
|
+
}),
|
|
734
|
+
/* @__PURE__ */ jsx(TableColumn, {
|
|
735
|
+
label: t("status"),
|
|
736
|
+
sortable: false
|
|
737
|
+
})
|
|
738
|
+
]
|
|
739
|
+
})
|
|
740
|
+
}),
|
|
741
|
+
/* @__PURE__ */ jsx(TableBody, {
|
|
742
|
+
className: "bg-background",
|
|
743
|
+
children: isLoading ? Array(5).fill(0).map((_, index) => /* @__PURE__ */ jsxs(TableRow, { children: [
|
|
744
|
+
/* @__PURE__ */ jsx(TableCell, {
|
|
745
|
+
className: "px-3 py-4",
|
|
746
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
747
|
+
className: "flex items-center space-x-2",
|
|
748
|
+
children: [/* @__PURE__ */ jsx(Skeleton, { className: "h-9 w-9 rounded-md" }), /* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-32" })]
|
|
749
|
+
})
|
|
750
|
+
}),
|
|
751
|
+
/* @__PURE__ */ jsx(TableCell, {
|
|
752
|
+
className: "px-3 py-4",
|
|
753
|
+
children: /* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-24" })
|
|
754
|
+
}),
|
|
755
|
+
/* @__PURE__ */ jsx(TableCell, {
|
|
756
|
+
className: "px-3 py-4",
|
|
757
|
+
children: /* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-24" })
|
|
758
|
+
}),
|
|
759
|
+
/* @__PURE__ */ jsx(TableCell, {
|
|
760
|
+
className: "px-3 py-4",
|
|
761
|
+
children: /* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-16" })
|
|
762
|
+
})
|
|
763
|
+
] }, `skeleton-${index}`)) : items.length === 0 ? /* @__PURE__ */ jsx(TableRow, { children: /* @__PURE__ */ jsx(TableCell, {
|
|
764
|
+
colSpan: 4,
|
|
765
|
+
className: "text-muted-foreground px-3 py-8 text-center text-sm",
|
|
766
|
+
children: t("no_subscriptions_found")
|
|
767
|
+
}) }) : items.map((subscription) => /* @__PURE__ */ jsxs(TableRow, {
|
|
768
|
+
className: "cursor-pointer",
|
|
769
|
+
onClick: () => handleSubscriptionClick(subscription.subscription_token),
|
|
770
|
+
children: [
|
|
771
|
+
/* @__PURE__ */ jsxs(TableCell, {
|
|
772
|
+
className: "text-muted-foreground flex max-w-[280px] items-center space-x-3 py-4 pr-3 pl-3 text-sm",
|
|
773
|
+
children: [/* @__PURE__ */ jsx("img", {
|
|
774
|
+
src: subscription.variant?.product?.image_url,
|
|
775
|
+
alt: subscription.variant?.product?.title,
|
|
776
|
+
width: 48,
|
|
777
|
+
height: 48,
|
|
778
|
+
className: "h-12 w-12 flex-shrink-0 rounded-md object-cover"
|
|
779
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
780
|
+
className: "text-foreground truncate text-sm font-medium",
|
|
781
|
+
children: subscription.variant?.product?.title
|
|
782
|
+
})]
|
|
783
|
+
}),
|
|
784
|
+
/* @__PURE__ */ jsx(TableCell, {
|
|
785
|
+
className: "text-muted-foreground px-3 py-4 text-sm whitespace-nowrap",
|
|
786
|
+
children: formatNextBillDate(subscription.next_bill_date ?? "")
|
|
787
|
+
}),
|
|
788
|
+
/* @__PURE__ */ jsx(TableCell, {
|
|
789
|
+
className: "px-3 py-4 text-sm whitespace-nowrap",
|
|
790
|
+
children: /* @__PURE__ */ jsx("span", {
|
|
791
|
+
className: "text-muted-foreground",
|
|
792
|
+
children: formatCurrency(subscription.price * subscription.quantity)
|
|
793
|
+
})
|
|
794
|
+
}),
|
|
795
|
+
/* @__PURE__ */ jsx(TableCell, {
|
|
796
|
+
className: "px-3 py-4 text-sm whitespace-nowrap",
|
|
797
|
+
children: /* @__PURE__ */ jsx(StatusPill, {
|
|
798
|
+
status: subscription.status,
|
|
799
|
+
children: startCase(subscription.status) || t("unknown_status")
|
|
800
|
+
})
|
|
801
|
+
})
|
|
802
|
+
]
|
|
803
|
+
}, subscription.subscription_token))
|
|
804
|
+
})
|
|
805
|
+
]
|
|
806
|
+
})
|
|
807
|
+
}),
|
|
808
|
+
/* @__PURE__ */ jsx(PaginationFooter, {
|
|
809
|
+
currentPage,
|
|
810
|
+
totalPages,
|
|
811
|
+
pageSize,
|
|
812
|
+
totalItems,
|
|
813
|
+
onPageChange: setCurrentPage,
|
|
814
|
+
t
|
|
815
|
+
})
|
|
816
|
+
]
|
|
817
|
+
});
|
|
818
|
+
}
|
|
819
|
+
//#endregion
|
|
820
|
+
//#region ../../subscriptions/ui/src/screens/SubscriptionsListScreen.tsx
|
|
821
|
+
function SubscriptionsListScreen$1({ customerId, onSubscriptionClick, t, isLoadingCustomer }) {
|
|
822
|
+
useScreenHeaderBreadcrumbs(useMemo(() => /* @__PURE__ */ jsx(Breadcrumb, { children: /* @__PURE__ */ jsx(BreadcrumbList, {
|
|
823
|
+
className: "text-lg",
|
|
824
|
+
children: /* @__PURE__ */ jsx(BreadcrumbItem, { children: /* @__PURE__ */ jsx(BreadcrumbPage, {
|
|
825
|
+
className: "font-semibold",
|
|
826
|
+
children: "Subscriptions"
|
|
827
|
+
}) })
|
|
828
|
+
}) }), []));
|
|
829
|
+
if (isLoadingCustomer) return /* @__PURE__ */ jsx("div", {
|
|
830
|
+
className: "mx-auto max-w-7xl px-4 py-4 sm:px-6 sm:py-6 lg:px-10 lg:py-8",
|
|
831
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
832
|
+
className: "space-y-3",
|
|
833
|
+
children: [/* @__PURE__ */ jsx("div", { className: "bg-muted h-10 animate-pulse rounded" }), /* @__PURE__ */ jsx("div", { className: "bg-muted h-64 animate-pulse rounded" })]
|
|
834
|
+
})
|
|
835
|
+
});
|
|
836
|
+
return /* @__PURE__ */ jsx("div", {
|
|
837
|
+
className: "mx-auto max-w-7xl px-4 py-4 sm:px-6 sm:py-6 lg:px-10 lg:py-8",
|
|
838
|
+
children: /* @__PURE__ */ jsx(SubscriptionsList, {
|
|
839
|
+
customerId,
|
|
840
|
+
onSubscriptionClick,
|
|
841
|
+
t
|
|
842
|
+
})
|
|
843
|
+
});
|
|
835
844
|
}
|
|
836
845
|
//#endregion
|
|
837
846
|
//#region src/screens/SubscriptionsListScreen.tsx
|
|
@@ -854,17 +863,12 @@ const translations = {
|
|
|
854
863
|
pagination: "Pagination"
|
|
855
864
|
};
|
|
856
865
|
function SubscriptionsListScreen({ customerId, isLoadingCustomer }) {
|
|
857
|
-
const client = usePortalTenantClient();
|
|
858
|
-
const subscriptionsApi = useMemo(() => createPortalSubscriptionsAdapter(client), [client]);
|
|
859
866
|
const { navigate } = useAppNavigation();
|
|
860
|
-
return /* @__PURE__ */ jsx(
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
onSubscriptionClick: (subscriptionToken) => navigate(`subscriptions/${subscriptionToken}`),
|
|
866
|
-
t: (key) => translations[key] ?? key
|
|
867
|
-
})
|
|
867
|
+
return /* @__PURE__ */ jsx(SubscriptionsListScreen$1, {
|
|
868
|
+
customerId,
|
|
869
|
+
isLoadingCustomer,
|
|
870
|
+
onSubscriptionClick: (subscriptionToken) => navigate(`subscriptions/${subscriptionToken}`),
|
|
871
|
+
t: (key) => translations[key] ?? key
|
|
868
872
|
});
|
|
869
873
|
}
|
|
870
874
|
//#endregion
|
|
@@ -1465,28 +1469,23 @@ function SubscriptionDetailScreen$1({ token, onNavigateToList, onNotFound, onErr
|
|
|
1465
1469
|
//#endregion
|
|
1466
1470
|
//#region src/screens/SubscriptionDetailScreen.tsx
|
|
1467
1471
|
function SubscriptionDetailScreen({ token, onToast }) {
|
|
1468
|
-
const client = usePortalTenantClient();
|
|
1469
|
-
const subscriptionsApi = useMemo(() => createPortalSubscriptionsAdapter(client), [client]);
|
|
1470
1472
|
const { navigate } = useAppNavigation();
|
|
1471
|
-
return /* @__PURE__ */ jsx(
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
}
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
}
|
|
1486
|
-
|
|
1487
|
-
onToast(`${message}: ${err instanceof Error ? err.message : "An error occurred"}`, "error");
|
|
1488
|
-
}
|
|
1489
|
-
})
|
|
1473
|
+
return /* @__PURE__ */ jsx(SubscriptionDetailScreen$1, {
|
|
1474
|
+
token,
|
|
1475
|
+
onNavigateToList: () => navigate("subscriptions"),
|
|
1476
|
+
onNotFound: () => {
|
|
1477
|
+
onToast("Subscription not found", "warning");
|
|
1478
|
+
navigate("subscriptions");
|
|
1479
|
+
},
|
|
1480
|
+
onError: (err) => {
|
|
1481
|
+
onToast(`Failed to load subscription: ${err instanceof Error ? err.message : "An error occurred"}`, "error");
|
|
1482
|
+
},
|
|
1483
|
+
onSuccess: (message) => {
|
|
1484
|
+
onToast(message, "success");
|
|
1485
|
+
},
|
|
1486
|
+
onMutationError: (message, err) => {
|
|
1487
|
+
onToast(`${message}: ${err instanceof Error ? err.message : "An error occurred"}`, "error");
|
|
1488
|
+
}
|
|
1490
1489
|
});
|
|
1491
1490
|
}
|
|
1492
1491
|
//#endregion
|
|
@@ -1509,17 +1508,17 @@ function SubscriptionsScreen({ onToast, background, textColor, accentColor, padd
|
|
|
1509
1508
|
const isLoadingCustomer = account === void 0;
|
|
1510
1509
|
if (isDetailView) return /* @__PURE__ */ jsx("div", {
|
|
1511
1510
|
...divProps,
|
|
1512
|
-
children: /* @__PURE__ */ jsx(SubscriptionDetailScreen, {
|
|
1511
|
+
children: /* @__PURE__ */ jsx(PortalSubscriptionsApiProvider, { children: /* @__PURE__ */ jsx(SubscriptionDetailScreen, {
|
|
1513
1512
|
token: detailToken,
|
|
1514
1513
|
onToast: effectiveToast
|
|
1515
|
-
})
|
|
1514
|
+
}) })
|
|
1516
1515
|
});
|
|
1517
1516
|
return /* @__PURE__ */ jsx("div", {
|
|
1518
1517
|
...divProps,
|
|
1519
|
-
children: /* @__PURE__ */ jsx(SubscriptionsListScreen, {
|
|
1518
|
+
children: /* @__PURE__ */ jsx(PortalSubscriptionsApiProvider, { children: /* @__PURE__ */ jsx(SubscriptionsListScreen, {
|
|
1520
1519
|
customerId,
|
|
1521
1520
|
isLoadingCustomer
|
|
1522
|
-
})
|
|
1521
|
+
}) })
|
|
1523
1522
|
});
|
|
1524
1523
|
}
|
|
1525
1524
|
const subscriptionsScreenPropertySchema = {
|
|
@@ -1534,4 +1533,4 @@ const subscriptionsScreenPropertySchema = {
|
|
|
1534
1533
|
//#endregion
|
|
1535
1534
|
export { SubscriptionsScreen_exports as n, subscriptionsScreenPropertySchema as r, SubscriptionsScreen as t };
|
|
1536
1535
|
|
|
1537
|
-
//# sourceMappingURL=SubscriptionsScreen-
|
|
1536
|
+
//# sourceMappingURL=SubscriptionsScreen-Dn3AEUJi.mjs.map
|