diff --git a/components/konstitisyon/handle-comments.js b/components/konstitisyon/handle-comments.js
new file mode 100644
index 0000000..b4d0c52
--- /dev/null
+++ b/components/konstitisyon/handle-comments.js
@@ -0,0 +1,117 @@
+'use client'
+
+import {useRef} from 'react'
+import PropTypes from 'prop-types'
+import Button from '@mui/material/Button'
+import TextField from '@mui/material/TextField'
+import Dialog from '@mui/material/Dialog'
+import DialogActions from '@mui/material/DialogActions'
+import DialogContent from '@mui/material/DialogContent'
+import DialogContentText from '@mui/material/DialogContentText'
+import DialogTitle from '@mui/material/DialogTitle'
+import {createItem, withToken} from '@directus/sdk'
+import LogoutCountdown from '../session/logout-countdown.js'
+import {directusClient} from '@/lib/directus.js'
+
+function hasRestrictedChar(text) {
+ const regex = /[<>&'"]/g
+
+ return Boolean(regex.test(text))
+}
+
+export default function HandleComments({session, selectedTitre, isOpen, setIsOpen, setError, setSuccess, setIsErrorAlertOpen, setIsSuccessAlertOpen}) {
+ const countdownRef = useRef()
+
+ const handleClose = () => {
+ setIsOpen(false)
+ }
+
+ const handleFormSubmit = async e => {
+ e.preventDefault()
+
+ const formData = new FormData(e.currentTarget)
+ const formJson = Object.fromEntries(formData.entries())
+ const {comment} = formJson
+
+ try {
+ if (hasRestrictedChar(comment)) {
+ setError('Le texte ne doit pas contenir certains caractères spéciaux : <, >, \', ".')
+ setIsErrorAlertOpen(true)
+
+ return
+ }
+
+ await directusClient.request(withToken(
+ session.user.accessToken,
+ createItem('commentaires', {
+ text: comment,
+ titre: selectedTitre,
+ status: 'draft'
+ })
+ ))
+
+ setSuccess('Envoyé avec succès. Commentaire en attente de validation.')
+ setIsSuccessAlertOpen(true)
+ } catch (error) {
+ if (error?.errors[0]?.message === 'Token expired.') {
+ countdownRef.current.startCountdown()
+ } else {
+ console.log(error?.errors[0]?.message)
+ setError(error?.errors[0]?.message)
+ setIsErrorAlertOpen(true)
+ }
+ }
+
+ handleClose()
+ }
+
+ return (
+ <>
+
+
+ >
+
+ )
+}
+
+HandleComments.propTypes = {
+ session: PropTypes.object,
+ selectedTitre: PropTypes.object.isRequired,
+ isOpen: PropTypes.bool.isRequired,
+ setIsOpen: PropTypes.func.isRequired,
+ setError: PropTypes.func.isRequired,
+ setSuccess: PropTypes.func.isRequired,
+ setIsErrorAlertOpen: PropTypes.func.isRequired,
+ setIsSuccessAlertOpen: PropTypes.func.isRequired
+}
diff --git a/components/konstitisyon/index.js b/components/konstitisyon/index.js
index 9764f65..c0cb096 100644
--- a/components/konstitisyon/index.js
+++ b/components/konstitisyon/index.js
@@ -1,14 +1,16 @@
'use client'
-
import PropTypes from 'prop-types'
+import {useState} from 'react'
import Box from '@mui/material/Box'
import Paper from '@mui/material/Paper'
import {styled} from '@mui/material/styles'
import IconButton from '@mui/material/IconButton'
import AddCommentIcon from '@mui/icons-material/AddComment'
import Tooltip, {tooltipClasses} from '@mui/material/Tooltip'
+import AuthAlert from '../auth-form/auth-alert.js'
import Titre from './titre.js'
import Article from './article.js'
+import HandleComments from './handle-comments.js'
import {formatKonstitisyon} from '@/lib/format.js'
const LightTooltip = styled(({className, ...props}) => (
@@ -24,27 +26,66 @@ const LightTooltip = styled(({className, ...props}) => (
export default function Konstitisyon({session, titres, articles}) {
const konstitisyon = formatKonstitisyon(titres, articles)
+ const [isOpen, setIsOpen] = useState(false)
+ const [isErrorAlertOpen, setIsErrorAlertOpen] = useState(false)
+ const [isSuccessAlertOpen, setIsSuccessAlertOpen] = useState(false)
+ const [selectedTitre, setSelectedTitre] = useState(null)
+ const [error, setError] = useState('')
+ const [success, setSuccess] = useState('')
+
+ const handleCommentsDialog = (titreId, titre) => {
+ setSelectedTitre({id: titreId, titre})
+ setIsOpen(true)
+ }
return (
-
- {konstitisyon.map(({titreId, titre, articles}) => (
-
-
- {articles.map(({id, numero, contenu}) => (
-
- ))}
- {session && (
-
-
-
-
-
-
-
- )}
-
- ))}
-
+ <>
+ {error && }
+
+ {success && }
+
+
+ {konstitisyon.map(({titreId, titre, articles}) => (
+
+
+ {articles.map(({id, numero, contenu}) => (
+
+ ))}
+ {session && (
+
+ handleCommentsDialog(titreId, titre)}>
+
+
+
+
+
+ )}
+
+ ))}
+ {selectedTitre && (
+
+ )}
+
+ >
)
}
diff --git a/components/session/logout-countdown.js b/components/session/logout-countdown.js
new file mode 100644
index 0000000..d82f913
--- /dev/null
+++ b/components/session/logout-countdown.js
@@ -0,0 +1,45 @@
+import PropTypes from 'prop-types'
+import {
+ useState, useEffect, forwardRef, useImperativeHandle
+} from 'react'
+import {signOut} from 'next-auth/react'
+
+const LogoutCountdown = forwardRef(({setError, setIsErrorAlertOpen}, ref) => {
+ const [counter, setCounter] = useState(5)
+ const [isCountdownActive, setIsCountdownActive] = useState(false)
+
+ useEffect(() => {
+ let timer
+
+ if (isCountdownActive) {
+ if (counter > 0) {
+ timer = setInterval(() => {
+ setCounter(prevCounter => prevCounter - 1)
+ }, 1000)
+ } else if (counter === 0) {
+ signOut()
+ }
+
+ setError(`Session expirée, reconnectez-vous ! Déconnexion dans... ${counter} sec`)
+ setIsErrorAlertOpen(true)
+ }
+
+ return () => clearInterval(timer)
+ }, [isCountdownActive, counter, setError, setIsErrorAlertOpen])
+
+ useImperativeHandle(ref, () => ({
+ startCountdown() {
+ setCounter(5)
+ setIsCountdownActive(true)
+ }
+ }))
+
+ return null
+})
+
+LogoutCountdown.propTypes = {
+ setError: PropTypes.func.isRequired,
+ setIsErrorAlertOpen: PropTypes.func.isRequired
+}
+
+export default LogoutCountdown