"use client" import { zodResolver } from "@hookform/resolvers/zod" import { useParams, useRouter } from "next/navigation" import { useEffect, useState } from "react" import { FormProvider, useForm } from "react-hook-form" import { useIntl } from "react-intl" import { profile } from "@scandic-hotels/common/constants/routes/myPages" import { logger } from "@scandic-hotels/common/logger" import { trpc } from "@scandic-hotels/trpc/client" import { langToApiLang } from "@scandic-hotels/trpc/constants/apiLang" import { getDefaultCountryFromLang } from "@/constants/languages" import { logout } from "@/constants/routes/handleAuth" import { editProfile } from "@/actions/editProfile" import Dialog from "@/components/Dialog" import ChangeNameDisclaimer from "@/components/MyPages/Profile/ChangeNameDisclaimer" import Button from "@/components/TempDesignSystem/Button" import Title from "@/components/TempDesignSystem/Text/Title" import { toast } from "@/components/TempDesignSystem/Toasts" import usePhoneNumberParsing from "@/hooks/usePhoneNumberParsing" import { formatPhoneNumber } from "@/utils/phone" import FormContent from "./FormContent" import { type EditProfileSchema, editProfileSchema } from "./schema" import styles from "./form.module.css" import type { Lang } from "@scandic-hotels/common/constants/language" import { type EditFormProps, Status, } from "@/types/components/myPages/myProfile/edit" const formId = "edit-profile" export default function Form({ user }: EditFormProps) { const intl = useIntl() const router = useRouter() const params = useParams() const lang = params.lang as Lang const utils = trpc.useUtils() /** * RHF isValid defaults to false and never * changes when JS is disabled, therefore * we need to keep it insync ourselves */ const [isValid, setIsValid] = useState(true) const { phoneNumber, phoneNumberCC } = usePhoneNumberParsing(user.phoneNumber) const methods = useForm({ defaultValues: { address: { city: user.address?.city ?? "", countryCode: user.address?.countryCode ?? "", streetAddress: user.address?.streetAddress ?? "", zipCode: user.address?.zipCode ?? "", }, dateOfBirth: user.dateOfBirth, email: user.email, language: user.language ?? langToApiLang[lang], phoneNumber: phoneNumber, phoneNumberCC: phoneNumber ? phoneNumberCC : getDefaultCountryFromLang(lang), password: "", newPassword: "", retypeNewPassword: "", }, mode: "all", criteriaMode: "all", resolver: zodResolver(editProfileSchema), reValidateMode: "onChange", }) const trigger = methods.trigger async function handleSubmit(data: EditProfileSchema) { const isPasswordChanged = !!data.newPassword const phoneNumber = formatPhoneNumber(data.phoneNumber, data.phoneNumberCC) const response = await editProfile({ ...data, phoneNumber }) switch (response.status) { case Status.error: if (response.issues?.length) { response.issues.forEach((issue) => { logger.error("Profile edit error:", issue) }) } toast.error(response.message) break case Status.success: toast.success(response.message) utils.user.get.invalidate() if (isPasswordChanged) { // Kept logout out of Next router forcing browser to navigate on logout url window.location.href = logout[lang] } else { const myStayReturnRoute = sessionStorage.getItem("myStayReturnRoute") if (myStayReturnRoute) { const returnRoute = JSON.parse(myStayReturnRoute) sessionStorage.removeItem("myStayReturnRoute") router.push(returnRoute.path) } else { router.push(profile[lang]) } router.refresh() // Can be removed on NextJs 15 } break } } useEffect(() => { setIsValid(methods.formState.isValid) }, [setIsValid, methods.formState.isValid]) useEffect(() => { trigger() }, [trigger]) return ( <>
{intl.formatMessage({ defaultMessage: "Welcome", })} {user.name}
{intl.formatMessage({ defaultMessage: "Discard changes", })} } />
) }