Files
pawol.nu/components/soumet/ekri-teks.js
T

439 lines
13 KiB
JavaScript
Raw Normal View History

2022-03-18 08:11:04 +04:00
import {useCallback, useEffect, forwardRef, useState} from 'react'
2022-01-19 06:35:04 +04:00
import {styled} from '@mui/material/styles'
2022-03-25 00:06:59 +04:00
import PropTypes from 'prop-types'
2021-05-24 02:57:18 +02:00
import axios from 'axios'
2022-03-18 08:11:04 +04:00
import {useSession} from 'next-auth/react'
import Box from '@mui/material/Box'
import Button from '@mui/material/Button'
import Container from '@mui/material/Container'
import FormControl from '@mui/material/FormControl'
import FormHelperText from '@mui/material/FormHelperText'
import Grid from '@mui/material/Unstable_Grid2'
import IconButton from '@mui/material/IconButton'
import InputAdornment from '@mui/material/InputAdornment'
import InputLabel from '@mui/material/InputLabel'
import LinearProgress from '@mui/material/LinearProgress'
import OutlinedInput from '@mui/material/OutlinedInput'
import Snackbar from '@mui/material/Snackbar'
import TextField from '@mui/material/TextField'
import Tooltip from '@mui/material/Tooltip'
import Typography from '@mui/material/Typography'
2022-01-19 07:06:26 +04:00
import MuiAlert from '@mui/material/Alert'
2022-03-25 00:06:59 +04:00
import VisibilityOffIcon from '@mui/icons-material/VisibilityOff'
2021-05-27 23:54:42 +02:00
2022-05-20 02:21:38 +04:00
import {jwennAnTeks} from '../../lib/oki-api'
2021-05-27 23:54:42 +02:00
import AjouteTradiksyon from './ajoute-tradiksyon'
2021-05-24 02:57:18 +02:00
2022-01-19 06:35:04 +04:00
const PREFIX = 'EkriTeks'
const classes = {
tooltip: `${PREFIX}-tooltip`
}
const StyledContainer = styled(Container)(() => ({
[`& .${classes.tooltip}`]: {
fontSize: 18
}
}))
2021-05-24 02:57:18 +02:00
const API_URL = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:1337'
2021-05-27 23:54:42 +02:00
const textLabels = {
fr: {
title: 'Traduction',
2022-03-26 16:44:52 +04:00
help: 'Traduction des paroles',
2021-05-27 23:54:42 +02:00
emoji: '🇫🇷'
},
en: {
title: 'Translation',
2022-03-26 16:44:52 +04:00
help: 'Translation of the lyrics',
2021-05-27 23:54:42 +02:00
emoji: '🇬🇧'
},
es: {
title: 'Traducción',
2022-03-26 16:44:52 +04:00
help: 'Traducción de la letra',
2021-05-27 23:54:42 +02:00
emoji: '🇪🇸'
2022-03-22 07:12:41 +04:00
},
de: {
title: 'Übersetzung',
2022-03-26 16:44:52 +04:00
help: 'Übersetzung von Liedtexten',
2022-03-22 07:12:41 +04:00
emoji: '🇩🇪'
},
it: {
title: 'Traduzione',
2022-03-26 16:44:52 +04:00
help: 'Traduzione del testo',
2022-03-22 07:12:41 +04:00
emoji: '🇮🇹'
2021-05-27 23:54:42 +02:00
}
}
2022-03-18 08:11:04 +04:00
const Alert = forwardRef(function Alert(props, ref) {
return <MuiAlert ref={ref} elevation={6} variant='filled' {...props} />
})
2021-05-24 02:57:18 +02:00
2022-01-19 06:35:04 +04:00
const RemoveTooltip = Tooltip
2021-05-27 23:54:42 +02:00
2022-03-27 04:51:37 +04:00
function EkriTeks({canAutoTranslate, selectedTeks, setSelectedTeks}) {
2022-03-18 08:11:04 +04:00
const {data: session} = useSession()
2021-05-24 02:57:18 +02:00
const {jwt, user} = session
2021-05-27 23:54:42 +02:00
const [teksEkri, setTeksEkri] = useState({awtis: '', tit: '', transkripsyon: ''})
2022-03-22 07:12:41 +04:00
const [tradiksyon, setTradiksyon] = useState({fr: '', en: '', es: '', de: '', it: ''})
2022-03-27 05:07:55 +04:00
const [kiChawLang, setKiChwalang] = useState(['fr'])
2021-05-24 02:57:18 +02:00
const [error, setError] = useState('')
const [success, setSuccess] = useState('')
const [loading, setLoading] = useState(false)
2022-03-25 00:06:59 +04:00
const [currentTeksId, setCurrentTeksId] = useState(null)
2021-05-24 02:57:18 +02:00
const [open, setOpen] = useState(false)
const [tradiksyonOtomatik, setTradiksyonOtomatik] = useState(false)
2021-05-24 02:57:18 +02:00
2021-05-27 23:54:42 +02:00
const handleUpdate = useCallback(update => {
2021-05-24 02:57:18 +02:00
setTeksEkri({...teksEkri, ...update})
2021-05-27 23:54:42 +02:00
}, [teksEkri])
const handleUpdateTradiksyon = useCallback(update => {
setTradiksyon({...tradiksyon, ...update})
}, [tradiksyon])
const handleRemoveTradiksyon = useCallback(idTradiksyon => {
setKiChwalang(kiChawLang.filter(t => t !== idTradiksyon))
2022-03-25 00:06:59 +04:00
}, [kiChawLang, setKiChwalang])
2021-05-24 02:57:18 +02:00
const handleClose = (event, reason) => {
if (reason === 'clickaway') {
return
}
setOpen(false)
setSuccess('')
setError('')
}
2022-05-20 02:21:38 +04:00
const handleClick = async () => {
2021-05-24 02:57:18 +02:00
setLoading(true)
2021-05-27 23:54:42 +02:00
const {awtis, tit, transkripsyon} = teksEkri
2022-03-22 07:12:41 +04:00
const {fr, en, es, de, it} = tradiksyon
2021-05-24 02:57:18 +02:00
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}`
}
2022-03-25 00:06:59 +04:00
if (currentTeksId) {
2022-05-20 02:21:38 +04:00
try {
const teks = await jwennAnTeks(currentTeksId, jwt)
const teksResponse = await axios.put(`${API_URL}/paroles/${currentTeksId}`, {
data: {
id: teks.id,
titre: tit,
transcription: transkripsyon,
traductions: {
2022-03-25 00:06:59 +04:00
francais: fr === '' ? null : fr,
2022-05-20 02:21:38 +04:00
anglais: en === '' ? null : en,
2022-03-25 00:06:59 +04:00
espagnol: es === '' ? null : es,
2022-05-20 02:21:38 +04:00
allemand: de === '' ? null : de,
italien: it === '' ? null : it
2022-03-25 00:06:59 +04:00
},
2022-05-20 02:21:38 +04:00
user: {
id: user.id,
username: user.username,
email: user.email
},
artistes: teks.artistes.map(({id}) => id),
traductionAuto: tradiksyonOtomatik
}
}, {
headers
2022-03-25 00:06:59 +04:00
})
2022-05-20 02:21:38 +04:00
const {data} = teksResponse
2022-05-23 18:34:55 +04:00
setSuccess(`Le morceau "${data.tit}" a été modifié avec succès. Il apparaîtra sur le site après validation.`)
2022-05-20 02:21:38 +04:00
setLoading(false)
} catch (error) {
setError(error?.response?.data)
setLoading(false)
}
2022-03-25 00:06:59 +04:00
} else {
2022-05-20 02:21:38 +04:00
try {
const artiste = await axios.post(`${API_URL}/artistes`, {
data: {
alias: awtis,
user: {
id: user.id,
username: user.username,
email: user.email
}
}
}, {
headers
})
const parole = await axios.post(`${API_URL}/paroles`, {
data: {
titre: tit,
transcription: transkripsyon,
traductions: {
2022-03-25 00:06:59 +04:00
francais: fr === '' ? null : fr,
2022-05-20 02:21:38 +04:00
anglais: en === '' ? null : en,
2022-03-25 00:06:59 +04:00
espagnol: es === '' ? null : es,
2022-05-20 02:21:38 +04:00
allemand: de === '' ? null : de,
italien: it === '' ? null : it
2022-03-25 00:06:59 +04:00
},
2022-05-20 02:21:38 +04:00
user: {
id: user.id,
username: user.username,
email: user.email
},
artistes: [artiste.data.id],
traductionAuto: tradiksyonOtomatik
}
}, {
headers
2022-03-25 00:06:59 +04:00
})
2022-05-20 02:21:38 +04:00
const {data} = parole
setSuccess(`Le texte "${data.titre}" a été soumis avec succès. Il apparaîtra sur le site après validation.`)
setLoading(false)
} catch (error) {
setError(error?.response?.data)
setLoading(false)
}
2022-03-25 00:06:59 +04:00
}
2021-05-24 02:57:18 +02:00
}
const handleReset = () => {
2021-05-27 23:54:42 +02:00
setTeksEkri({awtis: '', tit: '', transkripsyon: ''})
2022-03-22 07:12:41 +04:00
setTradiksyon({fr: '', en: '', es: '', de: '', it: ''})
2022-03-27 05:13:41 +04:00
setKiChwalang(['fr'])
2022-03-25 00:06:59 +04:00
setCurrentTeksId(null)
setTradiksyonOtomatik(false)
2021-05-24 02:57:18 +02:00
}
useEffect(() => {
if (success) {
setOpen(true)
handleReset()
}
}, [success])
useEffect(() => {
if (error) {
setOpen(true)
}
}, [error])
2022-03-25 00:06:59 +04:00
useEffect(() => {
if (selectedTeks) {
2022-03-27 05:13:41 +04:00
setTradiksyonOtomatik(false)
2022-05-05 17:58:05 +04:00
setCurrentTeksId(selectedTeks.id)
2022-03-25 00:06:59 +04:00
setTeksEkri({
2022-05-20 02:21:38 +04:00
awtis: new Intl.ListFormat('fr').format(selectedTeks.artistes.map(({alias}) => alias)),
tit: selectedTeks.titre,
transkripsyon: selectedTeks.transcription
2022-03-25 00:06:59 +04:00
})
setTradiksyon({
2022-05-20 02:21:38 +04:00
fr: selectedTeks?.traductions?.francais || '',
en: selectedTeks?.traductions?.anglais || '',
es: selectedTeks?.traductions?.espagnol || '',
de: selectedTeks?.traductions?.allemand || '',
it: selectedTeks?.traductions?.italien || ''
2022-03-25 00:06:59 +04:00
})
const jennLangId = () => {
const ids = []
2022-05-20 02:21:38 +04:00
if (selectedTeks?.traductions?.francais) {
2022-03-25 00:06:59 +04:00
ids.push('fr')
}
2022-05-20 02:21:38 +04:00
if (selectedTeks?.traductions?.anglais) {
2022-03-25 00:06:59 +04:00
ids.push('en')
}
2022-05-20 02:21:38 +04:00
if (selectedTeks?.traductions?.espagnol) {
2022-03-25 00:06:59 +04:00
ids.push('es')
}
2022-05-20 02:21:38 +04:00
if (selectedTeks?.traductions?.allemand) {
2022-03-25 00:06:59 +04:00
ids.push('de')
}
2022-05-20 02:21:38 +04:00
if (selectedTeks?.traductions?.italien) {
2022-03-25 00:06:59 +04:00
ids.push('it')
}
return ids
}
const langIds = jennLangId()
setKiChwalang(langIds)
}
return () => {
setSelectedTeks(null)
}
}, [teksEkri, selectedTeks, setSelectedTeks, kiChawLang])
2021-05-24 02:57:18 +02:00
return (
2022-01-19 06:35:04 +04:00
<StyledContainer maxWidth='sm'>
2022-02-05 14:36:49 +04:00
<Box sx={{textAlign: 'center', marginBottom: 2}}>
2022-03-27 05:20:30 +04:00
<Typography display='inline' variant='h6' component='h1'>
2022-05-23 18:34:55 +04:00
Soumettre une parole
</Typography>
</Box>
2021-05-24 02:57:18 +02:00
<form noValidate autoComplete='off'>
<Grid container style={{textAlign: 'center'}} spacing={1}>
<Grid xs>
2021-05-24 02:57:18 +02:00
<TextField
required
id='awtis'
name='awtis'
2022-02-05 14:36:49 +04:00
label='Artiste'
2021-05-24 02:57:18 +02:00
value={teksEkri.awtis}
2022-03-25 00:06:59 +04:00
disabled={Boolean(currentTeksId)}
2021-05-24 02:57:18 +02:00
variant='outlined'
helperText='Nom de lartiste (obligatoire)'
onChange={event => handleUpdate({awtis: event.target.value})}
/>
</Grid>
<Grid xs>
2021-05-24 02:57:18 +02:00
<TextField
required
id='tit'
name='tit'
2022-02-05 14:36:49 +04:00
label='Titre'
2022-03-25 00:06:59 +04:00
value={selectedTeks?.tit || teksEkri.tit}
2021-05-24 02:57:18 +02:00
variant='outlined'
helperText='Titre de la musique (obligatoire)'
onChange={event => handleUpdate({tit: event.target.value})}
/>
</Grid>
</Grid>
<TextField
fullWidth
multiline
required
2022-03-26 16:42:20 +04:00
helperText='Transcription des paroles (obligatoire)'
2021-05-24 02:57:18 +02:00
style={{marginTop: '1em'}}
id='transkripsyon'
2022-02-05 14:36:49 +04:00
label='Transcription'
2021-05-24 02:57:18 +02:00
value={teksEkri.transkripsyon}
rows={8}
variant='outlined'
onChange={event => handleUpdate({transkripsyon: event.target.value})}
/>
2021-05-27 23:54:42 +02:00
{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'>
2022-01-19 06:35:04 +04:00
<RemoveTooltip
2022-03-25 00:06:59 +04:00
title='Cacher la fenêtre'
2022-01-19 06:35:04 +04:00
placement='left'
classes={{
tooltip: classes.tooltip
}}
>
2021-05-27 23:54:42 +02:00
<IconButton
style={{bottom: 75}}
aria-label='remove-tradiksyon'
edge='end'
2022-01-19 07:06:26 +04:00
size='large'
2021-05-27 23:54:42 +02:00
onClick={() => handleRemoveTradiksyon(k)}
>
2022-03-25 00:06:59 +04:00
<VisibilityOffIcon />
2021-05-27 23:54:42 +02:00
</IconButton>
</RemoveTooltip>
</InputAdornment>
}
onChange={event => handleUpdateTradiksyon({[k]: event.target.value})}
/>
<FormHelperText id={`tradiksyon-${k}`}>{textLabels[k].help}</FormHelperText>
</FormControl>
))}
2021-05-24 02:57:18 +02:00
</form>
2022-03-27 03:32:16 +04:00
<AjouteTradiksyon
2022-03-27 04:51:37 +04:00
showSwitch={Boolean(canAutoTranslate) && Boolean(!currentTeksId)}
2022-05-20 02:21:38 +04:00
disableSwitch={tradiksyon.fr === '' || tradiksyon.en !== '' || tradiksyon.es !== '' || tradiksyon.de !== '' || tradiksyon.it !== ''}
2022-03-27 03:32:16 +04:00
tradiksyonOtomatik={tradiksyonOtomatik}
setTradiksyonOtomatik={setTradiksyonOtomatik}
chwaLang={kiChawLang}
setChwaLang={setKiChwalang}
/>
2021-05-24 02:57:18 +02:00
<div>
<Button
fullWidth
disabled={loading || teksEkri.awtis === '' || teksEkri.tit === '' || teksEkri.transkripsyon === ''}
2022-03-25 00:06:59 +04:00
style={{marginTop: 20}}
2021-05-24 02:57:18 +02:00
variant='contained'
color='primary'
onClick={handleClick}
>
<Typography style={{fontWeight: 'bold'}}>
2022-02-05 14:36:49 +04:00
Valider
2021-05-24 02:57:18 +02:00
</Typography>
</Button>
2022-03-25 00:06:59 +04:00
<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'}} />}
2021-05-24 02:57:18 +02:00
</div>
{success && (
2022-01-18 09:08:26 +04:00
<Snackbar open={open} autoHideDuration={10_000} onClose={handleClose}>
2021-05-24 02:57:18 +02:00
<Alert severity='success' onClose={handleClose}>
<strong>{success}</strong>
</Alert>
</Snackbar>
)}
{error && (
2022-05-20 02:21:38 +04:00
<Snackbar open={open} autoHideDuration={10_000} onClose={handleClose}>
2021-05-24 02:57:18 +02:00
<Alert severity='error' onClose={handleClose}>
2022-05-20 02:21:38 +04:00
<strong>Une erreur sest produite</strong> : <i>{error?.error?.message}</i>
2021-05-24 02:57:18 +02:00
</Alert>
</Snackbar>
)}
2022-01-19 06:35:04 +04:00
</StyledContainer>
2021-05-24 02:57:18 +02:00
)
}
2022-03-25 00:06:59 +04:00
EkriTeks.defaultProps = {
2022-05-17 00:29:09 +04:00
selectedTeks: null,
canAutoTranslate: null
2022-03-25 00:06:59 +04:00
}
EkriTeks.propTypes = {
2022-05-17 00:29:09 +04:00
canAutoTranslate: PropTypes.bool,
2022-03-25 00:06:59 +04:00
selectedTeks: PropTypes.object,
setSelectedTeks: PropTypes.func.isRequired,
}
2021-05-24 02:57:18 +02:00
export default EkriTeks