diff --git a/src/components/PhotoWallCropModal.tsx b/src/components/PhotoWallCropModal.tsx index c6f181f..d6f3d73 100644 --- a/src/components/PhotoWallCropModal.tsx +++ b/src/components/PhotoWallCropModal.tsx @@ -49,7 +49,7 @@ export function PhotoWallCropModal({ return (
-
+

Crop your photo

Adjust to match the wall photo ratio before uploading. diff --git a/src/pages/LoginPage.tsx b/src/pages/LoginPage.tsx index 9160ff6..fbfad60 100644 --- a/src/pages/LoginPage.tsx +++ b/src/pages/LoginPage.tsx @@ -260,7 +260,6 @@ export function LoginPage() {

{headline} - {/* Novel Lung Health Summit 2026 Kochi 22nd & 23rd August 2026 */}

{preview?.subtitle ? (

{preview.subtitle}

diff --git a/src/pages/PhotoSearchPage.tsx b/src/pages/PhotoSearchPage.tsx index 8072a22..42ad2a3 100644 --- a/src/pages/PhotoSearchPage.tsx +++ b/src/pages/PhotoSearchPage.tsx @@ -191,7 +191,7 @@ function MatchCard({ @@ -202,7 +202,7 @@ function MatchCard({ key={item.key} type="button" onClick={() => void onShare(item.key)} - className="inline-flex h-[34px] w-[34px] items-center justify-center rounded-lg border-0 border-[var(--theme-card-text-color)]/45 bg-[var(--theme-card-color)]/80 text-xs font-semibold text-[var(--theme-card-text-color)]" + className="inline-flex h-[34px] w-[34px] items-center justify-center rounded-lg border-0 border-[var(--theme-card-text-color)]/45 bg-[var(--theme-card-text-color)]/50 text-xs font-semibold text-[var(--theme-card-text-color)]" > {/* {item.label} */} diff --git a/src/pages/PhotoWallPresentPage.tsx b/src/pages/PhotoWallPresentPage.tsx index e32427e..7654777 100644 --- a/src/pages/PhotoWallPresentPage.tsx +++ b/src/pages/PhotoWallPresentPage.tsx @@ -101,13 +101,13 @@ export function PhotoWallPresentPage() { {data.photos.map((p) => (
{showNames && p.displayName ? (

{p.displayName} diff --git a/src/pages/PhotoWallUploadPage.tsx b/src/pages/PhotoWallUploadPage.tsx index bc21f95..21a5bb7 100644 --- a/src/pages/PhotoWallUploadPage.tsx +++ b/src/pages/PhotoWallUploadPage.tsx @@ -10,12 +10,14 @@ import { import { Download, ImagePlus, + Loader2, Share2, } from "lucide-react"; import { useParams } from "react-router-dom"; -import { AuthShell } from "../components/auth/AuthShell"; +import { HeaderMobile } from "../components/HeaderMobile"; +import { MobileShell } from "../components/MobileShell"; import { PhotoWallCropModal } from "../components/PhotoWallCropModal"; -import { PhotoWallEventHeader } from "../components/PhotoWallEventHeader"; +import { PublicEventChrome } from "../components/PublicEventChrome"; import { SharePlatformIcon } from "../components/SharePlatformIcon"; import { getPhotoWallUploadMeta, @@ -45,13 +47,29 @@ function fieldKey(f: PhotoWallPublicFormField): string { return String(f.name || f.label || "").trim(); } -function WhiteCard({ children }: { children: ReactNode }) { +function PhotoWallLayout({ + children, + meta, +}: { + children: ReactNode; + meta?: PhotoWallUploadMeta | null; +}) { return ( -

-
-
{children}
-
-
+ + {meta ? ( + + ) : ( + + )} +
+
{children}
+
+
); } @@ -91,6 +109,7 @@ export function PhotoWallUploadPage() { const [submitting, setSubmitting] = useState(false); const [picking, setPicking] = useState(false); const [done, setDone] = useState(null); + const [resultImageReady, setResultImageReady] = useState(false); const [actionMsg, setActionMsg] = useState(null); const [cropSession, setCropSession] = useState(null); /** Cached bytes for share/download — avoids CORS/network fail when opening the OS sheet. */ @@ -148,6 +167,15 @@ export function PhotoWallUploadPage() { if (fileRef.current) fileRef.current.value = ""; }, []); + useEffect(() => { + const src = done?.previewUrl || done?.fileUrl; + if (!done || !src) return; + const img = resultImgRef.current; + if (img?.complete && img.naturalWidth > 0) { + setResultImageReady(true); + } + }, [done]); + useEffect(() => { if (!done?.fileUrl) return; let cancelled = false; @@ -165,6 +193,7 @@ export function PhotoWallUploadPage() { const resetForNewUpload = useCallback(() => { setDone(null); + setResultImageReady(false); setShareFile(null); setActionMsg(null); setErr(null); @@ -221,6 +250,7 @@ export function PhotoWallUploadPage() { return; } setSubmitting(true); + setResultImageReady(false); setErr(null); setActionMsg(null); try { @@ -350,31 +380,46 @@ export function PhotoWallUploadPage() { if (!uploadToken) { return ( - - -

Missing upload link

-
-
+ +

Missing upload link

+
); } if (loading) { return ( - - -

Loading…

-
-
+ +

Loading…

+
); } if (err && !meta) { return ( - - -

{err}

-
-
+ +

{err}

+
+ ); + } + + if (submitting) { + const framing = Boolean(meta?.frameEnabled); + return ( + +
+
+
+ +
+

+ {framing ? "Creating your photo" : "Uploading your photo"} +

+

+ {framing ? "Hang tight — we're adding your frame." : "This may take a moment."} +

+
+
+
); } @@ -382,13 +427,8 @@ export function PhotoWallUploadPage() { const canDownload = Boolean(meta?.allowFramedDownload && (done.fileUrl || done.previewUrl)); const showShare = Boolean((done.fileUrl || done.previewUrl) && enabledSharePlatforms.length > 0); return ( - - - {meta?.event ? ( -
- -
- ) : null} + +

{done.framed ? "Your framed photo" : "Photo uploaded"}

@@ -396,17 +436,34 @@ export function PhotoWallUploadPage() { {done.awaitingApproval ? "Thanks! Your photo is waiting for approval." : done.framed - ? "Here’s your generated photo. You can edit, download, or share it." + ? "Here's your generated photo. You can edit, download, or share it." : "Thanks! Your photo was added to the wall."}

{(done.fileUrl || done.previewUrl) ? ( -
+
+ {!resultImageReady ? ( +
+
+

Preparing your photo…

+
+ ) : null} {done.framed setResultImageReady(true)} onError={(e) => { const img = e.currentTarget; // Retry without CORS mode if CDN blocks anonymous reads. @@ -417,7 +474,9 @@ export function PhotoWallUploadPage() { } if (done.fileUrl && img.src !== done.fileUrl) { img.src = done.fileUrl; + return; } + setResultImageReady(true); }} />
@@ -426,18 +485,18 @@ export function PhotoWallUploadPage() { {canDownload ? ( ) : null} @@ -451,42 +510,37 @@ export function PhotoWallUploadPage() { ) : ( -
+
{enabledSharePlatforms.map((item) => ( ))}
)}
) : null} - {actionMsg ?

{actionMsg}

: null} - - + {actionMsg ?

{actionMsg}

: null} +
+
); } return ( - - - {meta?.event ? ( -
- -
- ) : null} + +

Upload your photo

{meta?.form?.description || "Add a selfie to the event photo wall."} @@ -518,13 +572,13 @@ export function PhotoWallUploadPage() { type="button" disabled={picking} onClick={() => fileRef.current?.click()} - className="flex w-full flex-col items-center justify-center gap-2 rounded-lg border-2 border-dashed border-[#ccc] bg-[#fafafa] px-4 py-8 text-sm text-[#666] hover:border-[#D32F2F] hover:bg-[#fff5f5]" + className="flex w-full flex-col items-center justify-center gap-2 rounded-lg border-2 border-dashed border-[var(--theme-card-text-color)]/30 bg-[var(--theme-card-color)]/80 px-4 py-4 text-sm text-[var(--theme-card-text-color)] hover:border-[var(--theme-button-color)]/70" > {previewUrl ? ( Preview ) : ( <> - + {picking ? "Preparing…" : "Tap to take or choose a photo"} )} @@ -566,7 +620,7 @@ export function PhotoWallUploadPage() { onChange={(e) => setValues((v) => ({ ...v, [key]: e.target.value }))} required={required} rows={3} - className="w-full rounded-lg border border-[rgba(116,112,112,0.3)] px-3 py-2 text-sm transition-colors duration-300 ease-in-out focus:border-[var(--theme-button-color)] focus:outline-none focus:ring-2 focus:ring-[var(--theme-button-color)]/30" + className="w-full rounded-lg border border-[var(--theme-card-text-color)]/10 bg-[var(--theme-card-color)]/40 px-3 py-2 text-sm transition-colors duration-300 ease-in-out focus:border-[var(--theme-button-color)] focus:outline-none focus:ring-2 focus:ring-[var(--theme-button-color)]/30" /> ); @@ -582,7 +636,7 @@ export function PhotoWallUploadPage() { value={String(values[key] ?? "")} onChange={(e) => setValues((v) => ({ ...v, [key]: e.target.value }))} required={required} - className="h-10 w-full rounded-lg border border-[rgba(116,112,112,0.3)] px-3 text-sm transition-colors duration-300 ease-in-out focus:border-[var(--theme-button-color)] focus:outline-none focus:ring-2 focus:ring-[var(--theme-button-color)]/30" + className="h-10 w-full rounded-lg border border-[var(--theme-card-text-color)]/10 bg-[var(--theme-card-color)]/40 px-3 text-sm transition-colors duration-300 ease-in-out focus:border-[var(--theme-button-color)] focus:outline-none focus:ring-2 focus:ring-[var(--theme-button-color)]/30" /> ); @@ -593,13 +647,13 @@ export function PhotoWallUploadPage() { )} - +

{cropSession && meta ? ( ) : null} -
+ ); } diff --git a/src/pages/SocialSharePage.tsx b/src/pages/SocialSharePage.tsx index 45f0a9e..92c775c 100644 --- a/src/pages/SocialSharePage.tsx +++ b/src/pages/SocialSharePage.tsx @@ -397,7 +397,7 @@ export function SocialSharePage() { Here's your framed photo. You can download or share it.

{(done.fileUrl || done.previewUrl) ? ( -
+
{!resultImageReady ? (
) : null} - {actionMsg ?

{actionMsg}

: null} + {actionMsg ?

{actionMsg}

: null} );