Split MizikList and add GroupedVirtuoso
This commit is contained in:
@@ -21,19 +21,19 @@ 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 {formatKuveti} from '../../lib/kuveti'
|
||||||
import AwtisBiyografi from './awtis-biyografi'
|
import AwtisBiyografi from './awtis-biyografi'
|
||||||
import MizikLis from './mizik-lis'
|
import MizikLyen from './mizik-lyen'
|
||||||
|
|
||||||
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) => b.id - a.id)
|
const sortTeks = paroles => paroles.sort((a, b) => a.attributes.titre.localeCompare(b.attributes.titre, 'fr', {sensitivity: 'base'}))
|
||||||
|
|
||||||
export default function AwtisDetay({anAwtis}) {
|
export default function AwtisDetay({anAwtis}) {
|
||||||
const router = useRouter()
|
|
||||||
const [esByografiOuve, meteEsByografiOuve] = useState(false)
|
const [esByografiOuve, meteEsByografiOuve] = useState(false)
|
||||||
const {alias, biographie, paroles, photo} = anAwtis
|
const {alias, biographie, paroles, photo} = anAwtis
|
||||||
const sortedTeks = sortTeks(paroles.data)
|
const sortedTeks = sortTeks(paroles?.data)
|
||||||
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
|
||||||
@@ -42,12 +42,6 @@ export default function AwtisDetay({anAwtis}) {
|
|||||||
meteEsByografiOuve(true)
|
meteEsByografiOuve(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleBack = () => {
|
|
||||||
const href = '/awtis?paj&paj=1'
|
|
||||||
const as = '/awtis/paj/1'
|
|
||||||
router.push(href, as)
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container>
|
<Container>
|
||||||
<Box sx={{marginBlock: 2}}>
|
<Box sx={{marginBlock: 2}}>
|
||||||
@@ -64,7 +58,7 @@ export default function AwtisDetay({anAwtis}) {
|
|||||||
</Box>
|
</Box>
|
||||||
<Grid container direction='column' justifyContent='center' alignItems='center' spacing={3}>
|
<Grid container direction='column' justifyContent='center' alignItems='center' spacing={3}>
|
||||||
{biyo && (
|
{biyo && (
|
||||||
<Grid item xs={12} md={6}>
|
<Grid xs={12} md={6}>
|
||||||
<Card sx={{minWidth: 300}}>
|
<Card sx={{minWidth: 300}}>
|
||||||
<CardActionArea onClick={handleClick}>
|
<CardActionArea onClick={handleClick}>
|
||||||
<CardContent>
|
<CardContent>
|
||||||
@@ -79,7 +73,7 @@ export default function AwtisDetay({anAwtis}) {
|
|||||||
</Card>
|
</Card>
|
||||||
</Grid>
|
</Grid>
|
||||||
)}
|
)}
|
||||||
<Grid item xs={12} md={6}>
|
<Grid xs={12} md={6}>
|
||||||
<Box marginBottom={3}>
|
<Box marginBottom={3}>
|
||||||
{paroles.data.length > 1 ? (
|
{paroles.data.length > 1 ? (
|
||||||
<Accordion>
|
<Accordion>
|
||||||
@@ -91,29 +85,40 @@ export default function AwtisDetay({anAwtis}) {
|
|||||||
<Typography marginRight={2} textAlign='center' variant='body1' component='h2'><strong>Liste des paroles</strong></Typography>
|
<Typography marginRight={2} textAlign='center' variant='body1' component='h2'><strong>Liste des paroles</strong></Typography>
|
||||||
<Chip color='primary' label={paroles.data.length} size='small' variant='contained' />
|
<Chip color='primary' label={paroles.data.length} size='small' variant='contained' />
|
||||||
</AccordionSummary>
|
</AccordionSummary>
|
||||||
<AccordionDetails>
|
<AccordionDetails sx={{paddingInline: 0}}>
|
||||||
<MizikLis paroles={sortedTeks} />
|
{sortedTeks.map(anPawol => {
|
||||||
|
const {couverture} = anPawol.attributes
|
||||||
|
const kuvetiFormat = formatKuveti(couverture)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box key={anPawol.id} sx={{paddingBlock: 0.5}}>
|
||||||
|
<MizikLyen anPawol={anPawol} kuveti={kuvetiFormat} />
|
||||||
|
</Box>
|
||||||
|
)
|
||||||
|
})}
|
||||||
</AccordionDetails>
|
</AccordionDetails>
|
||||||
</Accordion>
|
</Accordion>
|
||||||
) : (
|
) : (
|
||||||
paroles.data.length === 0 ? (
|
paroles.data.length === 0 ? (
|
||||||
<Typography gutterBottom textAlign='center' variant='body1' component='h2'><strong>Aucune parole pour le moment</strong></Typography>
|
<Typography gutterBottom textAlign='center' variant='body1' component='h2'><strong>Aucune parole pour le moment</strong></Typography>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<Box>
|
||||||
<Typography gutterBottom textAlign='center' variant='body1' component='h2'><strong>Parole</strong></Typography>
|
<Typography gutterBottom textAlign='center' variant='body1' component='h2'><strong>Parole</strong></Typography>
|
||||||
<Paper>
|
<Paper sx={{height: '100%', paddingBlock: 2}}>
|
||||||
<MizikLis paroles={paroles.data} />
|
<MizikLyen anPawol={paroles.data[0]} kuveti={formatKuveti(paroles.data[0].attributes.couverture)} />
|
||||||
</Paper>
|
</Paper>
|
||||||
</>
|
</Box>
|
||||||
)
|
)
|
||||||
)}
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Box sx={{textAlign: 'center', marginBottom: 2}} >
|
<Box sx={{textAlign: 'center', marginBlock: 3}} >
|
||||||
<Button variant='outlined' startIcon={<KeyboardBackspaceIcon />} onClick={handleBack}>
|
<Link passHref href='/awtis'>
|
||||||
Retour aux artistes
|
<Button variant='outlined' startIcon={<KeyboardBackspaceIcon />}>
|
||||||
</Button>
|
Retour aux artistes
|
||||||
|
</Button>
|
||||||
|
</Link>
|
||||||
</Box>
|
</Box>
|
||||||
{esByografiOuve && (
|
{esByografiOuve && (
|
||||||
<AwtisBiyografi
|
<AwtisBiyografi
|
||||||
|
|||||||
@@ -1,95 +1,94 @@
|
|||||||
|
'use client'
|
||||||
|
|
||||||
|
import React from 'react'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
import {useRouter} from 'next/router'
|
import {useParams} from 'next/navigation'
|
||||||
|
import {GroupedVirtuoso} from 'react-virtuoso'
|
||||||
|
import List from '@mui/material/List'
|
||||||
|
import ListItem from '@mui/material/ListItem'
|
||||||
|
import ListSubheader from '@mui/material/ListSubheader'
|
||||||
|
|
||||||
import {styled} from '@mui/material/styles'
|
import {groupBy} from 'lodash'
|
||||||
import {List, ListItem, ListItemText} from '@mui/material'
|
import {formatKuveti} from '../../lib/kuveti'
|
||||||
import FiberNewOutlinedIcon from '@mui/icons-material/FiberNewOutlined'
|
import MizikLyen from './mizik-lyen'
|
||||||
import LibraryMusicIcon from '@mui/icons-material/LibraryMusic'
|
|
||||||
import ExplicitIcon from '@mui/icons-material/Explicit'
|
|
||||||
import {Peertube} from '@icons-pack/react-simple-icons'
|
|
||||||
|
|
||||||
import {esBrandNew} from '../../lib/date'
|
function grupPawol(pawol) {
|
||||||
import {getAlias} from '../../lib/utils/format'
|
const pawolTrie = pawol.sort((a, b) => a.attributes.titre.localeCompare(b.attributes.titre, 'fr', {sensitivity: 'base'}))
|
||||||
|
const grupPawol = groupBy(pawol, anPawol => anPawol.attributes.titre[0].toUpperCase())
|
||||||
|
const grupCounts = Object.values(grupPawol).map(anPawol => anPawol.length)
|
||||||
|
const grup = Object.keys(grupPawol)
|
||||||
|
grup.sort((a, b) => a[0].localeCompare(b[0], 'fr', {sensitivity: 'base'}))
|
||||||
|
|
||||||
const PREFIX = 'mizik-lis'
|
return {pawol: pawolTrie, grupCounts, grup}
|
||||||
|
|
||||||
const classes = {
|
|
||||||
root: `${PREFIX}-root`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const StyledList = styled(List)((
|
export default function MizikLis({niAwtis, paroles}) {
|
||||||
{
|
const params = useParams()
|
||||||
theme
|
const {pawol, grupCounts, grup} = grupPawol(paroles)
|
||||||
}
|
|
||||||
) => ({
|
|
||||||
[`&.${classes.root}`]: {
|
|
||||||
width: '100%',
|
|
||||||
maxWidth: 360,
|
|
||||||
backgroundColor: theme.palette.background.paper
|
|
||||||
}
|
|
||||||
}))
|
|
||||||
|
|
||||||
export default function MizikLis({meteEsMobilOuve, niAwtis, paroles, slugTeksChwazi, meteSlugTeksChwazi}) {
|
|
||||||
const router = useRouter()
|
|
||||||
|
|
||||||
const handleClick = slug => {
|
|
||||||
if (meteSlugTeksChwazi) {
|
|
||||||
meteSlugTeksChwazi(slug)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (slug !== slugTeksChwazi) {
|
|
||||||
if (niAwtis) {
|
|
||||||
router.push(`/paroles/${slug}`).then(() => window.scrollTo(0, 0))
|
|
||||||
} else {
|
|
||||||
router.push(`/paroles/${slug}#${slug}`).then(() => window.scrollTo(0, 0))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (meteEsMobilOuve) {
|
|
||||||
meteEsMobilOuve(false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StyledList component='nav' className={classes.root} aria-label='mizik'>
|
<GroupedVirtuoso
|
||||||
{paroles.map(({id, attributes}) => (
|
groupCounts={grupCounts}
|
||||||
<ListItem
|
components={MUIComponents}
|
||||||
key={id}
|
groupContent={index => <div>{grup[index]}</div>}
|
||||||
button
|
itemContent={index => {
|
||||||
id={attributes.slug}
|
const anPawol = pawol[index]
|
||||||
selected={slugTeksChwazi === attributes.slug}
|
const {couverture} = anPawol.attributes
|
||||||
onClick={() => handleClick(attributes.slug)}
|
const kuvetiFormat = formatKuveti(couverture)
|
||||||
>
|
|
||||||
<ListItemText primary={<strong>{attributes.titre}</strong>} secondary={niAwtis ? getAlias(attributes.artistes, attributes.prioriteArtistes) : null} />
|
return (
|
||||||
{attributes.gadeEmbed && !attributes.okiMizikID && (
|
<MizikLyen niAwtis={niAwtis} anPawol={anPawol} kuveti={kuvetiFormat} slug={params.slug} />
|
||||||
<Peertube style={{marginRight: 5}} />
|
)
|
||||||
)}
|
}}
|
||||||
{attributes.explicitLyrics && (
|
/>
|
||||||
<ExplicitIcon style={{marginRight: 5}} color='secondary' />
|
)
|
||||||
)}
|
}
|
||||||
{attributes.okiMizikID && (
|
|
||||||
<LibraryMusicIcon style={{fontSize: 40}} color='primary' />
|
const MUIComponents = {
|
||||||
)}
|
List: React.forwardRef(({style, children}, listRef) => (
|
||||||
{esBrandNew(attributes.publishedAt) && (
|
<List ref={listRef} style={{padding: 0, ...style, margin: 0}} component='div'>
|
||||||
<FiberNewOutlinedIcon style={{fontSize: 40}} color='primary' />
|
{children}
|
||||||
)}
|
</List>
|
||||||
</ListItem>
|
)),
|
||||||
))}
|
|
||||||
</StyledList>
|
Item: ({children, ...props}) => (
|
||||||
|
<ListItem component='div' {...props} style={{margin: 0, paddingInline: 0}}>
|
||||||
|
{children}
|
||||||
|
</ListItem>
|
||||||
|
),
|
||||||
|
|
||||||
|
Group: ({children, style, ...props}) => (
|
||||||
|
<ListSubheader
|
||||||
|
component='div'
|
||||||
|
{...props}
|
||||||
|
style={{
|
||||||
|
...style,
|
||||||
|
backgroundColor: 'transparent',
|
||||||
|
margin: 0,
|
||||||
|
paddingLeft: 5,
|
||||||
|
fontWeight: 'bold'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</ListSubheader>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
MizikLis.propTypes = {
|
MizikLis.propTypes = {
|
||||||
meteEsMobilOuve: PropTypes.func,
|
|
||||||
niAwtis: PropTypes.bool,
|
niAwtis: PropTypes.bool,
|
||||||
paroles: PropTypes.array.isRequired,
|
paroles: PropTypes.array.isRequired
|
||||||
slugTeksChwazi: PropTypes.string,
|
|
||||||
meteSlugTeksChwazi: PropTypes.func
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MizikLis.defaultProps = {
|
MUIComponents.List.propTypes = {
|
||||||
meteEsMobilOuve: null,
|
style: PropTypes.object,
|
||||||
niAwtis: false,
|
children: PropTypes.node.isRequired,
|
||||||
slugTeksChwazi: null,
|
}
|
||||||
meteSlugTeksChwazi: null
|
|
||||||
|
MUIComponents.Item.propTypes = {
|
||||||
|
children: PropTypes.node.isRequired,
|
||||||
|
}
|
||||||
|
|
||||||
|
MUIComponents.Group.propTypes = {
|
||||||
|
children: PropTypes.node.isRequired,
|
||||||
|
style: PropTypes.object,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,56 @@
|
|||||||
|
import PropTypes from 'prop-types'
|
||||||
|
import Link from 'next/link'
|
||||||
|
import ListItemButton from '@mui/material/ListItemButton'
|
||||||
|
import ListItemText from '@mui/material/ListItemText'
|
||||||
|
import Typography from '@mui/material/Typography'
|
||||||
|
import ListItemAvatar from '@mui/material/ListItemAvatar'
|
||||||
|
import Avatar from '@mui/material/Avatar'
|
||||||
|
import FiberNewOutlinedIcon from '@mui/icons-material/FiberNewOutlined'
|
||||||
|
import LibraryMusicIcon from '@mui/icons-material/LibraryMusic'
|
||||||
|
import ExplicitIcon from '@mui/icons-material/Explicit'
|
||||||
|
|
||||||
|
import {esBrandNew} from '../../lib/date'
|
||||||
|
import {getAlias} from '../../lib/utils/format'
|
||||||
|
|
||||||
|
const apiUrl = process.env.NEXT_PUBLIC_API_URL_ROOT || 'http://localhost:1337'
|
||||||
|
|
||||||
|
export default function MizikLyen({niAwtis, anPawol, kuveti, slug}) {
|
||||||
|
return (
|
||||||
|
<Link
|
||||||
|
passHref
|
||||||
|
href={`/paroles/${anPawol.attributes.slug}#${anPawol.attributes.slug}`}
|
||||||
|
style={{textDecoration: 'none', width: '100%', display: 'flex', alignItems: 'center'}}
|
||||||
|
>
|
||||||
|
<ListItemButton
|
||||||
|
sx={{padding: 0}}
|
||||||
|
id={anPawol.attributes.slug}
|
||||||
|
selected={slug === anPawol.attributes.slug}
|
||||||
|
>
|
||||||
|
<ListItemAvatar sx={{ml: 2.5}}>
|
||||||
|
<Avatar alt={anPawol.attributes.titre} src={`${apiUrl}${kuveti?.url}`} />
|
||||||
|
</ListItemAvatar>
|
||||||
|
<ListItemText
|
||||||
|
primary={<Typography sx={{fontWeight: 'bold'}} color='info.main'>{anPawol.attributes.titre}</Typography>}
|
||||||
|
secondary={niAwtis ? getAlias(anPawol.attributes.artistes, anPawol.attributes.prioriteArtistes) : null} />
|
||||||
|
|
||||||
|
{esBrandNew(anPawol.attributes.publishedAt) && (
|
||||||
|
<FiberNewOutlinedIcon style={{fontSize: 30, marginRight: 5}} color='primary' />
|
||||||
|
)}
|
||||||
|
|
||||||
|
{anPawol.attributes.explicitLyrics && (
|
||||||
|
<ExplicitIcon style={{marginRight: 5}} color='secondary' />
|
||||||
|
)}
|
||||||
|
{anPawol.attributes.okiMizikID && (
|
||||||
|
<LibraryMusicIcon style={{fontSize: 30, marginRight: 5}} color='primary' />
|
||||||
|
)}
|
||||||
|
</ListItemButton>
|
||||||
|
</Link>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
MizikLyen.propTypes = {
|
||||||
|
niAwtis: PropTypes.bool,
|
||||||
|
anPawol: PropTypes.object,
|
||||||
|
kuveti: PropTypes.object,
|
||||||
|
slug: PropTypes.string
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user