import {
AccountsPageContents,
AccountsPageFooter,
AccountsPageTitle,
} from "@/accounts/components/layouts/centered-paper";
import { appHomeRoute } from "@/accounts/services/redirect";
import { changeEmail, sendOTT } from "@/accounts/services/user";
import { LoadingButton } from "@/base/components/mui/LoadingButton";
import { isHTTPErrorWithStatus } from "@/base/http";
import log from "@/base/log";
import { VerticallyCentered } from "@ente/shared/components/Container";
import LinkButton from "@ente/shared/components/LinkButton";
import { LS_KEYS, getData, setLSUser } from "@ente/shared/storage/localStorage";
import { Alert, Box, TextField } from "@mui/material";
import { Formik, type FormikHelpers } from "formik";
import { t } from "i18next";
import { useRouter } from "next/router";
import { useEffect, useState } from "react";
import { Trans } from "react-i18next";
import * as Yup from "yup";
const Page: React.FC = () => {
const router = useRouter();
useEffect(() => {
const user = getData(LS_KEYS.USER);
if (!user?.token) {
void router.push("/");
}
}, []);
return (
{t("change_email")}
);
};
export default Page;
interface formValues {
email: string;
ott?: string;
}
const ChangeEmailForm: React.FC = () => {
const [loading, setLoading] = useState(false);
const [ottInputVisible, setShowOttInputVisibility] = useState(false);
const [email, setEmail] = useState(null);
const [showMessage, setShowMessage] = useState(false);
const router = useRouter();
const requestOTT = async (
{ email }: formValues,
{ setFieldError }: FormikHelpers,
) => {
try {
setLoading(true);
await sendOTT(email, "change");
setEmail(email);
setShowOttInputVisibility(true);
setShowMessage(true);
// TODO: What was this meant to focus on? The ref referred to an
// Form element that was removed. Is this still needed.
// setTimeout(() => {
// ottInputRef.current?.focus();
// }, 250);
} catch (e) {
log.error(e);
setFieldError(
"email",
isHTTPErrorWithStatus(e, 403)
? t("email_already_taken")
: t("generic_error"),
);
}
setLoading(false);
};
const requestEmailChange = async (
{ email, ott }: formValues,
{ setFieldError }: FormikHelpers,
) => {
try {
setLoading(true);
await changeEmail(email, ott!);
await setLSUser({ ...getData(LS_KEYS.USER), email });
setLoading(false);
void goToApp();
} catch (e) {
log.error(e);
setLoading(false);
setFieldError("ott", t("incorrect_code"));
}
};
const goToApp = () => router.push(appHomeRoute);
return (
initialValues={{ email: "" }}
validationSchema={
ottInputVisible
? Yup.object().shape({
email: Yup.string()
.email(t("invalid_email_error"))
.required(t("required")),
ott: Yup.string().required(t("required")),
})
: Yup.object().shape({
email: Yup.string()
.email(t("invalid_email_error"))
.required(t("required")),
})
}
validateOnChange={false}
validateOnBlur={false}
onSubmit={!ottInputVisible ? requestOTT : requestEmailChange}
>
{({ values, errors, handleChange, handleSubmit }) => (
<>
{showMessage && (
setShowMessage(false)}
>
),
}}
values={{ email }}
/>
)}
{ottInputVisible && (
setShowOttInputVisibility(false)}
>
{t("change_email")}?
)}
{t("go_back")}
>
)}
);
};