Merged in fix/phone-country-code-fix (pull request #2357)
fix: remove country code from prefilled phone input Approved-by: Simon.Emanuelsson
This commit is contained in:
@@ -1,13 +1,8 @@
|
||||
"use client"
|
||||
import { zodResolver } from "@hookform/resolvers/zod"
|
||||
import {
|
||||
isValidPhoneNumber,
|
||||
parsePhoneNumberWithError,
|
||||
} from "libphonenumber-js"
|
||||
import { useParams, useRouter } from "next/navigation"
|
||||
import { useEffect, useState } from "react"
|
||||
import { FormProvider, useForm } from "react-hook-form"
|
||||
import { usePhoneInput } from "react-international-phone"
|
||||
import { useIntl } from "react-intl"
|
||||
|
||||
import { type Lang, langToApiLang } from "@/constants/languages"
|
||||
@@ -21,6 +16,7 @@ import ChangeNameDisclaimer from "@/components/MyPages/Profile/ChangeNameDisclai
|
||||
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 FormContent from "./FormContent"
|
||||
import { type EditProfileSchema, editProfileSchema } from "./schema"
|
||||
@@ -47,14 +43,7 @@ export default function Form({ user }: EditFormProps) {
|
||||
*/
|
||||
const [isValid, setIsValid] = useState(true)
|
||||
|
||||
const { inputValue: phoneInput } = usePhoneInput({
|
||||
defaultCountry:
|
||||
user.phoneNumber && isValidPhoneNumber(user.phoneNumber)
|
||||
? parsePhoneNumberWithError(user.phoneNumber).country?.toLowerCase()
|
||||
: "se",
|
||||
forceDialCode: true,
|
||||
value: user.phoneNumber,
|
||||
})
|
||||
const { phoneNumber, phoneNumberCC } = usePhoneNumberParsing(user.phoneNumber)
|
||||
|
||||
const methods = useForm<EditProfileSchema>({
|
||||
defaultValues: {
|
||||
@@ -67,7 +56,8 @@ export default function Form({ user }: EditFormProps) {
|
||||
dateOfBirth: user.dateOfBirth,
|
||||
email: user.email,
|
||||
language: user.language ?? langToApiLang[lang],
|
||||
phoneNumber: phoneInput,
|
||||
phoneNumber: phoneNumber,
|
||||
phoneNumberCC: phoneNumberCC,
|
||||
password: "",
|
||||
newPassword: "",
|
||||
retypeNewPassword: "",
|
||||
|
||||
@@ -34,6 +34,7 @@ export const editProfileSchema = z
|
||||
editProfileErrors.PHONE_REQUIRED,
|
||||
editProfileErrors.PHONE_REQUESTED
|
||||
),
|
||||
phoneNumberCC: z.string(),
|
||||
|
||||
password: z.string().optional(),
|
||||
newPassword: z.literal("").optional().or(passwordValidator()),
|
||||
|
||||
@@ -73,6 +73,7 @@ export default function SignupForm({ title }: SignUpFormProps) {
|
||||
lastName: "",
|
||||
email: "",
|
||||
phoneNumber: "",
|
||||
phoneNumberCC: "",
|
||||
dateOfBirth: "",
|
||||
address: {
|
||||
countryCode: "",
|
||||
|
||||
@@ -33,6 +33,7 @@ export const signUpSchema = z.object({
|
||||
signupErrors.PHONE_REQUIRED,
|
||||
signupErrors.PHONE_REQUESTED
|
||||
),
|
||||
phoneNumberCC: z.string(),
|
||||
dateOfBirth: z.string().min(1, {
|
||||
message: signupErrors.BIRTH_DATE_REQUIRED,
|
||||
}),
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
"use client"
|
||||
import { zodResolver } from "@hookform/resolvers/zod"
|
||||
import { parsePhoneNumberFromString } from "libphonenumber-js"
|
||||
import { useCallback, useEffect, useMemo } from "react"
|
||||
import { FormProvider, useForm } from "react-hook-form"
|
||||
import { useIntl } from "react-intl"
|
||||
@@ -14,6 +13,7 @@ import Phone from "@/components/TempDesignSystem/Form/Phone"
|
||||
import Footnote from "@/components/TempDesignSystem/Text/Footnote"
|
||||
import { useFormTracking } from "@/components/TrackingSDK/hooks"
|
||||
import { useRoomContext } from "@/contexts/Details/Room"
|
||||
import usePhoneNumberParsing from "@/hooks/usePhoneNumberParsing"
|
||||
|
||||
import MemberPriceModal from "../MemberPriceModal"
|
||||
import JoinScandicFriendsCard from "./JoinScandicFriendsCard"
|
||||
@@ -54,14 +54,11 @@ export default function Details() {
|
||||
[idx, rooms]
|
||||
)
|
||||
|
||||
const initialPhoneNumber = initialData.phoneNumber
|
||||
const parsedInitialPhoneNumber = initialPhoneNumber
|
||||
? parsePhoneNumberFromString(initialPhoneNumber)
|
||||
: undefined
|
||||
let initialPhoneNumberCC = initialData.phoneNumberCC
|
||||
if (parsedInitialPhoneNumber && !initialPhoneNumberCC) {
|
||||
initialPhoneNumberCC = parsedInitialPhoneNumber.country ?? ""
|
||||
}
|
||||
const { phoneNumber, phoneNumberCC } = usePhoneNumberParsing(
|
||||
initialData.phoneNumber,
|
||||
initialData.phoneNumberCC
|
||||
)
|
||||
|
||||
const methods = useForm({
|
||||
defaultValues: {
|
||||
countryCode: initialData.countryCode,
|
||||
@@ -70,10 +67,8 @@ export default function Details() {
|
||||
join: initialData.join,
|
||||
lastName: initialData.lastName,
|
||||
membershipNo: initialData.membershipNo,
|
||||
phoneNumber: parsedInitialPhoneNumber?.isValid()
|
||||
? parsedInitialPhoneNumber.nationalNumber
|
||||
: initialPhoneNumber,
|
||||
phoneNumberCC: initialPhoneNumberCC,
|
||||
phoneNumber,
|
||||
phoneNumberCC,
|
||||
specialRequest: {
|
||||
comment: room.specialRequest.comment,
|
||||
},
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
"use client"
|
||||
import { zodResolver } from "@hookform/resolvers/zod"
|
||||
import { parsePhoneNumberFromString } from "libphonenumber-js"
|
||||
import { useCallback, useEffect } from "react"
|
||||
import { FormProvider, useForm } from "react-hook-form"
|
||||
import { useIntl } from "react-intl"
|
||||
@@ -14,6 +13,7 @@ import Phone from "@/components/TempDesignSystem/Form/Phone"
|
||||
import Footnote from "@/components/TempDesignSystem/Text/Footnote"
|
||||
import { useFormTracking } from "@/components/TrackingSDK/hooks"
|
||||
import { useRoomContext } from "@/contexts/Details/Room"
|
||||
import usePhoneNumberParsing from "@/hooks/usePhoneNumberParsing"
|
||||
|
||||
import MemberPriceModal from "../MemberPriceModal"
|
||||
import JoinScandicFriendsCard from "./JoinScandicFriendsCard"
|
||||
@@ -46,14 +46,11 @@ export default function Details({ user }: DetailsProps) {
|
||||
|
||||
const memberRate = "member" in room.roomRate ? room.roomRate.member : null
|
||||
|
||||
const initialPhoneNumber = user?.phoneNumber || initialData.phoneNumber
|
||||
const parsedInitialPhoneNumber = initialPhoneNumber
|
||||
? parsePhoneNumberFromString(initialPhoneNumber)
|
||||
: undefined
|
||||
let initialPhoneNumberCC = initialData.phoneNumberCC
|
||||
if (parsedInitialPhoneNumber && !initialPhoneNumberCC) {
|
||||
initialPhoneNumberCC = parsedInitialPhoneNumber.country ?? ""
|
||||
}
|
||||
const { phoneNumber, phoneNumberCC } = usePhoneNumberParsing(
|
||||
user?.phoneNumber || initialData.phoneNumber,
|
||||
initialData.phoneNumberCC
|
||||
)
|
||||
|
||||
const methods = useForm({
|
||||
defaultValues: {
|
||||
countryCode: user?.address?.countryCode || initialData.countryCode,
|
||||
@@ -64,10 +61,8 @@ export default function Details({ user }: DetailsProps) {
|
||||
join: initialData.join,
|
||||
lastName: user?.lastName || initialData.lastName,
|
||||
membershipNo: initialData.membershipNo,
|
||||
phoneNumber: parsedInitialPhoneNumber?.isValid()
|
||||
? parsedInitialPhoneNumber.nationalNumber
|
||||
: initialPhoneNumber,
|
||||
phoneNumberCC: initialPhoneNumberCC,
|
||||
phoneNumber,
|
||||
phoneNumberCC,
|
||||
zipCode: "zipCode" in initialData ? initialData.zipCode : undefined,
|
||||
specialRequest: {
|
||||
comment: room.specialRequest.comment,
|
||||
|
||||
@@ -4,6 +4,7 @@ import { signupErrors } from "@/components/Forms/Signup/schema"
|
||||
import { multiroomErrors } from "@/components/HotelReservation/EnterDetails/Details/Multiroom/schema"
|
||||
import { roomOneErrors } from "@/components/HotelReservation/EnterDetails/Details/RoomOne/schema"
|
||||
import { findMyBookingErrors } from "@/components/HotelReservation/FindMyBooking/schema"
|
||||
import { phoneErrors } from "@/utils/zod/phoneValidator"
|
||||
|
||||
import type { IntlShape } from "react-intl"
|
||||
|
||||
@@ -75,6 +76,11 @@ export function getErrorMessage(intl: IntlShape, errorCode?: string) {
|
||||
return intl.formatMessage({
|
||||
defaultMessage: "Phone is required",
|
||||
})
|
||||
case phoneErrors.PHONE_NUMBER_TOO_SHORT:
|
||||
return intl.formatMessage({
|
||||
defaultMessage: "The number you have entered is too short",
|
||||
})
|
||||
case phoneErrors.PHONE_REQUESTED:
|
||||
case signupErrors.PHONE_REQUESTED:
|
||||
case multiroomErrors.PHONE_REQUESTED:
|
||||
case roomOneErrors.PHONE_REQUESTED:
|
||||
|
||||
@@ -42,9 +42,9 @@ export default function Phone({
|
||||
const lang = useLang()
|
||||
const { formState, getFieldState, register, setValue } = useFormContext()
|
||||
const fieldState = getFieldState(name)
|
||||
const [phoneNumber, phoneNumberCC] = useWatch({
|
||||
const [phoneNumber, phoneNumberCC]: [string, string] = useWatch({
|
||||
name: [name, countrySelectorName],
|
||||
}) as [string, string]
|
||||
})
|
||||
|
||||
const { country, setCountry } = usePhoneInput({
|
||||
defaultCountry: phoneNumberCC
|
||||
|
||||
23
apps/scandic-web/hooks/usePhoneNumberParsing.ts
Normal file
23
apps/scandic-web/hooks/usePhoneNumberParsing.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
"use client"
|
||||
|
||||
import parsePhoneNumberFromString from "libphonenumber-js"
|
||||
|
||||
export default function usePhoneNumberParsing(
|
||||
initialPhoneNumber?: string,
|
||||
initialPhoneNumberCC?: string
|
||||
) {
|
||||
const parsedInitialPhoneNumber = initialPhoneNumber
|
||||
? parsePhoneNumberFromString(initialPhoneNumber)
|
||||
: undefined
|
||||
|
||||
let phoneNumberCC = initialPhoneNumberCC
|
||||
if (parsedInitialPhoneNumber && !phoneNumberCC) {
|
||||
phoneNumberCC = parsedInitialPhoneNumber.country ?? ""
|
||||
}
|
||||
|
||||
const phoneNumber = parsedInitialPhoneNumber?.isValid()
|
||||
? parsedInitialPhoneNumber.nationalNumber
|
||||
: initialPhoneNumber
|
||||
|
||||
return { phoneNumber, phoneNumberCC: phoneNumberCC?.toLowerCase() }
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { CountryCode } from "libphonenumber-js/min"
|
||||
import type { CountryCode } from "libphonenumber-js"
|
||||
import type { RegisterOptions } from "react-hook-form"
|
||||
|
||||
export type LowerCaseCountryCode = Lowercase<CountryCode>
|
||||
|
||||
@@ -1,19 +1,24 @@
|
||||
import { z } from "zod"
|
||||
|
||||
export const phoneErrors = {
|
||||
PHONE_NUMBER_TOO_SHORT: "PHONE_NUMBER_TOO_SHORT",
|
||||
PHONE_REQUESTED: "PHONE_REQUESTED",
|
||||
} as const
|
||||
|
||||
export function phoneValidator(
|
||||
msg = "Required field",
|
||||
invalidMsg = "Invalid type"
|
||||
) {
|
||||
return z
|
||||
.string({ invalid_type_error: invalidMsg, required_error: msg })
|
||||
.min(5, { message: "The number you have entered is too short" })
|
||||
.min(5, phoneErrors.PHONE_NUMBER_TOO_SHORT)
|
||||
.superRefine((value, ctx) => {
|
||||
if (value) {
|
||||
const containsAlphabeticChars = /[a-z]/gi.test(value)
|
||||
if (containsAlphabeticChars) {
|
||||
ctx.addIssue({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: "Please enter a valid phone number",
|
||||
message: phoneErrors.PHONE_REQUESTED,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user