feat(SW-160): update profile

This commit is contained in:
Simon Emanuelsson
2024-07-17 16:12:18 +02:00
committed by Michael Zetterberg
parent b6e22d51a5
commit 2337d37f1a
32 changed files with 459 additions and 244 deletions

View File

@@ -1,8 +1,8 @@
"use client"
import { zodResolver } from "@hookform/resolvers/zod"
import { isValidPhoneNumber, parsePhoneNumber } from "libphonenumber-js"
import { useParams } from "next/navigation"
import { useFormState as useReactFormState } from "react-dom"
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"
@@ -13,32 +13,32 @@ import { editProfile } from "@/actions/editProfile"
import Button from "@/components/TempDesignSystem/Button"
import Link from "@/components/TempDesignSystem/Link"
import Title from "@/components/TempDesignSystem/Text/Title"
import { toast } from "@/components/TempDesignSystem/Toasts"
import FormContent from "./FormContent"
import { type EditProfileSchema, editProfileSchema } from "./schema"
import styles from "./form.module.css"
import type {
EditFormProps,
State,
import {
type EditFormProps,
Status,
} from "@/types/components/myPages/myProfile/edit"
import type { Lang } from "@/constants/languages"
const formId = "edit-profile"
export default function Form({ user }: EditFormProps) {
const { formatMessage } = useIntl()
const intl = useIntl()
const router = useRouter()
const params = useParams()
const lang = params.lang as Lang
/**
* like react, react-hook-form also exports a useFormState hook,
* we want to clearly keep them separate by naming.
* RHF isValid defaults to false and never
* changes when JS is disabled, therefore
* we need to keep it insync ourselves
*/
const [state, formAction] = useReactFormState<State, FormData>(
editProfile,
null
)
const [isValid, setIsValid] = useState(true)
const { inputValue: phoneInput } = usePhoneInput({
defaultCountry:
@@ -61,7 +61,7 @@ export default function Form({ user }: EditFormProps) {
email: user.email,
language: user.language,
phoneNumber: phoneInput,
currentPassword: "",
password: "",
newPassword: "",
retypeNewPassword: "",
},
@@ -70,44 +70,77 @@ export default function Form({ user }: EditFormProps) {
reValidateMode: "onChange",
})
async function handleSubmit(data: EditProfileSchema) {
const response = await editProfile(data)
switch (response.status) {
case Status.error:
if (response.issues?.length) {
response.issues.forEach((issue) => {
console.error(issue)
})
}
toast.error(
intl.formatMessage({
id: "An error occured when trying to update profile.",
})
)
break
case Status.success:
toast.success(
intl.formatMessage({ id: "Successfully updated profile!" })
)
/**
* TODO: Toaster?
* Design only has toasters for credit cards
* and membership cards
*/
router.push(profile[lang])
break
}
}
useEffect(() => {
setIsValid(methods.formState.isValid)
}, [setIsValid, methods.formState.isValid])
return (
<section className={styles.container}>
<hgroup className={styles.title}>
<Title as="h4" color="red" level="h1" textTransform="capitalize">
{formatMessage({ id: "Welcome" })}
{intl.formatMessage({ id: "Welcome" })}
</Title>
<Title as="h4" color="burgundy" level="h2" textTransform="capitalize">
{user.name}
</Title>
</hgroup>
<div className={styles.btnContainer}>
<Button
asChild
intent="secondary"
size="small"
theme="base"
className={styles.btn}
>
<Button asChild intent="secondary" size="small" theme="base">
<Link href={profile[lang]}>
{formatMessage({ id: "Discard changes" })}
{intl.formatMessage({ id: "Discard changes" })}
</Link>
</Button>
<Button
disabled={
!methods.formState.isValid || methods.formState.isSubmitting
}
className={styles.btn}
disabled={!isValid || methods.formState.isSubmitting}
form={formId}
intent="primary"
size="small"
theme="base"
type="submit"
>
{formatMessage({ id: "Save" })}
{intl.formatMessage({ id: "Save" })}
</Button>
</div>
<form action={formAction} className={styles.form} id={formId}>
<form
/**
* Ignoring since ts doesn't recognize that tRPC
* parses FormData before reaching the route
* @ts-ignore */
action={editProfile}
className={styles.form}
id={formId}
onSubmit={methods.handleSubmit(handleSubmit)}
>
<FormProvider {...methods}>
<FormContent />
</FormProvider>