@fluid-app/portal-sdk 0.1.192 → 0.1.193

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 (21) hide show
  1. package/dist/{PortalContentApiProvider-Bwi7FOTs.mjs → PortalContentApiProvider-Bxtd3cTD.mjs} +242 -96
  2. package/dist/PortalContentApiProvider-Bxtd3cTD.mjs.map +1 -0
  3. package/dist/{PortalContentApiProvider-Cb-DGxBo.cjs → PortalContentApiProvider-D_0DbqrK.cjs} +242 -96
  4. package/dist/PortalContentApiProvider-D_0DbqrK.cjs.map +1 -0
  5. package/dist/{ProductsScreen-CdbwRM5O.mjs → ProductsScreen-CIZEyhz1.mjs} +2 -2
  6. package/dist/{ProductsScreen-Cd8hpH-3.mjs → ProductsScreen-COiPDOoi.mjs} +2 -2
  7. package/dist/{ProductsScreen-Cd8hpH-3.mjs.map → ProductsScreen-COiPDOoi.mjs.map} +1 -1
  8. package/dist/{ProductsScreen-BQqP8-N9.cjs → ProductsScreen-DjvCNiay.cjs} +2 -2
  9. package/dist/{ProductsScreen-BQqP8-N9.cjs.map → ProductsScreen-DjvCNiay.cjs.map} +1 -1
  10. package/dist/{ProductsScreen-DgPjO-HY.cjs → ProductsScreen-DliPMmcL.cjs} +2 -2
  11. package/dist/{ShareablesScreen-DoJ8EIDG.mjs → ShareablesScreen-B2VncQCU.mjs} +2 -2
  12. package/dist/{ShareablesScreen-C1PQmDVa.cjs → ShareablesScreen-BWIRh8uv.cjs} +2 -2
  13. package/dist/{ShareablesScreen-C1PQmDVa.cjs.map → ShareablesScreen-BWIRh8uv.cjs.map} +1 -1
  14. package/dist/{ShareablesScreen-BUuuUpDS.mjs → ShareablesScreen-U2Zgf6wh.mjs} +2 -2
  15. package/dist/{ShareablesScreen-BUuuUpDS.mjs.map → ShareablesScreen-U2Zgf6wh.mjs.map} +1 -1
  16. package/dist/{ShareablesScreen-BEm7wQaI.cjs → ShareablesScreen-nK7fJqjp.cjs} +2 -2
  17. package/dist/index.cjs +7 -7
  18. package/dist/index.mjs +7 -7
  19. package/package.json +19 -19
  20. package/dist/PortalContentApiProvider-Bwi7FOTs.mjs.map +0 -1
  21. package/dist/PortalContentApiProvider-Cb-DGxBo.cjs.map +0 -1
@@ -6712,6 +6712,63 @@ const FilePicker = ({ config: configInput = {}, onFilesSelected, onClose, open,
6712
6712
  })] });
6713
6713
  };
6714
6714
  //#endregion
6715
+ //#region ../../shareables/ui/src/hooks/use-thumbnail-meta.ts
6716
+ function useThumbnailMeta(src) {
6717
+ const [meta, setMeta] = (0, react.useState)(null);
6718
+ const [loadError, setLoadError] = (0, react.useState)(false);
6719
+ const fileName = src?.split("/").pop()?.split("?")[0] ?? "thumbnail";
6720
+ const handleLoad = (0, react.useCallback)((e) => {
6721
+ setLoadError(false);
6722
+ const img = e.currentTarget;
6723
+ setMeta((prev) => ({
6724
+ width: img.naturalWidth,
6725
+ height: img.naturalHeight,
6726
+ size: prev?.size ?? null
6727
+ }));
6728
+ }, []);
6729
+ const handleError = (0, react.useCallback)(() => {
6730
+ setLoadError(true);
6731
+ }, []);
6732
+ (0, react.useEffect)(() => {
6733
+ if (!src) {
6734
+ setMeta(null);
6735
+ return;
6736
+ }
6737
+ setMeta(null);
6738
+ const controller = new AbortController();
6739
+ fetch(src, {
6740
+ method: "HEAD",
6741
+ signal: controller.signal
6742
+ }).then((res) => {
6743
+ if (!res.ok) return;
6744
+ const len = res.headers.get("content-length");
6745
+ if (len) {
6746
+ const kb = Number(len) / 1024;
6747
+ const sizeStr = kb >= 1024 ? `${(kb / 1024).toFixed(1)} MB` : `${kb.toFixed(1)} KB`;
6748
+ setMeta((prev) => ({
6749
+ width: prev?.width ?? 0,
6750
+ height: prev?.height ?? 0,
6751
+ size: sizeStr
6752
+ }));
6753
+ }
6754
+ }).catch((err) => {
6755
+ if (err instanceof DOMException && err.name === "AbortError") return;
6756
+ console.warn("[useThumbnailMeta] HEAD failed:", err);
6757
+ });
6758
+ return () => controller.abort();
6759
+ }, [src]);
6760
+ (0, react.useEffect)(() => {
6761
+ setLoadError(false);
6762
+ }, [src]);
6763
+ return {
6764
+ meta,
6765
+ fileName,
6766
+ handleLoad,
6767
+ handleError,
6768
+ loadError
6769
+ };
6770
+ }
6771
+ //#endregion
6715
6772
  //#region ../../shareables/ui/src/components/playlists/RichTextEditor.tsx
6716
6773
  function RichTextEditor({ value, onChange, placeholder = "Start writing...", className, editorClassName }) {
6717
6774
  const editor = require_dist$3.useEditor({
@@ -7434,44 +7491,66 @@ function VideoThumbnailSelector({ videoUrl, thumbnailUrl, onThumbnailCaptured, o
7434
7491
  setFrameSelectorOpen(true);
7435
7492
  }, []);
7436
7493
  const isMetadataLoaded = duration > 0;
7494
+ const { meta: imgMeta, fileName: thumbFileName, handleLoad: handleImgLoad, handleError: handleImgError, loadError: imgLoadError } = useThumbnailMeta(thumbnailUrl);
7437
7495
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
7438
7496
  className: "space-y-3",
7439
7497
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
7440
7498
  className: "text-foreground mb-1.5 block text-sm font-medium",
7441
7499
  children: "Thumbnail"
7442
7500
  }), thumbnailUrl ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
7443
- className: "flex items-center gap-3",
7444
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
7501
+ className: "flex items-start gap-4",
7502
+ children: [imgLoadError ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
7503
+ className: "bg-muted flex h-28 w-48 shrink-0 items-center justify-center rounded-md border",
7504
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.ImageIcon, { className: "text-muted-foreground h-8 w-8" })
7505
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
7445
7506
  src: thumbnailUrl,
7446
7507
  alt: "Video thumbnail",
7447
- className: "h-16 w-24 shrink-0 rounded-md border object-cover"
7508
+ className: "w-48 shrink-0 rounded-md border object-contain",
7509
+ onLoad: handleImgLoad,
7510
+ onError: handleImgError
7448
7511
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
7449
- className: "min-w-0 flex-1",
7450
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
7451
- className: "text-foreground text-sm font-medium",
7452
- children: "Current thumbnail"
7453
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
7454
- className: "mt-2 flex flex-col items-start gap-2",
7455
- children: !disabled && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.Button, {
7456
- variant: "outline",
7457
- size: "sm",
7458
- onClick: handleOpenDialog,
7459
- className: "gap-1.5",
7460
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Camera, { className: "h-3.5 w-3.5" }), "Select from video frame"]
7461
- }), onThumbnailSelected && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.Button, {
7462
- variant: "outline",
7463
- size: "sm",
7464
- onClick: onThumbnailSelected,
7465
- className: "gap-1.5",
7466
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.ImageIcon, { className: "h-3.5 w-3.5" }), "Select New Image"]
7467
- })] })
7468
- })]
7512
+ className: "min-w-0 flex-1 pt-1",
7513
+ children: [
7514
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
7515
+ className: "text-foreground truncate text-sm font-medium",
7516
+ children: thumbFileName
7517
+ }),
7518
+ imgMeta && imgMeta.width > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
7519
+ className: "text-muted-foreground text-xs",
7520
+ children: [
7521
+ imgMeta.width,
7522
+ " × ",
7523
+ imgMeta.height,
7524
+ "px"
7525
+ ]
7526
+ }),
7527
+ imgMeta?.size && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
7528
+ className: "text-muted-foreground text-xs",
7529
+ children: imgMeta.size
7530
+ }),
7531
+ !disabled && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
7532
+ className: "mt-2 flex flex-col items-start gap-2",
7533
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.Button, {
7534
+ variant: "outline",
7535
+ size: "sm",
7536
+ onClick: handleOpenDialog,
7537
+ className: "gap-1.5",
7538
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Camera, { className: "h-3.5 w-3.5" }), "Select from video frame"]
7539
+ }), onThumbnailSelected && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.Button, {
7540
+ variant: "outline",
7541
+ size: "sm",
7542
+ onClick: onThumbnailSelected,
7543
+ className: "gap-1.5",
7544
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.ImageIcon, { className: "h-3.5 w-3.5" }), "Select New Image"]
7545
+ })]
7546
+ })
7547
+ ]
7469
7548
  })]
7470
7549
  }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
7471
- className: "flex items-center gap-3",
7550
+ className: "flex items-center gap-4",
7472
7551
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
7473
- className: "bg-muted flex h-16 w-24 shrink-0 items-center justify-center rounded-md border",
7474
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Camera, { className: "text-muted-foreground h-6 w-6" })
7552
+ className: "bg-muted flex h-28 w-48 shrink-0 items-center justify-center rounded-md border",
7553
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Camera, { className: "text-muted-foreground h-8 w-8" })
7475
7554
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
7476
7555
  className: "min-w-0 flex-1",
7477
7556
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
@@ -7593,52 +7672,77 @@ function buildEditState(mediaItem) {
7593
7672
  blockCrawler: mediaItem.seo?.block_crawler ?? mediaItem.settings?.seo?.block_crawler ?? false
7594
7673
  };
7595
7674
  }
7675
+ function ThumbnailWithMeta({ src, onReplace }) {
7676
+ const { meta, fileName, handleLoad, handleError, loadError } = useThumbnailMeta(src);
7677
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
7678
+ className: "flex items-start gap-4",
7679
+ children: [loadError ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
7680
+ className: "bg-muted flex h-28 w-48 shrink-0 items-center justify-center rounded-md border",
7681
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.ImageIcon, { className: "text-muted-foreground h-8 w-8" })
7682
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
7683
+ src,
7684
+ alt: "Thumbnail",
7685
+ className: "w-48 shrink-0 rounded-md border object-contain",
7686
+ onLoad: handleLoad,
7687
+ onError: handleError
7688
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
7689
+ className: "min-w-0 flex-1 pt-1",
7690
+ children: [
7691
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
7692
+ className: "text-foreground truncate text-sm font-medium",
7693
+ children: fileName
7694
+ }),
7695
+ meta && meta.width > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
7696
+ className: "text-muted-foreground text-xs",
7697
+ children: [
7698
+ meta.width,
7699
+ " × ",
7700
+ meta.height,
7701
+ "px"
7702
+ ]
7703
+ }),
7704
+ meta?.size && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
7705
+ className: "text-muted-foreground text-xs",
7706
+ children: meta.size
7707
+ }),
7708
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
7709
+ className: "mt-2",
7710
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.Button, {
7711
+ variant: "outline",
7712
+ size: "sm",
7713
+ onClick: onReplace,
7714
+ className: "gap-1.5",
7715
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.ImageIcon, { className: "h-3.5 w-3.5" }), "Select New Image"]
7716
+ })
7717
+ })
7718
+ ]
7719
+ })]
7720
+ });
7721
+ }
7596
7722
  function CurrentMediaPreview({ mediaItem, pendingFileUrl, pendingKind }) {
7597
7723
  const effectiveKind = pendingKind ?? mediaItem.content_format ?? mediaItem.kind;
7598
7724
  const effectiveVideoUrl = pendingKind === "video" ? pendingFileUrl : mediaItem.video_url;
7599
7725
  const effectiveImageUrl = pendingKind === "image" ? pendingFileUrl : pendingKind ? null : mediaItem.image_url;
7600
7726
  const effectivePdfUrl = pendingKind === "pdf" ? pendingFileUrl : mediaItem.pdf_url;
7601
- if (effectiveKind === "video" && effectiveVideoUrl) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
7602
- className: "space-y-3",
7603
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
7604
- className: "relative aspect-video w-full overflow-hidden rounded-lg border bg-black",
7605
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("video", {
7606
- src: effectiveVideoUrl,
7607
- poster: effectiveImageUrl ?? void 0,
7608
- controls: true,
7609
- preload: "metadata",
7610
- className: "absolute inset-0 h-full w-full object-contain"
7611
- })
7612
- }), effectiveImageUrl && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
7613
- className: "flex items-center gap-3",
7614
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
7615
- src: effectiveImageUrl,
7616
- alt: "Thumbnail",
7617
- className: "h-16 w-16 shrink-0 rounded-md border object-cover"
7618
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
7619
- className: "min-w-0 flex-1",
7620
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
7621
- className: "text-foreground text-sm font-medium",
7622
- children: "Thumbnail"
7623
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
7624
- className: "text-muted-foreground text-xs",
7625
- children: "Current video thumbnail"
7626
- })]
7627
- })]
7628
- })]
7727
+ if (effectiveKind === "video" && effectiveVideoUrl) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
7728
+ className: "relative aspect-video w-full overflow-hidden rounded-lg border bg-black",
7729
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("video", {
7730
+ src: effectiveVideoUrl,
7731
+ poster: effectiveImageUrl ?? void 0,
7732
+ controls: true,
7733
+ preload: "metadata",
7734
+ className: "absolute inset-0 h-full w-full object-contain"
7735
+ })
7629
7736
  });
7630
- if (effectiveKind === "pdf" && effectivePdfUrl) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
7631
- className: "flex items-center gap-3 rounded-lg border p-4",
7632
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.FileText, { className: "text-muted-foreground h-8 w-8 shrink-0" }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
7633
- className: "min-w-0 flex-1",
7634
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
7635
- className: "text-foreground truncate text-sm font-medium",
7636
- children: mediaItem.title ?? "PDF"
7637
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
7638
- className: "text-muted-foreground text-xs",
7639
- children: "pdf"
7640
- })]
7641
- })]
7737
+ if (effectiveKind === "pdf" && effectivePdfUrl) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
7738
+ className: "relative w-full overflow-hidden rounded-lg border",
7739
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("iframe", {
7740
+ src: `${effectivePdfUrl}#view=FitH`,
7741
+ sandbox: "allow-same-origin",
7742
+ className: "h-auto w-full",
7743
+ style: { minHeight: "50vh" },
7744
+ title: mediaItem.title ?? "PDF document"
7745
+ })
7642
7746
  });
7643
7747
  if (effectiveImageUrl) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
7644
7748
  className: "relative aspect-video w-full overflow-hidden rounded-lg border",
@@ -7873,15 +7977,12 @@ function MediaEditScreen({ mediaId, onNavigate: _onNavigate, onBack }) {
7873
7977
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
7874
7978
  className: "flex flex-col gap-4 px-4 pt-4 pb-24 md:px-10 md:py-6",
7875
7979
  children: [
7876
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
7877
- className: "mx-auto flex w-full max-w-5xl flex-wrap items-center gap-3",
7878
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h1", {
7879
- className: "text-foreground min-w-0 flex-1 text-xl font-semibold break-words",
7980
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
7981
+ className: "mx-auto flex w-full max-w-5xl items-center gap-3",
7982
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h1", {
7983
+ className: "text-foreground text-xl font-semibold break-words",
7880
7984
  children: editState.title || displayTitle || "Media"
7881
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
7882
- className: `inline-flex shrink-0 items-center rounded-full px-2.5 py-0.5 text-xs font-medium ${editState.active ? "bg-green-100 text-green-800" : "bg-gray-100 text-gray-600"}`,
7883
- children: editState.active ? "Active" : "Inactive"
7884
- })]
7985
+ })
7885
7986
  }),
7886
7987
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
7887
7988
  className: "mx-auto grid w-full max-w-5xl grid-cols-1 gap-6 md:grid-cols-[3fr_1fr]",
@@ -7922,8 +8023,8 @@ function MediaEditScreen({ mediaId, onNavigate: _onNavigate, onBack }) {
7922
8023
  const rawContentFormat = mediaItem.content_format;
7923
8024
  const effectiveKind = pendingKind ?? rawContentFormat ?? mediaItem.kind;
7924
8025
  const effectiveVideoUrl = pendingKind === "video" ? pendingMediaFile?.file_url : mediaItem.video_url;
7925
- if (effectiveKind !== "video" || !effectiveVideoUrl || readOnly) return null;
7926
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
8026
+ if (readOnly) return null;
8027
+ if (effectiveKind === "video" && effectiveVideoUrl) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
7927
8028
  className: "border-border mt-4 border-t pt-4",
7928
8029
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(VideoThumbnailSelector, {
7929
8030
  videoUrl: effectiveVideoUrl,
@@ -7952,6 +8053,44 @@ function MediaEditScreen({ mediaId, onNavigate: _onNavigate, onBack }) {
7952
8053
  children: "Pending — save to apply"
7953
8054
  })]
7954
8055
  });
8056
+ if (effectiveKind === "pdf") {
8057
+ const currentThumbnail = pendingThumbnail ?? mediaItem.image_url;
8058
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
8059
+ className: "border-border mt-4 border-t pt-4",
8060
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
8061
+ className: "space-y-3",
8062
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
8063
+ className: "text-foreground mb-1.5 block text-sm font-medium",
8064
+ children: "Thumbnail"
8065
+ }), currentThumbnail ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ThumbnailWithMeta, {
8066
+ src: currentThumbnail,
8067
+ onReplace: () => setIsThumbnailPickerOpen(true)
8068
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
8069
+ className: "flex items-center gap-4",
8070
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
8071
+ className: "bg-muted flex h-28 w-48 shrink-0 items-center justify-center rounded-md border",
8072
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.ImageIcon, { className: "text-muted-foreground h-8 w-8" })
8073
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
8074
+ className: "min-w-0 flex-1",
8075
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
8076
+ className: "text-muted-foreground mb-2 text-sm",
8077
+ children: "No thumbnail set"
8078
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.Button, {
8079
+ variant: "outline",
8080
+ size: "sm",
8081
+ onClick: () => setIsThumbnailPickerOpen(true),
8082
+ className: "gap-1.5",
8083
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.ImageIcon, { className: "h-3.5 w-3.5" }), "Select New Image"]
8084
+ })]
8085
+ })]
8086
+ })]
8087
+ }), pendingThumbnail && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
8088
+ className: "text-muted-foreground mt-1.5 text-xs",
8089
+ children: "Pending — save to apply"
8090
+ })]
8091
+ });
8092
+ }
8093
+ return null;
7955
8094
  })()
7956
8095
  ]
7957
8096
  }),
@@ -8039,7 +8178,7 @@ function MediaEditScreen({ mediaId, onNavigate: _onNavigate, onBack }) {
8039
8178
  className: "border-border bg-card rounded-lg border p-4 md:p-5",
8040
8179
  children: [
8041
8180
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
8042
- className: "mb-4 flex flex-wrap items-center justify-between gap-2",
8181
+ className: "mb-4 flex items-center justify-between",
8043
8182
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
8044
8183
  className: "text-foreground text-base font-semibold",
8045
8184
  children: "SEO And Link Sharing"
@@ -8226,14 +8365,24 @@ function deriveMediaType(mimeType) {
8226
8365
  return "image";
8227
8366
  }
8228
8367
  function FilePreview({ result, mediaType }) {
8229
- if (mediaType === "image") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
8230
- className: "relative aspect-video w-full overflow-hidden rounded-lg border",
8231
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
8232
- src: result.file_url,
8233
- alt: result.metadata.file_name,
8234
- className: "absolute inset-0 h-full w-full object-cover"
8235
- })
8236
- });
8368
+ const thumbnailSrc = mediaType === "image" ? result.file_url : result.thumbnail_url;
8369
+ if (thumbnailSrc) {
8370
+ const Icon = mediaType === "video" ? lucide_react.Video : mediaType === "pdf" ? lucide_react.FileText : null;
8371
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
8372
+ className: "relative aspect-video w-full overflow-hidden rounded-lg border",
8373
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
8374
+ src: thumbnailSrc,
8375
+ alt: result.metadata.file_name,
8376
+ className: "absolute inset-0 h-full w-full object-cover"
8377
+ }), Icon && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
8378
+ className: "absolute bottom-2 left-2 flex items-center gap-1.5 rounded-md bg-black/60 px-2 py-1 text-white",
8379
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Icon, { className: "h-3.5 w-3.5" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
8380
+ className: "text-xs font-medium",
8381
+ children: mediaType === "video" ? "Video" : "PDF"
8382
+ })]
8383
+ })]
8384
+ });
8385
+ }
8237
8386
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
8238
8387
  className: "flex items-center gap-3 rounded-lg border p-4",
8239
8388
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(mediaType === "video" ? lucide_react.Video : lucide_react.FileText, { className: "text-muted-foreground h-8 w-8 shrink-0" }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
@@ -8271,7 +8420,7 @@ function MediaCreateScreen({ onNavigate, onBack }) {
8271
8420
  }) }), [onBack, navigate]));
8272
8421
  const [title, setTitle] = (0, react.useState)("");
8273
8422
  const [description, setDescription] = (0, react.useState)("");
8274
- const [active, setActive] = (0, react.useState)(true);
8423
+ const [active] = (0, react.useState)(true);
8275
8424
  const [selectedResult, setSelectedResult] = (0, react.useState)(null);
8276
8425
  const [isPickerOpen, setIsPickerOpen] = (0, react.useState)(false);
8277
8426
  const [isCtaModalOpen, setIsCtaModalOpen] = (0, react.useState)(false);
@@ -8389,15 +8538,12 @@ function MediaCreateScreen({ onNavigate, onBack }) {
8389
8538
  children: isCreating ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Spinner, { className: "size-4" }) : "Save"
8390
8539
  })
8391
8540
  }),
8392
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
8541
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
8393
8542
  className: "mx-auto flex w-full max-w-5xl items-center gap-3",
8394
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h1", {
8543
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h1", {
8395
8544
  className: "text-foreground text-xl font-semibold",
8396
8545
  children: title.trim() || "New Media"
8397
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
8398
- className: `inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-medium ${active ? "bg-green-100 text-green-800" : "bg-gray-100 text-gray-600"}`,
8399
- children: active ? "Active" : "Inactive"
8400
- })]
8546
+ })
8401
8547
  }),
8402
8548
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
8403
8549
  className: "mx-auto grid w-full max-w-5xl gap-6 md:grid-cols-[3fr_1fr]",
@@ -11086,7 +11232,7 @@ function createMediaAdapter(client) {
11086
11232
  };
11087
11233
  },
11088
11234
  createMedia: async (mediaData) => {
11089
- const contentFormat = mediaData.kind === "image" || mediaData.kind === "video" || mediaData.kind === "pdf" || mediaData.kind === "ppt" || mediaData.kind === "link" ? mediaData.kind : void 0;
11235
+ const contentFormat = mediaData.kind === "image" || mediaData.kind === "video" || mediaData.kind === "pdf" || mediaData.kind === "ppt" ? mediaData.kind : void 0;
11090
11236
  return toBffMediumResponse((await portAdapter.createMedia({
11091
11237
  title: mediaData.title ?? "",
11092
11238
  description: mediaData.description,
@@ -11103,7 +11249,7 @@ function createMediaAdapter(client) {
11103
11249
  if (mediaData.active !== void 0) updateBody.status = mediaData.active ? "active" : "draft";
11104
11250
  const newUrl = mediaData.image_url ?? mediaData.video_url ?? mediaData.pdf_url ?? void 0;
11105
11251
  if (newUrl !== void 0) updateBody.url = newUrl;
11106
- if (mediaData.kind === "image" || mediaData.kind === "video" || mediaData.kind === "pdf" || mediaData.kind === "ppt" || mediaData.kind === "link") updateBody.content_format = mediaData.kind;
11252
+ if (mediaData.kind === "image" || mediaData.kind === "video" || mediaData.kind === "pdf" || mediaData.kind === "ppt") updateBody.content_format = mediaData.kind;
11107
11253
  if (mediaData.thumbnail_url !== void 0) updateBody.thumbnail_url = mediaData.thumbnail_url;
11108
11254
  if (mediaData.settings?.cta) {
11109
11255
  const rawType = mediaData.settings.cta.type;
@@ -11137,7 +11283,7 @@ function mapPlaylist(raw) {
11137
11283
  title: raw.title ?? "",
11138
11284
  description: raw.description ?? null,
11139
11285
  items_count: raw.items_count ?? 0,
11140
- user_id: raw.user_id,
11286
+ user_id: raw.member_id ?? void 0,
11141
11287
  is_favorited: raw.is_favorited,
11142
11288
  image_url: raw.image_url ?? null,
11143
11289
  created_at: raw.created_at ?? "",
@@ -11711,4 +11857,4 @@ Object.defineProperty(exports, "usePortalContentContext", {
11711
11857
  }
11712
11858
  });
11713
11859
 
11714
- //# sourceMappingURL=PortalContentApiProvider-Cb-DGxBo.cjs.map
11860
+ //# sourceMappingURL=PortalContentApiProvider-D_0DbqrK.cjs.map