diff --git a/frontend/eslint.config.js b/frontend/eslint.config.js index 0e16ee0..58184dd 100644 --- a/frontend/eslint.config.js +++ b/frontend/eslint.config.js @@ -1,7 +1,7 @@ import js from '@eslint/js'; import reactHooks from 'eslint-plugin-react-hooks'; import reactRefresh from 'eslint-plugin-react-refresh'; -import {defineConfig, globalIgnores} from 'eslint/config'; +import { defineConfig, globalIgnores } from 'eslint/config'; import globals from 'globals'; import process from 'process'; @@ -19,18 +19,35 @@ export default defineConfig([ globals: globals.browser, parserOptions: { ecmaVersion: 'latest', - ecmaFeatures: {jsx: true}, + ecmaFeatures: { jsx: true }, sourceType: 'module', }, }, rules: { - 'no-unused-vars': ['warn', {varsIgnorePattern: '^[A-Z_]'}], + // ----- TES RÈGLES ----- + 'no-unused-vars': ['warn', { varsIgnorePattern: '^[A-Z_]' }], 'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'warn', 'no-undef': 'error', 'no-trailing-spaces': 'error', 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'warn', + eqeqeq: ['error', 'always'], + curly: ['error', 'all'], + quotes: ['error', 'single', { avoidEscape: true }], + semi: ['error', 'always'], + indent: ['error', 4, { SwitchCase: 1 }], + 'comma-dangle': ['error', 'always-multiline'], + 'no-multiple-empty-lines': ['error', { max: 1, maxEOF: 0 }], + 'object-curly-spacing': ['error', 'always'], + 'prefer-const': 'error', + 'prefer-arrow-callback': 'error', + 'arrow-spacing': ['error', { before: true, after: true }], + 'no-var': 'error', + 'no-fallthrough': 'error', + 'no-unreachable': 'error', + 'no-extra-bind': 'error', + 'no-empty-function': 'warn', }, }, ]); diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx index 5420ea0..729e9b4 100644 --- a/frontend/src/App.jsx +++ b/frontend/src/App.jsx @@ -1,11 +1,11 @@ -import React, {Suspense} from 'react'; -import {BrowserRouter, Outlet, Route, Routes} from 'react-router-dom'; -import {NavBar} from './components/layout/NavBar'; -import {ProtectedRoute} from './components/routing/ProtectedRoute'; -import {Loader} from './components/ui/Loader'; +import React, { Suspense } from 'react'; +import { BrowserRouter, Outlet, Route, Routes } from 'react-router-dom'; +import { NavBar } from './components/layout/NavBar'; +import { ProtectedRoute } from './components/routing/ProtectedRoute'; +import { Loader } from './components/ui/Loader'; import _404 from './pages/errors/_404'; import Profile from './pages/Profile'; -import {AuthProviders} from './providers/AuthProviders'; +import { AuthProviders } from './providers/AuthProviders'; const Home = React.lazy(() => import('./pages/Home')); const SignIn = React.lazy(() => import('./pages/SignIn')); const SignUp = React.lazy(() => import('./pages/SignUp')); diff --git a/frontend/src/components/features/posts/Post.jsx b/frontend/src/components/features/posts/Post.jsx index ee96e0f..1440d8c 100644 --- a/frontend/src/components/features/posts/Post.jsx +++ b/frontend/src/components/features/posts/Post.jsx @@ -1,8 +1,8 @@ -import {memo, useEffect, useState} from 'react'; -import {Link} from 'react-router-dom'; +import { memo, useEffect, useState } from 'react'; +import { Link } from 'react-router-dom'; import CommentsModal from '../../../layout/CommentModal'; -import {DiffDate} from '../../utils/DiffDate'; -import {handleLikes} from '../../utils/HandleLikes'; +import { DiffDate } from '../../utils/DiffDate'; +import { handleLikes } from '../../utils/HandleLikes'; import ActionButtonsPost from './../../ui/ActionButtonsPost'; function Post({ @@ -27,16 +27,17 @@ function Post({ const savePP = author_imgUrl; const [newComments, setNewComments] = useState(comments); - useEffect((id) => { - if (userLikes[id]) setLiked(true); - }, []); + useEffect(() => { + if (userLikes[id]) { + setLiked(true); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [id]); - useEffect( - (id) => { - handleLikes(setNewLikes, liked, id); - }, - [liked] - ); + useEffect(() => { + handleLikes(setNewLikes, liked, id); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [liked]); useEffect(() => { const interval = setInterval(() => { diff --git a/frontend/src/components/features/posts/PostDetail.jsx b/frontend/src/components/features/posts/PostDetail.jsx index 4b5dc73..fde3084 100644 --- a/frontend/src/components/features/posts/PostDetail.jsx +++ b/frontend/src/components/features/posts/PostDetail.jsx @@ -1,13 +1,14 @@ import useMediaQuery from '@mui/material/useMediaQuery'; -import {memo, useEffect, useState} from 'react'; -import {useAuth} from '../../../providers/AuthProviders'; +import { memo, useEffect, useState } from 'react'; +import { useAuth } from '../../../providers/AuthProviders'; import MobileOverlay from '../../layout/MobileOverlay'; -import {fetchData} from '../../services/Fetch'; +import { fetchData } from '../../services/Fetch'; +import throwError from '../../services/throwError'; import ActionButtonsPost from '../../ui/ActionButtonsPost'; -import {Comments} from '../../ui/Comments'; -import {DiffDate} from '../../utils/DiffDate'; +import { Comments } from '../../ui/Comments'; +import { DiffDate } from '../../utils/DiffDate'; import FormatForm from '../../utils/FormatForm'; -import {handleLikes} from '../../utils/HandleLikes'; +import { handleLikes } from '../../utils/HandleLikes'; function PostDetail({ author = 'default_user', @@ -29,9 +30,9 @@ function PostDetail({ const [commented, setComment] = useState(false); const [saved, setSaved] = useState(false); const [IsOpen, setIsOpen] = useState(isDesktop); - const [authorPP, setAuthorPP] = useState(author_image_url); + const authorPP = author_image_url; - const {currentUser} = useAuth(); + const { currentUser } = useAuth(); const currentToken = localStorage.getItem('token'); const currentUserName = currentUser.username; const currentUserPP = currentUser.image_url; @@ -40,11 +41,13 @@ function PostDetail({ const [newComments, setNewComments] = useState(comments); useEffect(() => { - if (userLikes[id]) setLiked(true); + if (userLikes[id]) {setLiked(true);} + // eslint-disable-next-line react-hooks/exhaustive-deps }, []); useEffect(() => { handleLikes(setNewLikes, liked, id); + // eslint-disable-next-line react-hooks/exhaustive-deps }, [liked]); useEffect(() => { @@ -61,13 +64,13 @@ function PostDetail({ token, username, user_image_url, - id + id, ) { event.preventDefault(); - const {comment} = FormatForm(event); + const { comment } = FormatForm(event); - if (!comment) return; + if (!comment) {return;} fetchData(`${apiUrl}api/posts/${id}/comments`, { method: 'POST', @@ -75,9 +78,9 @@ function PostDetail({ 'Content-Type': 'application/json', Authorization: `Bearer ${token}`, }, - body: JSON.stringify({comment: comment}), + body: JSON.stringify({ comment: comment }), }).catch((error) => { - console.error(error); + throwError(error); }); setComment((prev) => [ @@ -291,7 +294,7 @@ function PostDetail({ currentToken, currentUserName, currentUserPP, - id + id, ); }} > @@ -369,7 +372,7 @@ function PostDetail({ currentToken, currentUserName, currentUserPP, - id + id, ) } > diff --git a/frontend/src/components/features/posts/PostList.jsx b/frontend/src/components/features/posts/PostList.jsx index e2be368..5701922 100644 --- a/frontend/src/components/features/posts/PostList.jsx +++ b/frontend/src/components/features/posts/PostList.jsx @@ -1,6 +1,7 @@ -import {useEffect, useState} from 'react'; -import {fetchData} from '../../services/Fetch'; -import {Loader} from './../../ui/Loader'; +import { useEffect, useState } from 'react'; +import { fetchData } from '../../services/Fetch'; +import throwError from '../../services/throwError'; +import { Loader } from './../../ui/Loader'; import Post from './Post'; export default function PostList() { @@ -13,14 +14,16 @@ export default function PostList() { .then((data) => { setPosts(data.posts ?? []); }) - .catch(() => {}) + .catch((error) => { + throwError(error); + }) .finally(() => setIsLoading(false)); - }, []); + }, [apiUrl]); if (isLoading) { return (
- {Array.from({length: 8}).map((_, i) => ( + {Array.from({ length: 8 }).map((_, i) => ( ))}
diff --git a/frontend/src/components/features/profiles/ProfileForm.jsx b/frontend/src/components/features/profiles/ProfileForm.jsx index 773251b..c3f4c05 100644 --- a/frontend/src/components/features/profiles/ProfileForm.jsx +++ b/frontend/src/components/features/profiles/ProfileForm.jsx @@ -1,19 +1,20 @@ -import {useRef, useState} from 'react'; -import {MdEdit} from 'react-icons/md'; -import {useAuth} from '../../../providers/AuthProviders'; -import {fetchData} from '../../services/Fetch'; +import { useRef, useState } from 'react'; +import { MdEdit } from 'react-icons/md'; +import { useAuth } from '../../../providers/AuthProviders'; +import { fetchData } from '../../services/Fetch'; +import throwError from '../../services/throwError'; -export default function ProfileForm({username, image_url, onClose}) { +export default function ProfileForm({ username, image_url, onClose }) { const [name, setName] = useState(username); const [avatar, setAvatar] = useState(image_url); const [isLoading, setIsLoading] = useState(false); - const [errors, setErrors] = useState({name: '', avatar: ''}); + const [errors, setErrors] = useState({ name: '', avatar: '' }); const [succes, setSucces] = useState(false); const initialName = useRef(username); const initialAvatar = useRef(image_url); - const {setCurrentUser} = useAuth(); + const { setCurrentUser } = useAuth(); const token = localStorage.getItem('token'); const apiUrl = import.meta.env.VITE_API_URL; @@ -25,7 +26,7 @@ export default function ProfileForm({username, image_url, onClose}) { const avatarChanged = avatar !== initialAvatar.current; if (name.trim() === '') { - setErrors({...errors, name: 'Le nom ne peut pas être vide.'}); + setErrors({ ...errors, name: 'Le nom ne peut pas être vide.' }); setSucces(false); setIsLoading(false); return; @@ -33,18 +34,18 @@ export default function ProfileForm({username, image_url, onClose}) { const urlRegex = /^https?:\/\/[^\s]+$/i; if (avatar.trim() !== '' && !urlRegex.test(avatar)) { - setErrors({...errors, avatar: "URL d'avatar invalide."}); + setErrors({ ...errors, avatar: "URL d'avatar invalide." }); setSucces(false); setIsLoading(false); return; } if (!nameChanged && !avatarChanged) - return setSucces(false) || setIsLoading(false); + {return setSucces(false) || setIsLoading(false);} const newData = {}; - if (nameChanged) newData.username = name; - if (avatarChanged) newData.image_url = avatar; + if (nameChanged) {newData.username = name;} + if (avatarChanged) {newData.image_url = avatar;} const data = await fetchData(`${apiUrl}api/auth/update-profile`, { method: 'PUT', @@ -56,7 +57,7 @@ export default function ProfileForm({username, image_url, onClose}) { }); if (!data || data.error) { - console.log(data); + throwError(data); setIsLoading(false); return; } else { diff --git a/frontend/src/components/layout/NavBar.jsx b/frontend/src/components/layout/NavBar.jsx index 8d22cab..44b49e2 100644 --- a/frontend/src/components/layout/NavBar.jsx +++ b/frontend/src/components/layout/NavBar.jsx @@ -1,15 +1,15 @@ import useMediaQuery from '@mui/material/useMediaQuery'; -import {useState} from 'react'; -import {FiHome, FiLogIn, FiLogOut, FiUserPlus} from 'react-icons/fi'; -import {Link, useLocation} from 'react-router-dom'; -import {useAuth} from '../../providers/AuthProviders'; +import { useState } from 'react'; +import { FiHome, FiLogIn, FiLogOut, FiUserPlus } from 'react-icons/fi'; +import { Link } from 'react-router-dom'; +import { useAuth } from '../../providers/AuthProviders'; export const NavBar = () => { - const location = useLocation(); - const {currentUser, setCurrentUser, isAuthenticate} = useAuth(); + const { currentUser, setCurrentUser, isAuthenticate } = useAuth(); const [isAuthenticated, setIsAuthenticated] = useState(isAuthenticate); const isDesktop = useMediaQuery('(min-width:1024px)'); + // eslint-disable-next-line no-unused-vars const [token, setToken] = useState(localStorage.getItem('token') || null); function handleLogOut() { @@ -66,7 +66,7 @@ export const NavBar = () => { onClick={() => { handleLogOut( currentUser, - isAuthenticate + isAuthenticate, ); }} > diff --git a/frontend/src/components/routing/ProtectedRoute.jsx b/frontend/src/components/routing/ProtectedRoute.jsx index ccf8a39..0b1559a 100644 --- a/frontend/src/components/routing/ProtectedRoute.jsx +++ b/frontend/src/components/routing/ProtectedRoute.jsx @@ -1,11 +1,11 @@ -import {Navigate, useLocation} from 'react-router-dom'; -import {useAuth} from '../../providers/AuthProviders'; +import { Navigate, useLocation } from 'react-router-dom'; +import { useAuth } from '../../providers/AuthProviders'; -export const ProtectedRoute = ({children}) => { - const {currentUser, isAuthenticate, loading} = useAuth(); +export const ProtectedRoute = ({ children }) => { + const { isAuthenticate, loading } = useAuth(); const location = useLocation(); - if (loading) return
Loading...
; + if (loading) {return
Loading...
;} if (!isAuthenticate) - return ; + {return ;} return
{children}
; }; diff --git a/frontend/src/components/services/Fetch.jsx b/frontend/src/components/services/Fetch.jsx index ce6a30b..c7640d0 100644 --- a/frontend/src/components/services/Fetch.jsx +++ b/frontend/src/components/services/Fetch.jsx @@ -1,3 +1,4 @@ +import throwError from './throwError'; export const fetchData = async (url, options = {}) => { try { const res = await fetch(url, { @@ -14,7 +15,7 @@ export const fetchData = async (url, options = {}) => { return await res.json(); } catch (error) { - console.error('Fetch error:', error); + throwError(error, 'Fetch error'); return null; } }; diff --git a/frontend/src/components/services/throwError.jsx b/frontend/src/components/services/throwError.jsx new file mode 100644 index 0000000..d046c4c --- /dev/null +++ b/frontend/src/components/services/throwError.jsx @@ -0,0 +1,5 @@ +export default function throwError(error, message = 'Une erreur est survenue') { + throw new Error( + `${message} : ${error instanceof Error ? error.message : error}`, + ); +} diff --git a/frontend/src/components/ui/ActionButtonsPost.jsx b/frontend/src/components/ui/ActionButtonsPost.jsx index 07133f8..6560f42 100644 --- a/frontend/src/components/ui/ActionButtonsPost.jsx +++ b/frontend/src/components/ui/ActionButtonsPost.jsx @@ -11,7 +11,7 @@ export default function ActionButtonsPost({ const capitalize = (str) => str.charAt(0).toUpperCase() + str.slice(1); const handleClick = (label) => { if (label === 'comment') { - if (onOpenComments) onOpenComments(); + if (onOpenComments) {onOpenComments();} } else { setAction((prev) => !prev); } diff --git a/frontend/src/components/ui/Comments.jsx b/frontend/src/components/ui/Comments.jsx index ac7ddcb..9e96898 100644 --- a/frontend/src/components/ui/Comments.jsx +++ b/frontend/src/components/ui/Comments.jsx @@ -1,4 +1,4 @@ -export const Comments = ({comment, index}) => { +export const Comments = ({ comment, index }) => { return (
{ +export const Loader = ({ loader = '' }) => { switch (loader) { case 'dote': return ( diff --git a/frontend/src/components/ui/ShowError.jsx b/frontend/src/components/ui/ShowError.jsx index d028d6e..4e42a9f 100644 --- a/frontend/src/components/ui/ShowError.jsx +++ b/frontend/src/components/ui/ShowError.jsx @@ -1,5 +1,5 @@ -export const ShowError = ({name, content, children = null}) => { - if (typeof content === 'boolean') return null; +export const ShowError = ({ name, content, children = null }) => { + if (typeof content === 'boolean') {return null;} return (

diff --git a/frontend/src/components/utils/DiffDate.jsx b/frontend/src/components/utils/DiffDate.jsx index 243c579..59f5b94 100644 --- a/frontend/src/components/utils/DiffDate.jsx +++ b/frontend/src/components/utils/DiffDate.jsx @@ -1,4 +1,4 @@ -export const DiffDate = ({myDate = new Date()}) => { +export const DiffDate = ({ myDate = new Date() }) => { const currentDate = new Date(); const diffMs = currentDate.getTime() - myDate.getTime(); diff --git a/frontend/src/layout/CommentModal.jsx b/frontend/src/layout/CommentModal.jsx index 0810474..484b2f0 100644 --- a/frontend/src/layout/CommentModal.jsx +++ b/frontend/src/layout/CommentModal.jsx @@ -1,10 +1,11 @@ import Box from '@mui/material/Box'; import Modal from '@mui/material/Modal'; -import {useState} from 'react'; -import {fetchData} from '../components/services/Fetch'; +import { useState } from 'react'; +import { fetchData } from '../components/services/Fetch'; +import throwError from '../components/services/throwError'; import FormatForm from '../components/utils/FormatForm'; -import {useAuth} from '../providers/AuthProviders'; -import {Comments} from './../components/ui/Comments'; +import { useAuth } from '../providers/AuthProviders'; +import { Comments } from './../components/ui/Comments'; async function handleComment( setComment, @@ -12,14 +13,14 @@ async function handleComment( token, username, user_image_url, - id + id, ) { event.preventDefault(); const apiUrl = import.meta.env.VITE_API_URL; - const {comment} = FormatForm(event); + const { comment } = FormatForm(event); - if (!comment) return; + if (!comment) {return;} fetchData(`${apiUrl}api/posts/${id}/comments`, { method: 'POST', @@ -27,9 +28,9 @@ async function handleComment( 'Content-Type': 'application/json', Authorization: `Bearer ${token}`, }, - body: JSON.stringify({comment: comment}), + body: JSON.stringify({ comment: comment }), }).catch((error) => { - console.error(error); + throwError(error); }); setComment((prev) => [ @@ -49,11 +50,10 @@ export default function CommentsModal({ isOpen, onClose, comments = [], - setComment, postId = 0, }) { const [newComments, setNewComments] = useState(comments); - const {currentUser} = useAuth(); + const { currentUser } = useAuth(); const currentToken = localStorage.getItem('token') ?? ''; const currentUserName = currentUser?.username; const currentUserPP = currentUser?.image_url; @@ -114,7 +114,7 @@ export default function CommentsModal({ currentToken, currentUserName, currentUserPP, - id + id, ) } > diff --git a/frontend/src/pages/Home.jsx b/frontend/src/pages/Home.jsx index 7412576..a82b79c 100644 --- a/frontend/src/pages/Home.jsx +++ b/frontend/src/pages/Home.jsx @@ -1,4 +1,4 @@ -import {Helmet} from 'react-helmet'; +import { Helmet } from 'react-helmet'; import PostList from './../components/features/posts/PostList'; export default function Home() { diff --git a/frontend/src/pages/PostDetails.jsx b/frontend/src/pages/PostDetails.jsx index a5fa854..7806224 100644 --- a/frontend/src/pages/PostDetails.jsx +++ b/frontend/src/pages/PostDetails.jsx @@ -1,12 +1,12 @@ -import {useEffect, useState} from 'react'; -import {Helmet} from 'react-helmet'; -import {useParams} from 'react-router-dom'; +import { useEffect, useState } from 'react'; +import { Helmet } from 'react-helmet'; +import { useParams } from 'react-router-dom'; import PostDetail from '../components/features/posts/PostDetail'; -import {fetchData} from '../components/services/Fetch'; -import {Loader} from '../components/ui/Loader'; +import { fetchData } from '../components/services/Fetch'; +import { Loader } from '../components/ui/Loader'; export default function PostDetails() { - const {id} = useParams(); + const { id } = useParams(); const [post, setPost] = useState(null); const [error, setError] = useState(); const apiUrl = import.meta.env.VITE_API_URL; @@ -15,21 +15,21 @@ export default function PostDetails() { fetchData(`${apiUrl}api/posts/${id}`) .then((data) => setPost(data.post)) .catch((error) => setError(error)); - }, [id]); + }, [id, apiUrl]); if (error) - return ( -

-

+ {return ( +

+

Une erreur est survenue 😢 -

-

- {error.message || String(error)} -

-
- ); +

+

+ {error.message || String(error)} +

+
+ );} - if (!post) return ; + if (!post) {return ;} return ( <> diff --git a/frontend/src/pages/Profile.jsx b/frontend/src/pages/Profile.jsx index 5345d95..65de5b4 100644 --- a/frontend/src/pages/Profile.jsx +++ b/frontend/src/pages/Profile.jsx @@ -1,24 +1,22 @@ import useMediaQuery from '@mui/material/useMediaQuery'; -import {useState} from 'react'; -import {Helmet} from 'react-helmet'; -import {MdEdit} from 'react-icons/md'; +import { useState } from 'react'; +import { Helmet } from 'react-helmet'; +import { MdEdit } from 'react-icons/md'; import ProfileForm from '../components/features/profiles/ProfileForm'; import MobileOverlay from '../components/layout/MobileOverlay'; -import {Loader} from '../components/ui/Loader'; -import {useAuth} from '../providers/AuthProviders'; +import { Loader } from '../components/ui/Loader'; +import { useAuth } from '../providers/AuthProviders'; export default function ProfilePage() { const isDesktop = useMediaQuery('(min-width:1024px)'); - const {currentUser, setCurrentUser, isAuthenticate} = useAuth(); + const { currentUser, setCurrentUser, isAuthenticate } = useAuth(); + // eslint-disable-next-line no-unused-vars const [isAuthenticated, setIsAuthenticated] = useState(isAuthenticate); const [isOpen, setIsOpen] = useState(isDesktop); - const {username, image_url, email, created_at} = currentUser; + const { username, image_url, email, created_at } = currentUser; const [token, setToken] = useState(localStorage.getItem('token') || null); const [locationData] = useState(location.state); - const apiUrl = import.meta.env.VITE_API_URL; - - function handleUpdateProfil(event, name, id) {} function handleLogOut() { localStorage.clear(); diff --git a/frontend/src/pages/SignIn.jsx b/frontend/src/pages/SignIn.jsx index 39fdcea..a2bd0c4 100644 --- a/frontend/src/pages/SignIn.jsx +++ b/frontend/src/pages/SignIn.jsx @@ -1,8 +1,8 @@ -import {useState} from 'react'; -import {Helmet} from 'react-helmet'; -import {useLocation, useNavigate} from 'react-router-dom'; -import {ShowError} from '../components/ui/ShowError'; -import {fetchData} from './../components/services/Fetch'; +import { useState } from 'react'; +import { Helmet } from 'react-helmet'; +import { useLocation } from 'react-router-dom'; +import { ShowError } from '../components/ui/ShowError'; +import { fetchData } from './../components/services/Fetch'; import validateInput from './../components/utils/ValidateInput'; export default function SignIn() { @@ -14,13 +14,12 @@ export default function SignIn() { password: '', }); const [isLoading, setIsLoading] = useState(false); - const navigate = useNavigate(); const location = useLocation(); const [locationData] = useState(location.state); function handleOnChangeInput(e) { - const {name, value} = e.target; - setFormData({...formData, [name]: value}); + const { name, value } = e.target; + setFormData({ ...formData, [name]: value }); const isValid = validateInput(name, value); setDisplayError({ ...displayError, @@ -31,7 +30,7 @@ export default function SignIn() { async function handleSubmit(e) { e.preventDefault(); setIsLoading(true); - const {email, password} = formData; + const { email, password } = formData; const apiUrl = import.meta.env.VITE_API_URL; if (!email || !password) { @@ -48,15 +47,17 @@ export default function SignIn() { const emailValidation = validateInput('email', email); const passwordValidation = validateInput('password', password); - const errors = { - email: emailValidation === true ? null : emailValidation, - password: passwordValidation === true ? null : passwordValidation, + const validationErrors = { + email: emailValidation === true ? false : emailValidation, + password: passwordValidation === true ? false : passwordValidation, }; - const hasErrors = Object.values(errors).some((err) => err == null); + const hasErrors = Object.values(validationErrors).some( + (err) => err !== false, + ); if (hasErrors) { - setDisplayError(errors); + setDisplayError(validationErrors); setIsLoading(false); return; } @@ -64,7 +65,7 @@ export default function SignIn() { try { const data = await fetchData(`${apiUrl}api/auth/login`, { method: 'POST', - header: {'Content-Type': 'application/json'}, + header: { 'Content-Type': 'application/json' }, body: JSON.stringify(formData), }); diff --git a/frontend/src/pages/SignUp.jsx b/frontend/src/pages/SignUp.jsx index 76ceb31..b99fccb 100644 --- a/frontend/src/pages/SignUp.jsx +++ b/frontend/src/pages/SignUp.jsx @@ -1,7 +1,7 @@ -import {useState} from 'react'; -import {Helmet} from 'react-helmet'; -import {fetchData} from '../components/services/Fetch'; -import {ShowError} from '../components/ui/ShowError'; +import { useState } from 'react'; +import { Helmet } from 'react-helmet'; +import { fetchData } from '../components/services/Fetch'; +import { ShowError } from '../components/ui/ShowError'; import validateInput from '../components/utils/ValidateInput'; export default function SignUp() { @@ -22,8 +22,8 @@ export default function SignUp() { const [isLoading, setIsLoading] = useState(false); function handleOnChangeInput(e) { - const {name, value} = e.target; - setFormData({...formData, [name]: value}); + const { name, value } = e.target; + setFormData({ ...formData, [name]: value }); const isValid = validateInput(name, value); setDisplayError({ ...displayError, @@ -36,7 +36,7 @@ export default function SignUp() { setIsLoading(true); const apiUrl = import.meta.env.VITE_API_URL; - const {username, email, password} = formData; + const { username, email, password } = formData; const errors = { username: username ? null : 'Veuillez entrer un nom d’utilisateur.', @@ -45,7 +45,7 @@ export default function SignUp() { }; const hasEmptyFields = Object.values(errors).some( - (err) => err !== null + (err) => err !== null, ); if (hasEmptyFields) { setDisplayError({ @@ -68,14 +68,11 @@ export default function SignUp() { }; const hasErrors = Object.values(validationErrors).some( - (err) => err == null + (err) => err !== false, ); + if (hasErrors) { - setDisplayError({ - ...displayError, - ...validationErrors, - }); - console.log('teste'); + setDisplayError(validationErrors); setIsLoading(false); return; } @@ -109,7 +106,7 @@ export default function SignUp() { if (data.token) { localStorage.setItem('token', data.token); } - setDisplayError({username: '', email: '', password: '', other: ''}); + setDisplayError({ username: '', email: '', password: '', other: '' }); setTimeout(() => { window.location.href = '/'; setIsLoading(false); diff --git a/frontend/src/providers/AuthProviders.jsx b/frontend/src/providers/AuthProviders.jsx index cf6c0a4..4599512 100644 --- a/frontend/src/providers/AuthProviders.jsx +++ b/frontend/src/providers/AuthProviders.jsx @@ -1,30 +1,31 @@ -import {createContext, useContext, useEffect, useState} from 'react'; -import {fetchData} from '../components/services/Fetch'; -import {Loader} from '../components/ui/Loader'; +import { createContext, useContext, useEffect, useState } from 'react'; +import { fetchData } from '../components/services/Fetch'; +import throwError from '../components/services/throwError'; +import { Loader } from '../components/ui/Loader'; const AuthContext = createContext(); -export const AuthProviders = ({children}) => { +export const AuthProviders = ({ children }) => { const [currentUser, setCurrentUser] = useState(null); - const [token, setToken] = useState(localStorage.getItem('token') || null); const [loading, setLoading] = useState(true); - const apiUrl = import.meta.env.VITE_API_URL; useEffect(() => { async function validateToken() { - if (!token) return setLoading(false); + const apiUrl = import.meta.env.VITE_API_URL; + const token = localStorage.getItem('token') || null; + if (!token) {return setLoading(false);} fetchData(`${apiUrl}api/auth/me`, { - headers: {Authorization: `Bearer ${token}`}, + headers: { Authorization: `Bearer ${token}` }, }) .then((data) => { - const {user} = data; + const { user } = data; setLoading(false); return setCurrentUser(user); }) .catch((error) => { setLoading(false); localStorage.removeItem('token'); - console.log(error); + throwError(error); }); } diff --git a/frontend/vite.config.js b/frontend/vite.config.js index 27aa0e2..6ab5297 100644 --- a/frontend/vite.config.js +++ b/frontend/vite.config.js @@ -1,5 +1,5 @@ import react from '@vitejs/plugin-react'; -import {defineConfig} from 'vite'; +import { defineConfig } from 'vite'; export default defineConfig({ plugins: [react()],