refactor: Add CreateForm to write comments
This commit is contained in:
@@ -26,6 +26,8 @@ export default function HandleComments({
|
|||||||
setSuccess={setSuccess}
|
setSuccess={setSuccess}
|
||||||
setIsErrorAlertOpen={setIsErrorAlertOpen}
|
setIsErrorAlertOpen={setIsErrorAlertOpen}
|
||||||
setIsSuccessAlertOpen={setIsSuccessAlertOpen}
|
setIsSuccessAlertOpen={setIsSuccessAlertOpen}
|
||||||
|
title={selectedTitre.titre}
|
||||||
|
label='Écrivez votre commentaire'
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,117 +1,14 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
import {useRef} from 'react'
|
import CreateForm from '../forms/create-form.js'
|
||||||
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 WriteComment({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
|
|
||||||
const formattedComment = comment.replaceAll('\'', '’')
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (hasRestrictedChar(formattedComment)) {
|
|
||||||
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: formattedComment,
|
|
||||||
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()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
export default function WriteComment(props) {
|
||||||
return (
|
return (
|
||||||
<>
|
<CreateForm
|
||||||
<Dialog
|
{...props}
|
||||||
open={isOpen}
|
collection='commentaires'
|
||||||
PaperProps={{
|
dialogText='Écrivez votre commentaire'
|
||||||
component: 'form',
|
label='commentaire'
|
||||||
onSubmit(event) {
|
/>
|
||||||
handleFormSubmit(event)
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
onClose={handleClose}
|
|
||||||
>
|
|
||||||
<DialogTitle>{selectedTitre.titre}</DialogTitle>
|
|
||||||
<DialogContent sx={{color: 'white'}}>
|
|
||||||
<DialogContentText sx={{color: 'white'}}>
|
|
||||||
Écrivez votre commentaire
|
|
||||||
</DialogContentText>
|
|
||||||
<TextField
|
|
||||||
autoFocus
|
|
||||||
required
|
|
||||||
multiline
|
|
||||||
fullWidth
|
|
||||||
mt={2}
|
|
||||||
rows={4}
|
|
||||||
id='comment'
|
|
||||||
name='comment'
|
|
||||||
label='Commentaire'
|
|
||||||
/>
|
|
||||||
</DialogContent>
|
|
||||||
<DialogActions>
|
|
||||||
<Button variant='contained' color='success' onClick={handleClose}>Annuler</Button>
|
|
||||||
<Button variant='contained' color='error' type='submit'>Valider</Button>
|
|
||||||
</DialogActions>
|
|
||||||
</Dialog>
|
|
||||||
<LogoutCountdown ref={countdownRef} setError={setError} setIsErrorAlertOpen={setIsErrorAlertOpen} />
|
|
||||||
</>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
WriteComment.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
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -0,0 +1,115 @@
|
|||||||
|
'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 LogoutCountdown from '../../session/logout-countdown.js'
|
||||||
|
import {handleSubmit} from '@/lib/directus.js'
|
||||||
|
import {formatFormContent} from '@/lib/format.js'
|
||||||
|
|
||||||
|
export default function CreateForm({
|
||||||
|
session,
|
||||||
|
selectedTitre,
|
||||||
|
isOpen,
|
||||||
|
setIsOpen,
|
||||||
|
setError,
|
||||||
|
setSuccess,
|
||||||
|
setIsErrorAlertOpen,
|
||||||
|
setIsSuccessAlertOpen,
|
||||||
|
dialogText,
|
||||||
|
collection,
|
||||||
|
title,
|
||||||
|
label
|
||||||
|
}) {
|
||||||
|
const countdownRef = useRef()
|
||||||
|
|
||||||
|
const handleClose = () => {
|
||||||
|
setIsOpen(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleFormSubmit = async e => {
|
||||||
|
e.preventDefault()
|
||||||
|
let requestObject
|
||||||
|
|
||||||
|
const formattedContent = formatFormContent(e.currentTarget)
|
||||||
|
|
||||||
|
if (collection === 'commentaires') {
|
||||||
|
requestObject = {
|
||||||
|
text: formattedContent,
|
||||||
|
titre: selectedTitre,
|
||||||
|
status: 'draft',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await handleSubmit({
|
||||||
|
accessToken: session.user.accessToken,
|
||||||
|
content: formattedContent,
|
||||||
|
collection,
|
||||||
|
requestObject,
|
||||||
|
setError,
|
||||||
|
setSuccess,
|
||||||
|
setIsErrorAlertOpen,
|
||||||
|
setIsSuccessAlertOpen,
|
||||||
|
countdownRef,
|
||||||
|
})
|
||||||
|
|
||||||
|
handleClose()
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Dialog
|
||||||
|
open={isOpen}
|
||||||
|
PaperProps={{
|
||||||
|
component: 'form',
|
||||||
|
onSubmit: handleFormSubmit,
|
||||||
|
}}
|
||||||
|
onClose={handleClose}
|
||||||
|
>
|
||||||
|
<DialogTitle>{title}</DialogTitle>
|
||||||
|
<DialogContent sx={{color: 'white'}}>
|
||||||
|
<DialogContentText sx={{color: 'white'}}>
|
||||||
|
{dialogText}
|
||||||
|
</DialogContentText>
|
||||||
|
<TextField
|
||||||
|
autoFocus
|
||||||
|
required
|
||||||
|
multiline
|
||||||
|
fullWidth
|
||||||
|
mt={2}
|
||||||
|
rows={4}
|
||||||
|
id='content'
|
||||||
|
name='content'
|
||||||
|
label={label}
|
||||||
|
/>
|
||||||
|
</DialogContent>
|
||||||
|
<DialogActions>
|
||||||
|
<Button variant='contained' color='success' onClick={handleClose}>Annuler</Button>
|
||||||
|
<Button variant='contained' color='error' type='submit'>Valider</Button>
|
||||||
|
</DialogActions>
|
||||||
|
</Dialog>
|
||||||
|
<LogoutCountdown ref={countdownRef} setError={setError} setIsErrorAlertOpen={setIsErrorAlertOpen} />
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
CreateForm.propTypes = {
|
||||||
|
session: PropTypes.object,
|
||||||
|
selectedTitre: PropTypes.object.isRequired,
|
||||||
|
isOpen: PropTypes.bool.isRequired,
|
||||||
|
setIsOpen: PropTypes.func.isRequired,
|
||||||
|
setError: PropTypes.func.isRequired,
|
||||||
|
setSuccess: PropTypes.func,
|
||||||
|
setIsErrorAlertOpen: PropTypes.func.isRequired,
|
||||||
|
setIsSuccessAlertOpen: PropTypes.func,
|
||||||
|
dialogText: PropTypes.string.isRequired,
|
||||||
|
collection: PropTypes.string.isRequired,
|
||||||
|
title: PropTypes.string.isRequired,
|
||||||
|
label: PropTypes.string.isRequired
|
||||||
|
}
|
||||||
+41
-1
@@ -1,4 +1,7 @@
|
|||||||
import {createDirectus, rest, authentication} from '@directus/sdk'
|
import {
|
||||||
|
createDirectus, rest, authentication, withToken, createItem
|
||||||
|
} from '@directus/sdk'
|
||||||
|
import {hasRestrictedChar} from './format.js'
|
||||||
|
|
||||||
const apiUrl = process.env.DIRECTUS_API_URL || process.env.NEXT_PUBLIC_DIRECTUS_API_URL
|
const apiUrl = process.env.DIRECTUS_API_URL || process.env.NEXT_PUBLIC_DIRECTUS_API_URL
|
||||||
|
|
||||||
@@ -6,3 +9,40 @@ export const directusClient = createDirectus(apiUrl)
|
|||||||
.with(authentication('cookie', {credentials: 'include', autoRefresh: true}))
|
.with(authentication('cookie', {credentials: 'include', autoRefresh: true}))
|
||||||
.with(rest())
|
.with(rest())
|
||||||
|
|
||||||
|
export async function handleSubmit({
|
||||||
|
accessToken,
|
||||||
|
content,
|
||||||
|
collection,
|
||||||
|
requestObject,
|
||||||
|
setError,
|
||||||
|
setSuccess,
|
||||||
|
setIsErrorAlertOpen,
|
||||||
|
setIsSuccessAlertOpen,
|
||||||
|
countdownRef,
|
||||||
|
}) {
|
||||||
|
try {
|
||||||
|
if (hasRestrictedChar(content)) {
|
||||||
|
setError('Le texte ne doit pas contenir certains caractères spéciaux : <, >, ", .')
|
||||||
|
setIsErrorAlertOpen(true)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
await directusClient.request(
|
||||||
|
withToken(
|
||||||
|
accessToken,
|
||||||
|
createItem(collection, requestObject)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
setSuccess('Envoyé avec succès. 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -24,3 +24,17 @@ export function formatDate(date, formatStr = 'PP') {
|
|||||||
locale: fr
|
locale: fr
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function hasRestrictedChar(text) {
|
||||||
|
const regex = /[<>&"]/g
|
||||||
|
|
||||||
|
return Boolean(regex.test(text))
|
||||||
|
}
|
||||||
|
|
||||||
|
export function formatFormContent(currentTarget) {
|
||||||
|
const formData = new FormData(currentTarget)
|
||||||
|
const formJson = Object.fromEntries(formData.entries())
|
||||||
|
const {content} = formJson
|
||||||
|
|
||||||
|
return content.replaceAll('\'', '’')
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user