// components/generic/CMS/Blocks/TextImageBlock.jsx import { useState } from "react"; import { ImageIcon } from "lucide-react"; import { Label } from "@/components/ui/label"; import { Input } from "@/components/ui/input"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select"; import { RichTextEditor } from "./TextBlock"; // reuse the shared editor import { AssetPickerSheet } from "../../AssetPickerSheet"; import { useAssetPreviewSrc } from "@/hooks/useAssetPreviewSrc"; import { MediaFallback } from "@/components/generic/MediaFallback"; export function TextImageBlock({ content, onUpdate, blockId, readOnly = false }) { const [pickerOpen, setPickerOpen] = useState(false); // content.url is redacted (null) server-side for S3 assets — re-resolve // through media.util.js instead of trusting the persisted url/thumbnail. const { src, loading } = useAssetPreviewSrc( { asset_id: content?.asset_id, storage_provider: content?.storage_provider, file_url: content?.url, thumbnail_url: content?.url }, { scope: "admin" }, ); return (
{/* ── Image position ── */}
{/* ── Text side — WYSIWYG ── */}
onUpdate({ ...content, body: html })} />
{/* ── Image side ── */}
{loading ? ( ) : src ? (
setPickerOpen(true)} > {content.alt

Change Image

) : ( )} {content.asset_id && (
onUpdate({ ...content, alt: e.target.value })} />
)}
{!readOnly && ( onUpdate({ ...content, asset_id: asset.asset_id, storage_provider: asset.storage_provider ?? null, url: asset.file_url, })} /> )}
); }