FunctionProject/website/components/FunctionPage/FunctionComments/FunctionComments.jsx

170 lines
5.3 KiB
React
Raw Normal View History

2020-08-03 12:04:07 +02:00
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 }) => {
2020-08-03 12:04:07 +02:00
// State pour poster un commentaire
const { isAuth, user } = useContext(UserContext)
const [inputState, setInputState] = useState({})
2020-08-03 12:04:07 +02:00
// State pour afficher les commentaires
const [commentsData, setCommentsData] = useState({ hasMore: true, rows: [] })
const [isLoadingComments, setLoadingComments] = useState(true)
const [pageComments, setPageComments] = useState(1)
2020-08-03 12:04:07 +02:00
// Récupère les commentaires si la page change
useEffect(() => {
2020-08-03 14:14:45 +02:00
getCommentsData().then(data =>
setCommentsData({
hasMore: data.hasMore,
rows: [...commentsData.rows, ...data.rows]
})
)
2020-08-03 12:04:07 +02:00
}, [pageComments])
2020-08-03 12:04:07 +02:00
// Permet la pagination au scroll
const observer = useRef()
2020-08-03 14:14:45 +02:00
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]
)
2020-08-03 12:04:07 +02:00
const getCommentsData = async () => {
setLoadingComments(true)
2020-08-03 14:14:45 +02:00
const { data } = await api.get(
`/comments/${functionId}/?page=${pageComments}&limit=10`
)
2020-08-03 12:04:07 +02:00
setLoadingComments(false)
return data
}
2020-08-03 14:14:45 +02:00
const handleChange = event => {
2020-08-03 12:04:07 +02:00
const inputStateNew = { ...inputState }
inputStateNew[event.target.name] = event.target.value
setInputState(inputStateNew)
}
2020-08-03 14:14:45 +02:00
const handleSubmit = async event => {
2020-08-03 12:04:07 +02:00
setLoadingComments(true)
event.preventDefault()
const token = user.token
if (isAuth && token != null && inputState.commentPost != null) {
try {
2020-08-03 14:14:45 +02:00
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]
})
2020-08-03 12:04:07 +02:00
setInputState({ commentPost: '' })
2020-08-03 14:14:45 +02:00
} catch {}
}
2020-08-03 12:04:07 +02:00
setLoadingComments(false)
}
2020-08-03 12:04:07 +02:00
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>
)}
2020-08-03 12:04:07 +02:00
</div>
</div>
</div>
<div className='container-fluid'>
2020-08-03 14:14:45 +02:00
{isLoadingComments && (
2020-08-03 12:04:07 +02:00
<div className='row justify-content-center'>
<Loader />
2020-08-03 14:14:45 +02:00
</div>
)}
2020-08-03 12:04:07 +02:00
<div className='row justify-content-center'>
{commentsData.rows.map((comment, index) => {
// Si c'est le dernier élément
if (commentsData.rows.length === index + 1) {
2020-08-03 14:14:45 +02:00
return (
<CommentCard
key={comment.id}
ref={lastCommentCardRef}
{...comment}
manageComment={{
setCommentsData,
commentsData,
setLoadingComments
}}
/>
)
2020-08-03 12:04:07 +02:00
}
2020-08-03 14:14:45 +02:00
return (
<CommentCard
key={comment.id}
{...comment}
manageComment={{
setCommentsData,
commentsData,
setLoadingComments
}}
/>
)
2020-08-03 12:04:07 +02:00
})}
</div>
</div>
</>
)
}
2020-08-03 12:04:07 +02:00
export default FunctionComments