Files
pawol.nu/components/soumet/ekri-teks.js
T
Cédric FAMIBELLE-PRONZOLA 07d9bd178c Fix TradiksyonOtomatik state
2022-03-27 05:13:41 +04:00

434 lines
12 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import {useCallback, useEffect, forwardRef, useState} from 'react'
import {styled} from '@mui/material/styles'
import PropTypes from 'prop-types'
import axios from 'axios'
import {useSession} from 'next-auth/react'
import {
Box,
Button,
Container,
FormControl,
FormHelperText,
Grid,
IconButton,
InputAdornment,
InputLabel,
LinearProgress,
OutlinedInput,
Snackbar,
TextField,
Tooltip,
Typography
} from '@mui/material'
import MuiAlert from '@mui/material/Alert'
import VisibilityOffIcon from '@mui/icons-material/VisibilityOff'
import AjouteTradiksyon from './ajoute-tradiksyon'
const PREFIX = 'EkriTeks'
const classes = {
tooltip: `${PREFIX}-tooltip`
}
const StyledContainer = styled(Container)(() => ({
[`& .${classes.tooltip}`]: {
fontSize: 18
}
}))
const API_URL = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:1337'
const textLabels = {
fr: {
title: 'Traduction',
help: 'Traduction des paroles',
emoji: '🇫🇷'
},
en: {
title: 'Translation',
help: 'Translation of the lyrics',
emoji: '🇬🇧'
},
es: {
title: 'Traducción',
help: 'Traducción de la letra',
emoji: '🇪🇸'
},
de: {
title: 'Übersetzung',
help: 'Übersetzung von Liedtexten',
emoji: '🇩🇪'
},
it: {
title: 'Traduzione',
help: 'Traduzione del testo',
emoji: '🇮🇹'
}
}
const Alert = forwardRef(function Alert(props, ref) {
return <MuiAlert ref={ref} elevation={6} variant='filled' {...props} />
})
const RemoveTooltip = Tooltip
function EkriTeks({canAutoTranslate, selectedTeks, setSelectedTeks}) {
const {data: session} = useSession()
const {jwt, user} = session
const [teksEkri, setTeksEkri] = useState({awtis: '', tit: '', transkripsyon: ''})
const [tradiksyon, setTradiksyon] = useState({fr: '', en: '', es: '', de: '', it: ''})
const [kiChawLang, setKiChwalang] = useState(['fr'])
const [error, setError] = useState('')
const [success, setSuccess] = useState('')
const [loading, setLoading] = useState(false)
const [currentTeksId, setCurrentTeksId] = useState(null)
const [open, setOpen] = useState(false)
const [tradiksyonOtomatik, setTradiksyonOtomatik] = useState(false)
const handleUpdate = useCallback(update => {
setTeksEkri({...teksEkri, ...update})
}, [teksEkri])
const handleUpdateTradiksyon = useCallback(update => {
setTradiksyon({...tradiksyon, ...update})
}, [tradiksyon])
const handleRemoveTradiksyon = useCallback(idTradiksyon => {
setKiChwalang(kiChawLang.filter(t => t !== idTradiksyon))
}, [kiChawLang, setKiChwalang])
const handleClose = (event, reason) => {
if (reason === 'clickaway') {
return
}
setOpen(false)
setSuccess('')
setError('')
}
const handleClick = () => {
setLoading(true)
const {awtis, tit, transkripsyon} = teksEkri
const {fr, en, es, de, it} = tradiksyon
if (teksEkri.awtis === '' || teksEkri.tit === '' || teksEkri.transkripsyon === '') {
setError({message: 'Certains champs sont obligatoires'})
setLoading(false)
return
}
const headers = {
'content-type': 'application/json',
Authorization: `Bearer ${jwt}`
}
if (currentTeksId) {
axios.get(`${API_URL}/teks/${currentTeksId}?_publicationState=preview&_where[published_at_null]=true`)
.then(awtisResponse => {
if (awtisResponse.data.user._id !== user._id) {
setLoading(false)
return setError({message: 'Opération non autorisé'})
}
axios.put(`${API_URL}/teks/${currentTeksId}`, {
tit,
transkripsyon,
tradiksyon: {
francais: fr === '' ? null : fr,
english: en === '' ? null : en,
espagnol: es === '' ? null : es,
deutsch: de === '' ? null : de,
italiano: it === '' ? null : it
},
user,
awtis: awtisResponse.data.awtis.map(id => id),
tradiksyonOtomatik
}, {
headers
})
.then(teksResponse => {
const {data} = teksResponse
setSuccess(`Le texte "${data.tit}" a été modifié avec succès. Il apparaîtra sur le site après validation.`)
setLoading(false)
})
.catch(error => {
setError(error)
setLoading(false)
})
})
.catch(error => {
setError(error)
setLoading(false)
})
} else {
axios.post(`${API_URL}/awtis`, {
alias: awtis,
user
}, {
headers
})
.then(awtisResponse => {
axios.post(`${API_URL}/teks`, {
tit,
transkripsyon,
tradiksyon: {
francais: fr === '' ? null : fr,
english: en === '' ? null : en,
espagnol: es === '' ? null : es,
deutsch: de === '' ? null : de,
italiano: it === '' ? null : it
},
user,
awtis: [awtisResponse.data._id],
tradiksyonOtomatik
}, {
headers
})
.then(teksResponse => {
const {data} = teksResponse
setSuccess(`Le texte "${data.tit}" a été soumis avec succès. Il apparaîtra sur le site après validation.`)
setLoading(false)
})
.catch(error => {
setError(error)
setLoading(false)
})
})
.catch(error => {
setError(error)
setLoading(false)
})
}
}
const handleReset = () => {
setTeksEkri({awtis: '', tit: '', transkripsyon: ''})
setTradiksyon({fr: '', en: '', es: '', de: '', it: ''})
setKiChwalang(['fr'])
setCurrentTeksId(null)
setTradiksyonOtomatik(false)
}
useEffect(() => {
if (success) {
setOpen(true)
handleReset()
}
}, [success])
useEffect(() => {
if (error) {
setOpen(true)
}
}, [error])
useEffect(() => {
if (selectedTeks) {
setTradiksyonOtomatik(false)
setCurrentTeksId(selectedTeks._id)
setTeksEkri({
awtis: new Intl.ListFormat('fr').format(selectedTeks.awtis.map(({alias}) => alias)),
tit: selectedTeks.tit,
transkripsyon: selectedTeks.transkripsyon
})
setTradiksyon({
fr: selectedTeks.tradiksyon.francais || '',
en: selectedTeks.tradiksyon.english || '',
es: selectedTeks.tradiksyon.espagnol || '',
de: selectedTeks.tradiksyon.deutsch || '',
it: selectedTeks.tradiksyon.italiano || ''
})
const jennLangId = () => {
const ids = []
const {francais, english, espagnol, deutsch, italiano} = selectedTeks.tradiksyon
if (francais) {
ids.push('fr')
}
if (english) {
ids.push('en')
}
if (espagnol) {
ids.push('es')
}
if (deutsch) {
ids.push('de')
}
if (italiano) {
ids.push('it')
}
return ids
}
const langIds = jennLangId()
setKiChwalang(langIds)
}
return () => {
setSelectedTeks(null)
}
}, [teksEkri, selectedTeks, setSelectedTeks, kiChawLang])
return (
<StyledContainer maxWidth='sm'>
<Box sx={{textAlign: 'center', marginBottom: 2}}>
<Typography display='inline' variant='h5' component='h1'>
Soumettre un texte
</Typography>
</Box>
<form noValidate autoComplete='off'>
<Grid container style={{textAlign: 'center'}} spacing={1}>
<Grid item xs>
<TextField
required
id='awtis'
name='awtis'
label='Artiste'
value={teksEkri.awtis}
disabled={Boolean(currentTeksId)}
variant='outlined'
helperText='Nom de lartiste (obligatoire)'
onChange={event => handleUpdate({awtis: event.target.value})}
/>
</Grid>
<Grid item xs>
<TextField
required
id='tit'
name='tit'
label='Titre'
value={selectedTeks?.tit || teksEkri.tit}
variant='outlined'
helperText='Titre de la musique (obligatoire)'
onChange={event => handleUpdate({tit: event.target.value})}
/>
</Grid>
</Grid>
<TextField
fullWidth
multiline
required
helperText='Transcription des paroles (obligatoire)'
style={{marginTop: '1em'}}
id='transkripsyon'
label='Transcription'
value={teksEkri.transkripsyon}
rows={8}
variant='outlined'
onChange={event => handleUpdate({transkripsyon: event.target.value})}
/>
{kiChawLang.length > 0 && kiChawLang.map(k => (
<FormControl key={k} fullWidth style={{marginBlock: 10}}>
<InputLabel htmlFor={`tradiksyon-${k}`}>
<span dangerouslySetInnerHTML={{__html: textLabels[k].emoji}} /> {textLabels[k].title}
</InputLabel>
<OutlinedInput
multiline
style={{marginTop: '1em'}}
id={`tradiksyon-${k}`}
name={`tradiksyon-${k}`}
label={`${textLabels[k].title}`}
value={tradiksyon[k]}
rows={8}
endAdornment={
<InputAdornment position='end'>
<RemoveTooltip
title='Cacher la fenêtre'
placement='left'
classes={{
tooltip: classes.tooltip
}}
>
<IconButton
style={{bottom: 75}}
aria-label='remove-tradiksyon'
edge='end'
size='large'
onClick={() => handleRemoveTradiksyon(k)}
>
<VisibilityOffIcon />
</IconButton>
</RemoveTooltip>
</InputAdornment>
}
onChange={event => handleUpdateTradiksyon({[k]: event.target.value})}
/>
<FormHelperText id={`tradiksyon-${k}`}>{textLabels[k].help}</FormHelperText>
</FormControl>
))}
</form>
<AjouteTradiksyon
showSwitch={Boolean(canAutoTranslate) && Boolean(!currentTeksId)}
disableSwitch={tradiksyon.fr === ''}
tradiksyonOtomatik={tradiksyonOtomatik}
setTradiksyonOtomatik={setTradiksyonOtomatik}
chwaLang={kiChawLang}
setChwaLang={setKiChwalang}
/>
<div>
<Button
fullWidth
disabled={loading || teksEkri.awtis === '' || teksEkri.tit === '' || teksEkri.transkripsyon === ''}
style={{marginTop: 20}}
variant='contained'
color='primary'
onClick={handleClick}
>
<Typography style={{fontWeight: 'bold'}}>
Valider
</Typography>
</Button>
<Button
fullWidth
disabled={loading || (teksEkri.awtis === '' && teksEkri.tit === '' && teksEkri.transkripsyon === '')}
style={{marginTop: 20}}
variant='contained'
color='secondary'
onClick={handleReset}
>
<Typography style={{fontWeight: 'bold'}}>
Tout effacer
</Typography>
</Button>
{loading && <LinearProgress size={24} style={{width: '100%', marginBlock: '1em'}} />}
</div>
{success && (
<Snackbar open={open} autoHideDuration={10_000} onClose={handleClose}>
<Alert severity='success' onClose={handleClose}>
<strong>{success}</strong>
</Alert>
</Snackbar>
)}
{error && (
<Snackbar open={open} autoHideDuration={6000} onClose={handleClose}>
<Alert severity='error' onClose={handleClose}>
<strong>Une erreur sest produite</strong> : <i>{error.message}</i>
</Alert>
</Snackbar>
)}
</StyledContainer>
)
}
EkriTeks.defaultProps = {
selectedTeks: null
}
EkriTeks.propTypes = {
canAutoTranslate: PropTypes.bool.isRequired,
selectedTeks: PropTypes.object,
setSelectedTeks: PropTypes.func.isRequired,
}
export default EkriTeks