Merge branch 'dev' into 'master'

Migration de strapi v3 vers la v4. Adapte les routes et le modèle de données

See merge request cedric-famibelle-pronzola/oki-front!1
This commit is contained in:
2022-05-19 22:42:39 +00:00
31 changed files with 625 additions and 446 deletions
+1
View File
@@ -2,6 +2,7 @@ PORT=3000
API_URL=http://localhost:1337
NEXT_PUBLIC_API_URL=$API_URL
SITE_URL=http://localhost:3001
NEXT_PUBLIC_READ_TOKEN=
# FUNKWHALE VARIABLE
NEXT_PUBLIC_OKI_MIZIK_URL=https://funkwhale-server.com
+8 -8
View File
@@ -14,7 +14,7 @@ import {
import MizikBadjMeni from './mizik-badj-meni'
export default function AwtisBiyografi({alias, teks, biyografi, esByografiOuve, meteEsByografiOuve}) {
export default function AwtisBiyografi({alias, paroles, biographie, esByografiOuve, meteEsByografiOuve}) {
const handleClose = () => {
meteEsByografiOuve(false)
}
@@ -40,7 +40,7 @@ export default function AwtisBiyografi({alias, teks, biyografi, esByografiOuve,
>
<Box display='flex' justifyContent='center' alignItems='center'>
<DialogTitle id='scroll-dialog-title' align='center'>{alias}</DialogTitle>
<MizikBadjMeni teks={teks} />
<MizikBadjMeni paroles={paroles} />
</Box>
<DialogContent dividers>
<DialogContentText
@@ -49,9 +49,9 @@ export default function AwtisBiyografi({alias, teks, biyografi, esByografiOuve,
id='scroll-dialog-description'
tabIndex={-1}
>
{biyografi ? (
{biographie ? (
<Typography component='span'>
{biyografi}
{biographie}
</Typography>
) : (
<Typography component='span'>
@@ -62,7 +62,7 @@ export default function AwtisBiyografi({alias, teks, biyografi, esByografiOuve,
</DialogContent>
<DialogActions style={{margin: 'auto'}}>
<Button variant='outlined' color='primary' onClick={handleClose}>
Fèmen
Fermer
</Button>
</DialogActions>
</Dialog>
@@ -72,12 +72,12 @@ export default function AwtisBiyografi({alias, teks, biyografi, esByografiOuve,
AwtisBiyografi.propTypes = {
alias: PropTypes.string.isRequired,
teks: PropTypes.array.isRequired,
biyografi: PropTypes.string,
paroles: PropTypes.array.isRequired,
biographie: PropTypes.string,
esByografiOuve: PropTypes.bool.isRequired,
meteEsByografiOuve: PropTypes.func.isRequired
}
AwtisBiyografi.defaultProps = {
biyografi: null
biographie: null
}
+13 -12
View File
@@ -13,18 +13,19 @@ import KeyboardBackspaceIcon from '@mui/icons-material/KeyboardBackspace'
import AwtisBiyografi from './awtis-biyografi'
import MizikLis from './mizik-lis'
const API_URL = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:1337'
const IMAGE_URL = process.env.NEXT_PUBLIC_API_URL_ROOT || 'http://localhost:1337'
const noImageUrl = 'https://place-hold.it/140x140?text=Indisponible'
const sortTeks = teks => teks.sort((a, b) => b.id - a.id)
const sortTeks = paroles => paroles.sort((a, b) => b.id - a.id)
export default function AwtisDetay({anAwtis}) {
const router = useRouter()
const [esByografiOuve, meteEsByografiOuve] = useState(false)
const {alias, biyografi, teks, foto} = anAwtis
const sortedTeks = sortTeks(teks)
const gwanBiyo = anAwtis.biyografi.length > 100
const {alias, biographie, paroles, photo} = anAwtis
const sortedTeks = sortTeks(paroles.data)
const gwanBiyo = biographie && biographie.length > 100
const biyo = gwanBiyo ? `${anAwtis.biyografi.slice(0, 100)}...` : anAwtis.biyografi
const biyo = gwanBiyo ? `${biographie.slice(0, 100)}...` : biographie
const handleClick = () => {
meteEsByografiOuve(true)
@@ -45,7 +46,7 @@ export default function AwtisDetay({anAwtis}) {
</Box>
<Box sx={{justifyContent: 'center', display: 'flex', marginBottom: 2}}>
<Avatar
src={`${API_URL}${foto[0].url}`}
src={`${photo?.data?.attributes?.url ? `${IMAGE_URL}${photo?.data?.attributes?.url}` : noImageUrl}`}
alt={`Photo ${alias}`}
sx={{width: 200, height: 200, border: `2px solid ${green[500]}`}}
/>
@@ -69,7 +70,7 @@ export default function AwtisDetay({anAwtis}) {
)}
<Grid item xs={12} md={6}>
<Box marginBottom={3}>
{teks.length > 1 ? (
{paroles.data.length > 1 ? (
<Accordion>
<AccordionSummary
expandIcon={<ExpandMoreIcon />}
@@ -77,7 +78,7 @@ export default function AwtisDetay({anAwtis}) {
id='panel-teks-header'
>
<Typography marginRight={2} textAlign='center' variant='body1' component='h2'><strong>Liste des textes</strong></Typography>
<Chip color='primary' label={teks.length} size='small' variant='contained' />
<Chip color='primary' label={paroles.data.length} size='small' variant='contained' />
</AccordionSummary>
<AccordionDetails>
<MizikLis teks={sortedTeks} />
@@ -87,7 +88,7 @@ export default function AwtisDetay({anAwtis}) {
<>
<Typography gutterBottom textAlign='center' variant='body1' component='h2'><strong>Texte</strong></Typography>
<Paper>
<MizikLis teks={teks} />
<MizikLis paroles={paroles.data} />
</Paper>
</>
)}
@@ -102,8 +103,8 @@ export default function AwtisDetay({anAwtis}) {
{esByografiOuve && (
<AwtisBiyografi
alias={alias}
teks={teks}
biyografi={biyografi}
paroles={paroles.data}
biographie={biographie}
esByografiOuve={esByografiOuve}
meteEsByografiOuve={meteEsByografiOuve}
/>
+11 -9
View File
@@ -23,6 +23,7 @@ import AwtisBiyografi from './awtis-biyografi'
const PREFIX = 'awtis-kat'
const SITE_URL = process.env.NEXT_PUBLIC_SITE_URL || 'http://localhost:3001'
const IMAGE_URL = process.env.NEXT_PUBLIC_API_URL_ROOT || 'http://localhost:1337'
const classes = {
root: `${PREFIX}-root`,
@@ -54,12 +55,13 @@ const Kat = styled('div')((
}
}))
export default function AwtisKat({anAwtis}) {
const noImageUrl = 'https://place-hold.it/140x140?text=Indisponible'
export default function AwtisKat({artiste}) {
const router = useRouter()
const [esByografiOuve, meteEsByografiOuve] = useState(false)
const noImageUrl = 'https://place-hold.it/140x140?text=Pa%20ni%20imaj'
const {alias, biyografi, teks, foto, slug} = anAwtis
const {alias, biographie, paroles, photo, slug} = artiste
const [expanded, setExpanded] = useState(false)
@@ -76,7 +78,7 @@ export default function AwtisKat({anAwtis}) {
className={classes.media}
component='img'
alt={alias}
image={`${foto.length > 0 ? `${process.env.NEXT_PUBLIC_API_URL}${foto[0].url}` : noImageUrl}`}
image={`${photo?.data?.attributes?.url ? `${IMAGE_URL}${photo?.data?.attributes?.url}` : noImageUrl}`}
title={alias}
/>
<CardContent>
@@ -84,7 +86,7 @@ export default function AwtisKat({anAwtis}) {
{alias}
</Typography>
<Typography align='center' variant='body2' color='textSecondary' component='h5'>
{anAwtis.teks.length} tèks
{`${paroles.data.length} ${paroles.data.length > 1 ? 'textes' : 'texte'}`}
</Typography>
</CardContent>
</CardActionArea>
@@ -104,15 +106,15 @@ export default function AwtisKat({anAwtis}) {
</CardActions>
<Collapse unmountOnExit in={expanded} timeout='auto'>
<CardContent>
<MizikLis teks={teks} />
<MizikLis paroles={paroles.data} />
</CardContent>
</Collapse>
</Card>
{esByografiOuve && (
<AwtisBiyografi
alias={alias}
teks={teks}
biyografi={biyografi}
paroles={paroles.data}
biographie={biographie}
esByografiOuve={esByografiOuve}
meteEsByografiOuve={meteEsByografiOuve}
/>
@@ -123,5 +125,5 @@ export default function AwtisKat({anAwtis}) {
}
AwtisKat.propTypes = {
anAwtis: PropTypes.object.isRequired
artiste: PropTypes.object.isRequired
}
+6 -6
View File
@@ -37,13 +37,13 @@ const Root = styled('div')((
}
}))
const sortTeks = teks => teks.sort((a, b) => b.id - a.id)
const sortTeks = paroles => paroles.sort((a, b) => b.id - a.id)
export default function MizikBadjMeni({teks}) {
export default function MizikBadjMeni({paroles}) {
const [open, setOpen] = useState(false)
const anchorRef = useRef(null)
const router = useRouter()
const sortedTeks = sortTeks(teks)
const sortedTeks = sortTeks(paroles)
const handleToggle = () => {
setOpen(previousOpen_ => !previousOpen_)
@@ -90,7 +90,7 @@ export default function MizikBadjMeni({teks}) {
vertical: 'top',
horizontal: 'right'
}}
badgeContent={teks.length}
badgeContent={paroles.length}
color='primary'
>
<MenuBookIcon style={{fontSize: 30}} />
@@ -105,7 +105,7 @@ export default function MizikBadjMeni({teks}) {
<Paper>
<ClickAwayListener onClickAway={handleClose}>
<MenuList autoFocusItem={open} id='menu-list-grow' onKeyDown={() => handleListKeyDown()}>
{sortedTeks.map(t => <MenuItem key={t.id} onClick={() => handleClick(t.slug)}>{t.tit}</MenuItem>)}
{sortedTeks.map(({id, attributes}) => <MenuItem key={id} onClick={() => handleClick(attributes.slug)}>{attributes.titre}</MenuItem>)}
</MenuList>
</ClickAwayListener>
</Paper>
@@ -117,5 +117,5 @@ export default function MizikBadjMeni({teks}) {
}
MizikBadjMeni.propTypes = {
teks: PropTypes.array.isRequired
paroles: PropTypes.array.isRequired
}
+11 -11
View File
@@ -27,7 +27,7 @@ const StyledList = styled(List)((
}
}))
export default function MizikLis({meteEsMobilOuve, niAwtis, teks, slugTeksChwazi, meteSlugTeksChwazi}) {
export default function MizikLis({meteEsMobilOuve, niAwtis, paroles, slugTeksChwazi, meteSlugTeksChwazi}) {
const router = useRouter()
const handleClick = slug => {
@@ -50,22 +50,22 @@ export default function MizikLis({meteEsMobilOuve, niAwtis, teks, slugTeksChwazi
return (
<StyledList component='nav' className={classes.root} aria-label='mizik'>
{teks.map(({slug, tit, awtis, published_at, okiMizikID, eksplisit}) => (
{paroles.map(({id, attributes}) => (
<ListItem
key={slug}
key={id}
button
id={slug}
selected={slugTeksChwazi === slug}
onClick={() => handleClick(slug)}
id={attributes.slug}
selected={slugTeksChwazi === attributes.slug}
onClick={() => handleClick(attributes.slug)}
>
<ListItemText primary={tit} secondary={niAwtis ? new Intl.ListFormat('fr').format(awtis.map(({alias}) => alias)) : null} />
{eksplisit && (
<ListItemText primary={attributes.titre} secondary={niAwtis ? new Intl.ListFormat('fr').format(attributes.artistes.data.map(({attributes}) => attributes.alias)) : null} />
{attributes.explicite && (
<ExplicitIcon style={{marginRight: 5}} color='secondary' />
)}
{okiMizikID && (
{attributes.okiMizikID && (
<LibraryMusicIcon style={{fontSize: 40}} color='primary' />
)}
{esBrandNew(published_at) && (
{esBrandNew(attributes.publishedAt) && (
<FiberNewOutlinedIcon style={{fontSize: 40}} color='primary' />
)}
</ListItem>
@@ -77,7 +77,7 @@ export default function MizikLis({meteEsMobilOuve, niAwtis, teks, slugTeksChwazi
MizikLis.propTypes = {
meteEsMobilOuve: PropTypes.func,
niAwtis: PropTypes.bool,
teks: PropTypes.array.isRequired,
paroles: PropTypes.array.isRequired,
slugTeksChwazi: PropTypes.string,
meteSlugTeksChwazi: PropTypes.func
}
+31 -25
View File
@@ -11,26 +11,25 @@ import {
} from '@mui/material'
import MuiAlert from '@mui/material/Alert'
const API_URL = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:1337'
const API_URL = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:1337/api'
const Alert = forwardRef(function Alert(props, ref) {
return <MuiAlert ref={ref} elevation={6} variant='filled' {...props} />
})
function EkriKomante({session, teks, meteEsKomanteOuve}) {
function EkriKomante({session, paroleId, meteEsKomanteOuve}) {
const {jwt, user} = session
const {id} = teks
const [komante, meteKomante] = useState({kontni: ''})
const [ere, meteEre] = useState('')
const [sikse, meteSikse] = useState('')
const [chaje, meteChaje] = useState(false)
const [esOuve, meteEsOuve] = useState(false)
const handleClick = () => {
const handleClick = async () => {
meteChaje(true)
const {kontni} = komante
if (kontni === '') {
meteEre({mesaj: 'Champ obligatoire'})
meteEre({error: {message: 'Champ obligatoire'}})
meteChaje(false)
return
@@ -41,21 +40,28 @@ function EkriKomante({session, teks, meteEsKomanteOuve}) {
Authorization: `Bearer ${jwt}`
}
axios.post(`${API_URL}/komante`, {
kontni,
teks: id,
user: user.id
}, {
headers
})
.then(() => {
meteSikse('Commentaire envoyé avec succès. Il apparaîtra sur le site après validation.')
meteChaje(false)
})
.catch(error => {
meteEre(error)
meteChaje(false)
try {
await axios.post(`${API_URL}/commentaires`, {
data: {
contenu: kontni,
parole: paroleId,
user: {
id: user.id,
username: user.username,
email: user.email
},
datePublication: new Date()
}
}, {
headers
})
meteSikse('Commentaire envoyé avec succès. Il apparaîtra sur le site après validation.')
meteChaje(false)
} catch (error) {
meteEre(error?.response?.data)
meteChaje(false)
}
}
const handleUpdate = useCallback(update => {
@@ -97,10 +103,10 @@ function EkriKomante({session, teks, meteEsKomanteOuve}) {
fullWidth
multiline
required
helperText='Votre commentaire (obligatoire)'
helperText='*Obligatoire. 500 caractères maximum'
style={{marginTop: '1em'}}
id='komante'
label='Kòmantè'
label='Commentaire'
value={komante.kontni}
rows={8}
variant='outlined'
@@ -123,16 +129,16 @@ function EkriKomante({session, teks, meteEsKomanteOuve}) {
{chaje && <LinearProgress size={24} style={{width: '100%', marginBlock: '1em'}} />}
</div>
{sikse && (
<Snackbar open={esOuve} autoHideDuration={3000} onClose={handleClose}>
<Snackbar open={esOuve} autoHideDuration={10_000} onClose={handleClose}>
<Alert severity='success' onClose={handleClose}>
<strong>{sikse}</strong>
</Alert>
</Snackbar>
)}
{ere && (
<Snackbar open={esOuve} autoHideDuration={3000} onClose={handleClose}>
<Snackbar open={esOuve} autoHideDuration={10_000} onClose={handleClose}>
<Alert severity='error' onClose={handleClose}>
<strong>Une erreur sest produite</strong> : <i>{ere.message}</i>
<strong>Une erreur sest produite</strong> : <i>{ere?.error?.message}</i>
</Alert>
</Snackbar>
)}
@@ -142,7 +148,7 @@ function EkriKomante({session, teks, meteEsKomanteOuve}) {
EkriKomante.propTypes = {
session: PropTypes.object.isRequired,
teks: PropTypes.object.isRequired,
paroleId: PropTypes.number.isRequired,
meteEsKomanteOuve: PropTypes.func.isRequired
}
+7 -7
View File
@@ -35,23 +35,23 @@ const StyledList = styled(List)((
}
}))
export default function KomanteList({komante}) {
export default function KomanteList({commentaires}) {
return (
<StyledList className={classes.root}>
{komante.map(({id, username, kontni, sentAt}) => (
{commentaires.map(({id, attributes}) => (
<div key={id}>
<ListItemText
primary={
<Typography gutterBottom style={{fontWeight: 'bold'}} variant='body1'>
{username}
<Typography gutterBottom style={{textDecoration: 'underline'}} variant='body1'>
<small>{attributes.user.data.attributes.username}</small>
</Typography>
}
/>
<ListItemText
primary={formatJsonString(kontni)}
primary={formatJsonString(attributes.contenu)}
secondary={
<Typography gutterBottom style={{marginBlock: 5, fontStyle: 'italic'}} variant='caption' display='block'>
{format(new Date(sentAt), 'Pp', {locale: fr})}
{format(new Date(attributes.datePublication), 'Pp', {locale: fr})}
</Typography>
}
/>
@@ -63,5 +63,5 @@ export default function KomanteList({komante}) {
}
KomanteList.propTypes = {
komante: PropTypes.array.isRequired
commentaires: PropTypes.array.isRequired
}
+9 -8
View File
@@ -45,7 +45,7 @@ const Root = styled('div')((
const KomanteTooltip = Tooltip
export default function VweKomante({komante, teks}) {
export default function VweKomante({commentaires, parole, paroleId}) {
const [esOuve, meteEsOuve] = useState(false)
const [esKoneksyonOuve, meteEsKoneksyonOuve] = useState(false)
const [esKomenteOuve, meteEsKomanteOuve] = useState(false)
@@ -88,7 +88,7 @@ export default function VweKomante({komante, teks}) {
size='large'
onClick={handleClick}
>
<Badge badgeContent={komante.length} color='primary'>
<Badge badgeContent={commentaires.length} color='primary'>
<CommentIcon />
</Badge>
</IconButton>
@@ -109,8 +109,8 @@ export default function VweKomante({komante, teks}) {
tabIndex={-1}
component='div'
>
{komante.length > 0 ? (
<KomanteList komante={komante} />
{commentaires.length > 0 ? (
<KomanteList commentaires={commentaires} />
) : (
<Typography component='div' align='center'>
Aucun commentaire
@@ -140,7 +140,7 @@ export default function VweKomante({komante, teks}) {
)}
{session && session.user && esKomenteOuve && (
<>
<EkriKomante session={session} teks={teks} meteEsKomanteOuve={meteEsKomanteOuve} />
<EkriKomante session={session} parole={parole} paroleId={paroleId} meteEsKomanteOuve={meteEsKomanteOuve} />
<Button fullWidth style={{marginBottom: 10}} color='primary' onClick={() => meteEsKomanteOuve(false)}>
Fermer
</Button>
@@ -152,10 +152,11 @@ export default function VweKomante({komante, teks}) {
}
VweKomante.defaultProps = {
komante: null
commentaires: null
}
VweKomante.propTypes = {
komante: PropTypes.array,
teks: PropTypes.object.isRequired
commentaires: PropTypes.array,
parole: PropTypes.object.isRequired,
paroleId: PropTypes.number.isRequired
}
+2 -7
View File
@@ -1,6 +1,5 @@
import {useState} from 'react'
import PropTypes from 'prop-types'
import axios from 'axios'
import Button from '@mui/material/Button'
import TextField from '@mui/material/TextField'
import Dialog from '@mui/material/Dialog'
@@ -10,9 +9,7 @@ import DialogContentText from '@mui/material/DialogContentText'
import DialogTitle from '@mui/material/DialogTitle'
import {validateEmail} from '../../lib/utils/emails'
import {jwennUserEpiEmail} from '../../lib/oki-api'
const API_URL = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:1337'
import {jwennUserEpiEmail, passwordRequest} from '../../lib/oki-api'
export default function ResetDialog({lyen, title, activation, content, open, setOpen, setLoading, setError, setSuccess}) {
const [email, setEmail] = useState('')
@@ -20,9 +17,7 @@ export default function ResetDialog({lyen, title, activation, content, open, set
const forgotPasswordRequest = async () => {
setLoading(true)
try {
await axios.post(`${API_URL}/auth/${lyen}`, {
email
})
await passwordRequest(lyen, email)
if (activation) {
const user = await jwennUserEpiEmail(email)
+5 -5
View File
@@ -67,7 +67,7 @@ function AjouteTradiksyon({showSwitch, disableSwitch, tradiksyonOtomatik, setTra
return (
<>
{showSwitch && (
<OtomatikSwitch tradiksyonOtomatik={tradiksyonOtomatik} setTradiksyonOtomatik={setTradiksyonOtomatik} disabled={!chwaLang.includes('fr') || disableSwitch} />
<OtomatikSwitch tradiksyonOtomatik={tradiksyonOtomatik} setTradiksyonOtomatik={setTradiksyonOtomatik} disabled={disableSwitch} />
)}
<Root style={{textAlign: 'center', marginTop: 20}}>
<Button
@@ -101,28 +101,28 @@ function AjouteTradiksyon({showSwitch, disableSwitch, tradiksyonOtomatik, setTra
root: classes.root
}}
onClick={handleClose}
>🇬🇧 English</StyledMenuItem>
>🇬🇧 Anglais</StyledMenuItem>
<StyledMenuItem
id='es'
classes={{
root: classes.root
}}
onClick={handleClose}
>🇪🇸 Español</StyledMenuItem>
>🇪🇸 Espagnol</StyledMenuItem>
<StyledMenuItem
id='de'
classes={{
root: classes.root
}}
onClick={handleClose}
>🇩🇪 Deutsch</StyledMenuItem>
>🇩🇪 Allemand</StyledMenuItem>
<StyledMenuItem
id='it'
classes={{
root: classes.root
}}
onClick={handleClose}
>🇮🇹 Italiano</StyledMenuItem>
>🇮🇹 Italien</StyledMenuItem>
</StyledMenu>
</Root>
</>
+7 -6
View File
@@ -15,7 +15,7 @@ import CircularProgress from '@mui/material/CircularProgress'
import Typography from '@mui/material/Typography'
import AudiotrackIcon from '@mui/icons-material/Audiotrack'
import {jwennTeksEpiUserId} from '../../lib/oki-api'
import {jwennUserEpiToken} from '../../lib/oki-api'
function Chwa(props) {
const {onClose, teksLis, selectedTeks, loading, open} = props
@@ -37,14 +37,14 @@ function Chwa(props) {
</Container>
) : (
<List sx={{pt: 0}}>
{teksLis.length > 0 ? teksLis.map(({id, tit, awtis}) => (
{teksLis.length > 0 ? teksLis.map(({id, titre, artistes}) => (
<ListItem key={id} button onClick={() => handleListItemClick(id)}>
<ListItemAvatar>
<Avatar sx={{bgcolor: green[100], color: green[600]}}>
<AudiotrackIcon />
</Avatar>
</ListItemAvatar>
<ListItemText primary={`${new Intl.ListFormat('fr').format(awtis.map(({alias}) => alias))} - ${tit}`} />
<ListItemText primary={`${new Intl.ListFormat('fr').format(artistes.map(({alias}) => alias))} - ${titre}`} />
</ListItem>
)) : (
<Typography sx={{textAlign: 'center'}} variant='button' component='div'>Aucun texte</Typography>
@@ -70,7 +70,6 @@ Chwa.propTypes = {
export default function ChwaTeks({selectedTeks, setSelectedTeks}) {
const {data: session} = useSession()
const [loading, setLoading] = useState(false)
const {user} = session
const [open, setOpen] = useState(false)
const [teksLis, setTeksLis] = useState([])
@@ -78,9 +77,11 @@ export default function ChwaTeks({selectedTeks, setSelectedTeks}) {
setOpen(true)
setLoading(true)
const jwennTeks = await jwennTeksEpiUserId(user.id)
const user = await jwennUserEpiToken(session?.jwt)
const {paroles} = user
const parolesList = paroles && paroles.length > 0 ? paroles : []
setTeksLis(jwennTeks)
setTeksLis(parolesList)
setLoading(false)
}
+91 -86
View File
@@ -23,6 +23,8 @@ import {
import MuiAlert from '@mui/material/Alert'
import VisibilityOffIcon from '@mui/icons-material/VisibilityOff'
import {jwennAnTeks} from '../../lib/oki-api'
import AjouteTradiksyon from './ajoute-tradiksyon'
const PREFIX = 'EkriTeks'
@@ -108,7 +110,7 @@ function EkriTeks({canAutoTranslate, selectedTeks, setSelectedTeks}) {
setError('')
}
const handleClick = () => {
const handleClick = async () => {
setLoading(true)
const {awtis, tit, transkripsyon} = teksEkri
const {fr, en, es, de, it} = tradiksyon
@@ -126,81 +128,85 @@ function EkriTeks({canAutoTranslate, selectedTeks, setSelectedTeks}) {
}
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ée'})
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: {
francais: fr === '' ? null : fr,
anglais: en === '' ? null : en,
espagnol: es === '' ? null : es,
allemand: de === '' ? null : de,
italien: it === '' ? null : it
},
user: {
id: user.id,
username: user.username,
email: user.email
},
artistes: teks.artistes.map(({id}) => id),
traductionAuto: tradiksyonOtomatik
}
}, {
headers
})
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)
})
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?.response?.data)
setLoading(false)
}
} else {
axios.post(`${API_URL}/awtis`, {
alias: awtis,
user
}, {
headers
})
.then(awtisResponse => {
axios.post(`${API_URL}/teks`, {
tit,
transkripsyon,
tradiksyon: {
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: {
francais: fr === '' ? null : fr,
english: en === '' ? null : en,
anglais: en === '' ? null : en,
espagnol: es === '' ? null : es,
deutsch: de === '' ? null : de,
italiano: it === '' ? null : it
allemand: de === '' ? null : de,
italien: 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)
user: {
id: user.id,
username: user.username,
email: user.email
},
artistes: [artiste.data.id],
traductionAuto: tradiksyonOtomatik
}
}, {
headers
})
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)
}
}
}
@@ -230,39 +236,38 @@ function EkriTeks({canAutoTranslate, selectedTeks, setSelectedTeks}) {
setTradiksyonOtomatik(false)
setCurrentTeksId(selectedTeks.id)
setTeksEkri({
awtis: new Intl.ListFormat('fr').format(selectedTeks.awtis.map(({alias}) => alias)),
tit: selectedTeks.tit,
transkripsyon: selectedTeks.transkripsyon
awtis: new Intl.ListFormat('fr').format(selectedTeks.artistes.map(({alias}) => alias)),
tit: selectedTeks.titre,
transkripsyon: selectedTeks.transcription
})
setTradiksyon({
fr: selectedTeks.tradiksyon.francais || '',
en: selectedTeks.tradiksyon.english || '',
es: selectedTeks.tradiksyon.espagnol || '',
de: selectedTeks.tradiksyon.deutsch || '',
it: selectedTeks.tradiksyon.italiano || ''
fr: selectedTeks?.traductions?.francais || '',
en: selectedTeks?.traductions?.anglais || '',
es: selectedTeks?.traductions?.espagnol || '',
de: selectedTeks?.traductions?.allemand || '',
it: selectedTeks?.traductions?.italien || ''
})
const jennLangId = () => {
const ids = []
const {francais, english, espagnol, deutsch, italiano} = selectedTeks.tradiksyon
if (francais) {
if (selectedTeks?.traductions?.francais) {
ids.push('fr')
}
if (english) {
if (selectedTeks?.traductions?.anglais) {
ids.push('en')
}
if (espagnol) {
if (selectedTeks?.traductions?.espagnol) {
ids.push('es')
}
if (deutsch) {
if (selectedTeks?.traductions?.allemand) {
ids.push('de')
}
if (italiano) {
if (selectedTeks?.traductions?.italien) {
ids.push('it')
}
@@ -369,7 +374,7 @@ function EkriTeks({canAutoTranslate, selectedTeks, setSelectedTeks}) {
</form>
<AjouteTradiksyon
showSwitch={Boolean(canAutoTranslate) && Boolean(!currentTeksId)}
disableSwitch={tradiksyon.fr === ''}
disableSwitch={tradiksyon.fr === '' || tradiksyon.en !== '' || tradiksyon.es !== '' || tradiksyon.de !== '' || tradiksyon.it !== ''}
tradiksyonOtomatik={tradiksyonOtomatik}
setTradiksyonOtomatik={setTradiksyonOtomatik}
chwaLang={kiChawLang}
@@ -410,9 +415,9 @@ function EkriTeks({canAutoTranslate, selectedTeks, setSelectedTeks}) {
</Snackbar>
)}
{error && (
<Snackbar open={open} autoHideDuration={6000} onClose={handleClose}>
<Snackbar open={open} autoHideDuration={10_000} onClose={handleClose}>
<Alert severity='error' onClose={handleClose}>
<strong>Une erreur sest produite</strong> : <i>{error.message}</i>
<strong>Une erreur sest produite</strong> : <i>{error?.error?.message}</i>
</Alert>
</Snackbar>
)}
+5 -1
View File
@@ -10,7 +10,11 @@ export default function OtomatikSwitch({tradiksyonOtomatik, setTradiksyonOtomati
return (
<FormGroup sx={{marginTop: 1}}>
<FormControlLabel control={<Switch checked={tradiksyonOtomatik && !disabled} onChange={handleChange} />} disabled={disabled} label='Traduction automatique après validation (français vers les autres langues)' />
<FormControlLabel
control={<Switch checked={tradiksyonOtomatik && !disabled} onChange={handleChange} />}
disabled={disabled}
label='Traduction du français vers les autres langues (remplir uniquement la traduction française)'
/>
</FormGroup>
)
}
+1 -1
View File
@@ -30,7 +30,7 @@ export default function DenyeTeks({denyeTeks}) {
</Container>
)}
<Grid container spacing={3}>
{denyeTeks.map(t => <TeksKat key={t.id} teks={t} />)}
{denyeTeks.map(t => <TeksKat key={t.id} parole={t} />)}
</Grid>
</Container>
</Root>
+13 -13
View File
@@ -44,15 +44,15 @@ const Root = styled('div')((
}
}))
const getMizikFiltered = (teks, filter) => {
if (teks) {
const filteredTitre = teks.filter(({tit}) => {
const deburredTit = deburr(tit)
const getMizikFiltered = (paroles, filter) => {
if (paroles) {
const filteredTitre = paroles.filter(({attributes}) => {
const deburredTit = deburr(attributes.titre)
return deburredTit.toLowerCase().includes(deburr(filter.toLowerCase()))
})
const filteredAlias = teks.filter(({awtis}) => {
const aliasLis = awtis.map(({alias}) => deburr(alias)).join(', ')
const filteredAlias = paroles.filter(({attributes}) => {
const aliasLis = attributes.artistes.data.map(({attributes}) => deburr(attributes.alias)).join(', ')
return aliasLis.toLowerCase().includes(deburr(filter.toLowerCase()))
})
@@ -60,13 +60,13 @@ const getMizikFiltered = (teks, filter) => {
}
}
export default function DrawerBar({meteEsMobilOuve, teks, anTeks}) {
const slug = anTeks ? anTeks.slug : null
export default function DrawerBar({meteEsMobilOuve, paroles, parole}) {
const slug = parole ? parole.slug : null
const [search, setSearch] = useState('')
const [slugTeksChwazi, meteSlugTeksChwazi] = useState(slug)
const mizikFiltered = getMizikFiltered(teks, search)
const mizikFiltered = getMizikFiltered(paroles, search)
const handleSearch = event => {
event.preventDefault()
@@ -94,7 +94,7 @@ export default function DrawerBar({meteEsMobilOuve, teks, anTeks}) {
<MizikLis
niAwtis
meteEsMobilOuve={meteEsMobilOuve}
teks={mizikFiltered}
paroles={mizikFiltered}
slugTeksChwazi={slugTeksChwazi}
meteSlugTeksChwazi={meteSlugTeksChwazi}
/>
@@ -105,11 +105,11 @@ export default function DrawerBar({meteEsMobilOuve, teks, anTeks}) {
DrawerBar.propTypes = {
meteEsMobilOuve: PropTypes.func,
teks: PropTypes.array.isRequired,
anTeks: PropTypes.object
paroles: PropTypes.array.isRequired,
parole: PropTypes.object
}
DrawerBar.defaultProps = {
meteEsMobilOuve: null,
anTeks: null
parole: null
}
+18 -18
View File
@@ -17,9 +17,9 @@ const kouteyAchteyIcons = {
Soundcloud: <Soundcloud />
}
function RannIframe({boutik, url, isMobile}) {
function RannIframe({plateforme, url, isMobile}) {
let src = ''
switch (boutik) {
switch (plateforme) {
case 'Tidal': {
const trackArray = url.split('/')
const trackId = trackArray[trackArray.length - 1]
@@ -54,7 +54,7 @@ function RannIframe({boutik, url, isMobile}) {
return (
<div style={{marginTop: 5}}>
{boutik === 'Tidal' && (
{plateforme === 'Tidal' && (
<iframe
src={src}
allowFullScreen='allowfullscreen'
@@ -64,7 +64,7 @@ function RannIframe({boutik, url, isMobile}) {
/>
)}
{boutik === 'Deezer' && (
{plateforme === 'Deezer' && (
<iframe
title='deezer-widget'
frameBorder='0'
@@ -74,7 +74,7 @@ function RannIframe({boutik, url, isMobile}) {
/>
)}
{boutik === 'Spotify' && (
{plateforme === 'Spotify' && (
<iframe
src={src}
width={`${isMobile ? '100%' : '50%'}`}
@@ -85,7 +85,7 @@ function RannIframe({boutik, url, isMobile}) {
/>
)}
{boutik === 'Soundcloud' && (
{plateforme === 'Soundcloud' && (
<iframe
src={src}
width={`${isMobile ? '100%' : '50%'}`}
@@ -99,18 +99,18 @@ function RannIframe({boutik, url, isMobile}) {
)
}
function EntegreMizik({anTeks, isMobile}) {
function EntegreMizik({parole, isMobile}) {
const [chwaMizik, meteChwaMizik] = useState(null)
const router = useRouter()
const {kouteyAchtey, slug, okiMizikID} = anTeks
const filteredKouteyAchtey = kouteyAchtey.filter(({boutik}) => boutik === 'Tidal' || boutik === 'Spotify' || boutik === 'Deezer' || boutik === 'Soundcloud')
const {streamAudio, slug, okiMizikID} = parole
const filteredKouteyAchtey = streamAudio.filter(({plateforme}) => plateforme === 'Tidal' || plateforme === 'Spotify' || plateforme === 'Deezer' || plateforme === 'Soundcloud')
const handleClick = (boutik, url) => {
if (chwaMizik && chwaMizik.boutik === boutik) {
const handleClick = (plateforme, url) => {
if (chwaMizik && chwaMizik.plateforme === plateforme) {
return meteChwaMizik(null)
}
meteChwaMizik({boutik, url})
meteChwaMizik({plateforme, url})
}
useEffect(() => {
@@ -121,31 +121,31 @@ function EntegreMizik({anTeks, isMobile}) {
return (
<Box align='center'>
{!okiMizikID && filteredKouteyAchtey.map(({id, boutik, url}) => (
{!okiMizikID && filteredKouteyAchtey.map(({id, plateforme, url}) => (
<IconButton
key={id}
aria-label='player'
size='large'
onClick={() => handleClick(boutik, url)}
onClick={() => handleClick(plateforme, url)}
>
{kouteyAchteyIcons[boutik]}
{kouteyAchteyIcons[plateforme]}
</IconButton>
))}
{chwaMizik && (
<RannIframe boutik={chwaMizik.boutik} url={chwaMizik.url} isMobile={isMobile} />
<RannIframe plateforme={chwaMizik.plateforme} url={chwaMizik.url} isMobile={isMobile} />
)}
</Box>
)
}
EntegreMizik.propTypes = {
anTeks: PropTypes.object.isRequired,
parole: PropTypes.object.isRequired,
isMobile: PropTypes.bool.isRequired
}
RannIframe.propTypes = {
boutik: PropTypes.string.isRequired,
plateforme: PropTypes.string.isRequired,
url: PropTypes.string.isRequired,
isMobile: PropTypes.bool.isRequired
}
+10 -10
View File
@@ -14,7 +14,7 @@ import Image from 'next/image'
import {grey} from '@mui/material/colors'
import {Link} from '@mui/material'
const apiUrl = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:1337'
const IMAGE_URL = process.env.NEXT_PUBLIC_API_URL_ROOT || 'http://localhost:1337'
const Widget = styled('div')(({theme}) => ({
padding: 16,
@@ -49,7 +49,7 @@ const TinyText = styled(Typography)({
letterSpacing: 0.2,
})
export default function Lekte({audio, url, teks}) {
export default function Lekte({audio, url, parole}) {
const audioRef = useRef(new Audio(audio))
const intervalRef = useRef()
const isReady = useRef(false)
@@ -58,7 +58,7 @@ export default function Lekte({audio, url, teks}) {
const [position, setPosition] = useState(0)
const [volume, setVolume] = useState(100)
const [isPlaying, setIsPlaying] = useState(false)
const awtis = teks.awtis.map(({alias}) => alias)
const awtis = parole.artistes.data.map(({attributes}) => attributes.alias)
function formatDuration(value) {
const minute = Math.floor(value / 60)
@@ -139,10 +139,10 @@ export default function Lekte({audio, url, teks}) {
<Box sx={{display: 'flex', alignItems: 'center'}}>
<CoverImage>
<Image
alt={teks.tit}
src={teks?.kouveti?.formats?.thumbnail ? `${apiUrl}${teks.kouveti.formats.thumbnail.url}` : '/oki-logo-192x192.png'}
width={teks?.kouveti?.formats?.thumbnail ? teks.kouveti.formats.thumbnail.width : 192}
height={teks?.kouveti?.formats?.thumbnail ? teks.kouveti.formats.thumbnail.height : 192}
alt={parole.titre}
src={parole?.couverture?.data?.attributes?.formats?.thumbnail ? `${IMAGE_URL}${parole.couverture.data.attributes.formats.thumbnail.url}` : '/oki-logo-192x192.png'}
width={parole?.kouveti?.data?.attributes?.formats?.thumbnail ? parole.couverture.data.attributes.formats.thumbnail.width : 192}
height={parole?.kouveti?.data?.attributes?.formats?.thumbnail ? parole.couverture.data.attributes.formats.thumbnail.height : 192}
/>
</CoverImage>
<Box sx={{ml: 1.5, minWidth: 0}}>
@@ -151,11 +151,11 @@ export default function Lekte({audio, url, teks}) {
</Typography>
<Typography>
<Link underline='hover' sx={{cursor: 'pointer'}} target='_blank' rel='noreferrer' href={url}>
<strong>{teks.tit}</strong>
<strong>{parole.titre}</strong>
</Link>
</Typography>
<Typography variant='caption'>
<i>{teks.lanne}</i>
<i>{parole.annee}</i>
</Typography>
</Box>
</Box>
@@ -263,5 +263,5 @@ export default function Lekte({audio, url, teks}) {
Lekte.propTypes = {
audio: PropTypes.string.isRequired,
url: PropTypes.string.isRequired,
teks: PropTypes.object.isRequired
parole: PropTypes.object.isRequired
}
+3 -3
View File
@@ -11,18 +11,18 @@ const DinamikLekte = dynamic(
{ssr: false, loading: () => <CircularProgress sx={{color: '#29d'}} />}
)
export default function OkiMizik({id, teks}) {
export default function OkiMizik({id, parole}) {
const mizikStreamUrl = `${MIZIK_URL}/rest/stream?u=${MIZIK_API_USER}&p=${MIZIK_API_PASSWORD}&id=${id}`
const detailsUrl = `${MIZIK_URL}/library/tracks/${id}`
return (
<Box style={{marginTop: '0.3em', display: 'flex', flexDirection: 'column', alignItems: 'center'}}>
<DinamikLekte audio={mizikStreamUrl} url={detailsUrl} teks={teks} />
<DinamikLekte audio={mizikStreamUrl} url={detailsUrl} parole={parole} />
</Box>
)
}
OkiMizik.propTypes = {
id: PropTypes.number.isRequired,
teks: PropTypes.object.isRequired
parole: PropTypes.object.isRequired
}
+5 -5
View File
@@ -43,15 +43,15 @@ const actions = [
{icon: <FileCopyIcon />, name: 'Copier le lien', code: 'copy'}
]
export default function Pataje({teks, setError, setSuccess}) {
const {tit, awtis, slug} = teks
export default function Pataje({parole, setError, setSuccess}) {
const {titre, artistes, slug} = parole
const [open, setOpen] = useState(false)
const patajeUrl = `${SITE_URL}/paroles/${slug}`
const alias = awtis.map(({alias}) => alias)
const alias = artistes.data.map(({attributes}) => attributes.alias)
const renderAwtis = new Intl.ListFormat('fr').format(alias)
const text = teks.user || teks.userAdmin ? `${renderAwtis} - ${tit} (Paroles et Traductions) - (texte soumis par ${teks?.user?.username || teks.userAdmin})` : `${renderAwtis} - ${tit} (Paroles et Traductions)`
const text = parole.user || parole.userAdmin ? `${renderAwtis} - ${titre} (Paroles et Traductions) - (texte soumis par ${parole?.user?.username || parole.userAdmin})` : `${renderAwtis} - ${parole} (Paroles et Traductions)`
const handleClose = () => {
setOpen(false)
@@ -123,7 +123,7 @@ export default function Pataje({teks, setError, setSuccess}) {
}
Pataje.propTypes = {
teks: PropTypes.object.isRequired,
parole: PropTypes.object.isRequired,
setError: PropTypes.func.isRequired,
setSuccess: PropTypes.func.isRequired
}
+19 -16
View File
@@ -117,7 +117,7 @@ const Root = styled('div')((
const drawerWidth = 240
export default function TeksDrawer({teks, anTeks, komante, denyeTeks}) {
export default function TeksDrawer({paroles, parole, paroleId, commentaires, denyeTeks}) {
const theme = useTheme()
const [esMobilOuve, meteEsMobilOuve] = useState(false)
const [open, setOpen] = useState(false)
@@ -161,21 +161,21 @@ export default function TeksDrawer({teks, anTeks, komante, denyeTeks}) {
>
<MenuIcon />
</IconButton>
{anTeks ? (
{parole ? (
<>
<Link passHref href='/paroles'>
<IconButton aria-label='return' size='medium'>
<KeyboardBackspaceIcon style={{fontSize: '1.5em'}} />
</IconButton>
</Link>
{anTeks.lyen && anTeks.lyen.length > 0 && (
{parole.streamVideo && parole.streamVideo.length > 0 && (
<div className={classes.vwe}>
<VweKouteAchte niVideyo anTeks={anTeks} />
<VweKouteAchte niVideyo parole={parole} />
</div>
)}
{anTeks.kouteyAchtey && anTeks.kouteyAchtey.length > 0 && (
{parole.streamVideo && parole.streamVideo.length > 0 && (
<div className={classes.koute}>
<VweKouteAchte niOdyo anTeks={anTeks} />
<VweKouteAchte niOdyo parole={parole} />
</div>
)}
</>
@@ -201,7 +201,7 @@ export default function TeksDrawer({teks, anTeks, komante, denyeTeks}) {
}}
onClose={handleDrawerToggle}
>
<DrawerBar meteEsMobilOuve={meteEsMobilOuve} teks={teks} anTeks={anTeks} />
<DrawerBar meteEsMobilOuve={meteEsMobilOuve} paroles={paroles} parole={parole} />
</Drawer>
</Hidden>
<Hidden smDown implementation='css'>
@@ -212,15 +212,16 @@ export default function TeksDrawer({teks, anTeks, komante, denyeTeks}) {
}}
variant='permanent'
>
<DrawerBar teks={teks} anTeks={anTeks} />
<DrawerBar paroles={paroles} parole={parole} />
</Drawer>
</Hidden>
</nav>
<main className={classes.content}>
{anTeks ? (
{parole ? (
<Teks
anTeks={anTeks}
komante={komante}
parole={parole}
paroleId={paroleId}
commentaires={commentaires}
open={open}
success={success}
error={error}
@@ -239,14 +240,16 @@ export default function TeksDrawer({teks, anTeks, komante, denyeTeks}) {
}
TeksDrawer.propTypes = {
teks: PropTypes.array.isRequired,
anTeks: PropTypes.object,
komante: PropTypes.array,
paroles: PropTypes.array.isRequired,
parole: PropTypes.object,
paroleId: PropTypes.number,
commentaires: PropTypes.array,
denyeTeks: PropTypes.array
}
TeksDrawer.defaultProps = {
anTeks: null,
komante: null,
parole: null,
paroleId: null,
commentaires: null,
denyeTeks: null
}
+20 -16
View File
@@ -14,6 +14,7 @@ import ExplicitIcon from '@mui/icons-material/Explicit'
import {styled} from '@mui/material/styles'
const PREFIX = 'teks-kat'
const IMAGE_URL = process.env.NEXT_PUBLIC_API_URL_ROOT || 'http://localhost:1337'
const classes = {
root: `${PREFIX}-root`,
@@ -30,12 +31,15 @@ const StyledGrid = styled(Grid)({
}
})
export default function TeksKat({teks}) {
const noImageUrl = 'https://place-hold.it/140x140?text=Indisponible'
export default function TeksKat({parole}) {
const router = useRouter()
const noImageUrl = 'https://place-hold.it/140x140?text=Pa%20ni%20imaj'
const {tit, awtis, lanne, kouveti, published_at, slug} = teks
const datPiblikasyon = format(new Date(published_at), 'P', {locale: fr})
const alias = awtis.map(({alias}) => alias)
const {attributes} = parole
const {titre, artistes, annee, couverture, publishedAt, slug} = attributes
const datPiblikasyon = format(new Date(publishedAt), 'P', {locale: fr})
const alias = artistes.data.map(({attributes}) => attributes.alias)
const handleClick = slug => {
router.push(`/paroles/${slug}#${slug}`).then(() => window.scrollTo(0, 0))
@@ -48,26 +52,26 @@ export default function TeksKat({teks}) {
<CardMedia
className={classes.media}
component='img'
alt={tit}
image={kouveti ? `${process.env.NEXT_PUBLIC_API_URL}${kouveti.url}` : noImageUrl}
title={tit}
alt={titre}
image={couverture?.data?.attributes?.url ? `${IMAGE_URL}${couverture.data.attributes.url}` : noImageUrl}
title={titre}
/>
<CardContent>
<Typography display='inline' style={{marginRight: 5}} variant='h6' component='h2'>
{tit}
{titre}
</Typography>
{teks.eksplisit && (
{parole.eksplisit && (
<ExplicitIcon style={{marginRight: 5}} color='secondary' fontSize='small' />
)}
<Typography variant='caption'>
{teks.user && (
{parole.user && (
<>
(<i>texte soumis par {teks.user.username}</i>)
(<i>texte soumis par {parole.user.username}</i>)
</>
)}
{teks.userAdmin && !teks.user && (
{parole.userAdmin && !parole.user && (
<>
(<i>texte soumis par {teks.userAdmin}</i>)
(<i>texte soumis par {parole.userAdmin}</i>)
</>
)}
</Typography>
@@ -75,7 +79,7 @@ export default function TeksKat({teks}) {
{new Intl.ListFormat('fr').format(alias)}
</Typography>
<Typography variant='body2' color='textSecondary' component='p'>
{lanne}
{annee}
</Typography>
<Typography align='center' style={{marginTop: '0.5em'}} variant='body1' color='textSecondary' component='p'>
Publié le : {datPiblikasyon}
@@ -88,5 +92,5 @@ export default function TeksKat({teks}) {
}
TeksKat.propTypes = {
teks: PropTypes.object.isRequired
parole: PropTypes.object.isRequired
}
+30 -29
View File
@@ -66,30 +66,30 @@ const Root = styled('div')((
}
}))
const langToArray = anTeks => {
const langToArray = parole => {
const langArray = []
if (anTeks && anTeks.tradiksyon) {
const {francais, english, espagnol, deutsch, italiano} = anTeks.tradiksyon
if (parole && parole.traductions) {
const {francais, anglais, espagnol, allemand, italien} = parole.traductions
if (francais) {
langArray.push({title: 'Traduction', flag: 'fr', lang: francais})
}
if (english) {
langArray.push({title: 'Translation', flag: 'en', lang: english})
if (anglais) {
langArray.push({title: 'Translation', flag: 'en', lang: anglais})
}
if (espagnol) {
langArray.push({title: 'Traducción', flag: 'es', lang: espagnol})
}
if (deutsch) {
langArray.push({title: 'Übersetzung', flag: 'de', lang: deutsch})
if (allemand) {
langArray.push({title: 'Übersetzung', flag: 'de', lang: allemand})
}
if (italiano) {
langArray.push({title: 'Traduzione', flag: 'it', lang: italiano})
if (italien) {
langArray.push({title: 'Traduzione', flag: 'it', lang: italien})
}
}
@@ -120,15 +120,15 @@ const Alert = forwardRef(function Alert(props, ref) {
const ExplicitTooltip = Tooltip
export default function Teks({anTeks, komante, open, success, error, setSuccess, setError, handleClose}) {
export default function Teks({parole, paroleId, commentaires, open, success, error, setSuccess, setError, handleClose}) {
const isMobile = useMediaQuery('(max-width:800px)')
const langArray = langToArray(anTeks)
const awtis = anTeks.awtis.map(({alias}) => alias)
const langArray = langToArray(parole)
const awtis = parole.artistes.data.map(({attributes}) => attributes.alias)
return (
<Root>
<div className={classes.pataje}>
<Pataje teks={anTeks} setError={setError} setSuccess={setSuccess} />
<Pataje parole={parole} setError={setError} setSuccess={setSuccess} />
</div>
<Box sx={{textAlign: 'center', marginTop: 9}}>
<Typography style={{marginTop: '0.8em'}} variant='h4' component='div' display='block'>
@@ -136,8 +136,8 @@ export default function Teks({anTeks, komante, open, success, error, setSuccess,
{new Intl.ListFormat('fr').format(awtis)}
</Typography>
<Typography variant='h5' component='div'>
{anTeks.tit} <small>({anTeks?.lanne})</small>
{anTeks.eksplisit && (
{parole.titre} <small>({parole?.annee})</small>
{parole.explicite && (
<ExplicitTooltip
title='Explicit Lyrics'
placement='bottom'
@@ -151,29 +151,29 @@ export default function Teks({anTeks, komante, open, success, error, setSuccess,
)}
</Typography>
<Grid container alignItems='center' justifyContent='center'>
{komante && (
<VweKomante komante={komante} teks={anTeks} />
{commentaires && (
<VweKomante commentaires={commentaires} parole={parole} paroleId={paroleId} />
)}
</Grid>
</Typography>
{anTeks.user && (
{parole?.user?.data && (
<Typography style={{marginBottom: '1.5em'}} display='block' variant='caption'>
<i>texte soumis par {anTeks.user.username}</i>
<i>texte soumis par {parole.user.data.attributes.username}</i>
</Typography>
)}
{anTeks.userAdmin && !anTeks.user && (
{parole.userAdmin && !parole.user && (
<Typography style={{marginBottom: '1.5em'}} display='block' variant='caption'>
<i>texte soumis par {anTeks.userAdmin}</i>
<i>texte soumis par {parole.userAdmin}</i>
</Typography>
)}
</Box>
{(anTeks.okiMizikID || anTeks.kouteyAchtey.length > 0) && (
{(parole.okiMizikID || parole.streamAudio.length > 0) && (
<Box sx={{textAlign: 'center'}}>
<EntegreMizik anTeks={anTeks} isMobile={isMobile} />
<EntegreMizik parole={parole} isMobile={isMobile} />
</Box>
)}
{anTeks.okiMizikID && (
<OkiMizik id={anTeks.okiMizikID} teks={anTeks} />
{parole.okiMizikID && (
<OkiMizik id={parole.okiMizikID} parole={parole} />
)}
<Grid container justifyContent='start' spacing={1}>
<Grid item xs={12} md={langArray.length > 0 ? 6 : null}>
@@ -182,7 +182,7 @@ export default function Teks({anTeks, komante, open, success, error, setSuccess,
Transcription
</Typography>
<Typography paragraph align={alignTeks(langArray, isMobile)} component='span'>
{formatJsonString(anTeks.transkripsyon)}
{formatJsonString(parole.transcription)}
</Typography>
</div>
</Grid>
@@ -242,8 +242,9 @@ export default function Teks({anTeks, komante, open, success, error, setSuccess,
}
Teks.propTypes = {
anTeks: PropTypes.object.isRequired,
komante: PropTypes.array,
parole: PropTypes.object.isRequired,
paroleId: PropTypes.number.isRequired,
commentaires: PropTypes.array,
open: PropTypes.bool.isRequired,
success: PropTypes.string,
error: PropTypes.string,
@@ -253,7 +254,7 @@ Teks.propTypes = {
}
Teks.defaultProps = {
komante: null,
commentaires: null,
success: '',
error: ''
}
+10 -10
View File
@@ -49,22 +49,22 @@ const vweyIcons = {
Dailymotion: <Dailymotion />,
Lbry: <Lbry />,
Rumble: <PlayCircleFilledIcon />,
Peertube: <Peertube />
Gadé: <Peertube />
}
export default function VweKouteAchte({anTeks, niVideyo, niOdyo}) {
export default function VweKouteAchte({parole, niVideyo, niOdyo}) {
const [ouve, meteOuve] = useState(false)
const {kouteyAchtey, lyen} = anTeks
const {streamAudio, streamVideo} = parole
const kouteyAchteyActions = kouteyAchtey.map(({boutik, url}) => ({
icon: kouteyAchteyIcons[boutik],
name: boutik,
const kouteyAchteyActions = streamAudio.map(({plateforme, url}) => ({
icon: kouteyAchteyIcons[plateforme],
name: plateforme,
link: url
}))
const vweyActions = lyen.map(({url, sit}) => ({
icon: vweyIcons[sit],
name: sit,
const vweyActions = streamVideo.map(({plateforme, url}) => ({
icon: vweyIcons[plateforme],
name: plateforme,
link: url
}))
@@ -115,7 +115,7 @@ export default function VweKouteAchte({anTeks, niVideyo, niOdyo}) {
}
VweKouteAchte.propTypes = {
anTeks: PropTypes.object.isRequired,
parole: PropTypes.object.isRequired,
niVideyo: PropTypes.bool,
niOdyo: PropTypes.bool
}
+137 -41
View File
@@ -1,21 +1,44 @@
import axios from 'axios'
import qs from 'qs'
const OKI_API = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:1337'
const AWTIS_POU_CHAK_PAJ = process.env.NEXT_PUBLIC_AWTIS_POU_CHAK_PAJ || 6
const readToken = process.env.NEXT_PUBLIC_READ_TOKEN || 'read-token'
const readAxiosInstance = axios.create({
headers: {
Authorization: `Bearer ${readToken}`
}
})
export async function jwennTeksEpiSlug(slug) {
const response = await axios.get(`${OKI_API}/teks?slug=${slug}&_where[published_at_null]=false`)
return response.data[0]
const query = qs.stringify({
populate: ['artistes', 'couverture'],
filters: {
slug: {
$eq: slug
}
}
}, {
encodeValuesOnly: true
})
const {data} = await readAxiosInstance.get(`${OKI_API}/paroles?${query}`)
return data.data[0]
}
export async function jwennAwtisEpiSlug(slug) {
const response = await axios.get(`${OKI_API}/awtis?slug=${slug}&_where[published_at_null]=false`)
return response.data[0]
}
export async function jwennAwtisKantite() {
const response = await axios.get(`${OKI_API}/awtis/count?_where[published_at_null]=false`)
return response.data
const query = qs.stringify({
populate: ['paroles', 'photo'],
filters: {
slug: {
$eq: slug
}
}
}, {
encodeValuesOnly: true
})
const {data} = await readAxiosInstance.get(`${OKI_API}/artistes?${query}`)
return data.data[0]
}
export async function jwennTeksKantite() {
@@ -25,55 +48,98 @@ export async function jwennTeksKantite() {
export async function jwennAwtisPajinasyon(paj) {
const start = AWTIS_POU_CHAK_PAJ * (paj - 1)
const query = `_sort=published_at:DESC&_start=${start}&_limit=${AWTIS_POU_CHAK_PAJ}&_where[published_at_null]=false`
const query = qs.stringify({
populate: ['paroles', 'photo'],
sort: ['publishedAt:desc'],
pagination: {
start,
limit: AWTIS_POU_CHAK_PAJ
}
}, {
encodeValuesOnly: true
})
const response = await axios.get(`${OKI_API}/awtis?${query}`)
return response.data
const {data} = await readAxiosInstance.get(`${OKI_API}/artistes?${query}`)
return data
}
export async function jwennTeks() {
const query = '_sort=tit:ASC&_where[published_at_null]=false'
const query = qs.stringify({
populate: ['artistes', 'couverture', 'user', 'userAdmin', 'commentaires', 'traductions', 'streamVideo', 'streamAudio'],
sort: ['titre:asc'],
pagination: {
pageSize: 100
}
}, {
encodeValuesOnly: true
})
const response = await axios.get(`${OKI_API}/teks?${query}`)
return response.data
const {data} = await readAxiosInstance.get(`${OKI_API}/paroles?${query}`)
return data.data
}
export async function jwennAwtisSlug() {
const query = '_sort=published_at:DESC&_where[published_at_null]=false'
const query = qs.stringify({
sort: ['publishedAt:desc']
})
const response = await axios.get(`${OKI_API}/awtis?${query}`)
const response = await readAxiosInstance.get(`${OKI_API}/artistes?${query}`)
const {data} = response
return data.map(({slug}) => slug)
return data.data.map(({attributes}) => attributes.slug)
}
export async function jwennTeksSlug() {
const query = qs.stringify({
sort: ['publishedAt:desc']
})
const response = await readAxiosInstance.get(`${OKI_API}/paroles?${query}`)
const {data} = response
return data.data.map(({attributes}) => attributes.slug)
}
export async function jwennDenyeTeks() {
const query = '_sort=published_at:DESC&_limit=6&_where[published_at_null]=false'
const query = qs.stringify({
populate: ['artistes', 'couverture'],
sort: ['publishedAt:desc'],
pagination: {
limit: 6
}
}, {
encodeValuesOnly: true
})
const response = await axios.get(`${OKI_API}/teks?${query}`)
return response.data
const {data} = await readAxiosInstance.get(`${OKI_API}/paroles?${query}`)
return data.data
}
export async function jwennAnTeks(teksId) {
const response = await axios.get(`${OKI_API}/teks/${teksId}`)
return response.data
}
export async function jwennAnTeks(teksId, token) {
const headers = {
'content-type': 'application/json',
Authorization: `Bearer ${token}`
}
export async function jwennTeksEpiUserId(userId) {
const query = `_sort=tit:ASC&_where[user.id]=${userId}&_publicationState=preview&published_at_null=true`
const response = await axios.get(`${OKI_API}/teks?${query}`)
return response.data
}
export async function jwennSlugs() {
const response = await axios.get(`${OKI_API}/slugs`)
const response = await axios.get(`${OKI_API}/paroles/${teksId}`, {headers})
return response.data
}
export async function jwennKomanteEpiTeksId(teksId) {
const query = `_sort=published_at:DESC&_where[teks]=${teksId}&_where[published_at_null]=false`
const response = await axios.get(`${OKI_API}/komante?${query}`)
return response.data
const query = qs.stringify({
sort: ['publishedAt:desc'],
populate: ['paroles', 'user'],
filters: {
parole: {
id: {
$eq: teksId
}
}
}
}, {
encodeValuesOnly: true
})
const {data} = await readAxiosInstance.get(`${OKI_API}/commentaires?${query}`)
return data.data
}
export async function jwennUserEpiToken(userToken) {
@@ -86,13 +152,43 @@ export async function jwennUserEpiToken(userToken) {
}
export async function jwennUserEpiUsername(username) {
const query = `_where[username]=${username}&_where[confirmed]=true`
const response = await axios.get(`${OKI_API}/users?${query}`)
const query = qs.stringify({
filters: {
username: {
$eq: username
}
}
}, {
encodeValuesOnly: true
})
const response = await readAxiosInstance.get(`${OKI_API}/users?${query}`)
return response.data[0]
}
export async function jwennUserEpiEmail(email) {
const query = `_where[email]=${email}&_where[confirmed]=false&_where[blocked]=false`
const response = await axios.get(`${OKI_API}/users?${query}`)
const query = qs.stringify({
filters: {
email: {
$eq: email
},
confirmed: {
$eq: false
},
blocked: {
$eq: false
}
}
}, {
encodeValuesOnly: true
})
const response = await readAxiosInstance.get(`${OKI_API}/users?${query}`)
return response.data[0]
}
export async function passwordRequest(lyen, email) {
await axios.post(`${OKI_API}/auth/${lyen}`, {
email
})
}
+1 -1
View File
@@ -22,7 +22,7 @@ const options = {
return null
} catch (error) {
const errorMessage = error.response.data.message[0].messages[0].message
const errorMessage = error.response.data.error.message
throw new Error(errorMessage)
}
}
+46 -21
View File
@@ -7,34 +7,38 @@ import HeadLayout from '../../components/head-layout'
import {jwennAwtisEpiSlug} from '../../lib/oki-api'
import Custom404 from '../404'
import Custom500 from '../500'
export default function SlugAwtis({error, anAwtis}) {
if (error) {
return <Custom404 statusCode={error} />
export default function SlugAwtis({errorCode, error404, errorMessage, anAwtis}) {
if (error404) {
return <Custom404 statusCode={error404} />
}
const {foto} = anAwtis
if (errorCode) {
console.log('⚠️ error', errorMessage)
return <Custom500 statusCode={errorCode} />
}
const {photo} = anAwtis
const formatKouveti = () => {
if (foto.length === 0) {
if (!photo) {
return null
}
const [anFoto] = foto
if (anFoto && anFoto.formats && anFoto.formats.large) {
return anFoto.formats.large
if (photo && photo.formats && photo.formats.large) {
return photo.formats.large
}
if (anFoto && anFoto.formats && anFoto.formats.medium) {
return anFoto.formats.medium
if (photo && photo.formats && photo.formats.medium) {
return photo.formats.medium
}
if (anFoto && anFoto.formats && anFoto.formats.small) {
return anFoto.formats.small
if (photo && photo.formats && photo.formats.small) {
return photo.formats.small
}
return anFoto
return photo
}
return (
@@ -43,10 +47,10 @@ export default function SlugAwtis({error, anAwtis}) {
imageWidth={formatKouveti() ? formatKouveti().width : null}
imageHeight={formatKouveti() ? formatKouveti().height : null}
imageMime={formatKouveti() ? formatKouveti().mime : null}
title={`${anAwtis.alias} - Paroles et Traductions`} tab={2} slug={`awtis/${anAwtis.slug}`}
title={`${anAwtis.attributes.alias} - Paroles et Traductions`} tab={2} slug={`awtis/${anAwtis.attributes.slug}`}
>
<Box sx={{display: 'flex', flexDirection: 'column', minHeight: '100vh'}}>
<AwtisDetay anAwtis={anAwtis} />
<AwtisDetay anAwtis={anAwtis.attributes} />
</Box>
<Footer />
</HeadLayout>
@@ -55,21 +59,42 @@ export default function SlugAwtis({error, anAwtis}) {
export async function getServerSideProps({query}) {
const {slug} = query
const anAwtis = await jwennAwtisEpiSlug(slug)
let anAwtis
let error404
let errorCode
let errorMessage
try {
anAwtis = await jwennAwtisEpiSlug(slug)
} catch (error) {
errorMessage = error.message
errorCode = true
}
if (!anAwtis) {
error404 = true
}
return {
props: {
error: Boolean(!anAwtis),
anAwtis: anAwtis ? anAwtis : null
error404: error404 || null,
errorCode: errorCode || null,
errorMessage: errorMessage || null,
anAwtis: anAwtis || null
}
}
}
SlugAwtis.defaultProps = {
anAwtis: null
anAwtis: null,
error404: null,
errorCode: null,
errorMessage: null,
}
SlugAwtis.propTypes = {
error: PropTypes.bool.isRequired,
error404: PropTypes.bool,
errorCode: PropTypes.bool,
errorMessage: PropTypes.string,
anAwtis: PropTypes.object
}
+58 -23
View File
@@ -1,51 +1,86 @@
import PropTypes from 'prop-types'
import {Container, Grid} from '@mui/material'
import {Box, Container, Grid} from '@mui/material'
import {jwennAwtisKantite, jwennAwtisPajinasyon} from '../../lib/oki-api'
import {jwennAwtisPajinasyon} from '../../lib/oki-api'
import AwtisKat from '../../components/awtis/awtis-kat'
import Pajinasyon from '../../components/awtis/pajinasyon'
import HeadLayout from '../../components/head-layout'
import Footer from '../../components/footer'
const AWTIS_POU_CHAK_PAJ = process.env.NEXT_PUBLIC_AWTIS_POU_CHAK_PAJ || 6
import Custom404 from '../404'
import Custom500 from '../500'
export default function Awtis({errorCode, error404, errorMessage, pajTotal, awtisPouChakPaj, paj}) {
if (error404) {
return <Custom404 statusCode={error404} />
}
if (errorCode) {
console.log('⚠️ error', errorMessage)
return <Custom500 statusCode={errorCode} />
}
export default function Awtis({pajTotal, awtisPouChakPaj, paj}) {
return (
<HeadLayout title='Awtis - Liste des artistes' tab={2} slug='awtis'>
<Pajinasyon pajTotal={pajTotal} paj={paj} />
<Container>
<Grid container spacing={{xs: 2, md: 3}}>
{awtisPouChakPaj.map(anAwtis => <AwtisKat key={anAwtis.id} anAwtis={anAwtis} />)}
</Grid>
</Container>
<Box sx={{display: 'flex', flexDirection: 'column', minHeight: '100vh'}}>
<Pajinasyon pajTotal={pajTotal} paj={paj} />
<Container sx={{marginBottom: 5, flexGrow: 100}}>
<Grid container spacing={{xs: 2, md: 3}}>
{awtisPouChakPaj.map(artiste => <AwtisKat key={artiste.id} artiste={artiste.attributes} />)}
</Grid>
</Container>
<Footer />
</Box>
</HeadLayout>
)
}
Awtis.propTypes = {
pajTotal: PropTypes.number.isRequired,
awtisPouChakPaj: PropTypes.array.isRequired,
paj: PropTypes.number.isRequired
}
export async function getServerSideProps({query}) {
const {paj} = query
let error404
let errorCode
let errorMessage
let awtisPouChakPaj
const pajParsed = Array.isArray(paj) ? Number.parseInt(paj[1], 10) : Number.parseInt(paj, 10)
const awtisPouChakPaj = await jwennAwtisPajinasyon(pajParsed)
const awtisCountRequest = await jwennAwtisKantite()
const awtisCount = Number.parseInt(awtisCountRequest, 10)
const pajTotal = Math.ceil(awtisCount / AWTIS_POU_CHAK_PAJ)
if (pajParsed > pajTotal) {
throw new Error('Pa twouvé paj-la')
try {
awtisPouChakPaj = await jwennAwtisPajinasyon(pajParsed)
} catch (error) {
errorMessage = error.message
errorCode = true
}
const pajTotal = Math.ceil(awtisPouChakPaj.meta.pagination.total / awtisPouChakPaj.meta.pagination.limit)
if (pajParsed > pajTotal || pajParsed < 1) {
error404 = true
}
return {
props: {
error404: error404 || null,
errorCode: errorCode || null,
errorMessage: errorMessage || null,
pajTotal,
awtisPouChakPaj,
awtisPouChakPaj: awtisPouChakPaj.data,
paj: pajParsed
}
}
}
Awtis.defaultProps = {
error404: null,
errorCode: null,
errorMessage: null,
}
Awtis.propTypes = {
error404: PropTypes.bool,
errorCode: PropTypes.bool,
errorMessage: PropTypes.string,
pajTotal: PropTypes.number.isRequired,
awtisPouChakPaj: PropTypes.array.isRequired,
paj: PropTypes.number.isRequired
}
+33 -32
View File
@@ -1,6 +1,6 @@
import PropTypes from 'prop-types'
import {jwennTeksEpiSlug, jwennTeks, jwennKomanteEpiTeksId} from '../../lib/oki-api'
import {jwennTeks, jwennKomanteEpiTeksId} from '../../lib/oki-api'
import TeksDrawer from '../../components/teks/teks-drawer'
import HeadLayout from '../../components/head-layout'
@@ -8,41 +8,41 @@ import HeadLayout from '../../components/head-layout'
import Custom500 from '../500'
import Custom404 from '../404'
const jwennAwtis = awtis => {
const alias = awtis.map(({alias}) => alias)
const jwennAwtis = artiste => {
const alias = artiste.data.map(({attributes}) => attributes.alias)
return new Intl.ListFormat('fr').format(alias)
}
export default function SlugTeks({hasError, errorMessage, teks, anTeks, slug, komante}) {
export default function SlugTeks({hasError, errorMessage, paroles, parole, slug, commentaires}) {
if (hasError) {
console.log('⚠️ error :', errorMessage)
return <Custom500 />
}
if (!anTeks) {
if (!parole) {
return <Custom404 />
}
const awtis = anTeks.awtis.length === 1 ? anTeks.awtis[0].alias : jwennAwtis(anTeks.awtis)
const {kouveti} = anTeks
const artistes = parole.attributes.artistes.length === 1 ? parole.attributes.artistes[0].data.attributes.alias : jwennAwtis(parole.attributes.artistes)
const {couverture} = parole.attributes
const formatKouveti = () => {
if (!kouveti) {
if (!couverture) {
return null
}
if (kouveti && kouveti.formats && kouveti.formats.large) {
return kouveti.formats.large
if (couverture && couverture.formats && couverture.formats.large) {
return couverture.formats.large
}
if (kouveti && kouveti.formats && kouveti.formats.medium) {
return kouveti.formats.medium
if (couverture && couverture.formats && couverture.formats.medium) {
return couverture.formats.medium
}
if (kouveti && kouveti.formats && kouveti.formats.small) {
return kouveti.formats.small
if (couverture && couverture.formats && couverture.formats.small) {
return couverture.formats.small
}
return kouveti
return couverture
}
return (
@@ -51,25 +51,26 @@ export default function SlugTeks({hasError, errorMessage, teks, anTeks, slug, ko
imageWidth={formatKouveti() ? formatKouveti().width : null}
imageHeight={formatKouveti() ? formatKouveti().height : null}
imageMime={formatKouveti() ? formatKouveti().mime : null}
title={`${awtis} - ${anTeks.tit} | Paroles et Traductions`} tab={1} slug={`paroles/${slug}`}
title={`${artistes} - ${parole.attributes.titre} | Paroles et Traductions`} tab={1} slug={`paroles/${slug}`}
>
<TeksDrawer teks={teks} anTeks={anTeks} komante={komante} />
<TeksDrawer paroles={paroles} parole={parole.attributes} paroleId={parole.id} commentaires={commentaires} />
</HeadLayout>
)
}
export async function getServerSideProps({query}) {
const {slug} = query
let teks
let anTeks
let paroles
let parole
let hasError
let errorMessage
let komante
let commentaires
try {
teks = await jwennTeks()
anTeks = await jwennTeksEpiSlug(slug)
komante = await jwennKomanteEpiTeksId(anTeks?.id)
paroles = await jwennTeks()
parole = paroles.find(({attributes}) => attributes.slug === slug)
commentaires = paroles.map(({attributes}) => attributes.commentaires)
commentaires = await jwennKomanteEpiTeksId(parole?.id)
} catch (error) {
errorMessage = error
hasError = true
@@ -79,10 +80,10 @@ export async function getServerSideProps({query}) {
props: {
hasError: hasError || null,
errorMessage: errorMessage ? errorMessage.message : null,
teks: teks || null,
anTeks: anTeks || null,
paroles: paroles || null,
parole: parole || null,
slug,
komante: komante || null
commentaires: commentaires || null
}
}
}
@@ -90,16 +91,16 @@ export async function getServerSideProps({query}) {
SlugTeks.defaultProps = {
hasError: null,
errorMessage: null,
teks: null,
anTeks: null,
komante: null
paroles: null,
parole: null,
commentaires: null
}
SlugTeks.propTypes = {
hasError: PropTypes.bool,
errorMessage: PropTypes.string,
teks: PropTypes.array,
anTeks: PropTypes.object,
paroles: PropTypes.array,
parole: PropTypes.object,
slug: PropTypes.string.isRequired,
komante: PropTypes.array
commentaires: PropTypes.array
}
+7 -7
View File
@@ -7,7 +7,7 @@ import HeadLayout from '../../components/head-layout'
import Custom500 from '../500'
export default function Teks({errorCode, errorMessage, teks, denyeTeks}) {
export default function Teks({errorCode, errorMessage, paroles, denyeTeks}) {
if (errorCode) {
console.log('⚠️ error', errorMessage)
return <Custom500 />
@@ -15,19 +15,19 @@ export default function Teks({errorCode, errorMessage, teks, denyeTeks}) {
return (
<HeadLayout title='Paroles et Traductions' tab={1} slug='paroles'>
<TeksDrawer teks={teks} denyeTeks={denyeTeks} />
<TeksDrawer paroles={paroles} denyeTeks={denyeTeks} />
</HeadLayout>
)
}
export async function getServerSideProps() {
let teks
let paroles
let denyeTeks
let hasError
let errorMessage
try {
teks = await jwennTeks()
paroles = await jwennTeks()
denyeTeks = await jwennDenyeTeks()
} catch (error) {
errorMessage = error.message
@@ -38,7 +38,7 @@ export async function getServerSideProps() {
props: {
errorCode: hasError || null,
errorMessage: errorMessage || null,
teks: teks || null,
paroles: paroles || null,
denyeTeks: denyeTeks || null
}
}
@@ -47,13 +47,13 @@ export async function getServerSideProps() {
Teks.defaultProps = {
errorCode: null,
errorMessage: null,
teks: null,
paroles: null,
denyeTeks: null
}
Teks.propTypes = {
errorCode: PropTypes.bool,
errorMessage: PropTypes.string,
teks: PropTypes.array,
paroles: PropTypes.array,
denyeTeks: PropTypes.array
}
+7 -9
View File
@@ -1,8 +1,8 @@
import {jwennAwtisSlug, jwennSlugs} from '../lib/oki-api'
import {jwennAwtisSlug, jwennTeksSlug} from '../lib/oki-api'
const url = process.env.NEXT_PUBLIC_SITE_URL || 'http://localhost'
const createSitemap = (teks, awtisSlug) => (
const createSitemap = (teksSlug, awtisSlug) => (
`<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
@@ -25,10 +25,10 @@ const createSitemap = (teks, awtisSlug) => (
<loc>${url}/soumet</loc>
<priority>0.5</priority>
</url>
${teks
.map(m => `
${teksSlug
.map(slug => `
<url>
<loc>${`${url}/paroles/${m}`}</loc>
<loc>${`${url}/paroles/${slug}`}</loc>
</url>
`)
.join('')}
@@ -48,13 +48,11 @@ export default function Sitemap() {
}
export async function getServerSideProps({res}) {
const request = await jwennSlugs()
const teksSlug = await jwennTeksSlug()
const awtisSlug = await jwennAwtisSlug()
console.log('awtisSlug', awtisSlug)
res.setHeader('Content-Type', 'text/xml')
res.write(createSitemap(request, awtisSlug))
res.write(createSitemap(teksSlug, awtisSlug))
res.end()
return {