feat(WEB-170): edit profile view

This commit is contained in:
Simon Emanuelsson
2024-04-11 18:51:38 +02:00
parent 82e4d40203
commit 9396b2c3d5
114 changed files with 3642 additions and 2171 deletions
@@ -0,0 +1,97 @@
"use client"
import "react-international-phone/style.css"
import { useController, useFormContext, useWatch } from "react-hook-form"
import { useCallback, useEffect, useRef } from "react"
import { defaultCountries, getCountry } from "react-international-phone"
import ErrorMessage from "@/components/TempDesignSystem/Form/ErrorMessage"
import { PhoneInput, type PhoneInputRefType } from "react-international-phone"
import styles from "./phone.module.css"
import type { PhoneProps } from "./phone"
export default function Phone({
name = "phone",
placeholder = "",
registerOptions = {
required: true,
},
}: PhoneProps) {
const phoneRef = useRef<PhoneInputRefType>(null)
const { control, formState } = useFormContext()
const countryValue = useWatch({ name: "country" })
const defaultCountry = getCountry({
countries: defaultCountries,
field: "name",
value: countryValue,
})
/**
* Holds the previous selected country to be able to update
* countrycode based on country select field.
* Since PhoneInput inputs the countrys dialcode (country code) upon
* selection, we need to check if the current value is just
* the previously selected countrys dialcode number.
*/
const prevSelectedCountry = useRef<string | undefined>(countryValue)
const { field } = useController({
control,
name,
rules: registerOptions,
})
const handleCountrySelectForPhone = useCallback(
(country: string) => {
const selectedCountry = getCountry({
countries: defaultCountries,
field: "name",
value: country,
})
if (selectedCountry) {
phoneRef.current?.setCountry(selectedCountry.iso2)
prevSelectedCountry.current = country
}
},
[phoneRef.current, prevSelectedCountry.current]
)
useEffect(() => {
if (countryValue) {
if (field.value) {
if (prevSelectedCountry.current) {
if (prevSelectedCountry.current !== countryValue) {
const selectedCountryPrev = getCountry({
countries: defaultCountries,
field: "name",
value: prevSelectedCountry.current,
})
if (
field.value.replace("+", "") === selectedCountryPrev?.dialCode
) {
handleCountrySelectForPhone(countryValue)
}
}
} else {
handleCountrySelectForPhone(countryValue)
}
} else {
handleCountrySelectForPhone(countryValue)
}
}
}, [countryValue, prevSelectedCountry.current])
return (
<div className={styles.phone}>
<PhoneInput
{...field}
className={styles.input}
defaultCountry={defaultCountry?.iso2 ?? "se"}
placeholder={placeholder}
preferredCountries={["de", "dk", "fi", "no", "se", "gb"]}
ref={phoneRef}
/>
<ErrorMessage errors={formState.errors} name={name} />
</div>
)
}
@@ -0,0 +1,25 @@
.phone {
--react-international-phone-border-color: var(--some-black-color, #757575);
--react-international-phone-border-radius: 0.4rem;
--react-international-phone-font-size: 1.6rem;
--react-international-phone-height: 4rem;
--react-international-phone-text-color: color:
var(--some-black-color, #757575);
}
.phone :global(.react-international-phone-input-container) {
display: grid;
/* r-i-p sets their width dynamically and doesn't respect the width property of its parent */
grid-template-columns: 4.7rem minmax(20.3rem, 1fr);
width: min(28rem, 100%);
}
/* react-international-phone only exposes variables to change border-color */
.phone :global(.react-international-phone-country-selector-button),
.phone :global(.react-international-phone-input) {
border-width: 0.2rem;
}
.phone :global(.react-international-phone-input) {
padding: 0.8rem 1.6rem;
}
@@ -0,0 +1,7 @@
import type { RegisterOptions } from "react-hook-form"
export type PhoneProps = {
name?: string
placeholder?: string
registerOptions?: RegisterOptions
}