From 7f758d9d0bbe377f78322977ddbc04caf188919a Mon Sep 17 00:00:00 2001 From: SrJuggernaut Date: Tue, 6 Feb 2024 20:19:02 -0600 Subject: [PATCH] feat: updated cuenta page --- src/app/cuenta/CuentaTabs.tsx | 76 ++++++++++++++++ src/app/cuenta/UpdateEmail.tsx | 2 +- src/app/cuenta/UpdatePassword.tsx | 2 +- src/app/cuenta/UpdateUserName.tsx | 16 +++- src/app/cuenta/UpdateUserPreferences.tsx | 106 +++++++++++++++++++++++ src/app/cuenta/page.tsx | 13 +-- 6 files changed, 204 insertions(+), 11 deletions(-) create mode 100644 src/app/cuenta/CuentaTabs.tsx create mode 100644 src/app/cuenta/UpdateUserPreferences.tsx diff --git a/src/app/cuenta/CuentaTabs.tsx b/src/app/cuenta/CuentaTabs.tsx new file mode 100644 index 0000000..8b9509b --- /dev/null +++ b/src/app/cuenta/CuentaTabs.tsx @@ -0,0 +1,76 @@ +'use client' +import Button from '@/components/ui/Button' +import ButtonGroup from '@/components/ui/ButtonGroup' +import useSession from '@/hooks/useSession' +import { css } from '@/styled-system/css' +import { AnimatePresence, motion } from 'framer-motion' +import { useState, type FC } from 'react' +import UpdateEmail from './UpdateEmail' +import UpdatePassword from './UpdatePassword' +import UpdateUserName from './UpdateUserName' +import UpdateUserPreferences from './UpdateUserPreferences' + +type Tab = 'perfil' | 'login' + +const CuentaTabs: FC = () => { + useSession('/login') + const [currentTab, setCurrentTab] = useState('perfil') + + return ( + <> + + + + +
+ + {currentTab === 'login' && ( + + + + + )} + {currentTab === 'perfil' && ( + + + + + )} + +
+ + ) +} + +export default CuentaTabs diff --git a/src/app/cuenta/UpdateEmail.tsx b/src/app/cuenta/UpdateEmail.tsx index e0ed714..ad8f439 100644 --- a/src/app/cuenta/UpdateEmail.tsx +++ b/src/app/cuenta/UpdateEmail.tsx @@ -61,7 +61,7 @@ const UpdateEmail: FC = () => { } }, validationSchema: updateEmailSchema, - isInitialValid: false + validateOnMount: true }) if (status !== 'idle' || session === undefined) { diff --git a/src/app/cuenta/UpdatePassword.tsx b/src/app/cuenta/UpdatePassword.tsx index 16b47a0..bc75507 100644 --- a/src/app/cuenta/UpdatePassword.tsx +++ b/src/app/cuenta/UpdatePassword.tsx @@ -68,7 +68,7 @@ const UpdatePassword: FC = () => { } }, validationSchema: updatePasswordSchema, - isInitialValid: false + validateOnMount: true }) if (status !== 'idle' || session === undefined) { diff --git a/src/app/cuenta/UpdateUserName.tsx b/src/app/cuenta/UpdateUserName.tsx index e4f144a..64aa1c7 100644 --- a/src/app/cuenta/UpdateUserName.tsx +++ b/src/app/cuenta/UpdateUserName.tsx @@ -10,7 +10,7 @@ import { nanoid } from '@reduxjs/toolkit' import { AppwriteException } from 'appwrite' import { updateName } from 'entgamers-database/frontend/session' import { useFormik } from 'formik' -import { type FC } from 'react' +import { useEffect, type FC } from 'react' import { object, string } from 'yup' interface UpdateUserNameData { @@ -22,7 +22,7 @@ const UpdateUserNameSchema = object({ }) const UpdateUserName: FC = () => { - const { status, session } = useSession('/login') + const { status, session, user } = useSession('/login') const dispatch = useAppDispatch() const formik = useFormik({ @@ -57,9 +57,19 @@ const UpdateUserName: FC = () => { } }, validationSchema: UpdateUserNameSchema, - isInitialValid: false + validateOnMount: true, + initialTouched: { name: true } }) + useEffect(() => { + if (status !== 'idle' && session !== undefined) { + formik.setValues({ + name: user?.name ?? '' + }) + .catch(console.error) + } + }, [status, session]) + if (status !== 'idle' || session === undefined) { // TODO: Replace with Skeleton return null diff --git a/src/app/cuenta/UpdateUserPreferences.tsx b/src/app/cuenta/UpdateUserPreferences.tsx new file mode 100644 index 0000000..cfddb49 --- /dev/null +++ b/src/app/cuenta/UpdateUserPreferences.tsx @@ -0,0 +1,106 @@ +'use client' +import Button from '@/components/ui/Button' +import Typography from '@/components/ui/Typography' +import FormGroup from '@/components/ui/form/FormGroup' +import TextArea from '@/components/ui/form/TextArea' +import { useAppDispatch } from '@/hooks/useAppDispatch' +import useManageError from '@/hooks/useManageError' +import useSession from '@/hooks/useSession' +import { setCurrentUser } from '@/state/sessionSlice' +import { updatePreferences, type UserPreferences } from 'entgamers-database/frontend/session' +import { useFormik } from 'formik' +import { useEffect, type FC } from 'react' +import { array, object, string, type ObjectSchema } from 'yup' + +const socialLinksSchema: ObjectSchema = object({ + bio: string().max(280, 'La descripción debe tener menos de 280 caracteres'), + profilePicture: string().url('La imagen debe ser una URL'), + socialLinks: array().of( + object({ + label: string().required('La etiqueta es requerida'), + url: string().url('La URL debe ser una URL').required('La URL es requerida') + }) + ).min(0) +}) + +const UpdateUserPreferences: FC = () => { + const { status, session, user } = useSession('/login') + const dispatch = useAppDispatch() + const { manageError } = useManageError() + + const formik = useFormik({ + initialValues: { + bio: '', + profilePicture: '', + socialLinks: [] + }, + onSubmit: async ({ bio, profilePicture, socialLinks }) => { + try { + const updatedUserWithPreferences = await updatePreferences({ bio, profilePicture, socialLinks }) + dispatch(setCurrentUser(updatedUserWithPreferences)) + } catch (error) { + manageError(error, 'Error mientras se actualizaba las preferencias', ' Error desconocido mientras se actualizaba las preferencias', 'error') + } + }, + validationSchema: socialLinksSchema, + validateOnMount: true + }) + + useEffect(() => { + if (status === 'idle' && session !== undefined) { + formik.setValues({ + bio: user?.prefs.bio ?? '', + profilePicture: user?.prefs.profilePicture ?? '', + socialLinks: user?.prefs.socialLinks ?? [] + }) + .catch(console.error) + } + }, [status, session]) + + if (status !== 'idle' || session === undefined) { + // TODO: Replace with Skeleton + return null + } + + return ( + <> + + Preferencias + +
+ + +