diff --git a/website/components/FunctionCard/FunctionCard.jsx b/website/components/FunctionCard/FunctionCard.jsx index 1f409c7..42565b9 100644 --- a/website/components/FunctionCard/FunctionCard.jsx +++ b/website/components/FunctionCard/FunctionCard.jsx @@ -2,7 +2,7 @@ import Link from 'next/link' import { useState, forwardRef, memo } from 'react' import date from 'date-and-time' import Loader from '../Loader' -import { API_URL } from '../../utils/config/config' +import { API_URL } from '../../utils/api' import './FunctionCard.css' const FunctionCard = memo( diff --git a/website/components/FunctionPage/CommentCard/CommentCard.jsx b/website/components/FunctionPage/CommentCard/CommentCard.jsx index 1faf419..fc18dc6 100644 --- a/website/components/FunctionPage/CommentCard/CommentCard.jsx +++ b/website/components/FunctionPage/CommentCard/CommentCard.jsx @@ -3,10 +3,9 @@ import { useEffect, useState, forwardRef, useContext } from 'react' import date from 'date-and-time' import htmlParser from 'html-react-parser' import { UserContext } from '../../../contexts/UserContext' -import { API_URL } from '../../../utils/config/config' import ReactMarkdown from 'react-markdown' import CodeBlock from '../../CodeBlock' -import api from '../../../utils/api' +import api, { API_URL } from '../../../utils/api' import './CommentCard.css' const CommentCard = forwardRef((props, ref) => { diff --git a/website/components/FunctionPage/FunctionComponentTop.jsx b/website/components/FunctionPage/FunctionComponentTop.jsx index cedc34c..0f8b55a 100644 --- a/website/components/FunctionPage/FunctionComponentTop.jsx +++ b/website/components/FunctionPage/FunctionComponentTop.jsx @@ -5,8 +5,7 @@ import { faStar } from '@fortawesome/free-solid-svg-icons' import { faStar as farStar } from '@fortawesome/free-regular-svg-icons' import date from 'date-and-time' import { UserContext } from '../../contexts/UserContext' -import api from '../../utils/api' -import { API_URL } from '../../utils/config/config' +import api, { API_URL } from '../../utils/api' import '../FunctionCard/FunctionCard.css' const FunctionComponentTop = props => { diff --git a/website/components/FunctionPage/FunctionPage.jsx b/website/components/FunctionPage/FunctionPage.jsx index 3b71a36..3c38343 100644 --- a/website/components/FunctionPage/FunctionPage.jsx +++ b/website/components/FunctionPage/FunctionPage.jsx @@ -1,5 +1,5 @@ import { useState } from 'react' -import { API_URL } from '../../utils/config/config' +import { API_URL } from '../../utils/api' import HeadTag from '../HeadTag' import FunctionTabsTop from './FunctionTabsTop' import FunctionComponentTop from './FunctionComponentTop' diff --git a/website/components/UserCard/UserCard.jsx b/website/components/UserCard/UserCard.jsx index 22fae0e..767306f 100644 --- a/website/components/UserCard/UserCard.jsx +++ b/website/components/UserCard/UserCard.jsx @@ -1,6 +1,6 @@ import Link from 'next/link' import { forwardRef, memo } from 'react' -import { API_URL } from '../../utils/config/config' +import { API_URL } from '../../utils/api' import './UserCard.css' const UserCard = memo( diff --git a/website/pages/404.jsx b/website/pages/404.jsx index d23a327..4d72f67 100644 --- a/website/pages/404.jsx +++ b/website/pages/404.jsx @@ -10,9 +10,14 @@ const Error404 = () => ( image='/images/error404.png' />
-

Erreur 404

+

+ Erreur 404 +

- Cette page n'existe pas! Revenir à la page d'accueil ? + Cette page n'existe pas!{' '} + + Revenir à la page d'accueil ? +

diff --git a/website/pages/about.jsx b/website/pages/about.jsx index 2ebd5be..eae9d1e 100644 --- a/website/pages/about.jsx +++ b/website/pages/about.jsx @@ -2,7 +2,7 @@ import axios from 'axios' import ReactMarkdown from 'react-markdown/with-html' import HeadTag from '../components/HeadTag' -const About = (props) => { +const About = props => { return ( <> {

À-propos

-

(README.md du GitHub)

+

+ (README.md du{' '} + + GitHub + + ) +

@@ -24,9 +40,11 @@ const About = (props) => { source={props.data} escapeHtml={false} linkTarget='_blank' - transformLinkUri={(uri) => { + transformLinkUri={uri => { if (uri.startsWith('./')) { - return `https://github.com/Divlo/FunctionProject/blob/master/${uri.slice(2)}` + return `https://github.com/Divlo/FunctionProject/blob/master/${uri.slice( + 2 + )}` } return uri }} @@ -39,7 +57,9 @@ const About = (props) => { } export async function getServerSideProps (_context) { - const { data } = await axios.get('https://raw.githubusercontent.com/Divlo/FunctionProject/master/README.md') + const { data } = await axios.get( + 'https://raw.githubusercontent.com/Divlo/FunctionProject/master/README.md' + ) return { props: { data } } diff --git a/website/pages/admin/[slug].jsx b/website/pages/admin/[slug].jsx index b5cc43d..73b979e 100644 --- a/website/pages/admin/[slug].jsx +++ b/website/pages/admin/[slug].jsx @@ -6,42 +6,68 @@ import AddEditFunction from '../../components/FunctionAdmin/AddEditFunction' import EditArticleFunction from '../../components/FunctionAdmin/EditArticleFunction' import EditFormFunction from '../../components/FunctionAdmin/EditFormFunction' import redirect from '../../utils/redirect' -import api from '../../utils/api' -import { API_URL } from '../../utils/config/config' +import api, { API_URL } from '../../utils/api' import '../../components/FunctionPage/FunctionTabs.css' import '../../public/css/pages/admin.css' -const AdminFunctionComponent = (props) => { +const AdminFunctionComponent = props => { const [slideIndex, setSlideIndex] = useState(0) const handleDeleteFunction = async () => { - await api.delete(`/admin/functions/${props.functionInfo.id}`, { headers: { Authorization: props.user.token } }) + await api.delete(`/admin/functions/${props.functionInfo.id}`, { + headers: { Authorization: props.user.token } + }) redirect({}, '/admin') } return ( <> - +
- setSlideIndex(index)} index={slideIndex}> + setSlideIndex(index)} + index={slideIndex} + >
{ isEditing />
- +
@@ -72,8 +100,9 @@ export async function getServerSideProps (context) { if (!user.isAdmin) { return redirect(context, '/404') } - return api.get(`/admin/functions/${slug}`, { headers: { Authorization: user.token } }) - .then((response) => { + return api + .get(`/admin/functions/${slug}`, { headers: { Authorization: user.token } }) + .then(response => { return { props: { user, diff --git a/website/pages/admin/index.jsx b/website/pages/admin/index.jsx index 55c17d7..cacc811 100644 --- a/website/pages/admin/index.jsx +++ b/website/pages/admin/index.jsx @@ -10,54 +10,77 @@ import AddEditFunction from '../../components/FunctionAdmin/AddEditFunction' import redirect from '../../utils/redirect' import '../../public/css/pages/admin.css' -const Admin = (props) => { +const Admin = props => { const [isOpen, setIsOpen] = useState(false) const toggleModal = () => setIsOpen(!isOpen) return ( <> - + {/* Création d'une fonction */} - {(isOpen) - ? ( - -
-
-
-
-
- - - -

Crée une nouvelle fonction

-
+ {isOpen ? ( + +
+
+
+
+
+ + + +

Crée une nouvelle fonction

+
-
- -
+
+
- - ) - - : ( - -
-

Administration

- - - - - - - -
-
- )} +
+
+ ) : ( + +
+

Administration

+ + + + + + + +
+
+ )} ) } diff --git a/website/pages/admin/manageCategories.jsx b/website/pages/admin/manageCategories.jsx index 0bce32a..5d76e82 100644 --- a/website/pages/admin/manageCategories.jsx +++ b/website/pages/admin/manageCategories.jsx @@ -15,23 +15,36 @@ import '../../public/css/pages/admin.css' const defaultCategoryState = { name: '', color: '#ffffff' } -const AddEditCategory = (props) => { +const AddEditCategory = props => { const [inputState, setInputState] = useState(props.defaultInputState) const [message, setMessage] = useState('') const [isLoading, setIsLoading] = useState(false) const handleChange = (event, isTypeCheck = false) => { const inputStateNew = { ...inputState } - inputStateNew[event.target.name] = (event.target.files != null) ? event.target.files[0] : (isTypeCheck) ? event.target.checked : event.target.value + inputStateNew[event.target.name] = + event.target.files != null + ? event.target.files[0] + : isTypeCheck + ? event.target.checked + : event.target.value setInputState(inputStateNew) } const apiCallCategory = () => { - if (props.isEditing) return api.put(`/admin/categories/${inputState.id}`, { name: inputState.name, color: inputState.color }, { headers: { Authorization: props.user.token } }) - return api.post('/admin/categories', inputState, { headers: { Authorization: props.user.token } }) + if (props.isEditing) { + return api.put( + `/admin/categories/${inputState.id}`, + { name: inputState.name, color: inputState.color }, + { headers: { Authorization: props.user.token } } + ) + } + return api.post('/admin/categories', inputState, { + headers: { Authorization: props.user.token } + }) } - const handleSubmit = (event) => { + const handleSubmit = event => { event.preventDefault() setIsLoading(true) apiCallCategory() @@ -39,8 +52,10 @@ const AddEditCategory = (props) => { setIsLoading(false) window.location.reload(true) }) - .catch((error) => { - setMessage(`

Erreur: ${error.response.data.message}

`) + .catch(error => { + setMessage( + `

Erreur: ${error.response.data.message}

` + ) setIsLoading(false) }) } @@ -51,10 +66,20 @@ const AddEditCategory = (props) => {
- - + + -

{(props.isEditing) ? 'Modifier la catégorie' : 'Crée une nouvelle catégorie'}

+

+ {props.isEditing + ? 'Modifier la catégorie' + : 'Crée une nouvelle catégorie'} +

@@ -62,25 +87,39 @@ const AddEditCategory = (props) => {
- - + +
- - handleChange({ target: { name: 'color', value: color.hex } })} /> + + + handleChange({ target: { name: 'color', value: color.hex } })} + />
- +
- { - (isLoading) - ? - : htmlParser(message) - } + {isLoading ? : htmlParser(message)}
@@ -88,22 +127,26 @@ const AddEditCategory = (props) => { ) } -const manageCategories = (props) => { +const manageCategories = props => { const [, categories] = useAPI('/categories') const [isOpen, setIsOpen] = useState(false) const [isEditing, setIsEditing] = useState(false) - const [defaultInputState, setDefaultInputState] = useState(defaultCategoryState) + const [defaultInputState, setDefaultInputState] = useState( + defaultCategoryState + ) const toggleModal = () => setIsOpen(!isOpen) - const handleRemoveCategory = async (categoryId) => { + const handleRemoveCategory = async categoryId => { try { - await api.delete(`/admin/categories/${categoryId}`, { headers: { Authorization: props.user.token } }) + await api.delete(`/admin/categories/${categoryId}`, { + headers: { Authorization: props.user.token } + }) window.location.reload(true) } catch {} } - const handleEditCategory = (categoryInfo) => { + const handleEditCategory = categoryInfo => { setDefaultInputState(categoryInfo) setIsEditing(true) toggleModal() @@ -111,64 +154,124 @@ const manageCategories = (props) => { return ( <> - + - { - (isOpen) - ? ( - - - - ) - : ( -
-
-
-

Gérer les catégories

- -
-
-
-
-
- - - - - - - - - - + {isOpen ? ( + + + + ) : ( +
+
+
+

Gérer les catégories

+ +
+
+
+
+
+
idnamecolorcreatedAtupdatedAtModifierSupprimer
+ + + + + + + + + + + + + {categories.map(category => { + return ( + + + + + + + + - - - {categories.map((category) => { - return ( - - - - - - - - - - ) - })} - -
+ id + + name + + color + + createdAt + + updatedAt + + Modifier + + Supprimer +
{category.id}{category.name}{category.color} + {date.format( + new Date(category.createdAt), + 'DD/MM/YYYY à HH:mm', + true + )} + + {date.format( + new Date(category.updatedAt), + 'DD/MM/YYYY à HH:mm', + true + )} + + handleEditCategory({ + name: category.name, + color: category.color, + id: category.id + })} + > + + handleRemoveCategory(category.id)} + > + +
{category.id}{category.name}{category.color}{date.format(new Date(category.createdAt), 'DD/MM/YYYY à HH:mm', true)}{date.format(new Date(category.updatedAt), 'DD/MM/YYYY à HH:mm', true)} handleEditCategory({ name: category.name, color: category.color, id: category.id })}> - - handleRemoveCategory(category.id)}> - -
-
-
+ ) + })} + +
- ) - } +
+
+ )} ) } diff --git a/website/pages/admin/manageQuotes.jsx b/website/pages/admin/manageQuotes.jsx index 0227fda..815b9db 100644 --- a/website/pages/admin/manageQuotes.jsx +++ b/website/pages/admin/manageQuotes.jsx @@ -8,8 +8,12 @@ import HeadTag from '../../components/HeadTag' import api from '../../utils/api' import '../../public/css/pages/admin.css' -const manageQuotes = (props) => { - const [quotesData, setQuotesData] = useState({ hasMore: true, rows: [], totalItems: 0 }) +const manageQuotes = props => { + const [quotesData, setQuotesData] = useState({ + hasMore: true, + rows: [], + totalItems: 0 + }) const [isLoadingQuotes, setLoadingQuotes] = useState(true) const [pageQuotes, setPageQuotes] = useState(1) @@ -20,7 +24,9 @@ const manageQuotes = (props) => { const getQuotesData = async () => { setLoadingQuotes(true) - const { data } = await api.get(`/admin/quotes?limit=20page=${pageQuotes}`, { headers: { Authorization: props.user.token } }) + const { data } = await api.get(`/admin/quotes?limit=20page=${pageQuotes}`, { + headers: { Authorization: props.user.token } + }) setQuotesData({ hasMore: data.hasMore, rows: [...quotesData.rows, ...data.rows], @@ -31,33 +37,48 @@ const manageQuotes = (props) => { // Permet la pagination au scroll const observer = useRef() - const lastQuoteRef = useCallback((node) => { - if (isLoadingQuotes) return - if (observer.current) observer.current.disconnect() - observer.current = new window.IntersectionObserver((entries) => { - if (entries[0].isIntersecting && quotesData.hasMore) { - setPageQuotes(pageQuotes + 1) - } - }, { threshold: 1 }) - if (node) observer.current.observe(node) - }, [isLoadingQuotes, quotesData.hasMore]) + const lastQuoteRef = useCallback( + node => { + if (isLoadingQuotes) return + if (observer.current) observer.current.disconnect() + observer.current = new window.IntersectionObserver( + entries => { + if (entries[0].isIntersecting && quotesData.hasMore) { + setPageQuotes(pageQuotes + 1) + } + }, + { threshold: 1 } + ) + if (node) observer.current.observe(node) + }, + [isLoadingQuotes, quotesData.hasMore] + ) const handleValidationQuote = async (id, isValid) => { try { - await api.put(`/admin/quotes/${id}`, { isValid }, { headers: { Authorization: props.user.token } }) + await api.put( + `/admin/quotes/${id}`, + { isValid }, + { headers: { Authorization: props.user.token } } + ) window.location.reload(true) } catch {} } return ( <> - +

Liste des citations (non validées) :

-

Total de {quotesData.totalItems} citations.

+

+ Total de {quotesData.totalItems} citations. +

@@ -66,35 +87,72 @@ const manageQuotes = (props) => { - - - - - + + + + + {quotesData.rows.map((currentQuote, index) => { const quoteJSX = ( <> - - + + - - ) // Si c'est le dernier élément if (quotesData.rows.length === index + 1) { - return {quoteJSX} + return ( + + {quoteJSX} + + ) } return {quoteJSX} })} diff --git a/website/pages/functions/[slug].jsx b/website/pages/functions/[slug].jsx index 3ca4859..e7a90f7 100644 --- a/website/pages/functions/[slug].jsx +++ b/website/pages/functions/[slug].jsx @@ -7,12 +7,18 @@ import redirect from '../../utils/redirect' import api from '../../utils/api' import '../../public/css/pages/FunctionComponent.css' -const FunctionTabManager = (props) => { +const FunctionTabManager = props => { if (props.type === 'form') { return ( - +
- +
@@ -25,7 +31,10 @@ const FunctionTabManager = (props) => { } return ( - +
@@ -36,18 +45,23 @@ const FunctionTabManager = (props) => { ) } -const FunctionComponent = (props) => ( +const FunctionComponent = props => ( ) export async function getServerSideProps (context) { const { slug } = context.params - return api.get(`/functions/${slug}`) - .then((response) => ({ props: response.data })) + return api + .get(`/functions/${slug}`) + .then(response => ({ props: response.data })) .catch(() => redirect(context, '/404')) } diff --git a/website/pages/functions/chronometerTimer.jsx b/website/pages/functions/chronometerTimer.jsx index e7885c4..c5c5350 100644 --- a/website/pages/functions/chronometerTimer.jsx +++ b/website/pages/functions/chronometerTimer.jsx @@ -30,7 +30,7 @@ const Chronometer = () => { } else { if (interval) clearInterval(interval) interval = setInterval(() => { - setTimeLength((time) => time + 1) + setTimeLength(time => time + 1) }, 1000) } setIsPlaying(!isPlaying) @@ -44,7 +44,10 @@ const Chronometer = () => { const getFormattedValue = () => { const minutesAndSeconds = convertSeconds(timeLength) - const minutes = (minutesAndSeconds.minutes < 100) ? (('0' + minutesAndSeconds.minutes).slice(-2)) : minutesAndSeconds.minutes + const minutes = + minutesAndSeconds.minutes < 100 + ? ('0' + minutesAndSeconds.minutes).slice(-2) + : minutesAndSeconds.minutes const seconds = ('0' + minutesAndSeconds.seconds).slice(-2) return `${minutes}:${seconds}` } @@ -65,9 +68,15 @@ const Chronometer = () => {
-
@@ -82,14 +91,24 @@ const Chronometer = () => { const Pomodoro = () => { return (
- } /> + } + />
) } -const FunctionTabManager = (props) => { +const FunctionTabManager = props => { return ( - +
@@ -106,17 +125,23 @@ const FunctionTabManager = (props) => { ) } -const chronometerTimer = (props) => ( +const chronometerTimer = props => ( ) export async function getServerSideProps (context) { - return api.get('/functions/chronometerTimer') - .then((response) => ({ props: response.data })) + return api + .get('/functions/chronometerTimer') + .then(response => ({ props: response.data })) .catch(() => redirect(context, '/404')) } diff --git a/website/pages/functions/randomQuote.jsx b/website/pages/functions/randomQuote.jsx index a5b6011..0fbb2ff 100644 --- a/website/pages/functions/randomQuote.jsx +++ b/website/pages/functions/randomQuote.jsx @@ -43,8 +43,16 @@ const GenerateQuote = () => {
- - + +
@@ -53,7 +61,10 @@ const GenerateQuote = () => {

- {quote?.author}

-
+
{ let pageQuotes = 1 const QuoteList = () => { - const [quotesData, setQuotesData] = useState({ hasMore: true, rows: [], totalItems: 0 }) + const [quotesData, setQuotesData] = useState({ + hasMore: true, + rows: [], + totalItems: 0 + }) const [isLoadingQuotes, setLoadingQuotes] = useState(true) // Récupère les citations initiales useEffect(() => { - getQuotesData().then((data) => setQuotesData(data)) + getQuotesData().then(data => setQuotesData(data)) }, []) const getQuotesData = async () => { @@ -86,32 +101,40 @@ const QuoteList = () => { // Permet la pagination au scroll const observer = useRef() - const lastQuoteRef = useCallback((node) => { - if (isLoadingQuotes) return - if (observer.current) observer.current.disconnect() - observer.current = new window.IntersectionObserver((entries) => { - if (entries[0].isIntersecting && quotesData.hasMore) { - pageQuotes += 1 - getQuotesData().then((data) => { - setQuotesData((oldData) => { - return { - hasMore: data.hasMore, - rows: [...oldData.rows, ...data.rows], - totalItems: data.totalItems - } - }) - }) - } - }, { threshold: 1 }) - if (node) observer.current.observe(node) - }, [isLoadingQuotes, quotesData.hasMore]) + const lastQuoteRef = useCallback( + node => { + if (isLoadingQuotes) return + if (observer.current) observer.current.disconnect() + observer.current = new window.IntersectionObserver( + entries => { + if (entries[0].isIntersecting && quotesData.hasMore) { + pageQuotes += 1 + getQuotesData().then(data => { + setQuotesData(oldData => { + return { + hasMore: data.hasMore, + rows: [...oldData.rows, ...data.rows], + totalItems: data.totalItems + } + }) + }) + } + }, + { threshold: 1 } + ) + if (node) observer.current.observe(node) + }, + [isLoadingQuotes, quotesData.hasMore] + ) return (

Liste des citations :

-

Total de {quotesData.totalItems} citations.

+

+ Total de {quotesData.totalItems} citations. +

@@ -120,19 +143,32 @@ const QuoteList = () => {
Citation/ProverbeAuteurProposée parValiderSupprimer + Citation/Proverbe + + Auteur + + Proposée par + + Valider + + Supprimer +
{currentQuote.quote}{currentQuote.author} - + {currentQuote.quote} + + {currentQuote.author} + + {currentQuote.user.name} handleValidationQuote(currentQuote.id, true)} className='table-row text-center' style={{ cursor: 'pointer' }}> - + + handleValidationQuote(currentQuote.id, true)} + className='table-row text-center' + style={{ cursor: 'pointer' }} + > + handleValidationQuote(currentQuote.id, false)} className='table-row text-center' style={{ cursor: 'pointer' }}> - + + handleValidationQuote(currentQuote.id, false)} + className='table-row text-center' + style={{ cursor: 'pointer' }} + > +
- - - + + + {quotesData.rows.map((currentQuote, index) => { const quoteJSX = ( <> - - + + @@ -140,7 +176,11 @@ const QuoteList = () => { ) // Si c'est le dernier élément if (quotesData.rows.length === index + 1) { - return {quoteJSX} + return ( + + {quoteJSX} + + ) } return {quoteJSX} })} @@ -158,25 +198,30 @@ const SuggestQuote = () => { const [message, setMessage] = useState('') const [isLoading, setIsLoading] = useState(false) - const handleChange = (event) => { + const handleChange = event => { const inputStateNew = { ...inputState } inputStateNew[event.target.name] = event.target.value setInputState(inputStateNew) } - const handleSubmit = (event) => { + const handleSubmit = event => { setIsLoading(true) event.preventDefault() const token = user.token if (isAuth && token != null) { - api.post('/quotes', inputState, { headers: { Authorization: token } }) + api + .post('/quotes', inputState, { headers: { Authorization: token } }) .then(({ data }) => { setInputState({ quote: '', author: '' }) - setMessage(`

Succès: ${data.message}

`) + setMessage( + `

Succès: ${data.message}

` + ) setIsLoading(false) }) - .catch((error) => { - setMessage(`

Erreur: ${error.response.data.message}

`) + .catch(error => { + setMessage( + `

Erreur: ${error.response.data.message}

` + ) setIsLoading(false) }) } @@ -185,7 +230,11 @@ const SuggestQuote = () => { if (!isAuth) { return (

- Vous devez être connecté pour proposer une citation. + Vous devez être{' '} + + connecté + {' '} + pour proposer une citation.

) } @@ -195,42 +244,68 @@ const SuggestQuote = () => {

Proposer une citation :

-

Vous pouvez proposer des citations, et une fois validé elles seront rajoutés à la liste des citations.

+

+ Vous pouvez proposer des citations, et une fois validé elles seront + rajoutés à la liste des citations. +

- -
Citation/ProverbeAuteurProposée par + Citation/Proverbe + + Auteur + + Proposée par +
{currentQuote.quote}{currentQuote.author} - + {currentQuote.quote} + + {currentQuote.author} + + {currentQuote.user.name}