"use client"; import { useCallback, useEffect, useRef, useState, type ChangeEvent, } from "react"; import Upload from "../../../../components/controls/Upload"; import { useMessages, useTranslation } from "../../../../contexts/MessagesContext"; import { useCreateFlow } from "../../context/CreateFlowContext"; import { CreateFlowHeaderLockup } from "../../components/CreateFlowHeaderLockup"; import { CreateFlowStepShell } from "../../components/CreateFlowStepShell"; import { CREATE_FLOW_MD_UP_COLUMN_MAX_CLASS } from "../../components/createFlowLayoutTokens"; import { fetchAuthSession } from "../../../../../lib/create/api"; import { ASSETS, getAssetPath } from "../../../../../lib/assetUtils"; import { UploadToServerError, uploadCreateFlowFile, } from "../../../../../lib/create/uploadToServer"; import { clearPendingCommunityAvatarFile, storePendingCommunityAvatarFile, } from "../../../../../lib/create/pendingCommunityAvatarUpload"; /** Create Community — Figma Flow — Upload `20094:41524`. */ export function CommunityUploadScreen() { const m = useMessages(); const u = m.create.community.communityUpload; const { markCreateFlowInteraction, state, updateState } = useCreateFlow(); const tUpload = useTranslation("create.upload"); const fileInputRef = useRef(null); const [signedIn, setSignedIn] = useState(null); const [localPreviewUrl, setLocalPreviewUrl] = useState(null); const [busy, setBusy] = useState(false); const [errorMessage, setErrorMessage] = useState(null); useEffect(() => { let cancelled = false; void fetchAuthSession().then(({ user }) => { if (!cancelled) setSignedIn(Boolean(user)); }); return () => { cancelled = true; }; }, []); useEffect( () => () => { if (localPreviewUrl) URL.revokeObjectURL(localPreviewUrl); }, [localPreviewUrl], ); const resolveUploadError = useCallback( (err: unknown) => { if (err instanceof UploadToServerError) { if (err.status === 413) return tUpload("errors.tooLarge"); if (err.status === 401) return tUpload("errors.unauthorized"); if (err.code === "server_misconfigured") { return tUpload("errors.misconfigured"); } } return tUpload("errors.generic"); }, [tUpload], ); const handleFileChange = useCallback( async (e: ChangeEvent) => { const file = e.target.files?.[0]; e.target.value = ""; if (!file) return; markCreateFlowInteraction(); setErrorMessage(null); if (signedIn) { setBusy(true); try { const { url } = await uploadCreateFlowFile(file, "communityAvatar"); setLocalPreviewUrl((prev) => { if (prev) URL.revokeObjectURL(prev); return null; }); updateState({ communityAvatarUrl: url }); } catch (err) { setErrorMessage(resolveUploadError(err)); } finally { setBusy(false); } return; } if (signedIn === false) { try { await storePendingCommunityAvatarFile(file); setLocalPreviewUrl((prev) => { if (prev) URL.revokeObjectURL(prev); return URL.createObjectURL(file); }); } catch { setErrorMessage(tUpload("errors.generic")); } } }, [ markCreateFlowInteraction, resolveUploadError, signedIn, tUpload, updateState, ], ); const handleClearPendingUpload = useCallback(() => { markCreateFlowInteraction(); setErrorMessage(null); setLocalPreviewUrl((prev) => { if (prev) URL.revokeObjectURL(prev); return null; }); if ( typeof state.communityAvatarUrl === "string" && state.communityAvatarUrl.trim().length > 0 ) { updateState({ communityAvatarUrl: undefined }); } // Clear any anonymous staged blob so the post-sign-in flush won't resurrect it. void clearPendingCommunityAvatarFile(); if (fileInputRef.current) { fileInputRef.current.value = ""; } }, [markCreateFlowInteraction, state.communityAvatarUrl, updateState]); const displaySrc = typeof state.communityAvatarUrl === "string" && state.communityAvatarUrl.trim().length > 0 ? state.communityAvatarUrl.trim() : localPreviewUrl; const hasPreview = typeof displaySrc === "string" && displaySrc.length > 0; return (
{hasPreview ? (
{/* eslint-disable-next-line @next/next/no-img-element -- user/device file or same-origin upload URL */} {u.previewAlt}
) : ( { if (!busy) fileInputRef.current?.click(); }} /> )} {signedIn === false ? (

{u.signInToUploadNote}

) : null} {errorMessage ? (

{errorMessage}

) : null}
); }