@fluid-app/portal-sdk 0.1.218 → 0.1.220
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/{AppDownloadScreen-CZ0EOIZ5.mjs → AppDownloadScreen-Bhix461K.mjs} +1 -1
- package/dist/{AppDownloadScreen-CZ0EOIZ5.mjs.map → AppDownloadScreen-Bhix461K.mjs.map} +1 -1
- package/dist/{AppDownloadScreen-CBoC31wL.cjs → AppDownloadScreen-DwBzuPcF.cjs} +1 -1
- package/dist/{AppDownloadScreen-CBoC31wL.cjs.map → AppDownloadScreen-DwBzuPcF.cjs.map} +1 -1
- package/dist/{FluidProvider-22PONJDa.mjs → FluidProvider-DTttgSXi.mjs} +2 -2
- package/dist/{FluidProvider-22PONJDa.mjs.map → FluidProvider-DTttgSXi.mjs.map} +1 -1
- package/dist/{FluidProvider-DTdi38VO.cjs → FluidProvider-Dm4BhF_t.cjs} +2 -2
- package/dist/{FluidProvider-DTdi38VO.cjs.map → FluidProvider-Dm4BhF_t.cjs.map} +1 -1
- package/dist/{MessagingScreen-BM21ZxGL.mjs → MessagingScreen-CwEXQJlW.mjs} +2 -2
- package/dist/{MessagingScreen-BM21ZxGL.mjs.map → MessagingScreen-CwEXQJlW.mjs.map} +1 -1
- package/dist/{MessagingScreen-ehHW4LwI.cjs → MessagingScreen-DLQ5V0m4.cjs} +2 -2
- package/dist/{MessagingScreen-ehHW4LwI.cjs.map → MessagingScreen-DLQ5V0m4.cjs.map} +1 -1
- package/dist/{MessagingScreen-BDlC9VWJ.cjs → MessagingScreen-YBXJL7a9.cjs} +2 -2
- package/dist/{MySiteScreen-DUN5TTvU.mjs → MySiteScreen-BAPWqDfm.mjs} +11 -31
- package/dist/{MySiteScreen-DUN5TTvU.mjs.map → MySiteScreen-BAPWqDfm.mjs.map} +1 -1
- package/dist/{MySiteScreen-B0aOIzU4.cjs → MySiteScreen-CEX1qxdj.cjs} +2 -3
- package/dist/{MySiteScreen-B1L8coGs.cjs → MySiteScreen-DaNlmVSi.cjs} +24 -44
- package/dist/MySiteScreen-DaNlmVSi.cjs.map +1 -0
- package/dist/{PortalProductsApiProvider-CE71zDj9.mjs → PortalProductsApiProvider-BwIRudl_.mjs} +1 -1
- package/dist/{PortalProductsApiProvider-CE71zDj9.mjs.map → PortalProductsApiProvider-BwIRudl_.mjs.map} +1 -1
- package/dist/{PortalProductsApiProvider-Ca1oeTtJ.cjs → PortalProductsApiProvider-CRaocswH.cjs} +1 -1
- package/dist/{PortalProductsApiProvider-Ca1oeTtJ.cjs.map → PortalProductsApiProvider-CRaocswH.cjs.map} +1 -1
- package/dist/{ProfileScreen-DNRpWpex.cjs → ProfileScreen-B0WRifk_.cjs} +2 -2
- package/dist/{ProfileScreen-DNRpWpex.cjs.map → ProfileScreen-B0WRifk_.cjs.map} +1 -1
- package/dist/{ProfileScreen-VonnJyFa.mjs → ProfileScreen-BuejQU_V.mjs} +2 -2
- package/dist/{ProfileScreen-VonnJyFa.mjs.map → ProfileScreen-BuejQU_V.mjs.map} +1 -1
- package/dist/{ProfileScreen-CN1DDd-Q.cjs → ProfileScreen-g3se9Jw-.cjs} +2 -2
- package/dist/{ShareablesScreen-smU5pGyH.cjs → ShareablesScreen-CqvPzH1v.cjs} +3 -5
- package/dist/{PortalContentApiProvider-C9FeVwRb.mjs → ShareablesScreen-DV2nikzp.mjs} +460 -119
- package/dist/ShareablesScreen-DV2nikzp.mjs.map +1 -0
- package/dist/{PortalContentApiProvider-RXBp8FNj.cjs → ShareablesScreen-DwnMBftJ.cjs} +457 -156
- package/dist/ShareablesScreen-DwnMBftJ.cjs.map +1 -0
- package/dist/{ShopScreen-BAbAc2ah.cjs → ShopScreen-C-Ki6fuh.cjs} +3 -3
- package/dist/{ShopScreen-DQ1-68kV.mjs → ShopScreen-C2K1C2tt.mjs} +3 -3
- package/dist/{ShopScreen-DQ1-68kV.mjs.map → ShopScreen-C2K1C2tt.mjs.map} +1 -1
- package/dist/{ShopScreen-DcJ0DLvB.cjs → ShopScreen-smzNn37E.cjs} +3 -3
- package/dist/{ShopScreen-DcJ0DLvB.cjs.map → ShopScreen-smzNn37E.cjs.map} +1 -1
- package/dist/{UpgradeScreen-BdY0rCoF.cjs → UpgradeScreen-CNXQ1hcP.cjs} +1 -1
- package/dist/{UpgradeScreen-Dau5Elx4.mjs → UpgradeScreen-ChLiVSf7.mjs} +1 -1
- package/dist/{UpgradeScreen-Dau5Elx4.mjs.map → UpgradeScreen-ChLiVSf7.mjs.map} +1 -1
- package/dist/{UpgradeScreen-DrBa2uzD.cjs → UpgradeScreen-DMJUK4dl.cjs} +1 -1
- package/dist/{UpgradeScreen-DrBa2uzD.cjs.map → UpgradeScreen-DMJUK4dl.cjs.map} +1 -1
- package/dist/{dist-DWs3-WOI.cjs → dist-Bxa9x0H9.cjs} +218 -1
- package/dist/{dist-DWs3-WOI.cjs.map → dist-Bxa9x0H9.cjs.map} +1 -1
- package/dist/index.cjs +24 -53
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -20
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +1 -20
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +25 -52
- package/dist/index.mjs.map +1 -1
- package/dist/{portal_tenant_content-0zpnjBot.cjs → portal_tenant_content-BvYxmADB.cjs} +18 -1
- package/dist/portal_tenant_content-BvYxmADB.cjs.map +1 -0
- package/dist/{portal_tenant_content-DzIQtSLE.mjs → portal_tenant_content-nHEI2qEY.mjs} +13 -2
- package/dist/portal_tenant_content-nHEI2qEY.mjs.map +1 -0
- package/dist/{sortable.esm-CJLSD-Ce.mjs → sortable.esm-fSGrAZU2.mjs} +141 -2
- package/dist/sortable.esm-fSGrAZU2.mjs.map +1 -0
- package/package.json +14 -14
- package/dist/MySiteScreen-B1L8coGs.cjs.map +0 -1
- package/dist/PortalContentApiProvider-C9FeVwRb.mjs.map +0 -1
- package/dist/PortalContentApiProvider-RXBp8FNj.cjs.map +0 -1
- package/dist/ProductsScreen-BD53vh6Y.cjs +0 -103
- package/dist/ProductsScreen-BD53vh6Y.cjs.map +0 -1
- package/dist/ProductsScreen-BtUZxJCt.mjs +0 -91
- package/dist/ProductsScreen-BtUZxJCt.mjs.map +0 -1
- package/dist/ProductsScreen-DNpzJ6lh.cjs +0 -15
- package/dist/ProductsScreen-pkOeOW8M.mjs +0 -13
- package/dist/ShareablesScreen-CW1e9x4K.mjs +0 -188
- package/dist/ShareablesScreen-CW1e9x4K.mjs.map +0 -1
- package/dist/ShareablesScreen-D1J2Kljk.mjs +0 -15
- package/dist/ShareablesScreen-DC8xXUo4.cjs +0 -200
- package/dist/ShareablesScreen-DC8xXUo4.cjs.map +0 -1
- package/dist/portal_tenant_content-0zpnjBot.cjs.map +0 -1
- package/dist/portal_tenant_content-DzIQtSLE.mjs.map +0 -1
- package/dist/sortable.esm-CJLSD-Ce.mjs.map +0 -1
- package/dist/use-mysite-portal-BV-BP3CE.mjs +0 -141
- package/dist/use-mysite-portal-BV-BP3CE.mjs.map +0 -1
- package/dist/use-mysite-portal-DzDYRU0u.cjs +0 -219
- package/dist/use-mysite-portal-DzDYRU0u.cjs.map +0 -1
|
@@ -1,13 +1,16 @@
|
|
|
1
|
-
import { t as useDropzone } from "./es-Cw_Kikmu.mjs";
|
|
2
|
-
import { A as
|
|
1
|
+
import { r as __exportAll, t as useDropzone } from "./es-Cw_Kikmu.mjs";
|
|
2
|
+
import { A as playlists_show, C as playlists_create, D as playlists_items_remove, E as playlists_items_list, M as shares_create, N as shares_list, O as playlists_items_reorder, T as playlists_items_add, _ as media_products_add, a as content_playlists_metrics_share_visits, b as media_show, c as dam_asset_paths_list, d as dam_assets_discard, f as dam_assets_list, g as media_list, h as media_destroy, i as content_pages_metrics_visits, j as playlists_update, k as playlists_list, l as dam_assets_create, m as media_create, n as content_media_metrics_visits, o as content_playlists_metrics_visits, p as dam_query, r as content_pages_metrics_share_visits, s as dam_asset_paths_create, t as content_media_metrics_share_visits, u as dam_assets_destroy, v as media_products_list, w as playlists_destroy, x as media_update, y as media_products_remove } from "./portal_tenant_content-nHEI2qEY.mjs";
|
|
3
3
|
import { n as usePortalTenantClient } from "./PortalTenantClientProvider-4ZmY6hac.mjs";
|
|
4
|
-
import { $ as DropdownMenuSeparator, A as Select, At as Checkbox, B as Form, C as Skeleton, Cn as AlertDialogFooter, Dn as Content, En as Button, Et as CardContent, G as FormMessage, H as FormField, J as DropdownMenuContent, K as Label, L as Input, M as SelectItem, N as SelectTrigger, Nn as useZodForm, P as SelectValue, Pn as cn, S as Slider, Sn as AlertDialogDescription, Tn as AlertDialogTitle, U as FormItem, V as FormControl, W as FormLabel, Y as DropdownMenuItem, _ as Switch, bn as AlertDialogCancel, c as Tabs, cn as Breadcrumb, dn as BreadcrumbList, dt as DialogPortal, et as DropdownMenuSub, fn as BreadcrumbPage, ft as DialogTitle, ht as PopoverTrigger, i as TooltipTrigger, it as Dialog, j as SelectContent, k as Separator, l as TabsList, ln as BreadcrumbItem, lt as DialogHeader, mn as Badge, mt as PopoverContent, n as TooltipContent, nt as DropdownMenuSubTrigger, ot as DialogContent, pn as BreadcrumbSeparator, pt as Popover, q as DropdownMenu, r as TooltipProvider, rt as DropdownMenuTrigger, s as Textarea, st as DialogDescription, t as Tooltip, tt as DropdownMenuSubContent, u as TabsTrigger, un as BreadcrumbLink, ut as DialogOverlay, vn as AlertDialog, wn as AlertDialogHeader, wt as Card, xn as AlertDialogContent, y as Spinner, yn as AlertDialogAction } from "./src-BEKH1DXO.mjs";
|
|
4
|
+
import { $ as DropdownMenuSeparator, A as Select, At as Checkbox, B as Form, C as Skeleton, Cn as AlertDialogFooter, Dn as Content, En as Button, Et as CardContent, G as FormMessage, H as FormField, J as DropdownMenuContent, K as Label, L as Input, M as SelectItem, N as SelectTrigger, Nn as useZodForm, P as SelectValue, Pn as cn, S as Slider, Sn as AlertDialogDescription, Tn as AlertDialogTitle, U as FormItem, V as FormControl, W as FormLabel, Y as DropdownMenuItem, _ as Switch, b as fluidToast, bn as AlertDialogCancel, c as Tabs, cn as Breadcrumb, dn as BreadcrumbList, dt as DialogPortal, et as DropdownMenuSub, fn as BreadcrumbPage, ft as DialogTitle, ht as PopoverTrigger, i as TooltipTrigger, it as Dialog, j as SelectContent, k as Separator, l as TabsList, ln as BreadcrumbItem, lt as DialogHeader, mn as Badge, mt as PopoverContent, n as TooltipContent, nt as DropdownMenuSubTrigger, ot as DialogContent, pn as BreadcrumbSeparator, pt as Popover, q as DropdownMenu, r as TooltipProvider, rt as DropdownMenuTrigger, s as Textarea, st as DialogDescription, t as Tooltip, tt as DropdownMenuSubContent, u as TabsTrigger, un as BreadcrumbLink, ut as DialogOverlay, vn as AlertDialog, wn as AlertDialogHeader, wt as Card, xn as AlertDialogContent, y as Spinner, yn as AlertDialogAction } from "./src-BEKH1DXO.mjs";
|
|
5
5
|
import { n as useScreenHeaderActions, r as useScreenHeaderBreadcrumbs } from "./ScreenHeaderContext-BDjNSUfr.mjs";
|
|
6
|
+
import { t as useAccount } from "./use-account-Cvig0exB.mjs";
|
|
7
|
+
import { t as useStore } from "./use-store-efmQhKpB.mjs";
|
|
8
|
+
import { n as useAppNavigation } from "./AppNavigationContext-Cq3BDKSf.mjs";
|
|
6
9
|
import { a as useEditor, o as Placeholder, r as EditorContent, t as StarterKit } from "./dist-D39Yezrv.mjs";
|
|
7
10
|
import { t as SearchSort } from "./SearchSort-DXBt-uj0.mjs";
|
|
8
11
|
import { n as TextAlign, t as Underline } from "./dist-Cis8L6HV.mjs";
|
|
9
|
-
import { a as verticalListSortingStrategy, c as PointerSensor, d as useSensors, f as CSS, i as useSortable, l as closestCenter, n as arrayMove, o as DndContext, r as sortableKeyboardCoordinates, s as KeyboardSensor, t as SortableContext, u as useSensor } from "./sortable.esm-
|
|
10
|
-
import { o as usePortalProductsApi } from "./PortalProductsApiProvider-
|
|
12
|
+
import { a as verticalListSortingStrategy, c as PointerSensor, d as useSensors, f as CSS, i as useSortable, l as closestCenter, n as arrayMove, o as DndContext, p as PORTAL_MYSITE_KEYS, r as sortableKeyboardCoordinates, s as KeyboardSensor, t as SortableContext, u as useSensor } from "./sortable.esm-fSGrAZU2.mjs";
|
|
13
|
+
import { o as usePortalProductsApi, t as PortalProductsApiProvider } from "./PortalProductsApiProvider-BwIRudl_.mjs";
|
|
11
14
|
import React, { PureComponent, createContext, createRef, forwardRef, useCallback, useContext, useEffect, useImperativeHandle, useMemo, useRef, useState } from "react";
|
|
12
15
|
import { keepPreviousData, useInfiniteQuery, useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
|
13
16
|
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -286,6 +289,25 @@ const useUpdatePlaylistMutation = (options) => {
|
|
|
286
289
|
}
|
|
287
290
|
});
|
|
288
291
|
};
|
|
292
|
+
const useReorderPlaylistItemsMutation = (options) => {
|
|
293
|
+
const api = useShareablesApi();
|
|
294
|
+
const queryClient = useQueryClient();
|
|
295
|
+
return useMutation({
|
|
296
|
+
mutationFn: ({ playlistId, data }) => {
|
|
297
|
+
if (!api.playlists.reorderPlaylistItems) return Promise.resolve();
|
|
298
|
+
return api.playlists.reorderPlaylistItems(playlistId, data);
|
|
299
|
+
},
|
|
300
|
+
onSuccess: (_, { playlistId }) => {
|
|
301
|
+
if (api.playlists.reorderPlaylistItems) queryClient.invalidateQueries({ queryKey: shareablesKeys.playlists.detail(playlistId) });
|
|
302
|
+
options?.onSuccess?.(playlistId);
|
|
303
|
+
},
|
|
304
|
+
onError: (error, { playlistId }) => {
|
|
305
|
+
if (isCancellationError(error)) return;
|
|
306
|
+
console.error("Error reordering playlist items:", error);
|
|
307
|
+
options?.onError?.(error, playlistId);
|
|
308
|
+
}
|
|
309
|
+
});
|
|
310
|
+
};
|
|
289
311
|
//#endregion
|
|
290
312
|
//#region ../../shareables/ui/src/context.tsx
|
|
291
313
|
const MISSING_PROVIDER = Symbol("missing-shareables-provider");
|
|
@@ -576,6 +598,83 @@ function ShareableListLayout({ filters, children, isLoading, error, errorMessage
|
|
|
576
598
|
});
|
|
577
599
|
}
|
|
578
600
|
//#endregion
|
|
601
|
+
//#region ../../shareables/ui/src/components/shared/ShareableListRow.tsx
|
|
602
|
+
/**
|
|
603
|
+
* Container className for a list-view rendering of shareables. Pairs with
|
|
604
|
+
* `ShareableListRow` and mirrors `SHAREABLE_GRID_CLASS` for symmetry.
|
|
605
|
+
*/
|
|
606
|
+
const SHAREABLE_LIST_CLASS = "divide-border divide-y rounded-lg border";
|
|
607
|
+
/**
|
|
608
|
+
* Single row in a shareables list view. The row body (thumbnail + title) is
|
|
609
|
+
* a `<button>` for keyboard/click navigation; `leading` and `trailing` slots
|
|
610
|
+
* are siblings so their interactive elements don't nest inside the body
|
|
611
|
+
* button. Hover styling applies to the entire row container.
|
|
612
|
+
*/
|
|
613
|
+
function ShareableListRow({ imageUrl, imageAlt, title, subtitle, onClick, leading, trailing }) {
|
|
614
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
615
|
+
className: "hover:bg-muted flex items-center gap-3 px-4 py-3 transition-colors",
|
|
616
|
+
children: [
|
|
617
|
+
leading,
|
|
618
|
+
/* @__PURE__ */ jsxs("button", {
|
|
619
|
+
type: "button",
|
|
620
|
+
onClick,
|
|
621
|
+
className: "flex min-w-0 flex-1 items-center gap-4 text-left",
|
|
622
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
623
|
+
className: "bg-muted h-12 w-12 shrink-0 overflow-hidden rounded-md",
|
|
624
|
+
children: imageUrl ? /* @__PURE__ */ jsx("img", {
|
|
625
|
+
src: imageUrl,
|
|
626
|
+
alt: imageAlt ?? title,
|
|
627
|
+
className: "h-full w-full object-cover"
|
|
628
|
+
}) : /* @__PURE__ */ jsx("div", { className: "bg-muted h-full w-full" })
|
|
629
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
630
|
+
className: "min-w-0 flex-1",
|
|
631
|
+
children: [/* @__PURE__ */ jsx("p", {
|
|
632
|
+
className: "text-foreground truncate text-sm font-medium",
|
|
633
|
+
children: title || "Untitled"
|
|
634
|
+
}), subtitle != null && subtitle !== false && /* @__PURE__ */ jsx("p", {
|
|
635
|
+
className: "text-muted-foreground flex items-center gap-1.5 text-xs",
|
|
636
|
+
children: subtitle
|
|
637
|
+
})]
|
|
638
|
+
})]
|
|
639
|
+
}),
|
|
640
|
+
trailing
|
|
641
|
+
]
|
|
642
|
+
});
|
|
643
|
+
}
|
|
644
|
+
//#endregion
|
|
645
|
+
//#region ../../shareables/ui/src/components/shared/ViewModeToggle.tsx
|
|
646
|
+
/**
|
|
647
|
+
* Segmented list/grid toggle used in the filter bar of every shareable
|
|
648
|
+
* listing screen. Stateless — callers own the `viewMode` state.
|
|
649
|
+
*/
|
|
650
|
+
function ViewModeToggle({ value, onChange }) {
|
|
651
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
652
|
+
className: "border-input bg-muted flex items-center rounded-lg border p-0.5",
|
|
653
|
+
children: [/* @__PURE__ */ jsx(ToggleButton, {
|
|
654
|
+
active: value === "list",
|
|
655
|
+
label: "List view",
|
|
656
|
+
onClick: () => onChange("list"),
|
|
657
|
+
children: /* @__PURE__ */ jsx(List, { className: "h-4 w-4" })
|
|
658
|
+
}), /* @__PURE__ */ jsx(ToggleButton, {
|
|
659
|
+
active: value === "grid",
|
|
660
|
+
label: "Grid view",
|
|
661
|
+
onClick: () => onChange("grid"),
|
|
662
|
+
children: /* @__PURE__ */ jsx(LayoutGrid, { className: "h-4 w-4" })
|
|
663
|
+
})]
|
|
664
|
+
});
|
|
665
|
+
}
|
|
666
|
+
function ToggleButton({ active, label, onClick, children }) {
|
|
667
|
+
return /* @__PURE__ */ jsx("button", {
|
|
668
|
+
type: "button",
|
|
669
|
+
onClick,
|
|
670
|
+
title: label,
|
|
671
|
+
"aria-label": label,
|
|
672
|
+
"aria-pressed": active,
|
|
673
|
+
className: cn("flex h-8 w-8 items-center justify-center rounded-md transition-all", active ? "bg-background text-foreground shadow-sm" : "text-muted-foreground hover:text-foreground"),
|
|
674
|
+
children
|
|
675
|
+
});
|
|
676
|
+
}
|
|
677
|
+
//#endregion
|
|
579
678
|
//#region ../../shareables/ui/src/components/screens/ProductsScreen.tsx
|
|
580
679
|
const PAGE_SIZE$4 = 24;
|
|
581
680
|
const SORT_OPTIONS$1 = [
|
|
@@ -606,6 +705,7 @@ const SORT_OPTIONS$1 = [
|
|
|
606
705
|
];
|
|
607
706
|
function ProductsScreen({ countryCode, fetchProducts: fetchPortalProducts, onNavigate }) {
|
|
608
707
|
const client = useShareablesClient();
|
|
708
|
+
const { navigate } = useShareablesUI();
|
|
609
709
|
useScreenHeaderBreadcrumbs(useMemo(() => /* @__PURE__ */ jsx(Breadcrumb, { children: /* @__PURE__ */ jsx(BreadcrumbList, {
|
|
610
710
|
className: "text-lg",
|
|
611
711
|
children: /* @__PURE__ */ jsx(BreadcrumbItem, { children: /* @__PURE__ */ jsx(BreadcrumbPage, {
|
|
@@ -616,6 +716,7 @@ function ProductsScreen({ countryCode, fetchProducts: fetchPortalProducts, onNav
|
|
|
616
716
|
const [searchTerm, setSearchTerm] = useState("");
|
|
617
717
|
const [debouncedSearch, setDebouncedSearch] = useState("");
|
|
618
718
|
const [sortValue, setSortValue] = useState("created_at_desc");
|
|
719
|
+
const [viewMode, setViewMode] = useState("grid");
|
|
619
720
|
const observerTarget = useRef(null);
|
|
620
721
|
useEffect(() => {
|
|
621
722
|
const timer = setTimeout(() => {
|
|
@@ -703,9 +804,9 @@ function ProductsScreen({ countryCode, fetchProducts: fetchPortalProducts, onNav
|
|
|
703
804
|
errorMessage: "Failed to load products. Please try again.",
|
|
704
805
|
isEmpty: products.length === 0,
|
|
705
806
|
emptyMessage: debouncedSearch ? "No products match your search." : "No products available.",
|
|
706
|
-
filters: /* @__PURE__ */
|
|
707
|
-
className: "flex justify-end",
|
|
708
|
-
children: /* @__PURE__ */ jsx("div", {
|
|
807
|
+
filters: /* @__PURE__ */ jsxs("div", {
|
|
808
|
+
className: "flex items-center justify-end gap-2",
|
|
809
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
709
810
|
className: "w-full max-w-sm",
|
|
710
811
|
children: /* @__PURE__ */ jsx(SearchSort, {
|
|
711
812
|
searchValue: searchTerm,
|
|
@@ -715,14 +816,18 @@ function ProductsScreen({ countryCode, fetchProducts: fetchPortalProducts, onNav
|
|
|
715
816
|
sortValue,
|
|
716
817
|
onSortChange: setSortValue
|
|
717
818
|
})
|
|
718
|
-
})
|
|
819
|
+
}), /* @__PURE__ */ jsx(ViewModeToggle, {
|
|
820
|
+
value: viewMode,
|
|
821
|
+
onChange: setViewMode
|
|
822
|
+
})]
|
|
719
823
|
}),
|
|
824
|
+
loadingFilterShape: "search-view",
|
|
720
825
|
footer: isFetchingNextPage && /* @__PURE__ */ jsx("div", {
|
|
721
826
|
className: "flex justify-center py-4",
|
|
722
827
|
children: /* @__PURE__ */ jsx("div", { className: "border-primary h-6 w-6 animate-spin rounded-full border-2 border-t-transparent" })
|
|
723
828
|
}),
|
|
724
829
|
sentinelRef: observerTarget,
|
|
725
|
-
children: /* @__PURE__ */ jsx("div", {
|
|
830
|
+
children: viewMode === "grid" ? /* @__PURE__ */ jsx("div", {
|
|
726
831
|
className: SHAREABLE_GRID_CLASS,
|
|
727
832
|
children: products.map((product) => /* @__PURE__ */ jsx(ShareProductCard, {
|
|
728
833
|
product: {
|
|
@@ -732,6 +837,14 @@ function ProductsScreen({ countryCode, fetchProducts: fetchPortalProducts, onNav
|
|
|
732
837
|
},
|
|
733
838
|
mediaCount: product.media_count
|
|
734
839
|
}, product.id))
|
|
840
|
+
}) : /* @__PURE__ */ jsx("div", {
|
|
841
|
+
className: SHAREABLE_LIST_CLASS,
|
|
842
|
+
children: products.map((product) => /* @__PURE__ */ jsx(ShareableListRow, {
|
|
843
|
+
imageUrl: product.image_url,
|
|
844
|
+
title: product.title,
|
|
845
|
+
subtitle: product.media_count != null ? `${product.media_count} assets` : void 0,
|
|
846
|
+
onClick: () => navigate(`product/${product.id}`)
|
|
847
|
+
}, product.id))
|
|
735
848
|
})
|
|
736
849
|
});
|
|
737
850
|
}
|
|
@@ -1701,21 +1814,9 @@ function MediaListingScreen({ onNavigate }) {
|
|
|
1701
1814
|
}), kindFilter === opt.value && /* @__PURE__ */ jsx(Check, { className: "text-muted-foreground size-4" })]
|
|
1702
1815
|
}, opt.value))
|
|
1703
1816
|
})] }),
|
|
1704
|
-
/* @__PURE__ */
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
type: "button",
|
|
1708
|
-
onClick: () => setViewMode("list"),
|
|
1709
|
-
className: `flex h-8 w-8 items-center justify-center rounded-md transition-all ${viewMode === "list" ? "bg-background text-foreground shadow-sm" : "text-muted-foreground hover:text-foreground"}`,
|
|
1710
|
-
title: "List view",
|
|
1711
|
-
children: /* @__PURE__ */ jsx(List, { className: "h-4 w-4" })
|
|
1712
|
-
}), /* @__PURE__ */ jsx("button", {
|
|
1713
|
-
type: "button",
|
|
1714
|
-
onClick: () => setViewMode("grid"),
|
|
1715
|
-
className: `flex h-8 w-8 items-center justify-center rounded-md transition-all ${viewMode === "grid" ? "bg-background text-foreground shadow-sm" : "text-muted-foreground hover:text-foreground"}`,
|
|
1716
|
-
title: "Grid view",
|
|
1717
|
-
children: /* @__PURE__ */ jsx(LayoutGrid, { className: "h-4 w-4" })
|
|
1718
|
-
})]
|
|
1817
|
+
/* @__PURE__ */ jsx(ViewModeToggle, {
|
|
1818
|
+
value: viewMode,
|
|
1819
|
+
onChange: setViewMode
|
|
1719
1820
|
})
|
|
1720
1821
|
]
|
|
1721
1822
|
})]
|
|
@@ -1785,37 +1886,20 @@ function MediaListingScreen({ onNavigate }) {
|
|
|
1785
1886
|
}, item.id);
|
|
1786
1887
|
})
|
|
1787
1888
|
}) : /* @__PURE__ */ jsx("div", {
|
|
1788
|
-
className:
|
|
1889
|
+
className: SHAREABLE_LIST_CLASS,
|
|
1789
1890
|
children: filteredItems.map((item) => {
|
|
1790
1891
|
const canEdit = !readOnly && item.owner_type === "user";
|
|
1791
|
-
return /* @__PURE__ */
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
className: "h-full w-full object-cover"
|
|
1803
|
-
}) : /* @__PURE__ */ jsx("div", { className: "bg-muted h-full w-full" })
|
|
1804
|
-
}), /* @__PURE__ */ jsxs("div", {
|
|
1805
|
-
className: "min-w-0 flex-1",
|
|
1806
|
-
children: [/* @__PURE__ */ jsx("p", {
|
|
1807
|
-
className: "text-foreground truncate text-sm font-medium",
|
|
1808
|
-
children: item.title ?? "Untitled"
|
|
1809
|
-
}), /* @__PURE__ */ jsxs("p", {
|
|
1810
|
-
className: "text-muted-foreground flex items-center gap-1.5 text-xs",
|
|
1811
|
-
children: [getMediaKindLabel(item.kind), item.owner_type === "user" && /* @__PURE__ */ jsx(Badge, {
|
|
1812
|
-
variant: "secondary",
|
|
1813
|
-
className: "px-1.5 py-0 text-[10px] leading-4",
|
|
1814
|
-
children: "My Media"
|
|
1815
|
-
})]
|
|
1816
|
-
})]
|
|
1817
|
-
})]
|
|
1818
|
-
}), canEdit && /* @__PURE__ */ jsx(MediaRowActionsMenu, { onDelete: () => setPendingDeleteId(item.id) })]
|
|
1892
|
+
return /* @__PURE__ */ jsx(ShareableListRow, {
|
|
1893
|
+
imageUrl: item.image_url,
|
|
1894
|
+
imageAlt: item.title ?? "",
|
|
1895
|
+
title: item.title ?? "Untitled",
|
|
1896
|
+
subtitle: /* @__PURE__ */ jsxs(Fragment$1, { children: [getMediaKindLabel(item.kind), item.owner_type === "user" && /* @__PURE__ */ jsx(Badge, {
|
|
1897
|
+
variant: "secondary",
|
|
1898
|
+
className: "px-1.5 py-0 text-[10px] leading-4",
|
|
1899
|
+
children: "My Media"
|
|
1900
|
+
})] }),
|
|
1901
|
+
onClick: () => navigate(`media/${item.id}`),
|
|
1902
|
+
trailing: canEdit && /* @__PURE__ */ jsx(MediaRowActionsMenu, { onDelete: () => setPendingDeleteId(item.id) })
|
|
1819
1903
|
}, item.id);
|
|
1820
1904
|
})
|
|
1821
1905
|
})
|
|
@@ -8934,6 +9018,7 @@ function PlaylistsListingScreen(_props) {
|
|
|
8934
9018
|
const [debouncedSearch, setDebouncedSearch] = useState("");
|
|
8935
9019
|
const [sortValue, setSortValue] = useState("title");
|
|
8936
9020
|
const [ownerFilter, setOwnerFilter] = useState("all");
|
|
9021
|
+
const [viewMode, setViewMode] = useState("grid");
|
|
8937
9022
|
const [selectedIds, setSelectedIds] = useState(/* @__PURE__ */ new Set());
|
|
8938
9023
|
const [pendingDeleteId, setPendingDeleteId] = useState(null);
|
|
8939
9024
|
useEffect(() => {
|
|
@@ -9104,33 +9189,39 @@ function PlaylistsListingScreen(_props) {
|
|
|
9104
9189
|
value: ownerFilter,
|
|
9105
9190
|
onValueChange: setOwnerFilter,
|
|
9106
9191
|
myLabel: "My Playlists"
|
|
9107
|
-
}), /* @__PURE__ */
|
|
9108
|
-
className: "ml-auto
|
|
9109
|
-
children: /* @__PURE__ */ jsx(
|
|
9110
|
-
|
|
9111
|
-
|
|
9112
|
-
|
|
9113
|
-
|
|
9114
|
-
|
|
9115
|
-
|
|
9116
|
-
|
|
9117
|
-
|
|
9118
|
-
|
|
9119
|
-
|
|
9120
|
-
|
|
9121
|
-
|
|
9122
|
-
|
|
9123
|
-
|
|
9124
|
-
|
|
9125
|
-
|
|
9126
|
-
|
|
9127
|
-
|
|
9128
|
-
|
|
9129
|
-
|
|
9130
|
-
|
|
9131
|
-
|
|
9132
|
-
|
|
9133
|
-
|
|
9192
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
9193
|
+
className: "ml-auto flex items-center gap-2",
|
|
9194
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
9195
|
+
className: "w-full max-w-sm",
|
|
9196
|
+
children: /* @__PURE__ */ jsx(SearchSort, {
|
|
9197
|
+
searchValue: searchTerm,
|
|
9198
|
+
onSearchChange: setSearchTerm,
|
|
9199
|
+
placeholder: "Search playlists...",
|
|
9200
|
+
sortOptions: [
|
|
9201
|
+
{
|
|
9202
|
+
label: "Name (A-Z)",
|
|
9203
|
+
value: "title"
|
|
9204
|
+
},
|
|
9205
|
+
{
|
|
9206
|
+
label: "Name (Z-A)",
|
|
9207
|
+
value: "-title"
|
|
9208
|
+
},
|
|
9209
|
+
{
|
|
9210
|
+
label: "Date Created (Newest)",
|
|
9211
|
+
value: "-created_at"
|
|
9212
|
+
},
|
|
9213
|
+
{
|
|
9214
|
+
label: "Date Created (Oldest)",
|
|
9215
|
+
value: "created_at"
|
|
9216
|
+
}
|
|
9217
|
+
],
|
|
9218
|
+
sortValue,
|
|
9219
|
+
onSortChange: setSortValue
|
|
9220
|
+
})
|
|
9221
|
+
}), /* @__PURE__ */ jsx(ViewModeToggle, {
|
|
9222
|
+
value: viewMode,
|
|
9223
|
+
onChange: setViewMode
|
|
9224
|
+
})]
|
|
9134
9225
|
})]
|
|
9135
9226
|
});
|
|
9136
9227
|
const footer = /* @__PURE__ */ jsxs(Fragment$1, { children: [isFetchingNextPage && /* @__PURE__ */ jsx("div", {
|
|
@@ -9152,8 +9243,8 @@ function PlaylistsListingScreen(_props) {
|
|
|
9152
9243
|
}),
|
|
9153
9244
|
footer,
|
|
9154
9245
|
sentinelRef: observerTarget,
|
|
9155
|
-
loadingFilterShape: "search-
|
|
9156
|
-
children: /* @__PURE__ */ jsx("div", {
|
|
9246
|
+
loadingFilterShape: "search-view",
|
|
9247
|
+
children: viewMode === "grid" ? /* @__PURE__ */ jsx("div", {
|
|
9157
9248
|
className: GRID_CLASS,
|
|
9158
9249
|
children: filteredPlaylists.map((playlist) => {
|
|
9159
9250
|
const firstItem = playlist.items?.[0];
|
|
@@ -9175,6 +9266,61 @@ function PlaylistsListingScreen(_props) {
|
|
|
9175
9266
|
onDelete: onDeletePlaylist ? () => setPendingDeleteId(playlist.id) : void 0
|
|
9176
9267
|
}, playlist.id);
|
|
9177
9268
|
})
|
|
9269
|
+
}) : /* @__PURE__ */ jsx("div", {
|
|
9270
|
+
className: SHAREABLE_LIST_CLASS,
|
|
9271
|
+
children: filteredPlaylists.map((playlist) => {
|
|
9272
|
+
const firstItem = playlist.items?.[0];
|
|
9273
|
+
const imageUrl = playlist.image_url ?? firstItem?.image_url ?? firstItem?.relateable?.image_url ?? firstItem?.relateable?.compressed_image_url;
|
|
9274
|
+
const itemCount = playlist.items_count ?? playlist.items?.length ?? 0;
|
|
9275
|
+
const canEdit = !readOnly && playlist.user_id === user?.id;
|
|
9276
|
+
const isSelected = selectedIds.has(playlist.id);
|
|
9277
|
+
const title = playlist.title || "Untitled Playlist";
|
|
9278
|
+
return /* @__PURE__ */ jsx(ShareableListRow, {
|
|
9279
|
+
imageUrl,
|
|
9280
|
+
title,
|
|
9281
|
+
subtitle: /* @__PURE__ */ jsxs(Badge, {
|
|
9282
|
+
variant: "secondary",
|
|
9283
|
+
className: "px-1.5 py-0 text-[10px] leading-4",
|
|
9284
|
+
children: [
|
|
9285
|
+
itemCount,
|
|
9286
|
+
" ",
|
|
9287
|
+
itemCount === 1 ? "item" : "items"
|
|
9288
|
+
]
|
|
9289
|
+
}),
|
|
9290
|
+
onClick: () => navigate(`playlists/${playlist.id}`),
|
|
9291
|
+
leading: /* @__PURE__ */ jsx(Checkbox, {
|
|
9292
|
+
checked: isSelected,
|
|
9293
|
+
onCheckedChange: (checked) => handleToggleSelection(playlist.id, checked === true),
|
|
9294
|
+
"aria-label": `Select ${title}`
|
|
9295
|
+
}),
|
|
9296
|
+
trailing: /* @__PURE__ */ jsxs(Fragment$1, { children: [onToggleFavorite && /* @__PURE__ */ jsx("button", {
|
|
9297
|
+
type: "button",
|
|
9298
|
+
onClick: () => handleFavorite(playlist.id),
|
|
9299
|
+
"aria-label": playlist.is_favorited ? "Unfavorite" : "Favorite",
|
|
9300
|
+
className: "hover:bg-muted-foreground/10 flex h-8 w-8 items-center justify-center rounded-md transition-colors",
|
|
9301
|
+
children: /* @__PURE__ */ jsx(Heart, { className: cn("h-4 w-4 transition-colors", playlist.is_favorited ? "fill-destructive text-destructive" : "text-muted-foreground") })
|
|
9302
|
+
}), canEdit && /* @__PURE__ */ jsxs(DropdownMenu, { children: [/* @__PURE__ */ jsx(DropdownMenuTrigger, {
|
|
9303
|
+
asChild: true,
|
|
9304
|
+
children: /* @__PURE__ */ jsx(Button, {
|
|
9305
|
+
variant: "ghost",
|
|
9306
|
+
size: "sm",
|
|
9307
|
+
className: "h-8 w-8 p-0",
|
|
9308
|
+
"aria-label": "Playlist actions",
|
|
9309
|
+
children: /* @__PURE__ */ jsx(MoreVertical, { className: "h-4 w-4" })
|
|
9310
|
+
})
|
|
9311
|
+
}), /* @__PURE__ */ jsxs(DropdownMenuContent, {
|
|
9312
|
+
align: "end",
|
|
9313
|
+
children: [/* @__PURE__ */ jsxs(DropdownMenuItem, {
|
|
9314
|
+
onClick: () => handleEdit(playlist.id),
|
|
9315
|
+
children: [/* @__PURE__ */ jsx(Pencil, { className: "mr-2 h-4 w-4" }), "Edit"]
|
|
9316
|
+
}), onDeletePlaylist && /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(DropdownMenuSeparator, {}), /* @__PURE__ */ jsxs(DropdownMenuItem, {
|
|
9317
|
+
variant: "destructive",
|
|
9318
|
+
onClick: () => setPendingDeleteId(playlist.id),
|
|
9319
|
+
children: [/* @__PURE__ */ jsx(Trash2, { className: "mr-2 h-4 w-4" }), "Delete"]
|
|
9320
|
+
})] })]
|
|
9321
|
+
})] })] })
|
|
9322
|
+
}, playlist.id);
|
|
9323
|
+
})
|
|
9178
9324
|
})
|
|
9179
9325
|
}), /* @__PURE__ */ jsx(AlertDialog, {
|
|
9180
9326
|
open: pendingDeleteId !== null,
|
|
@@ -10060,6 +10206,7 @@ function SortableTable({ items, setItems, onDeleteItem, isDeletePending, enableR
|
|
|
10060
10206
|
}
|
|
10061
10207
|
//#endregion
|
|
10062
10208
|
//#region ../../shareables/ui/src/components/playlists/form/PlaylistItemsSection.tsx
|
|
10209
|
+
const REORDER_DEBOUNCE_MS = 500;
|
|
10063
10210
|
const PLAYLIST_CONTENT_TYPES = new Set([
|
|
10064
10211
|
"Medium",
|
|
10065
10212
|
"Page",
|
|
@@ -10129,9 +10276,53 @@ function PlaylistItemsSection({ playlistId }) {
|
|
|
10129
10276
|
});
|
|
10130
10277
|
}
|
|
10131
10278
|
});
|
|
10279
|
+
const reorderItemsMutation = useReorderPlaylistItemsMutation();
|
|
10280
|
+
const reorderTimerRef = useRef(null);
|
|
10281
|
+
const reorderRollbackRef = useRef(null);
|
|
10282
|
+
useEffect(() => () => {
|
|
10283
|
+
if (reorderTimerRef.current) clearTimeout(reorderTimerRef.current);
|
|
10284
|
+
}, []);
|
|
10285
|
+
const canPersistReorder = !!api.playlists.reorderPlaylistItems;
|
|
10132
10286
|
const mergeAndOrder = useCallback((reorderedContent) => {
|
|
10133
|
-
|
|
10134
|
-
|
|
10287
|
+
const ordered = computeOrderedItems([...reorderedContent, ...tailItems]);
|
|
10288
|
+
if (playlistId && canPersistReorder && reorderTimerRef.current === null && reorderRollbackRef.current === null) reorderRollbackRef.current = tableItems;
|
|
10289
|
+
updateItems(ordered);
|
|
10290
|
+
if (!playlistId || !canPersistReorder) return;
|
|
10291
|
+
if (reorderTimerRef.current) clearTimeout(reorderTimerRef.current);
|
|
10292
|
+
reorderTimerRef.current = setTimeout(() => {
|
|
10293
|
+
reorderTimerRef.current = null;
|
|
10294
|
+
const rollback = reorderRollbackRef.current;
|
|
10295
|
+
reorderItemsMutation.mutate({
|
|
10296
|
+
playlistId,
|
|
10297
|
+
data: { items: ordered.filter((item) => Number.isInteger(item.id) && typeof item.order === "number").map((item) => ({
|
|
10298
|
+
id: item.id,
|
|
10299
|
+
order: item.order
|
|
10300
|
+
})) }
|
|
10301
|
+
}, {
|
|
10302
|
+
onSuccess: () => {
|
|
10303
|
+
if (reorderTimerRef.current === null) reorderRollbackRef.current = null;
|
|
10304
|
+
else reorderRollbackRef.current = ordered;
|
|
10305
|
+
},
|
|
10306
|
+
onError: (error) => {
|
|
10307
|
+
if (rollback) updateItems(rollback);
|
|
10308
|
+
reorderRollbackRef.current = null;
|
|
10309
|
+
showToast({
|
|
10310
|
+
title: "Failed to save new item order",
|
|
10311
|
+
type: "error",
|
|
10312
|
+
error
|
|
10313
|
+
});
|
|
10314
|
+
}
|
|
10315
|
+
});
|
|
10316
|
+
}, REORDER_DEBOUNCE_MS);
|
|
10317
|
+
}, [
|
|
10318
|
+
tailItems,
|
|
10319
|
+
tableItems,
|
|
10320
|
+
updateItems,
|
|
10321
|
+
playlistId,
|
|
10322
|
+
canPersistReorder,
|
|
10323
|
+
reorderItemsMutation.mutate,
|
|
10324
|
+
showToast
|
|
10325
|
+
]);
|
|
10135
10326
|
const handleDeleteItem = (itemId) => {
|
|
10136
10327
|
removeItem(itemId);
|
|
10137
10328
|
if (playlistId) removeItemMutation.mutate({
|
|
@@ -10187,13 +10378,7 @@ function PlaylistItemsSection({ playlistId }) {
|
|
|
10187
10378
|
type: "success"
|
|
10188
10379
|
});
|
|
10189
10380
|
} catch {}
|
|
10190
|
-
else
|
|
10191
|
-
addItem(newItem);
|
|
10192
|
-
showToast({
|
|
10193
|
-
title: "Item added. Save the playlist to persist these items.",
|
|
10194
|
-
type: "warning"
|
|
10195
|
-
});
|
|
10196
|
-
}
|
|
10381
|
+
else addItem(newItem);
|
|
10197
10382
|
}
|
|
10198
10383
|
};
|
|
10199
10384
|
const filePickerContextValue = useMemo(() => {
|
|
@@ -10795,31 +10980,6 @@ function ShareablesApp({ screen, detailId, action, onNavigate, onBack, countryCo
|
|
|
10795
10980
|
return content;
|
|
10796
10981
|
}
|
|
10797
10982
|
//#endregion
|
|
10798
|
-
//#region ../../shareables/ui/src/components/ProductsApp.tsx
|
|
10799
|
-
function ProductsApp({ countryCode, companyLogoUrl, fetchProducts, fetchProduct, productId: controlledProductId, onSelectProduct: onSelectProductProp, onBack: onBackProp }) {
|
|
10800
|
-
const [internalProductId, setInternalProductId] = useState(null);
|
|
10801
|
-
const activeProductId = controlledProductId !== void 0 ? controlledProductId : internalProductId;
|
|
10802
|
-
const handleSelectProduct = onSelectProductProp ?? setInternalProductId;
|
|
10803
|
-
const handleBack = onBackProp ?? (() => setInternalProductId(null));
|
|
10804
|
-
const handleNavigate = (screen, detailId) => {
|
|
10805
|
-
if (screen === "products" && detailId) handleSelectProduct(detailId);
|
|
10806
|
-
};
|
|
10807
|
-
if (activeProductId) return /* @__PURE__ */ jsx(ProductDetailScreen, {
|
|
10808
|
-
productId: activeProductId,
|
|
10809
|
-
countryCode,
|
|
10810
|
-
fetchProduct,
|
|
10811
|
-
onNavigate: handleNavigate,
|
|
10812
|
-
onBack: handleBack
|
|
10813
|
-
});
|
|
10814
|
-
return /* @__PURE__ */ jsx(ProductsScreen, {
|
|
10815
|
-
countryCode,
|
|
10816
|
-
fetchProducts,
|
|
10817
|
-
onNavigate: (screen, detailId) => {
|
|
10818
|
-
if (detailId) handleSelectProduct(detailId);
|
|
10819
|
-
}
|
|
10820
|
-
});
|
|
10821
|
-
}
|
|
10822
|
-
//#endregion
|
|
10823
10983
|
//#region ../../file-picker/api-client/src/api/url-proxy.ts
|
|
10824
10984
|
const urlProxyResponseSchema = z.object({
|
|
10825
10985
|
data: z.string(),
|
|
@@ -11485,6 +11645,9 @@ function createPlaylistsAdapter(client) {
|
|
|
11485
11645
|
items: [],
|
|
11486
11646
|
items_count: 0
|
|
11487
11647
|
};
|
|
11648
|
+
},
|
|
11649
|
+
reorderPlaylistItems: async (playlistId, data) => {
|
|
11650
|
+
await playlists_items_reorder(client, playlistId, { items: data.items });
|
|
11488
11651
|
}
|
|
11489
11652
|
};
|
|
11490
11653
|
}
|
|
@@ -11851,6 +12014,184 @@ function PortalContentApiProvider({ children }) {
|
|
|
11851
12014
|
});
|
|
11852
12015
|
}
|
|
11853
12016
|
//#endregion
|
|
11854
|
-
|
|
12017
|
+
//#region src/screens/ShareablesScreen.tsx
|
|
12018
|
+
var ShareablesScreen_exports = /* @__PURE__ */ __exportAll({
|
|
12019
|
+
ShareablesScreen: () => ShareablesScreen,
|
|
12020
|
+
shareablesScreenPropertySchema: () => shareablesScreenPropertySchema
|
|
12021
|
+
});
|
|
12022
|
+
/**
|
|
12023
|
+
* Parse the current shareables sub-route from the full slug.
|
|
12024
|
+
*
|
|
12025
|
+
* System nav slugs are "share/products", "share/media", "share/playlists".
|
|
12026
|
+
* Detail pages append an ID: "share/products/123", "share/media/456".
|
|
12027
|
+
*
|
|
12028
|
+
* "share/products" → screen="products", detailId=null
|
|
12029
|
+
* "share/products/123" → screen="products", detailId="123"
|
|
12030
|
+
* "share/media/456" → screen="media", detailId="456"
|
|
12031
|
+
* "share/playlists" → screen="playlists", detailId=null
|
|
12032
|
+
* "share/playlists/789" → screen="playlists", detailId="789"
|
|
12033
|
+
* "share/files" → screen="files", detailId=null
|
|
12034
|
+
* "share" → screen=null (default to products)
|
|
12035
|
+
*/
|
|
12036
|
+
function parseShareablesRoute(currentSlug) {
|
|
12037
|
+
const slugWithoutPrefix = currentSlug.replace(/^share\/?/, "");
|
|
12038
|
+
if (!slugWithoutPrefix) return {
|
|
12039
|
+
screen: null,
|
|
12040
|
+
detailId: null,
|
|
12041
|
+
action: null
|
|
12042
|
+
};
|
|
12043
|
+
const parts = slugWithoutPrefix.split("/");
|
|
12044
|
+
return {
|
|
12045
|
+
screen: parts[0] || null,
|
|
12046
|
+
detailId: parts[1] || null,
|
|
12047
|
+
action: parts[2] || null
|
|
12048
|
+
};
|
|
12049
|
+
}
|
|
12050
|
+
function ShareablesScreen({ background, textColor, accentColor, padding, borderRadius, ...divProps }) {
|
|
12051
|
+
return /* @__PURE__ */ jsx("div", {
|
|
12052
|
+
...divProps,
|
|
12053
|
+
className: `h-full ${divProps.className ?? ""}`,
|
|
12054
|
+
children: /* @__PURE__ */ jsx(PortalProductsApiProvider, { children: /* @__PURE__ */ jsx(PortalContentApiProvider, { children: /* @__PURE__ */ jsx(ShareablesScreenContent, {}) }) })
|
|
12055
|
+
});
|
|
12056
|
+
}
|
|
12057
|
+
/** Inner component rendered inside providers so hooks can access context. */
|
|
12058
|
+
function ShareablesScreenContent() {
|
|
12059
|
+
const shareablesCtx = usePortalContentContext();
|
|
12060
|
+
const { productsApi: portalProductsApi } = shareablesCtx;
|
|
12061
|
+
const filePickerApi = useFilePickerApi();
|
|
12062
|
+
const { data: account } = useAccount();
|
|
12063
|
+
const { data: store } = useStore();
|
|
12064
|
+
const { currentSlug, navigate } = useAppNavigation();
|
|
12065
|
+
const isCustomer = account?.member_type === "customer";
|
|
12066
|
+
const client = usePortalTenantClient();
|
|
12067
|
+
const queryClient = useQueryClient();
|
|
12068
|
+
const fetchProducts = useCallback(async (search, cursor, limit, sort) => {
|
|
12069
|
+
if (search) return portalProductsApi.searchProducts(search, {
|
|
12070
|
+
cursor,
|
|
12071
|
+
limit
|
|
12072
|
+
});
|
|
12073
|
+
return portalProductsApi.listProducts({
|
|
12074
|
+
cursor,
|
|
12075
|
+
limit,
|
|
12076
|
+
sort
|
|
12077
|
+
});
|
|
12078
|
+
}, [portalProductsApi]);
|
|
12079
|
+
const fetchProduct = useCallback(async (id) => portalProductsApi.getProduct(id), [portalProductsApi]);
|
|
12080
|
+
const { screen, detailId, action } = parseShareablesRoute(currentSlug);
|
|
12081
|
+
const handleNavigate = useCallback((subScreen, id) => {
|
|
12082
|
+
navigate(id ? `share/${subScreen}/${id}` : `share/${subScreen}`);
|
|
12083
|
+
}, [navigate]);
|
|
12084
|
+
const handleBack = useCallback(() => {
|
|
12085
|
+
if (detailId && screen) navigate(`share/${screen}`);
|
|
12086
|
+
else navigate("share/products");
|
|
12087
|
+
}, [
|
|
12088
|
+
navigate,
|
|
12089
|
+
detailId,
|
|
12090
|
+
screen
|
|
12091
|
+
]);
|
|
12092
|
+
return /* @__PURE__ */ jsx(ShareablesCoreProvider, {
|
|
12093
|
+
config: useMemo(() => ({
|
|
12094
|
+
user: account ? { id: account.id } : null,
|
|
12095
|
+
repContext: true
|
|
12096
|
+
}), [account]),
|
|
12097
|
+
children: /* @__PURE__ */ jsx(ShareablesUIProvider, {
|
|
12098
|
+
config: useMemo(() => ({
|
|
12099
|
+
user: account ? {
|
|
12100
|
+
id: account.id,
|
|
12101
|
+
company: { logo_url: store?.logo_url ?? null }
|
|
12102
|
+
} : void 0,
|
|
12103
|
+
affiliateId: null,
|
|
12104
|
+
basePath: "",
|
|
12105
|
+
navigate: (path) => {
|
|
12106
|
+
const cleanPath = path.replace(/^\//, "");
|
|
12107
|
+
navigate(cleanPath.startsWith("share/") ? cleanPath : `share/${cleanPath}`);
|
|
12108
|
+
},
|
|
12109
|
+
showToast: (opts) => {
|
|
12110
|
+
fluidToast({
|
|
12111
|
+
title: opts.title,
|
|
12112
|
+
type: opts.type
|
|
12113
|
+
});
|
|
12114
|
+
if (opts.error) console.error("[Shareables]", opts.error);
|
|
12115
|
+
},
|
|
12116
|
+
filePickerApi,
|
|
12117
|
+
onToggleFavorite: async (params) => {
|
|
12118
|
+
const result = await toggleFavorite(client, params.favoriteableId, params.favoriteableType);
|
|
12119
|
+
queryClient.invalidateQueries({ queryKey: PORTAL_MYSITE_KEYS.favorites() });
|
|
12120
|
+
return result;
|
|
12121
|
+
},
|
|
12122
|
+
onMySiteShare: async (params) => {
|
|
12123
|
+
await toggleFavorite(client, params.relateable_id, params.relateable_type);
|
|
12124
|
+
queryClient.invalidateQueries({ queryKey: PORTAL_MYSITE_KEYS.favorites() });
|
|
12125
|
+
},
|
|
12126
|
+
onDeletePlaylist: isCustomer ? void 0 : async (playlistId) => {
|
|
12127
|
+
await shareablesCtx.playlistsAdapter.deletePlaylist(playlistId);
|
|
12128
|
+
},
|
|
12129
|
+
mediaProductsApi: isCustomer ? void 0 : shareablesCtx.mediaProductsAdapter,
|
|
12130
|
+
searchProducts: isCustomer ? void 0 : async (query, options) => {
|
|
12131
|
+
const limit = options?.limit ?? 25;
|
|
12132
|
+
const cursor = options?.cursor ?? void 0;
|
|
12133
|
+
const result = query.trim().length > 0 ? await portalProductsApi.searchProducts(query, {
|
|
12134
|
+
cursor,
|
|
12135
|
+
limit
|
|
12136
|
+
}) : await portalProductsApi.listProducts({
|
|
12137
|
+
cursor,
|
|
12138
|
+
limit
|
|
12139
|
+
});
|
|
12140
|
+
return {
|
|
12141
|
+
products: (result.products ?? []).map((p) => p.id != null ? {
|
|
12142
|
+
id: p.id,
|
|
12143
|
+
name: p.name ?? p.title ?? "Untitled",
|
|
12144
|
+
image_url: p.image_url ?? null,
|
|
12145
|
+
price: p.price ?? null
|
|
12146
|
+
} : null).filter((p) => p !== null),
|
|
12147
|
+
nextCursor: result.meta?.pagination?.next_cursor ?? null
|
|
12148
|
+
};
|
|
12149
|
+
},
|
|
12150
|
+
readOnly: isCustomer,
|
|
12151
|
+
uploadThumbnail: isCustomer ? void 0 : async (blob, filename) => {
|
|
12152
|
+
const formData = new FormData();
|
|
12153
|
+
formData.append("asset[name]", filename);
|
|
12154
|
+
formData.append("asset[file]", blob, filename);
|
|
12155
|
+
const url = (await client.requestWithFormData("/api/content/dam/assets", formData)).asset?.default_variant_url;
|
|
12156
|
+
if (!url) throw new Error("Thumbnail upload succeeded but no URL returned");
|
|
12157
|
+
return url;
|
|
12158
|
+
}
|
|
12159
|
+
}), [
|
|
12160
|
+
account,
|
|
12161
|
+
store,
|
|
12162
|
+
navigate,
|
|
12163
|
+
filePickerApi,
|
|
12164
|
+
isCustomer,
|
|
12165
|
+
shareablesCtx.playlistsAdapter,
|
|
12166
|
+
shareablesCtx.mediaProductsAdapter,
|
|
12167
|
+
portalProductsApi,
|
|
12168
|
+
client,
|
|
12169
|
+
queryClient
|
|
12170
|
+
]),
|
|
12171
|
+
children: /* @__PURE__ */ jsx(ShareablesApp, {
|
|
12172
|
+
screen,
|
|
12173
|
+
detailId,
|
|
12174
|
+
action,
|
|
12175
|
+
companyLogoUrl: void 0,
|
|
12176
|
+
countryCode: void 0,
|
|
12177
|
+
fetchProducts,
|
|
12178
|
+
fetchProduct,
|
|
12179
|
+
onNavigate: handleNavigate,
|
|
12180
|
+
onBack: handleBack
|
|
12181
|
+
})
|
|
12182
|
+
})
|
|
12183
|
+
});
|
|
12184
|
+
}
|
|
12185
|
+
const shareablesScreenPropertySchema = {
|
|
12186
|
+
widgetType: "ShareablesScreen",
|
|
12187
|
+
displayName: "Shareables Screen",
|
|
12188
|
+
tabsConfig: [{
|
|
12189
|
+
id: "styling",
|
|
12190
|
+
label: "Styling"
|
|
12191
|
+
}],
|
|
12192
|
+
fields: []
|
|
12193
|
+
};
|
|
12194
|
+
//#endregion
|
|
12195
|
+
export { ShareablesScreen_exports as n, shareablesScreenPropertySchema as r, ShareablesScreen as t };
|
|
11855
12196
|
|
|
11856
|
-
//# sourceMappingURL=
|
|
12197
|
+
//# sourceMappingURL=ShareablesScreen-DV2nikzp.mjs.map
|