From bf70ea167197ed9e6204842a2f339b688865713b Mon Sep 17 00:00:00 2001 From: pradeepkumar Date: Thu, 5 Mar 2026 05:51:45 +0530 Subject: [PATCH] feat: Return S3 keys from image uploads and resolve them for display previews in the CMS. --- src/app/dashboard/cms/page.tsx | 45 ++++++++++++++++++++++++++++------ 1 file changed, 37 insertions(+), 8 deletions(-) diff --git a/src/app/dashboard/cms/page.tsx b/src/app/dashboard/cms/page.tsx index 0ab9a20..dc57820 100644 --- a/src/app/dashboard/cms/page.tsx +++ b/src/app/dashboard/cms/page.tsx @@ -289,15 +289,14 @@ export default function CmsPage() { } } - // Generic image upload — returns the presigned download URL + // Generic image upload — returns the S3 key for permanent storage async function handleImageUpload(file: File): Promise { setIsUploadingImage(true); setModalError(''); try { const { uploadUrl, key } = await uploadService.getPresignedUploadUrl(file.name, file.type, 'properties'); await uploadService.uploadFileToS3(uploadUrl, file); - const downloadUrl = await uploadService.getPresignedDownloadUrl(key); - return downloadUrl; + return key; } catch (err) { setModalError(getErrorMessage(err)); return ''; @@ -306,6 +305,19 @@ export default function CmsPage() { } } + // Resolve an S3 key or URL for display — returns a viewable URL + async function resolveImageUrl(value: string): Promise { + if (!value) return ''; + // Already a full URL or local asset path — use directly + if (value.startsWith('http') || value.startsWith('/')) return value; + // Treat as S3 key — get presigned download URL + try { + return await uploadService.getPresignedDownloadUrl(value); + } catch { + return value; + } + } + // --------------------------------------------------------------------------- // Section-specific form renderers // --------------------------------------------------------------------------- @@ -649,14 +661,27 @@ export default function CmsPage() { ); } - // Reusable image upload field - function renderImageUploadField(label: string, currentUrl: string, onUrlChange: (url: string) => void) { + // Reusable image upload field with S3 key resolution for preview + function ImageUploadField({ label, currentUrl, onUrlChange }: { label: string; currentUrl: string; onUrlChange: (url: string) => void }) { + const [previewUrl, setPreviewUrl] = useState(''); + + useEffect(() => { + if (!currentUrl) { setPreviewUrl(''); return; } + // If it's already a full URL or local path, use directly + if (currentUrl.startsWith('http') || currentUrl.startsWith('/')) { + setPreviewUrl(currentUrl); + } else { + // S3 key — resolve to presigned URL for preview + resolveImageUrl(currentUrl).then(setPreviewUrl); + } + }, [currentUrl]); + return (
- {currentUrl && ( + {previewUrl && (
- Preview { (e.target as HTMLImageElement).style.display = 'none'; }} /> + Preview { (e.target as HTMLImageElement).style.display = 'none'; }} />
)} @@ -671,11 +696,15 @@ export default function CmsPage() { or enter URL below
- onUrlChange(e.target.value)} placeholder="https://..." /> + onUrlChange(e.target.value)} placeholder="S3 key or https://..." /> ); } + function renderImageUploadField(label: string, currentUrl: string, onUrlChange: (url: string) => void) { + return ; + } + // --- About Us form renderers --- function renderAboutHeroForm() {