168 lines
5.2 KiB
JavaScript
168 lines
5.2 KiB
JavaScript
import { useState, useEffect, useContext, useRef, useCallback } from 'react'
|
|
import Link from 'next/link'
|
|
import { UserContext } from '../../../contexts/UserContext'
|
|
import CommentCard from '../CommentCard/CommentCard'
|
|
import Loader from '../../Loader'
|
|
import api from '../../../utils/api'
|
|
import './FunctionComments.css'
|
|
|
|
const FunctionComments = ({ functionId }) => {
|
|
// State pour poster un commentaire
|
|
const { isAuth, user } = useContext(UserContext)
|
|
const [inputState, setInputState] = useState({})
|
|
|
|
// State pour afficher les commentaires
|
|
const [commentsData, setCommentsData] = useState({ hasMore: true, rows: [] })
|
|
const [isLoadingComments, setLoadingComments] = useState(true)
|
|
const [pageComments, setPageComments] = useState(1)
|
|
|
|
// Récupère les commentaires si la page change
|
|
useEffect(() => {
|
|
getCommentsData().then(data =>
|
|
setCommentsData({
|
|
hasMore: data.hasMore,
|
|
rows: [...commentsData.rows, ...data.rows]
|
|
})
|
|
)
|
|
}, [pageComments])
|
|
|
|
// Permet la pagination au scroll
|
|
const observer = useRef()
|
|
const lastCommentCardRef = useCallback(
|
|
node => {
|
|
if (isLoadingComments) return
|
|
if (observer.current) observer.current.disconnect()
|
|
observer.current = new window.IntersectionObserver(
|
|
entries => {
|
|
if (entries[0].isIntersecting && commentsData.hasMore) {
|
|
setPageComments(pageComments + 1)
|
|
}
|
|
},
|
|
{ threshold: 1 }
|
|
)
|
|
if (node) observer.current.observe(node)
|
|
},
|
|
[isLoadingComments, commentsData.hasMore]
|
|
)
|
|
|
|
const getCommentsData = async () => {
|
|
setLoadingComments(true)
|
|
const { data } = await api.get(
|
|
`/comments/${functionId}/?page=${pageComments}&limit=10`
|
|
)
|
|
setLoadingComments(false)
|
|
return data
|
|
}
|
|
|
|
const handleChange = event => {
|
|
const inputStateNew = { ...inputState }
|
|
inputStateNew[event.target.name] = event.target.value
|
|
setInputState(inputStateNew)
|
|
}
|
|
|
|
const handleSubmit = async event => {
|
|
setLoadingComments(true)
|
|
event.preventDefault()
|
|
const token = user.token
|
|
if (isAuth && token != null && inputState.commentPost != null) {
|
|
try {
|
|
const response = await api.post(
|
|
`/comments/${functionId}`,
|
|
{ message: inputState.commentPost },
|
|
{ headers: { Authorization: token } }
|
|
)
|
|
const comment = {
|
|
...response.data,
|
|
user: { name: user.name, logo: user.logo }
|
|
}
|
|
setCommentsData({
|
|
hasMore: commentsData.hasMore,
|
|
rows: [comment, ...commentsData.rows]
|
|
})
|
|
setInputState({ commentPost: '' })
|
|
} catch {}
|
|
}
|
|
setLoadingComments(false)
|
|
}
|
|
|
|
return (
|
|
<>
|
|
<div className='FunctionComments__post container-fluid'>
|
|
<div className='row FunctionComments__row'>
|
|
<div className='col-24'>
|
|
{isAuth ? (
|
|
<form onSubmit={handleSubmit}>
|
|
<div className='form-group FunctionComments__post-group'>
|
|
<label className='form-label' htmlFor='commentPost'>
|
|
Ajouter un commentaire :
|
|
</label>
|
|
<textarea
|
|
className='FunctionComments__textarea form-control'
|
|
value={inputState.commentPost}
|
|
onChange={handleChange}
|
|
name='commentPost'
|
|
id='commentPost'
|
|
placeholder="Idée d'amélioration, avis, remarque, partage d'expérience personnel, ... (Markdown autorisé)"
|
|
/>
|
|
</div>
|
|
<div className='form-group' style={{ marginTop: '0.7em' }}>
|
|
<button type='submit' className='btn btn-dark'>
|
|
Envoyer
|
|
</button>
|
|
</div>
|
|
</form>
|
|
) : (
|
|
<p className='text-center'>
|
|
Vous devez être{' '}
|
|
<Link href='/users/login'>
|
|
<a>connecté</a>
|
|
</Link>{' '}
|
|
pour poster un commentaire.
|
|
</p>
|
|
)}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div className='container-fluid'>
|
|
{isLoadingComments && (
|
|
<div className='row justify-content-center'>
|
|
<Loader />
|
|
</div>
|
|
)}
|
|
<div className='row justify-content-center'>
|
|
{commentsData.rows.map((comment, index) => {
|
|
// Si c'est le dernier élément
|
|
if (commentsData.rows.length === index + 1) {
|
|
return (
|
|
<CommentCard
|
|
key={comment.id}
|
|
ref={lastCommentCardRef}
|
|
{...comment}
|
|
manageComment={{
|
|
setCommentsData,
|
|
commentsData,
|
|
setLoadingComments
|
|
}}
|
|
/>
|
|
)
|
|
}
|
|
return (
|
|
<CommentCard
|
|
key={comment.id}
|
|
{...comment}
|
|
manageComment={{
|
|
setCommentsData,
|
|
commentsData,
|
|
setLoadingComments
|
|
}}
|
|
/>
|
|
)
|
|
})}
|
|
</div>
|
|
</div>
|
|
</>
|
|
)
|
|
}
|
|
|
|
export default FunctionComments
|