import { useState } from "react"; import { Mail, Loader2 } from "lucide-react"; import { useMutation } from "@tanstack/react-query"; import toast from "react-hot-toast"; import { api } from "@/services/api"; import { useAuth } from "@/auth/useAuth"; import { Card, CardContent, CardDescription, CardHeader, CardTitle, } from "@/components/ui/card"; import { Button, Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, Input, Label, } from "@edr/ui-common"; /** * Lets the signed-in backoffice user change their own email. Goes through * /me/contact/otp + /me/contact rather than the generic (unverified) * /auth/update-profile route, so the new address is proven before it's * written — see account.controller.ts on the API side. */ export function ChangeEmailCard() { const { user } = useAuth(); const sendOtpMutation = useMutation( api.account.sendContactOtp.mutationOptions(), ); const updateContactMutation = useMutation( api.account.updateContact.mutationOptions(), ); const [open, setOpen] = useState(false); const [step, setStep] = useState<"enterEmail" | "enterOtp">("enterEmail"); const [newEmail, setNewEmail] = useState(""); const [otp, setOtp] = useState(""); const [formError, setFormError] = useState(""); const closeDialog = () => { setOpen(false); setStep("enterEmail"); setNewEmail(""); setOtp(""); setFormError(""); }; const sendOtp = () => { setFormError(""); if (!newEmail.trim()) { setFormError("Enter the new email address."); return; } sendOtpMutation.mutate( { channel: "email", value: newEmail.trim() }, { onSuccess: (result) => { toast.success(`Verification code sent to ${result.sentTo}`); setStep("enterOtp"); }, }, ); }; const confirmOtp = () => { setFormError(""); if (!otp.trim()) { setFormError("Enter the verification code."); return; } updateContactMutation.mutate( { channel: "email", value: newEmail.trim(), otp: otp.trim() }, { onSuccess: () => { toast.success("Email updated."); closeDialog(); // Refetches the session so the new email shows everywhere — simplest // way to refresh the cached user without a dedicated context method. window.location.reload(); }, }, ); }; return ( Email {user?.email ? `Current email: ${user.email}` : "Change your account email."} !next && closeDialog()}> Change email {step === "enterEmail" ? "We'll send a verification code to the new address." : `Enter the code sent to ${newEmail}.`} {step === "enterEmail" ? (
setNewEmail(e.target.value)} /> {formError &&

{formError}

}
) : (
setOtp(e.target.value)} /> {formError &&

{formError}

}
)} {step === "enterEmail" ? ( ) : ( )}
); }