"use client"; import { useState } from "react"; import { refreshIdentityData, useIdentityData, } from "components/IdentityProvider"; import { InputSetting } from "components/SettingsLayout"; import { Input } from "components/Input"; import { ButtonPrimary } from "components/Buttons"; import { DotLoader } from "components/utils/DotLoader"; import { useToaster } from "components/Toast"; import { EmailConfirm } from "components/Subscribe/EmailSubscribe"; import { confirmAccountEmailChange, requestAccountEmailChange, type AccountEmailChangeError, } from "actions/emailAuth"; const ERROR_MESSAGES: Record = { unauthorized: "You need to be logged in to do that.", invalid_email: "That doesn't look like a valid email.", same_email: "That's already the email on your account.", invalid_code: "Incorrect code!", email_belongs_to_other_account: "That email is already linked to another Leaflet account.", database_error: "Something went wrong. Please try again.", }; export function AccountEmailForm(props: { helpText?: React.ReactNode }) { let { identity } = useIdentityData(); let toaster = useToaster(); let currentEmail = identity?.email ?? null; let [email, setEmail] = useState(""); let [loading, setLoading] = useState(false); let [pending, setPending] = useState<{ tokenId: string; email: string; } | null>(null); let showError = (error: AccountEmailChangeError) => toaster({ content:
{ERROR_MESSAGES[error]}
, type: "error", }); let requestChange = async () => { if (loading || !email) return; setLoading(true); try { let res = await requestAccountEmailChange(email); if (!res.ok) return showError(res.error); setPending({ tokenId: res.value.tokenId, email: email.trim() }); } catch { toaster({ content: (
We couldn't send the email. Please try again!
), type: "error", }); } finally { setLoading(false); } }; let confirmChange = async (code: string) => { if (!pending || loading) return; setLoading(true); let res = await confirmAccountEmailChange(pending.tokenId, code); setLoading(false); if (!res.ok) return showError(res.error); setPending(null); setEmail(""); refreshIdentityData(); toaster({ content: (
Your email is now {res.value.email}
), type: "success", }); }; if (pending) return (
setPending(null)} />
); return (
{ e.preventDefault(); requestChange(); }} > setEmail(e.target.value)} />
{loading ? ( ) : currentEmail ? ( "Change Email" ) : ( "Add Email" )}
); }