refactor: Add CreateForm to write comments

This commit is contained in:
2024-06-21 12:39:37 +04:00
parent def7dd60db
commit 6870f1e459
5 changed files with 180 additions and 112 deletions
@@ -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
View File
@@ -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)
}
}
}
+14
View File
@@ -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('\'', '')
}