"use client" import { zodResolver } from "@hookform/resolvers/zod" import { cx } from "class-variance-authority" import { useRouter } from "next/navigation" import { FormProvider, useForm } from "react-hook-form" import { useIntl } from "react-intl" import { logger } from "@scandic-hotels/common/logger" import { Button } from "@scandic-hotels/design-system/Button" import Checkbox from "@scandic-hotels/design-system/Form/Checkbox" import { Typography } from "@scandic-hotels/design-system/Typography" import { trpc } from "@scandic-hotels/trpc/client" import { signupErrors, type SignUpSchema, signUpSchema, } from "@scandic-hotels/trpc/routers/user/schemas" import { getDefaultCountryFromLang } from "@/constants/languages" import { membershipTermsAndConditions, privacyPolicy, } from "@/constants/webHrefs" import CountrySelect from "@/components/TempDesignSystem/Form/Country" import DateSelect from "@/components/TempDesignSystem/Form/Date" import Input from "@/components/TempDesignSystem/Form/Input" import PasswordInput from "@/components/TempDesignSystem/Form/PasswordInput" import Phone from "@/components/TempDesignSystem/Form/Phone" import Link from "@/components/TempDesignSystem/Link" import { toast } from "@/components/TempDesignSystem/Toasts" import { useFormTracking } from "@/components/TrackingSDK/hooks" import useLang from "@/hooks/useLang" import { formatPhoneNumber } from "@/utils/phone" // import { type SignUpSchema, signUpSchema } from "./schema" import styles from "./form.module.css" import type { SignUpFormProps } from "@/types/components/form/signupForm" export default function SignupForm({ title }: SignUpFormProps) { const intl = useIntl() const router = useRouter() const lang = useLang() const signupButtonText = intl.formatMessage({ defaultMessage: "Join now", }) const signup = trpc.user.signup.useMutation({ onSuccess: (data) => { if (data.success && data.redirectUrl) { router.push(data.redirectUrl) } }, onError: (error) => { if (error.data?.code === "CONFLICT") { toast.error( intl.formatMessage({ defaultMessage: "An account with this email already exists. Please try signing in instead.", }) ) return } toast.error( intl.formatMessage({ defaultMessage: "Something went wrong!", }) ) logger.error("Component Signup error:", error) }, }) const methods = useForm({ defaultValues: { firstName: "", lastName: "", email: "", phoneNumber: "", phoneNumberCC: getDefaultCountryFromLang(lang), dateOfBirth: "", address: { countryCode: "", zipCode: "", }, password: "", termsAccepted: false, }, mode: "all", criteriaMode: "all", resolver: zodResolver(signUpSchema), reValidateMode: "onChange", shouldFocusError: true, }) const { control, subscribe } = methods const { trackFormSubmit } = useFormTracking("signup", subscribe, control) async function onSubmit(data: SignUpSchema) { const phoneNumber = formatPhoneNumber(data.phoneNumber, data.phoneNumberCC) signup.mutate({ ...data, phoneNumber, language: lang }) trackFormSubmit() } return (
{title ? (

{title}

) : null}

{intl.formatMessage({ defaultMessage: "Contact information", })}

{intl.formatMessage({ defaultMessage: "Birth date", })}

{intl.formatMessage({ defaultMessage: "Password", })}

{intl.formatMessage({ defaultMessage: "Terms and conditions", })}

{intl.formatMessage({ defaultMessage: "I accept", })}

{intl.formatMessage( { defaultMessage: "By accepting the Terms and Conditions for Scandic Friends I understand that my personal data will be processed in accordance with Scandic's Privacy Policy.", }, { termsAndConditionsLink: (str) => ( {str} ), privacyPolicy: (str) => ( {str} ), } )}

{/* This is a manual validation trigger workaround: - The Controller component (which Input uses) doesn't re-render on submit, which prevents automatic error display. - Future fix requires Input component refactoring (out of scope for now). */} {!methods.formState.isValid ? ( ) : ( )}
) }