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({
void onNativeShare()}
- 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)]"
>
@@ -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 (
-
+
+ {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}
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() {
-
+
Edit / Upload new photo
{canDownload ? (
void onDownload()}
- className="inline-flex h-11 w-full items-center justify-center gap-2 rounded-lg border border-[#ddd] bg-white px-4 text-sm font-semibold text-[#333] hover:bg-[#fafafa]"
+ className="inline-flex h-11 w-full items-center justify-center gap-2 rounded-lg border border-zinc-300 bg-zinc-100 text-gray-600 px-4 text-sm font-semibold"
>
-
+
Download photo
) : null}
@@ -451,42 +510,37 @@ export function PhotoWallUploadPage() {
void onNativeShare()}
- className="inline-flex h-11 w-full items-center justify-center gap-2 rounded-lg border border-[#ddd] bg-white px-4 text-sm font-semibold text-[#333] hover:bg-[#fafafa]"
+ className="inline-flex h-11 w-full items-center justify-center gap-2 rounded-lg border border-zinc-300 bg-zinc-100 text-gray-600 px-4 text-sm font-semibold"
>
-
+
Share
) : (
-
+
{enabledSharePlatforms.map((item) => (
void onShare(item.key)}
- className="inline-flex h-10 items-center justify-center gap-2 rounded-lg border border-[#ddd] bg-white px-3 text-xs font-semibold text-[#333] hover:bg-[#fafafa]"
+ className="inline-flex h-10 items-center justify-center gap-2 rounded-lg border border-zinc-300 bg-zinc-100 text-gray-600 px-3 text-xs font-semibold"
>
- {item.label}
+ {/* {item.label} */}
))}
)}
) : 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 ? (
) : (
<>
-
+
{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() {
{submitting ? "Uploading…" : "Upload"}
)}
-
+
{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}
);