feat: display titrePhare on OKI artist
This commit is contained in:
@@ -9,6 +9,7 @@ import AccordionSummary from '@mui/material/AccordionSummary'
|
|||||||
import Box from '@mui/material/Box'
|
import Box from '@mui/material/Box'
|
||||||
import Button from '@mui/material/Button'
|
import Button from '@mui/material/Button'
|
||||||
import CardActionArea from '@mui/material/CardActionArea'
|
import CardActionArea from '@mui/material/CardActionArea'
|
||||||
|
import CardMedia from '@mui/material/CardMedia'
|
||||||
import Chip from '@mui/material/Chip'
|
import Chip from '@mui/material/Chip'
|
||||||
import Container from '@mui/material/Container'
|
import Container from '@mui/material/Container'
|
||||||
import Grid from '@mui/material/Grid'
|
import Grid from '@mui/material/Grid'
|
||||||
@@ -20,44 +21,83 @@ import Typography from '@mui/material/Typography'
|
|||||||
import {green} from '@mui/material/colors'
|
import {green} from '@mui/material/colors'
|
||||||
import ExpandMoreIcon from '@mui/icons-material/ExpandMore'
|
import ExpandMoreIcon from '@mui/icons-material/ExpandMore'
|
||||||
import KeyboardBackspaceIcon from '@mui/icons-material/KeyboardBackspace'
|
import KeyboardBackspaceIcon from '@mui/icons-material/KeyboardBackspace'
|
||||||
|
import OpenInNewIcon from '@mui/icons-material/OpenInNew'
|
||||||
import VerifiedIcon from '@mui/icons-material/Verified'
|
import VerifiedIcon from '@mui/icons-material/Verified'
|
||||||
|
import {Spotify, Applemusic, Deezer, Tidal, Youtubemusic, Amazon, Soundcloud} from '@icons-pack/react-simple-icons'
|
||||||
|
|
||||||
import {formatKuveti} from '../../lib/kuveti'
|
import {formatKuveti} from '../../lib/kuveti'
|
||||||
import AwtisBiyografi from './awtis-biyografi'
|
import AwtisBiyografi from './awtis-biyografi'
|
||||||
import MizikLyen from './mizik-lyen'
|
import MizikLyen from './mizik-lyen'
|
||||||
|
|
||||||
|
const PLATFORM_CONFIG = {
|
||||||
|
Spotify: {label: 'Spotify', bg: '#1DB954', color: '#fff', Icon: Spotify},
|
||||||
|
Applemusic: {label: 'Apple Music', bg: '#FC3C44', color: '#fff', Icon: Applemusic},
|
||||||
|
Deezer: {label: 'Deezer', bg: '#EF5466', color: '#fff', Icon: Deezer},
|
||||||
|
Tidal: {label: 'Tidal', bg: '#000000', color: '#fff', Icon: Tidal},
|
||||||
|
Qobuz: {label: 'Qobuz', bg: '#00245B', color: '#fff', Icon: null},
|
||||||
|
Youtubemusic: {label: 'YouTube Music', bg: '#FF0000', color: '#fff', Icon: Youtubemusic},
|
||||||
|
Amazon: {label: 'Amazon Music', bg: '#00A8E1', color: '#fff', Icon: Amazon},
|
||||||
|
Soundcloud: {label: 'SoundCloud', bg: '#FF5500', color: '#fff', Icon: Soundcloud},
|
||||||
|
}
|
||||||
|
|
||||||
const IMAGE_URL = process.env.NEXT_PUBLIC_API_URL_ROOT || '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 noImageUrl = 'https://place-hold.it/140x140?text=Indisponible'
|
||||||
|
|
||||||
const sortTeks = paroles => paroles.sort((a, b) => a.titre.localeCompare(b.titre, 'fr', {sensitivity: 'base'}))
|
const sortTeks = paroles => paroles.sort((a, b) => a.titre.localeCompare(b.titre, 'fr', {sensitivity: 'base'}))
|
||||||
|
|
||||||
|
function StreamButton({lyen}) {
|
||||||
|
const config = PLATFORM_CONFIG[lyen.plateforme] || {label: lyen.plateforme, bg: '#555', color: '#fff', Icon: null}
|
||||||
|
const PlatformIcon = config.Icon
|
||||||
|
return (
|
||||||
|
<Button
|
||||||
|
href={lyen.url}
|
||||||
|
target='_blank'
|
||||||
|
rel='noopener noreferrer'
|
||||||
|
size='small'
|
||||||
|
startIcon={PlatformIcon ? <PlatformIcon size={16} color={config.color} /> : null}
|
||||||
|
endIcon={<OpenInNewIcon sx={{fontSize: 11}} />}
|
||||||
|
sx={{
|
||||||
|
bgcolor: config.bg,
|
||||||
|
color: config.color,
|
||||||
|
fontWeight: 700,
|
||||||
|
fontSize: '0.72rem',
|
||||||
|
textTransform: 'none',
|
||||||
|
'&:hover': {bgcolor: config.bg, opacity: 0.85},
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{config.label}
|
||||||
|
</Button>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
export default function AwtisDetay({anAwtis}) {
|
export default function AwtisDetay({anAwtis}) {
|
||||||
const [esByografiOuve, meteEsByografiOuve] = useState(false)
|
const [esByografiOuve, meteEsByografiOuve] = useState(false)
|
||||||
const {alias, biographie, paroles, photo, isOKIAwtis} = anAwtis
|
const {alias, biographie, paroles, photo, isOKIAwtis, titrePhare} = anAwtis
|
||||||
const sortedTeks = sortTeks(paroles)
|
const sortedTeks = sortTeks(paroles)
|
||||||
const gwanBiyo = biographie && biographie.length > 100
|
const gwanBiyo = biographie && biographie.length > 100
|
||||||
|
|
||||||
const biyo = gwanBiyo ? `${biographie.slice(0, 100)}...` : biographie
|
const biyo = gwanBiyo ? `${biographie.slice(0, 100)}...` : biographie
|
||||||
|
|
||||||
const handleClick = () => {
|
const hasStreaming = isOKIAwtis && titrePhare?.streamAudio?.length > 0
|
||||||
meteEsByografiOuve(true)
|
const coverUrl = titrePhare?.couverture
|
||||||
}
|
? `${IMAGE_URL}${titrePhare.couverture.formats?.small?.url || titrePhare.couverture.formats?.thumbnail?.url || titrePhare.couverture.url}`
|
||||||
|
: null
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container>
|
<Container>
|
||||||
<Box sx={{marginTop: 8, marginBottom: 2}}>
|
<Box sx={{mt: 8, mb: 2}}>
|
||||||
<Typography sx={{textAlign: 'center'}} variant='h6' component='h1'>
|
<Typography sx={{textAlign: 'center'}} variant='h6' component='h1'>
|
||||||
{alias}
|
{alias}
|
||||||
</Typography>
|
</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
<Box sx={{justifyContent: 'center', display: 'flex', marginBottom: 2}}>
|
|
||||||
|
<Box sx={{display: 'flex', justifyContent: 'center', mb: 2}}>
|
||||||
<Avatar
|
<Avatar
|
||||||
src={photo?.url ? `${IMAGE_URL}${photo?.formats?.small?.url || photo?.formats?.thumbnail?.url || photo?.url}` : noImageUrl}
|
src={photo?.url ? `${IMAGE_URL}${photo?.formats?.small?.url || photo?.formats?.thumbnail?.url || photo?.url}` : noImageUrl}
|
||||||
alt={`Photo ${alias}`}
|
alt={`Photo ${alias}`}
|
||||||
sx={{width: 200, height: 200, border: `2px solid ${green[500]}`}}
|
sx={{width: 200, height: 200, border: `2px solid ${green[500]}`}}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
{isOKIAwtis && (
|
{isOKIAwtis && (
|
||||||
<Box sx={{display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 0.75, mb: 2}}>
|
<Box sx={{display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 0.75, mb: 2}}>
|
||||||
<Chip
|
<Chip
|
||||||
@@ -71,11 +111,12 @@ export default function AwtisDetay({anAwtis}) {
|
|||||||
</Typography>
|
</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
)}
|
)}
|
||||||
<Grid sx={{alignItems:'center'}} container direction='column' spacing={3}>
|
|
||||||
|
<Grid sx={{alignItems: 'center'}} container direction='column' spacing={3}>
|
||||||
{biyo && (
|
{biyo && (
|
||||||
<Grid size={{xs: 12, md: 6}}>
|
<Grid size={{xs: 12, md: 6}}>
|
||||||
<Card sx={{minWidth: 300}}>
|
<Card sx={{minWidth: 300}}>
|
||||||
<CardActionArea onClick={handleClick}>
|
<CardActionArea onClick={() => meteEsByografiOuve(true)}>
|
||||||
<CardContent>
|
<CardContent>
|
||||||
<Typography gutterBottom variant='body1' component='h2'>
|
<Typography gutterBottom variant='body1' component='h2'>
|
||||||
<strong>Biographie</strong>
|
<strong>Biographie</strong>
|
||||||
@@ -88,6 +129,39 @@ export default function AwtisDetay({anAwtis}) {
|
|||||||
</Card>
|
</Card>
|
||||||
</Grid>
|
</Grid>
|
||||||
)}
|
)}
|
||||||
|
{hasStreaming && (
|
||||||
|
<Grid size={{xs: 12, md: 6}}>
|
||||||
|
<Card sx={{overflow: 'hidden'}}>
|
||||||
|
<Grid container>
|
||||||
|
{coverUrl && (
|
||||||
|
<Grid size={{xs: 12, sm: 4}}>
|
||||||
|
<CardMedia
|
||||||
|
component='img'
|
||||||
|
image={coverUrl}
|
||||||
|
alt={titrePhare.titre}
|
||||||
|
sx={{height: '100%', minHeight: 140, objectFit: 'cover'}}
|
||||||
|
/>
|
||||||
|
</Grid>
|
||||||
|
)}
|
||||||
|
<Grid size={{xs: 12, sm: coverUrl ? 8 : 12}}>
|
||||||
|
<CardContent>
|
||||||
|
<Typography variant='subtitle1' sx={{fontWeight: 700}} gutterBottom>
|
||||||
|
{titrePhare.titre}
|
||||||
|
</Typography>
|
||||||
|
<Typography variant='caption' sx={{color: 'text.secondary', display: 'block', mb: 1.5}}>
|
||||||
|
Écouter sur
|
||||||
|
</Typography>
|
||||||
|
<Box sx={{display: 'flex', flexWrap: 'wrap', gap: 1}}>
|
||||||
|
{titrePhare.streamAudio.map((lyen, i) => (
|
||||||
|
<StreamButton key={i} lyen={lyen} />
|
||||||
|
))}
|
||||||
|
</Box>
|
||||||
|
</CardContent>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</Card>
|
||||||
|
</Grid>
|
||||||
|
)}
|
||||||
<Grid size={{xs: 12, md: 6}}>
|
<Grid size={{xs: 12, md: 6}}>
|
||||||
<Box marginbottom={3}>
|
<Box marginbottom={3}>
|
||||||
{paroles.length > 1 ? (
|
{paroles.length > 1 ? (
|
||||||
@@ -97,14 +171,13 @@ export default function AwtisDetay({anAwtis}) {
|
|||||||
aria-controls='panel-teks-content'
|
aria-controls='panel-teks-content'
|
||||||
id='panel-teks-header'
|
id='panel-teks-header'
|
||||||
>
|
>
|
||||||
<Typography sx={{marginRight: 2, textAlign:'center' }} variant='body1' component='h2'><strong>Liste des paroles</strong></Typography>
|
<Typography sx={{marginRight: 2, textAlign: 'center'}} variant='body1' component='h2'><strong>Liste des paroles</strong></Typography>
|
||||||
<Chip color='primary' label={paroles.length} size='small' variant='contained' />
|
<Chip color='primary' label={paroles.length} size='small' variant='contained' />
|
||||||
</AccordionSummary>
|
</AccordionSummary>
|
||||||
<AccordionDetails sx={{paddingInline: 0}}>
|
<AccordionDetails sx={{paddingInline: 0}}>
|
||||||
{sortedTeks.map(anPawol => {
|
{sortedTeks.map(anPawol => {
|
||||||
const {couverture} = anPawol
|
const {couverture} = anPawol
|
||||||
const kuvetiFormat = couverture?.formats?.thumbnail || formatKuveti(couverture)
|
const kuvetiFormat = couverture?.formats?.thumbnail || formatKuveti(couverture)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box key={anPawol.id} sx={{paddingBlock: 0.5}}>
|
<Box key={anPawol.id} sx={{paddingBlock: 0.5}}>
|
||||||
<MizikLyen anPawol={anPawol} kuveti={kuvetiFormat} />
|
<MizikLyen anPawol={anPawol} kuveti={kuvetiFormat} />
|
||||||
@@ -128,13 +201,15 @@ export default function AwtisDetay({anAwtis}) {
|
|||||||
</Box>
|
</Box>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Box sx={{textAlign: 'center', marginBlock: 3}} >
|
|
||||||
|
<Box sx={{textAlign: 'center', marginBlock: 3}}>
|
||||||
<Link passHref href='/awtis'>
|
<Link passHref href='/awtis'>
|
||||||
<Button variant='outlined' startIcon={<KeyboardBackspaceIcon />}>
|
<Button variant='outlined' startIcon={<KeyboardBackspaceIcon />}>
|
||||||
Retour aux artistes
|
Retour aux artistes
|
||||||
</Button>
|
</Button>
|
||||||
</Link>
|
</Link>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
{esByografiOuve && (
|
{esByografiOuve && (
|
||||||
<AwtisBiyografi
|
<AwtisBiyografi
|
||||||
alias={alias}
|
alias={alias}
|
||||||
|
|||||||
+1
-1
@@ -92,7 +92,7 @@ export async function jwennTeksEpiSlug(slug) {
|
|||||||
|
|
||||||
export async function jwennAwtisEpiSlug(slug) {
|
export async function jwennAwtisEpiSlug(slug) {
|
||||||
const query = qs.stringify({
|
const query = qs.stringify({
|
||||||
populate: ['paroles', 'photo', 'paroles.couverture'],
|
populate: ['paroles', 'photo', 'paroles.couverture', 'titrePhare', 'titrePhare.streamAudio', 'titrePhare.streamVideo', 'titrePhare.couverture'],
|
||||||
filters: {
|
filters: {
|
||||||
slug: {
|
slug: {
|
||||||
$eq: slug
|
$eq: slug
|
||||||
|
|||||||
Reference in New Issue
Block a user