Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Profil - Uprava udajov #160

Merged
merged 6 commits into from
Nov 11, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
124 changes: 124 additions & 0 deletions src/components/Profile/ProfileForm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
import {useMutation, useQuery} from '@tanstack/react-query'
import axios from 'axios'
import {useRouter} from 'next/router'
import {FC} from 'react'
import {SubmitHandler, useForm} from 'react-hook-form'

import styles from '@/components/FormItems/Form.module.scss'
import {FormInput} from '@/components/FormItems/FormInput/FormInput'
import {SelectOption} from '@/components/FormItems/FormSelect/FormSelect'
import {IGeneralPostResponse} from '@/types/api/general'
import {Profile} from '@/types/api/personal'
import {AuthContainer} from '@/utils/AuthContainer'
import {useSeminarInfo} from '@/utils/useSeminarInfo'

import {Button} from '../Clickable/Clickable'
import {SchoolSubForm} from '../SchoolSubForm/SchoolSubForm'

export type ProfileFormValues = {
first_name?: string
last_name?: string
phone?: string
parent_phone?: string
new_school_description?: string
without_school: boolean
school?: SelectOption | null
school_not_found: boolean
grade: number | ''
}

const defaultValues: ProfileFormValues = {
first_name: '',
last_name: '',
phone: '',
parent_phone: '',
new_school_description: '',
without_school: false,
school: null,
school_not_found: false,
grade: '',
}

export const ProfileForm: FC = () => {
const {isAuthed} = AuthContainer.useContainer()

const {data} = useQuery({
queryKey: ['personal', 'profiles', 'myprofile'],
queryFn: () => axios.get<Profile>(`/api/personal/profiles/myprofile`),
enabled: isAuthed,
})
const profile = data?.data
const profileValues: ProfileFormValues = {
first_name: profile?.first_name,
last_name: profile?.last_name,
phone: profile?.phone ?? '',
parent_phone: profile?.parent_phone ?? '',
new_school_description: '',
without_school: profile?.school_id === 1,
school: ({id: profile?.school.code, label: profile?.school.verbose_name} as SelectOption) ?? null,
school_not_found: profile?.school_id === 0,
grade: profile?.grade ?? '',
}

const {handleSubmit, control, watch, setValue} = useForm<ProfileFormValues>({
defaultValues,
values: profileValues,
})

const scrollToTop = () => {
window.scrollTo({
top: 0,
behavior: 'smooth',
})
}

const router = useRouter()

const {seminar} = useSeminarInfo()

const transformFormData = (data: ProfileFormValues) => ({
profile: {
first_name: data.first_name,
last_name: data.last_name,
school: data.school?.id,
phone: data.phone,
parent_phone: data.parent_phone,
grade: data.grade,
},
new_school_description: data.new_school_description || '',
})

const {mutate: submitFormData} = useMutation({
mutationFn: (data: ProfileFormValues) => {
return axios.put<IGeneralPostResponse>(`/api/user/user`, transformFormData(data))
},
onSuccess: () => router.push(`/${seminar}/profil`),
})

const onSubmit: SubmitHandler<ProfileFormValues> = async (data) => {
submitFormData(data)
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

asi raz pridame daky eslint rule co trochu zjednoti/da bacha na async funkcie... tu deklarujeme fuknciu ako async ale nevolame v nej await, co nejakemu rulu vadi, ale v podstate je to tu v pohode


const requiredRule = {required: '* Toto pole nemôže byť prázdne.'}
const phoneRule = {
validate: (val?: string) => {
if (val && !/^(\+\d{10,12})$/u.test(val.replaceAll(/\s+/gu, '')))
return '* Zadaj telefónne číslo vo formáte validnom formáte +421 123 456 789 alebo +421123456789.'
},
}
return (
<div>
<form className={styles.form} onSubmit={handleSubmit(onSubmit)}>
<FormInput control={control} name="first_name" label="krstné meno*" rules={requiredRule} />
<FormInput control={control} name="last_name" label="priezvisko*" rules={requiredRule} />
<SchoolSubForm control={control} watch={watch} setValue={setValue} />
<FormInput control={control} name="phone" label="telefónne číslo" rules={phoneRule} />
<FormInput control={control} name="parent_phone" label="telefónne číslo na rodiča" rules={phoneRule} />
<p style={{fontWeight: 'bold'}}>* takto označéné polia sú povinné</p>
<Button type="submit" onClick={scrollToTop}>
Uložiť údaje
</Button>
</form>
</div>
)
}
24 changes: 14 additions & 10 deletions src/components/SchoolSubForm/SchoolSubForm.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import {useQuery} from '@tanstack/react-query'
import axios from 'axios'
import {FC, useEffect, useRef} from 'react'
import {useRef} from 'react'
import {Control, UseFormSetValue, UseFormWatch} from 'react-hook-form'
import {useUpdateEffect} from 'usehooks-ts'

import styles from '@/components/FormItems/Form.module.scss'
import {IGrade} from '@/types/api/competition'
Expand All @@ -11,15 +12,20 @@ import {FormAutocomplete} from '../FormItems/FormAutocomplete/FormAutocomplete'
import {FormCheckbox} from '../FormItems/FormCheckbox/FormCheckbox'
import {FormInput} from '../FormItems/FormInput/FormInput'
import {FormSelect, SelectOption} from '../FormItems/FormSelect/FormSelect'
import {ProfileFormValues} from '../Profile/ProfileForm'
import {RegisterFormValues} from '../RegisterForm/RegisterForm'

type SchoolSubFormProps = {
control: Control<RegisterFormValues, unknown>
watch: UseFormWatch<RegisterFormValues>
setValue: UseFormSetValue<RegisterFormValues>
type SchoolSubFormProps<T extends RegisterFormValues | ProfileFormValues> = {
control: Control<T, unknown>
watch: UseFormWatch<T>
setValue: UseFormSetValue<T>
}

export const SchoolSubForm: FC<SchoolSubFormProps> = ({control, watch, setValue}) => {
export const SchoolSubForm = ({
control,
watch,
setValue,
}: SchoolSubFormProps<RegisterFormValues | ProfileFormValues>) => {
const [school_not_found, without_school] = watch(['school_not_found', 'without_school'])

const otherSchoolItem = useRef<SelectOption>()
Expand Down Expand Up @@ -49,7 +55,7 @@ export const SchoolSubForm: FC<SchoolSubFormProps> = ({control, watch, setValue}
const schoolItems = allSchoolItems.filter(({id}) => ![0, 1].includes(id))

// predvyplnenie/zmazania hodnôt pri zakliknutí checkboxu pre užívateľa po škole
useEffect(() => {
useUpdateEffect(() => {
if (without_school) {
setValue('school', withoutSchoolItem.current)
setValue('grade', 13)
Expand All @@ -58,18 +64,16 @@ export const SchoolSubForm: FC<SchoolSubFormProps> = ({control, watch, setValue}
setValue('school', null)
setValue('grade', '')
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [without_school])

// predvyplnenie/zmazania hodnôt pri zakliknutí checkboxu pre neznámu školu
useEffect(() => {
useUpdateEffect(() => {
if (school_not_found) {
setValue('school', otherSchoolItem.current)
} else if (!without_school) {
setValue('school', null)
setValue('grade', '')
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [school_not_found])

const requiredRule = {required: '* Toto pole nemôže byť prázdne.'}
Expand Down
12 changes: 12 additions & 0 deletions src/pages/strom/profil/uprava.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import {NextPage} from 'next'

import {PageLayout} from '@/components/PageLayout/PageLayout'
import {ProfileForm} from '@/components/Profile/ProfileForm'

const Profil: NextPage = () => (
<PageLayout contentWidth={2} title="Profil">
<ProfileForm />
</PageLayout>
)

export default Profil
Loading