115 lines
4.5 KiB
JavaScript
115 lines
4.5 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
|