Create CommentsList component
This commit is contained in:
@@ -9,3 +9,6 @@ NEXTAUTH_SECRET=NEXTAUTH_SECRET
|
|||||||
USER_ROLE=DIRECTUS_USER_ROLE_ID
|
USER_ROLE=DIRECTUS_USER_ROLE_ID
|
||||||
NEXT_PUBLIC_URL=http://0.0.0.0:3000
|
NEXT_PUBLIC_URL=http://0.0.0.0:3000
|
||||||
NEXT_PUBLIC_DIRECTUS_API_URL=$DIRECTUS_API_URL
|
NEXT_PUBLIC_DIRECTUS_API_URL=$DIRECTUS_API_URL
|
||||||
|
|
||||||
|
# COMMENTS
|
||||||
|
COMMENTS_PER_PAGE=5
|
||||||
|
|||||||
@@ -0,0 +1,111 @@
|
|||||||
|
/* eslint-disable camelcase */
|
||||||
|
import React, {useEffect, useState} from 'react'
|
||||||
|
import PropTypes from 'prop-types'
|
||||||
|
import List from '@mui/material/List'
|
||||||
|
import ListItem from '@mui/material/ListItem'
|
||||||
|
import ListItemText from '@mui/material/ListItemText'
|
||||||
|
import DialogTitle from '@mui/material/DialogTitle'
|
||||||
|
import Dialog from '@mui/material/Dialog'
|
||||||
|
import Typography from '@mui/material/Typography'
|
||||||
|
import Pagination from '@mui/material/Pagination'
|
||||||
|
import Divider from '@mui/material/Divider'
|
||||||
|
import Box from '@mui/material/Box'
|
||||||
|
import {readItems, withToken} from '@directus/sdk'
|
||||||
|
import {directusClient} from '@/lib/directus.js'
|
||||||
|
import {formatDate} from '@/lib/format.js'
|
||||||
|
|
||||||
|
const commentsPerPage = process.env.NEXT_PUBLIC_COMMENTS_PER_PAGE || 2
|
||||||
|
|
||||||
|
export default function CommentsList({session, selectedTitre, isOpen, setIsOpen, setError, setIsErrorAlertOpen}) {
|
||||||
|
const [comments, setComments] = useState([])
|
||||||
|
const [page, setPage] = useState(1)
|
||||||
|
|
||||||
|
const pageCount = Math.ceil(comments.length / commentsPerPage)
|
||||||
|
|
||||||
|
const startIndex = (page - 1) * commentsPerPage
|
||||||
|
const selectedComments = comments.slice(startIndex, startIndex + commentsPerPage)
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
async function fetchComments() {
|
||||||
|
try {
|
||||||
|
const result = await directusClient.request(withToken(
|
||||||
|
session.user.accessToken,
|
||||||
|
readItems('commentaires', {
|
||||||
|
filter: {
|
||||||
|
titre: selectedTitre.id
|
||||||
|
},
|
||||||
|
sort: '-date_created'
|
||||||
|
}))
|
||||||
|
)
|
||||||
|
|
||||||
|
setComments(result)
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to fetch comments', error)
|
||||||
|
setError(error.message)
|
||||||
|
setIsErrorAlertOpen(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isOpen) {
|
||||||
|
fetchComments()
|
||||||
|
}
|
||||||
|
}, [isOpen, selectedTitre, setError, setIsErrorAlertOpen, session])
|
||||||
|
|
||||||
|
const handleClose = () => {
|
||||||
|
setIsOpen(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleChange = (event, value) => {
|
||||||
|
setPage(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Dialog open={isOpen} onClose={handleClose}>
|
||||||
|
<DialogTitle>Commentaires</DialogTitle>
|
||||||
|
<List sx={{width: '100%', maxWidth: 360, bgcolor: 'background.paper'}}>
|
||||||
|
{selectedComments && selectedComments.length > 0 ? selectedComments.map(({id, date_created, text, user_created}) => (
|
||||||
|
<React.Fragment key={id}>
|
||||||
|
<ListItem alignItems='flex-start'>
|
||||||
|
<ListItemText
|
||||||
|
primary={
|
||||||
|
<Typography sx={{textDecoration: 'underline'}} component='span' variant='body2'>
|
||||||
|
{user_created.split('-')[0]}
|
||||||
|
</Typography>
|
||||||
|
}
|
||||||
|
secondary={
|
||||||
|
<>
|
||||||
|
<Typography
|
||||||
|
sx={{display: 'inline'}}
|
||||||
|
component='span'
|
||||||
|
variant='body2'
|
||||||
|
color='text.primary'
|
||||||
|
>
|
||||||
|
{text}
|
||||||
|
</Typography>
|
||||||
|
{` — ${formatDate(date_created, 'PPPPpppp')}`}
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</ListItem>
|
||||||
|
|
||||||
|
<Divider component='li' />
|
||||||
|
</React.Fragment>
|
||||||
|
)) : (
|
||||||
|
<Typography textAlign='center'>Aucun commentaire</Typography>
|
||||||
|
)}
|
||||||
|
</List>
|
||||||
|
<Box sx={{display: 'flex', justifyContent: 'center'}}>
|
||||||
|
<Pagination size='small' sx={{marginBlock: 3}} color='success' count={pageCount} page={page} onChange={handleChange} />
|
||||||
|
</Box>
|
||||||
|
</Dialog>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
CommentsList.propTypes = {
|
||||||
|
session: PropTypes.object,
|
||||||
|
selectedTitre: PropTypes.object.isRequired,
|
||||||
|
isOpen: PropTypes.bool.isRequired,
|
||||||
|
setIsOpen: PropTypes.func.isRequired,
|
||||||
|
setError: PropTypes.func.isRequired,
|
||||||
|
setIsErrorAlertOpen: PropTypes.func.isRequired
|
||||||
|
}
|
||||||
@@ -6,11 +6,13 @@ import Paper from '@mui/material/Paper'
|
|||||||
import {styled} from '@mui/material/styles'
|
import {styled} from '@mui/material/styles'
|
||||||
import IconButton from '@mui/material/IconButton'
|
import IconButton from '@mui/material/IconButton'
|
||||||
import AddCommentIcon from '@mui/icons-material/AddComment'
|
import AddCommentIcon from '@mui/icons-material/AddComment'
|
||||||
|
import CommentIcon from '@mui/icons-material/Comment'
|
||||||
import Tooltip, {tooltipClasses} from '@mui/material/Tooltip'
|
import Tooltip, {tooltipClasses} from '@mui/material/Tooltip'
|
||||||
import AuthAlert from '../auth-form/auth-alert.js'
|
import AuthAlert from '../auth-form/auth-alert.js'
|
||||||
import Titre from './titre.js'
|
import Titre from './titre.js'
|
||||||
import Article from './article.js'
|
import Article from './article.js'
|
||||||
import HandleComments from './handle-comments.js'
|
import HandleComments from './handle-comments.js'
|
||||||
|
import CommentsList from './comments-list.js'
|
||||||
import {formatKonstitisyon} from '@/lib/format.js'
|
import {formatKonstitisyon} from '@/lib/format.js'
|
||||||
|
|
||||||
const LightTooltip = styled(({className, ...props}) => (
|
const LightTooltip = styled(({className, ...props}) => (
|
||||||
@@ -26,16 +28,23 @@ const LightTooltip = styled(({className, ...props}) => (
|
|||||||
|
|
||||||
export default function Konstitisyon({session, titres, articles}) {
|
export default function Konstitisyon({session, titres, articles}) {
|
||||||
const konstitisyon = formatKonstitisyon(titres, articles)
|
const konstitisyon = formatKonstitisyon(titres, articles)
|
||||||
const [isOpen, setIsOpen] = useState(false)
|
const [isWriteCommentsOpen, setIsWriteCommentsOpen] = useState(false)
|
||||||
|
const [isReadCommentsOpen, setIsReadCommentsOpen] = useState(false)
|
||||||
const [isErrorAlertOpen, setIsErrorAlertOpen] = useState(false)
|
const [isErrorAlertOpen, setIsErrorAlertOpen] = useState(false)
|
||||||
const [isSuccessAlertOpen, setIsSuccessAlertOpen] = useState(false)
|
const [isSuccessAlertOpen, setIsSuccessAlertOpen] = useState(false)
|
||||||
const [selectedTitre, setSelectedTitre] = useState(null)
|
const [selectedTitre, setSelectedTitre] = useState(null)
|
||||||
const [error, setError] = useState('')
|
const [error, setError] = useState('')
|
||||||
const [success, setSuccess] = useState('')
|
const [success, setSuccess] = useState('')
|
||||||
|
|
||||||
const handleCommentsDialog = (titreId, titre) => {
|
const handleCommentsDialog = (titreId, titre, action) => {
|
||||||
setSelectedTitre({id: titreId, titre})
|
setSelectedTitre({id: titreId, titre})
|
||||||
setIsOpen(true)
|
|
||||||
|
if (action === 'write') {
|
||||||
|
setIsWriteCommentsOpen(true)
|
||||||
|
} else if (action === 'read') {
|
||||||
|
console.log('read comment')
|
||||||
|
setIsReadCommentsOpen(true)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -62,27 +71,48 @@ export default function Konstitisyon({session, titres, articles}) {
|
|||||||
<Article key={id} session={session} articleId={id} numero={numero} contenu={contenu} />
|
<Article key={id} session={session} articleId={id} numero={numero} contenu={contenu} />
|
||||||
))}
|
))}
|
||||||
{session && (
|
{session && (
|
||||||
<Box sx={{textAlign: 'right'}}>
|
<Box sx={{display: 'flex', justifyContent: 'space-between'}}>
|
||||||
<IconButton size='large' aria-label='commenter' onClick={() => handleCommentsDialog(titreId, titre)}>
|
<Box>
|
||||||
|
<IconButton size='large' aria-label='Voir les commentaires' onClick={() => handleCommentsDialog(titreId, titre, 'read')}>
|
||||||
|
<LightTooltip title='Voir les commentaires'>
|
||||||
|
<CommentIcon color='warning' fontSize='inherit' />
|
||||||
|
</LightTooltip>
|
||||||
|
</IconButton>
|
||||||
|
</Box>
|
||||||
|
<Box>
|
||||||
|
<IconButton size='large' aria-label='commenter' onClick={() => handleCommentsDialog(titreId, titre, 'write')}>
|
||||||
<LightTooltip title='Commenter'>
|
<LightTooltip title='Commenter'>
|
||||||
<AddCommentIcon color='warning' fontSize='inherit' />
|
<AddCommentIcon color='warning' fontSize='inherit' />
|
||||||
</LightTooltip>
|
</LightTooltip>
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</Box>
|
</Box>
|
||||||
|
</Box>
|
||||||
)}
|
)}
|
||||||
</Paper>
|
</Paper>
|
||||||
))}
|
))}
|
||||||
{selectedTitre && (
|
{selectedTitre && (
|
||||||
|
<>
|
||||||
<HandleComments
|
<HandleComments
|
||||||
session={session}
|
session={session}
|
||||||
selectedTitre={selectedTitre}
|
selectedTitre={selectedTitre}
|
||||||
isOpen={isOpen}
|
isOpen={isWriteCommentsOpen}
|
||||||
setIsOpen={setIsOpen}
|
setIsOpen={setIsWriteCommentsOpen}
|
||||||
setError={setError}
|
setError={setError}
|
||||||
setSuccess={setSuccess}
|
setSuccess={setSuccess}
|
||||||
setIsErrorAlertOpen={setIsErrorAlertOpen}
|
setIsErrorAlertOpen={setIsErrorAlertOpen}
|
||||||
setIsSuccessAlertOpen={setIsSuccessAlertOpen}
|
setIsSuccessAlertOpen={setIsSuccessAlertOpen}
|
||||||
/>
|
/>
|
||||||
|
<CommentsList
|
||||||
|
session={session}
|
||||||
|
selectedTitre={selectedTitre}
|
||||||
|
isOpen={isReadCommentsOpen}
|
||||||
|
setIsOpen={setIsReadCommentsOpen}
|
||||||
|
setError={setError}
|
||||||
|
setSuccess={setSuccess}
|
||||||
|
setIsErrorAlertOpen={setIsErrorAlertOpen}
|
||||||
|
setIsSuccessAlertOpen={setIsSuccessAlertOpen}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
)}
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
</>
|
</>
|
||||||
|
|||||||
Reference in New Issue
Block a user