@fluid-app/portal-sdk 0.1.199 → 0.1.201

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 (81) hide show
  1. package/dist/{ContactsScreen-DvohvoOE.cjs → ContactsScreen-BQ6pvYOa.cjs} +291 -281
  2. package/dist/ContactsScreen-BQ6pvYOa.cjs.map +1 -0
  3. package/dist/{ContactsScreen-Cheiwaxn.cjs → ContactsScreen-Bw2GcYtk.cjs} +2 -2
  4. package/dist/{ContactsScreen-BtBNMZzG.mjs → ContactsScreen-BzRFTCBS.mjs} +17 -7
  5. package/dist/ContactsScreen-BzRFTCBS.mjs.map +1 -0
  6. package/dist/{FluidProvider-D177ez3m.cjs → FluidProvider-BRkRo8Wl.cjs} +12 -992
  7. package/dist/FluidProvider-BRkRo8Wl.cjs.map +1 -0
  8. package/dist/{FluidProvider-DiJy4Zve.mjs → FluidProvider-BTZAiT69.mjs} +9 -820
  9. package/dist/FluidProvider-BTZAiT69.mjs.map +1 -0
  10. package/dist/{MessagingScreen-Cu3tcpPs.mjs → MessagingScreen-Bk3Eh1dN.mjs} +2 -2
  11. package/dist/{MessagingScreen-Cu3tcpPs.mjs.map → MessagingScreen-Bk3Eh1dN.mjs.map} +1 -1
  12. package/dist/{MessagingScreen-Ysi48svi.cjs → MessagingScreen-DN2eQRxF.cjs} +6 -6
  13. package/dist/{MessagingScreen-gKidMcrr.cjs → MessagingScreen-DtDbS3VZ.cjs} +2 -2
  14. package/dist/{MessagingScreen-gKidMcrr.cjs.map → MessagingScreen-DtDbS3VZ.cjs.map} +1 -1
  15. package/dist/{PortalContentApiProvider-CPnqELEX.cjs → PortalContentApiProvider-BDbrZCyI.cjs} +115 -89
  16. package/dist/PortalContentApiProvider-BDbrZCyI.cjs.map +1 -0
  17. package/dist/{PortalContentApiProvider-CWRAw9kL.mjs → PortalContentApiProvider-CzLqEN5C.mjs} +116 -90
  18. package/dist/PortalContentApiProvider-CzLqEN5C.mjs.map +1 -0
  19. package/dist/{ProductsScreen-CQ5-A8AL.cjs → ProductsScreen-68jB202M.cjs} +2 -2
  20. package/dist/{ProductsScreen-CQ5-A8AL.cjs.map → ProductsScreen-68jB202M.cjs.map} +1 -1
  21. package/dist/{ProductsScreen-CexZ0gx9.mjs → ProductsScreen-BeNUsjh1.mjs} +2 -2
  22. package/dist/{ProductsScreen-Al6H4ujs.mjs → ProductsScreen-BidL3ZF5.mjs} +2 -2
  23. package/dist/{ProductsScreen-Al6H4ujs.mjs.map → ProductsScreen-BidL3ZF5.mjs.map} +1 -1
  24. package/dist/{ProductsScreen-BnwMOZ4-.cjs → ProductsScreen-Bq0f4pQL.cjs} +2 -2
  25. package/dist/{ProfileScreen-CGS7YkcT.cjs → ProfileScreen-BMNq0NEB.cjs} +6 -6
  26. package/dist/{ProfileScreen-hE1S_99P.mjs → ProfileScreen-D-pTegtY.mjs} +3 -3
  27. package/dist/{ProfileScreen-hE1S_99P.mjs.map → ProfileScreen-D-pTegtY.mjs.map} +1 -1
  28. package/dist/{ProfileScreen-DJZoMzE6.cjs → ProfileScreen-D5OxmzhM.cjs} +101 -101
  29. package/dist/{ProfileScreen-DJZoMzE6.cjs.map → ProfileScreen-D5OxmzhM.cjs.map} +1 -1
  30. package/dist/{QuickShareWidget-0GD4KWAr.cjs → QuickShareWidget-C_p3tPs5.cjs} +2 -2
  31. package/dist/QuickShareWidget-C_p3tPs5.cjs.map +1 -0
  32. package/dist/{QuickShareWidget-DZzrQjOx.mjs → QuickShareWidget-xKcV3ZQ5.mjs} +2 -2
  33. package/dist/QuickShareWidget-xKcV3ZQ5.mjs.map +1 -0
  34. package/dist/{ShareablesScreen-CzTU7e0l.mjs → ShareablesScreen-BRfgOnpL.mjs} +2 -2
  35. package/dist/{ShareablesScreen-CzTU7e0l.mjs.map → ShareablesScreen-BRfgOnpL.mjs.map} +1 -1
  36. package/dist/{ShareablesScreen-DujtMoAi.cjs → ShareablesScreen-BYP65ZnU.cjs} +2 -2
  37. package/dist/{ShareablesScreen-CmZ5CX99.cjs → ShareablesScreen-CCqADUXE.cjs} +2 -2
  38. package/dist/{ShareablesScreen-CmZ5CX99.cjs.map → ShareablesScreen-CCqADUXE.cjs.map} +1 -1
  39. package/dist/{ShareablesScreen-yscAsNpq.mjs → ShareablesScreen-YnNF0dD6.mjs} +2 -2
  40. package/dist/{ShopScreen-Bdo59te-.mjs → ShopScreen-BOJGcSyG.mjs} +3 -3
  41. package/dist/{ShopScreen-Bdo59te-.mjs.map → ShopScreen-BOJGcSyG.mjs.map} +1 -1
  42. package/dist/{ShopScreen-R9zk7d5d.cjs → ShopScreen-BzyBZ24D.cjs} +6 -6
  43. package/dist/{ShopScreen-DKlDKNom.cjs → ShopScreen-DeLp93hN.cjs} +3 -3
  44. package/dist/{ShopScreen-DKlDKNom.cjs.map → ShopScreen-DeLp93hN.cjs.map} +1 -1
  45. package/dist/{SpacerWidget-Da_sNa_X.mjs → SpacerWidget-BJFO-Xyh.mjs} +2 -2
  46. package/dist/SpacerWidget-BJFO-Xyh.mjs.map +1 -0
  47. package/dist/{SpacerWidget-CLFbkgoz.cjs → SpacerWidget-D9lOLPr5.cjs} +2 -2
  48. package/dist/SpacerWidget-D9lOLPr5.cjs.map +1 -0
  49. package/dist/{TableWidget-lKjTu7Go.cjs → TableWidget-C7qiWZc3.cjs} +1 -1
  50. package/dist/{TableWidget-B65hwjKS.mjs → TableWidget-DRByd9ig.mjs} +9 -9
  51. package/dist/TableWidget-DRByd9ig.mjs.map +1 -0
  52. package/dist/{TableWidget-FDbnEYZb.cjs → TableWidget-DUnz9hrD.cjs} +9 -9
  53. package/dist/TableWidget-DUnz9hrD.cjs.map +1 -0
  54. package/dist/index.cjs +68 -70
  55. package/dist/index.cjs.map +1 -1
  56. package/dist/index.d.cts +126 -133
  57. package/dist/index.d.cts.map +1 -1
  58. package/dist/index.d.mts +126 -133
  59. package/dist/index.d.mts.map +1 -1
  60. package/dist/index.mjs +25 -25
  61. package/dist/src-BNcNh8fM.cjs +963 -0
  62. package/dist/src-BNcNh8fM.cjs.map +1 -0
  63. package/dist/src-BjCPR0aG.mjs +788 -0
  64. package/dist/src-BjCPR0aG.mjs.map +1 -0
  65. package/package.json +16 -16
  66. package/dist/ContactsScreen-BtBNMZzG.mjs.map +0 -1
  67. package/dist/ContactsScreen-DvohvoOE.cjs.map +0 -1
  68. package/dist/FluidProvider-D177ez3m.cjs.map +0 -1
  69. package/dist/FluidProvider-DiJy4Zve.mjs.map +0 -1
  70. package/dist/PortalContentApiProvider-CPnqELEX.cjs.map +0 -1
  71. package/dist/PortalContentApiProvider-CWRAw9kL.mjs.map +0 -1
  72. package/dist/QuickShareWidget-0GD4KWAr.cjs.map +0 -1
  73. package/dist/QuickShareWidget-DZzrQjOx.mjs.map +0 -1
  74. package/dist/SpacerWidget-CLFbkgoz.cjs.map +0 -1
  75. package/dist/SpacerWidget-Da_sNa_X.mjs.map +0 -1
  76. package/dist/TableWidget-B65hwjKS.mjs.map +0 -1
  77. package/dist/TableWidget-FDbnEYZb.cjs.map +0 -1
  78. package/dist/countries-api-context-Dob_AzPO.mjs +0 -13
  79. package/dist/countries-api-context-Dob_AzPO.mjs.map +0 -1
  80. package/dist/countries-api-context-G-NW4BoH.cjs +0 -25
  81. package/dist/countries-api-context-G-NW4BoH.cjs.map +0 -1
@@ -619,7 +619,7 @@ function ProductsScreen({ countryCode, fetchProducts: fetchPortalProducts, onNav
619
619
  }, [handleIntersect]);
620
620
  const products = (0, react.useMemo)(() => {
621
621
  if (!data) return [];
622
- if (usePortal) return data?.pages.flatMap((page) => page.products.map((p) => ({
622
+ if (usePortal) return data?.pages.flatMap((page) => (page.products ?? []).map((p) => ({
623
623
  id: p.id ?? 0,
624
624
  title: p.name ?? "",
625
625
  image_url: p.images?.[0]?.url ?? null,
@@ -8939,6 +8939,7 @@ function PlaylistsListingScreen(_props) {
8939
8939
  const [sortValue, setSortValue] = (0, react.useState)("title");
8940
8940
  const [ownerFilter, setOwnerFilter] = (0, react.useState)("all");
8941
8941
  const [selectedIds, setSelectedIds] = (0, react.useState)(/* @__PURE__ */ new Set());
8942
+ const [pendingDeleteId, setPendingDeleteId] = (0, react.useState)(null);
8942
8943
  (0, react.useEffect)(() => {
8943
8944
  setSelectedIds(/* @__PURE__ */ new Set());
8944
8945
  }, [ownerFilter]);
@@ -9070,27 +9071,31 @@ function PlaylistsListingScreen(_props) {
9070
9071
  const handleEdit = (0, react.useCallback)((playlistId) => {
9071
9072
  navigate(`playlists/${playlistId}/edit`);
9072
9073
  }, [navigate]);
9073
- const handleDelete = (0, react.useCallback)(async (playlistId) => {
9074
- if (!onDeletePlaylist) return;
9075
- if (!window.confirm("Are you sure you want to delete this playlist?")) return;
9076
- try {
9077
- await onDeletePlaylist(playlistId);
9074
+ const { mutate: deletePlaylist, isPending: isDeleting } = (0, _tanstack_react_query.useMutation)({
9075
+ mutationFn: (playlistId) => {
9076
+ if (!onDeletePlaylist) return Promise.reject(/* @__PURE__ */ new Error("Delete not available"));
9077
+ return onDeletePlaylist(playlistId);
9078
+ },
9079
+ onSuccess: () => {
9078
9080
  queryClient.invalidateQueries({ queryKey: shareablesKeys.playlists.all });
9079
9081
  showToast({
9080
9082
  title: "Playlist deleted",
9081
9083
  type: "success"
9082
9084
  });
9083
- } catch {
9085
+ setPendingDeleteId(null);
9086
+ },
9087
+ onError: (error) => {
9084
9088
  showToast({
9085
9089
  title: "Failed to delete playlist",
9086
- type: "error"
9090
+ type: "error",
9091
+ error
9087
9092
  });
9093
+ setPendingDeleteId(null);
9088
9094
  }
9089
- }, [
9090
- onDeletePlaylist,
9091
- queryClient,
9092
- showToast
9093
- ]);
9095
+ });
9096
+ const confirmDelete = (0, react.useCallback)(() => {
9097
+ if (pendingDeleteId != null) deletePlaylist(pendingDeleteId);
9098
+ }, [pendingDeleteId, deletePlaylist]);
9094
9099
  if (isLoading) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
9095
9100
  className: "space-y-6 px-4 py-4 md:px-10 md:py-6",
9096
9101
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
@@ -9178,7 +9183,7 @@ function PlaylistsListingScreen(_props) {
9178
9183
  onSelectionChange: (selected) => handleToggleSelection(playlist.id, selected),
9179
9184
  onToggleFavorite: onToggleFavorite ? () => handleFavorite(playlist.id) : void 0,
9180
9185
  onEdit: () => handleEdit(playlist.id),
9181
- onDelete: onDeletePlaylist ? () => void handleDelete(playlist.id) : void 0
9186
+ onDelete: onDeletePlaylist ? () => setPendingDeleteId(playlist.id) : void 0
9182
9187
  }, playlist.id);
9183
9188
  })
9184
9189
  }),
@@ -9193,6 +9198,24 @@ function PlaylistsListingScreen(_props) {
9193
9198
  error && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
9194
9199
  className: "bg-destructive/10 text-destructive rounded-lg px-3 py-2",
9195
9200
  children: ["Error: ", error.message]
9201
+ }),
9202
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.AlertDialog, {
9203
+ open: pendingDeleteId !== null,
9204
+ onOpenChange: (open) => {
9205
+ if (!open && !isDeleting) setPendingDeleteId(null);
9206
+ },
9207
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.AlertDialogContent, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.AlertDialogHeader, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.AlertDialogTitle, { children: "Delete this playlist?" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.AlertDialogDescription, { children: "This removes the playlist from your library. Shared links that point to it will stop working." })] }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.AlertDialogFooter, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.AlertDialogCancel, {
9208
+ disabled: isDeleting,
9209
+ children: "Cancel"
9210
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.AlertDialogAction, {
9211
+ onClick: (e) => {
9212
+ e.preventDefault();
9213
+ confirmDelete();
9214
+ },
9215
+ disabled: isDeleting,
9216
+ className: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
9217
+ children: isDeleting ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Spinner, { className: "size-4" }) : "Delete"
9218
+ })] })] })
9196
9219
  })
9197
9220
  ]
9198
9221
  });
@@ -9278,7 +9301,7 @@ function TaggedProductsList({ products, onProductClick }) {
9278
9301
  const displayPrice = resolvePrice(product);
9279
9302
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
9280
9303
  onClick: (e) => handleProductClick(product.id, e),
9281
- className: "group bg-muted hover:bg-muted-600 flex w-[168px] shrink-0 flex-col gap-2 rounded-lg p-3 text-left transition-all",
9304
+ className: "group bg-muted hover:bg-muted/60 flex w-[168px] shrink-0 flex-col gap-2 rounded-lg p-3 text-left transition-all",
9282
9305
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
9283
9306
  className: "bg-background relative h-[168px] w-full overflow-hidden rounded-lg",
9284
9307
  children: renderImage({
@@ -9380,7 +9403,7 @@ function PlaylistItemsList({ items, onSelectItem, selectedItemIndex = 0, onNavig
9380
9403
  const fileType = getFileType(item.media_format ?? relateable?.media_format, item.image_url ?? relateable?.image_url);
9381
9404
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
9382
9405
  onClick: () => handleCardClick(index),
9383
- className: `hover:bg-muted-600 flex w-full cursor-pointer items-start gap-3 rounded-lg p-3 text-left transition-all ${index === selectedItemIndex ? "bg-muted-600" : "bg-muted"}`,
9406
+ className: `hover:bg-muted/60 flex w-full cursor-pointer items-start gap-3 rounded-lg p-3 text-left transition-all ${index === selectedItemIndex ? "bg-muted/60" : "bg-muted"}`,
9384
9407
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
9385
9408
  className: "bg-background relative h-[104px] w-[104px] shrink-0 overflow-hidden rounded-lg",
9386
9409
  children: [renderImage({
@@ -9460,11 +9483,9 @@ function PlaylistItemsList({ items, onSelectItem, selectedItemIndex = 0, onNavig
9460
9483
  const DEFAULT_IMAGE$1 = "https://assets.fluid.app/fluid-admin/images/we-commerce/we-commerce.png";
9461
9484
  function PlaylistDetailScreen({ playlistId, onNavigate }) {
9462
9485
  const api = useShareablesApi();
9463
- const { navigate, showToast, onDeletePlaylist, user, readOnly } = useShareablesUI();
9486
+ const { navigate, user, readOnly } = useShareablesUI();
9464
9487
  const [isDescriptionExpanded, setIsDescriptionExpanded] = (0, react.useState)(false);
9465
9488
  const [selectedPlaylistItemIndex, setSelectedPlaylistItemIndex] = (0, react.useState)(0);
9466
- const [isDeleteOpen, setIsDeleteOpen] = (0, react.useState)(false);
9467
- const [isDeleting, setIsDeleting] = (0, react.useState)(false);
9468
9489
  const { data: playlistResponse, isLoading } = (0, _tanstack_react_query.useQuery)({
9469
9490
  queryKey: shareablesKeys.playlists.detail(Number(playlistId)),
9470
9491
  queryFn: () => api.playlists.getPlaylistById(Number(playlistId))
@@ -9475,25 +9496,19 @@ function PlaylistDetailScreen({ playlistId, onNavigate }) {
9475
9496
  const displayTitle = playlist?.title || "";
9476
9497
  require_ScreenHeaderContext.useScreenHeaderActions((0, react.useMemo)(() => {
9477
9498
  if (!canEdit) return null;
9478
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
9499
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
9479
9500
  className: "flex items-center gap-2",
9480
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.Button, {
9501
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.Button, {
9481
9502
  variant: "outline",
9482
9503
  size: "sm",
9483
9504
  onClick: () => navigate(`playlists/${playlistId}/edit`),
9484
9505
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Pencil, { className: "mr-1 h-3.5 w-3.5" }), "Edit"]
9485
- }), onDeletePlaylist && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.Button, {
9486
- variant: "destructive",
9487
- size: "sm",
9488
- onClick: () => setIsDeleteOpen(true),
9489
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Trash2, { className: "mr-1 h-3.5 w-3.5" }), "Delete"]
9490
- })]
9506
+ })
9491
9507
  });
9492
9508
  }, [
9493
9509
  canEdit,
9494
9510
  navigate,
9495
- playlistId,
9496
- onDeletePlaylist
9511
+ playlistId
9497
9512
  ]));
9498
9513
  require_ScreenHeaderContext.useScreenHeaderBreadcrumbs((0, react.useMemo)(() => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Breadcrumb, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.BreadcrumbList, {
9499
9514
  className: "text-lg",
@@ -9513,31 +9528,6 @@ function PlaylistDetailScreen({ playlistId, onNavigate }) {
9513
9528
  }) })
9514
9529
  ]
9515
9530
  }) }), [displayTitle, navigate]));
9516
- const handleDelete = (0, react.useCallback)(async () => {
9517
- if (!onDeletePlaylist) return;
9518
- setIsDeleting(true);
9519
- try {
9520
- await onDeletePlaylist(Number(playlistId));
9521
- showToast({
9522
- title: "Playlist deleted successfully",
9523
- type: "success"
9524
- });
9525
- navigate("playlists");
9526
- } catch {
9527
- showToast({
9528
- title: "Failed to delete playlist",
9529
- type: "error"
9530
- });
9531
- } finally {
9532
- setIsDeleting(false);
9533
- setIsDeleteOpen(false);
9534
- }
9535
- }, [
9536
- onDeletePlaylist,
9537
- playlistId,
9538
- showToast,
9539
- navigate
9540
- ]);
9541
9531
  const selectedPlaylistItem = playlist?.items?.[selectedPlaylistItemIndex];
9542
9532
  const displayImage = selectedPlaylistItem?.image_url ?? selectedPlaylistItem?.relateable?.image_url ?? selectedPlaylistItem?.relateable?.compressed_image_url ?? DEFAULT_IMAGE$1;
9543
9533
  const strippedDescription = stripTags(playlist?.description || playlist?.search_engine_optimizer?.description || "");
@@ -9557,9 +9547,9 @@ function PlaylistDetailScreen({ playlistId, onNavigate }) {
9557
9547
  children: "Playlist not found or failed to load."
9558
9548
  })
9559
9549
  });
9560
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
9550
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
9561
9551
  className: "flex flex-col gap-4 px-4 py-4 md:px-10 md:py-6",
9562
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
9552
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
9563
9553
  className: "mx-auto flex w-full max-w-[480px] flex-col gap-6 md:h-[calc(100vh-140px)] md:max-w-none md:flex-row",
9564
9554
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
9565
9555
  className: "aspect-square w-full md:aspect-auto md:h-full",
@@ -9627,21 +9617,7 @@ function PlaylistDetailScreen({ playlistId, onNavigate }) {
9627
9617
  })
9628
9618
  ]
9629
9619
  })]
9630
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Dialog, {
9631
- open: isDeleteOpen,
9632
- onOpenChange: setIsDeleteOpen,
9633
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.DialogContent, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.DialogHeader, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.DialogTitle, { children: "Delete Playlist" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.DialogDescription, { children: "Are you sure you want to delete this playlist? This action cannot be undone." })] }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.DialogFooter, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Button, {
9634
- variant: "outline",
9635
- onClick: () => setIsDeleteOpen(false),
9636
- disabled: isDeleting,
9637
- children: "Cancel"
9638
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Button, {
9639
- variant: "destructive",
9640
- onClick: () => void handleDelete(),
9641
- disabled: isDeleting,
9642
- children: isDeleting ? "Deleting..." : "Delete"
9643
- })] })] })
9644
- })]
9620
+ })
9645
9621
  });
9646
9622
  }
9647
9623
  //#endregion
@@ -9840,19 +9816,30 @@ function PlaylistFormHeader({ playlistId, isEditMode, onSubmit, isSaving }) {
9840
9816
  };
9841
9817
  require_ScreenHeaderContext.useScreenHeaderActions((0, react.useMemo)(() => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
9842
9818
  className: "flex items-center gap-2",
9843
- children: [playlistId && onDeletePlaylist && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.Button, {
9844
- variant: "destructive",
9845
- size: "sm",
9846
- onClick: () => setIsDeleteOpen(true),
9847
- disabled: isMutating,
9848
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Trash2, { className: "mr-1 h-4 w-4" }), "Delete"]
9849
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Button, {
9819
+ children: [playlistId && onDeletePlaylist && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.DropdownMenu, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.DropdownMenuTrigger, {
9820
+ asChild: true,
9821
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Button, {
9822
+ variant: "outline",
9823
+ size: "sm",
9824
+ className: "h-8 w-8 p-0",
9825
+ "aria-label": "Playlist actions",
9826
+ disabled: isMutating,
9827
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.MoreVertical, { className: "h-4 w-4" })
9828
+ })
9829
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.DropdownMenuContent, {
9830
+ align: "end",
9831
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.DropdownMenuItem, {
9832
+ onClick: () => setIsDeleteOpen(true),
9833
+ className: "text-destructive focus:text-destructive",
9834
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Trash2, { className: "mr-2 h-4 w-4" }), "Delete"]
9835
+ })
9836
+ })] }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Button, {
9850
9837
  onClick: () => {
9851
9838
  onSubmit().catch(() => {});
9852
9839
  },
9853
9840
  disabled: isMutating || !isDirty || !isFormValid,
9854
9841
  size: "sm",
9855
- children: isSaving ? "Saving..." : "Save"
9842
+ children: isSaving ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Spinner, { className: "size-4" }) : "Save"
9856
9843
  })]
9857
9844
  }), [
9858
9845
  playlistId,
@@ -9881,19 +9868,22 @@ function PlaylistFormHeader({ playlistId, isEditMode, onSubmit, isSaving }) {
9881
9868
  }) })
9882
9869
  ]
9883
9870
  }) }), [isEditMode, navigate]));
9884
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Dialog, {
9871
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.AlertDialog, {
9885
9872
  open: isDeleteOpen,
9886
- onOpenChange: setIsDeleteOpen,
9887
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.DialogContent, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.DialogHeader, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.DialogTitle, { children: "Delete Playlist" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.DialogDescription, { children: "Are you sure you want to delete this playlist? This action cannot be undone." })] }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.DialogFooter, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Button, {
9888
- variant: "outline",
9889
- onClick: () => setIsDeleteOpen(false),
9873
+ onOpenChange: (open) => {
9874
+ if (!open && !isDeleting) setIsDeleteOpen(false);
9875
+ },
9876
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.AlertDialogContent, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.AlertDialogHeader, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.AlertDialogTitle, { children: "Delete this playlist?" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.AlertDialogDescription, { children: "This removes the playlist from your library. Shared links that point to it will stop working." })] }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.AlertDialogFooter, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.AlertDialogCancel, {
9890
9877
  disabled: isDeleting,
9891
9878
  children: "Cancel"
9892
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Button, {
9893
- variant: "destructive",
9894
- onClick: () => void handleDelete(),
9879
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.AlertDialogAction, {
9880
+ onClick: (e) => {
9881
+ e.preventDefault();
9882
+ handleDelete();
9883
+ },
9895
9884
  disabled: isDeleting,
9896
- children: isDeleting ? "Deleting..." : "Delete"
9885
+ className: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
9886
+ children: isDeleting ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Spinner, { className: "size-4" }) : "Delete"
9897
9887
  })] })] })
9898
9888
  });
9899
9889
  }
@@ -10457,6 +10447,42 @@ function PlaylistFormContent({ playlistId, playlist, isEditMode, itemsToUse, onB
10457
10447
  const { form, updateField, validateForm } = usePlaylistForm();
10458
10448
  const playlistTitle = form.title || "";
10459
10449
  const slugValue = form.slug ?? "";
10450
+ require_ScreenHeaderContext.useScreenHeaderBreadcrumbs((0, react.useMemo)(() => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Breadcrumb, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.BreadcrumbList, {
10451
+ className: "text-lg",
10452
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.BreadcrumbItem, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.BreadcrumbLink, {
10453
+ href: "#",
10454
+ onClick: (e) => {
10455
+ e.preventDefault();
10456
+ (onBack ?? (() => navigate("playlists")))();
10457
+ },
10458
+ children: "Playlists"
10459
+ }) }), isEditMode ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
10460
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.BreadcrumbSeparator, {}),
10461
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.BreadcrumbItem, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.BreadcrumbLink, {
10462
+ href: "#",
10463
+ onClick: (e) => {
10464
+ e.preventDefault();
10465
+ navigate(`playlists/${playlistId}`);
10466
+ },
10467
+ className: "block max-w-[40vw] truncate align-bottom md:max-w-[60ch]",
10468
+ children: playlistTitle || "Playlist"
10469
+ }) }),
10470
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.BreadcrumbSeparator, {}),
10471
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.BreadcrumbItem, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.BreadcrumbPage, {
10472
+ className: "font-semibold",
10473
+ children: "Edit"
10474
+ }) })
10475
+ ] }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.BreadcrumbSeparator, {}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.BreadcrumbItem, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.BreadcrumbPage, {
10476
+ className: "font-semibold",
10477
+ children: "New Playlist"
10478
+ }) })] })]
10479
+ }) }), [
10480
+ isEditMode,
10481
+ playlistTitle,
10482
+ onBack,
10483
+ navigate,
10484
+ playlistId
10485
+ ]));
10460
10486
  (0, react.useEffect)(() => {
10461
10487
  const isCustomSlug = form.custom_slug || playlist?.custom_slug || false;
10462
10488
  if (playlistTitle && !isCustomSlug) {
@@ -11976,4 +12002,4 @@ Object.defineProperty(exports, "usePortalContentContext", {
11976
12002
  }
11977
12003
  });
11978
12004
 
11979
- //# sourceMappingURL=PortalContentApiProvider-CPnqELEX.cjs.map
12005
+ //# sourceMappingURL=PortalContentApiProvider-BDbrZCyI.cjs.map