diff --git a/app/(app)/profile-settings.tsx b/app/(app)/profile-settings.tsx index 45a329d..05c823a 100644 --- a/app/(app)/profile-settings.tsx +++ b/app/(app)/profile-settings.tsx @@ -2,6 +2,7 @@ import Screen from '@lib/components/screen'; import { QueryKeys } from '@lib/models/query_keys.model'; import { IUser } from '@lib/models/user.model'; import ProfilePictureSection from '@lib/modules/profile-settings/ProfilePictureSection'; +import ProfileSection from '@lib/modules/profile-settings/ProfileSection'; import { profileService } from '@lib/services/profile.service'; import { useAuthStore } from '@lib/store/auth.store'; import { useSuspenseQuery } from '@tanstack/react-query'; @@ -12,13 +13,15 @@ export default function ProfileSettingsPage() { const user = useAuthStore((state) => state.user); const profileQuery = useSuspenseQuery({ queryKey: [QueryKeys.ProfileWithRelations, user?.id], - queryFn: () => profileService.fetchProfile(user!.id) + queryFn: () => profileService.fetchProfile(user!.id), + networkMode: 'offlineFirst' }); return ( }> - + + ); diff --git a/lib/modules/profile-settings/ProfileSection.tsx b/lib/modules/profile-settings/ProfileSection.tsx new file mode 100644 index 0000000..4148a20 --- /dev/null +++ b/lib/modules/profile-settings/ProfileSection.tsx @@ -0,0 +1,153 @@ +import { zodResolver } from '@hookform/resolvers/zod'; +import { QueryKeys } from '@lib/models/query_keys.model'; +import { IUserWithPhoneAndSocial } from '@lib/models/user.model'; +import { profileService } from '@lib/services/profile.service'; +import { useToastController } from '@tamagui/toast'; +import { useMutation, useQueryClient } from '@tanstack/react-query'; +import { useCallback } from 'react'; +import { Controller, useForm } from 'react-hook-form'; +import { + Button, + Card, + Fieldset, + Form, + Input, + Label, + Spinner, + Text, + TextArea, + View +} from 'tamagui'; +import { z } from 'zod'; +import { ISectionProps } from '.'; + +const profileSchema = z.object({ + firstName: z.string().optional(), + lastName: z.string().optional(), + bio: z.string().optional() +}); + +type ProfileSchemaType = z.infer; + +export default function ProfileSection({ user }: ISectionProps) { + const queryClient = useQueryClient(); + const toast = useToastController(); + const mutation = useMutation({ + mutationFn: (data) => profileService.updateProfile(user.id, data), + onSuccess(_data, variables) { + queryClient.setQueryData( + [QueryKeys.ProfileWithRelations, user.id], + (v) => { + if (!v) return; + + return { + ...v, + ...variables + }; + } + ); + } + }); + + const form = useForm({ + resolver: zodResolver(profileSchema), + defaultValues: { + firstName: user.firstName, + lastName: user.lastName, + bio: user.bio ?? undefined + } + }); + + const onSubmit = useCallback(async (input: ProfileSchemaType) => { + try { + await mutation.mutateAsync({ + ...input + }); + + toast.show('Sparat!', { toastType: 'success' }); + } catch (error) { + toast.show('Error!', { toastType: 'error' }); + } + }, []); + + return ( + + + Profil + + +
+ +
+ ( + <> + + + + )} + /> +
+
+ ( + <> + + + + )} + /> +
+
+ ( + <> + +