From 1eed95b76ae464c89009d2170af4d25df14132c5 Mon Sep 17 00:00:00 2001 From: J-Babin Date: Fri, 7 Mar 2025 14:22:03 +0100 Subject: [PATCH 1/3] fix(profile): connection to back --- src/api/user.ts | 43 ++++++++++++++++ src/components/navbar/navbar.tsx | 8 ++- src/pages/profile/profile.tsx | 84 +++++++++++++++++++++++--------- src/schema/profile.ts | 6 +-- 4 files changed, 110 insertions(+), 31 deletions(-) create mode 100644 src/api/user.ts diff --git a/src/api/user.ts b/src/api/user.ts new file mode 100644 index 0000000..76f1242 --- /dev/null +++ b/src/api/user.ts @@ -0,0 +1,43 @@ +import { apiAuthenticated } from './index'; + +/** + * Updates the password for the authenticated user. + * + * @param {string} currentPassword - The user's current password. + * @param {string} password - The user's new password. + * @param {string} confirmPassword - The user's new password confirmation. + * @returns {Promise} - A promise that resolves when the password is updated. + * @throws {Promise} - A promise that rejects with an error message if the current password is incorrect. + * @route - /api/v1//user/me/password + * @method - PATCH + * @authentication - required + * Check if password and currentPassword are different + */ +export async function updatePassword( + currentPassword: string, + password: string, + confirmPassword: string, +): Promise { + if (password !== confirmPassword) { + throw new Error('Passwords do not match'); + } + + return apiAuthenticated('/api/v1/user/me/password', { + method: 'PATCH', + data: JSON.stringify({ currentPassword, password, confirmPassword }), + }); +} + +// Update user details for the authenticated user. + +/** + * Updates the details for the authenticated user. + * + * @param {string} email - The user's new email address. + * @param {string} username - The user's new username. + * @returns {Promise} - A promise that resolves when the user details are updated. + * @throws {Promise} - A promise that rejects with an error message if the email is invalid. + * @route - /api/v1/user/me + * @method - PATCH + * @authentication - required + */ diff --git a/src/components/navbar/navbar.tsx b/src/components/navbar/navbar.tsx index 4dd68da..07dba73 100644 --- a/src/components/navbar/navbar.tsx +++ b/src/components/navbar/navbar.tsx @@ -162,11 +162,9 @@ export const Navbar = () => { {t('navbar.analysis')} - {/**/} - {/* */} - {/* {t('account-dropdown.profile')}*/} - {/* */} - {/**/} + + {t('account-dropdown.profile')} + {t('account-dropdown.theme')} diff --git a/src/pages/profile/profile.tsx b/src/pages/profile/profile.tsx index 9cf97fd..1a6b7c2 100644 --- a/src/pages/profile/profile.tsx +++ b/src/pages/profile/profile.tsx @@ -1,6 +1,5 @@ -import { useState } from 'react'; +import { useEffect, useState } from 'react'; import { useAuthStore } from '@/store/auth.ts'; -import { useNavigate } from 'react-router-dom'; import { useTranslation } from 'react-i18next'; import { Avatar, AvatarImage } from '@radix-ui/react-avatar'; import { Pencil, PencilOff, SquarePen, LogOut, Trash, Save } from 'lucide-react'; @@ -12,6 +11,8 @@ import { Form, FormControl, FormField, FormItem, FormMessage } from '@/component import { Card } from '@/components/ui/card'; import { Button } from '@/components/ui/button.tsx'; import { Input } from '@/components/ui/input'; +import { updatePassword } from '@/api/user'; +import { useNavigate } from 'react-router-dom'; /** * Profile component renders the user's profile page. @@ -60,29 +61,46 @@ import { Input } from '@/components/ui/input'; */ export const Profile = () => { const { t } = useTranslation('profile'); - const { logout, user } = useAuthStore((state) => state); - const navigate = useNavigate(); + const { user } = useAuthStore((state) => state); const [isEditing, setIsEditing] = useState(false); + const navigate = useNavigate(); + + useEffect(() => { + console.log('User:', user); + }, [user]); const form = useForm>({ resolver: zodResolver(ProfileSchema), defaultValues: { email: user?.email, + username: user?.username, password: '', currentPassword: '', - newPassword: '', confirmPassword: '', }, }); const onSubmit = async (data: z.infer) => { - console.log(data); - setIsEditing(false); - }; + console.log('Modification', data); + try { + if (!data.currentPassword || !data.password || !data.confirmPassword) { + console.error('Please fill all the fields'); + return; + } - const handleLogout = () => { - logout(); - navigate('/login'); + if (data.email !== user?.email || data.username !== user?.username) { + // update email and username + console.log('Email and username updated successfully'); + } + + await updatePassword(data.currentPassword, data.password, data.confirmPassword); + console.log('Password updated successfully'); + form.reset(); + navigate('/profile'); + } catch (error) { + console.error('Error updating password:', error); + } + setIsEditing(false); }; const handleEditToggle = () => { @@ -99,6 +117,9 @@ export const Profile = () => { return (
+ {/* + * This Block is for the Avatar Image and the edit button + */} {

{user?.username}

+ {/* + * This block is for the form fields when user is not in edit mode + */}
( @@ -133,8 +157,26 @@ export const Profile = () => { )} /> + {/* + * This block is for password fields when user is in edit mode + */} {isEditing && ( <> + {/* ajouter une field pour le username */} + ( + + + + + + + )} + /> + { /> ( @@ -201,6 +243,9 @@ export const Profile = () => { {isEditing ? t('Cancel') : t('Modify')} + {/* + * This block is for Save button when user is in edit mode + */} {isEditing && ( )} - + {/* + * This block is for Delete account when user is not in edit mode + */} {!isEditing && ( <> - -
- +
); }; From c21003726533372ce80f70167865ec102290900a Mon Sep 17 00:00:00 2001 From: J-Babin Date: Fri, 28 Mar 2025 10:30:51 +0100 Subject: [PATCH 3/3] fix(profile): forgot import not used --- src/pages/profile/profile.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/pages/profile/profile.tsx b/src/pages/profile/profile.tsx index 88e0813..6a84d80 100644 --- a/src/pages/profile/profile.tsx +++ b/src/pages/profile/profile.tsx @@ -2,13 +2,12 @@ import { useEffect, useState } from 'react'; import { useAuthStore } from '@/store/auth.ts'; import { useTranslation } from 'react-i18next'; import { Avatar, AvatarImage } from '@radix-ui/react-avatar'; -import { Pencil, PencilOff, SquarePen, LogOut, Trash, Save } from 'lucide-react'; +import { Pencil, PencilOff, SquarePen, Trash, Save } from 'lucide-react'; import { useForm } from 'react-hook-form'; import { z } from 'zod'; import { zodResolver } from '@hookform/resolvers/zod'; import { ProfileSchema } from '@/schema/profile.ts'; import { Form, FormControl, FormField, FormItem, FormMessage } from '@/components/ui/form.tsx'; -import { Card } from '@/components/ui/card'; import { Button } from '@/components/ui/button.tsx'; import { Input } from '@/components/ui/input'; import { updatePassword } from '@/api/user';