import React, { useState, useEffect, useRef } from "react"; import { useTranslation } from "react-i18next"; import { useQueryClient } from "@tanstack/react-query"; import { useSettings } from "#/hooks/query/use-settings"; import { openHands } from "#/api/open-hands-axios"; import { displaySuccessToast } from "#/utils/custom-toast-handlers"; // Email validation regex pattern const EMAIL_REGEX = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/; function EmailInputSection({ email, onEmailChange, onSaveEmail, onResendVerification, isSaving, isResendingVerification, isEmailChanged, emailVerified, isEmailValid, children, }: { email: string; onEmailChange: (e: React.ChangeEvent) => void; onSaveEmail: () => void; onResendVerification: () => void; isSaving: boolean; isResendingVerification: boolean; isEmailChanged: boolean; emailVerified?: boolean; isEmailValid: boolean; children: React.ReactNode; }) { const { t } = useTranslation(); return (
{isEmailChanged && !isEmailValid && (
{t("SETTINGS$INVALID_EMAIL_FORMAT")}
)}
{emailVerified === false && ( )}
{children}
); } function VerificationAlert() { const { t } = useTranslation(); return (

{t("SETTINGS$EMAIL_VERIFICATION_REQUIRED")}

{t("SETTINGS$EMAIL_VERIFICATION_RESTRICTION_MESSAGE")}

); } // These components have been replaced with toast notifications function UserSettingsScreen() { const { t } = useTranslation(); const { data: settings, isLoading, refetch } = useSettings(); const [email, setEmail] = useState(""); const [originalEmail, setOriginalEmail] = useState(""); const [isSaving, setIsSaving] = useState(false); const [isResendingVerification, setIsResendingVerification] = useState(false); const [isEmailValid, setIsEmailValid] = useState(true); const queryClient = useQueryClient(); const pollingIntervalRef = useRef(null); const prevVerificationStatusRef = useRef(undefined); useEffect(() => { if (settings?.EMAIL) { setEmail(settings.EMAIL); setOriginalEmail(settings.EMAIL); setIsEmailValid(EMAIL_REGEX.test(settings.EMAIL)); } }, [settings?.EMAIL]); useEffect(() => { if (pollingIntervalRef.current) { window.clearInterval(pollingIntervalRef.current); pollingIntervalRef.current = null; } if ( prevVerificationStatusRef.current === false && settings?.EMAIL_VERIFIED === true ) { // Display toast notification instead of setting state displaySuccessToast(t("SETTINGS$EMAIL_VERIFIED_SUCCESSFULLY")); setTimeout(() => { queryClient.invalidateQueries({ queryKey: ["settings"] }); }, 2000); } prevVerificationStatusRef.current = settings?.EMAIL_VERIFIED; if (settings?.EMAIL_VERIFIED === false) { pollingIntervalRef.current = window.setInterval(() => { refetch(); }, 5000); } return () => { if (pollingIntervalRef.current) { window.clearInterval(pollingIntervalRef.current); pollingIntervalRef.current = null; } }; }, [settings?.EMAIL_VERIFIED, refetch, queryClient, t]); const handleEmailChange = (e: React.ChangeEvent) => { const newEmail = e.target.value; setEmail(newEmail); setIsEmailValid(EMAIL_REGEX.test(newEmail)); }; const handleSaveEmail = async () => { if (email === originalEmail || !isEmailValid) return; try { setIsSaving(true); await openHands.post("/api/email", { email }, { withCredentials: true }); setOriginalEmail(email); // Display toast notification instead of setting state displaySuccessToast(t("SETTINGS$EMAIL_SAVED_SUCCESSFULLY")); queryClient.invalidateQueries({ queryKey: ["settings"] }); } catch (error) { // eslint-disable-next-line no-console console.error(t("SETTINGS$FAILED_TO_SAVE_EMAIL"), error); } finally { setIsSaving(false); } }; const handleResendVerification = async () => { try { setIsResendingVerification(true); await openHands.put("/api/email/verify", {}, { withCredentials: true }); // Display toast notification instead of setting state displaySuccessToast(t("SETTINGS$VERIFICATION_EMAIL_SENT")); } catch (error) { // eslint-disable-next-line no-console console.error(t("SETTINGS$FAILED_TO_RESEND_VERIFICATION"), error); } finally { setIsResendingVerification(false); } }; const isEmailChanged = email !== originalEmail; return (
{isLoading ? (
) : ( {settings?.EMAIL_VERIFIED === false && } )}
); } export default UserSettingsScreen;