104 lines
2.7 KiB
TypeScript
Raw Normal View History

2022-05-29 17:53:27 +08:00
import { resizeImage } from '@/web/utils/common'
import { css, cx } from '@emotion/css'
2022-06-14 23:23:34 +08:00
import { memo } from 'react'
2022-06-25 13:47:07 +08:00
import { useNavigate } from 'react-router-dom'
2022-05-29 17:53:27 +08:00
import Image from './Image'
2022-08-03 23:48:39 +08:00
import { prefetchArtist } from '@/web/api/hooks/useArtist'
2022-05-29 17:53:27 +08:00
2022-06-08 00:07:04 +08:00
const Artist = ({ artist }: { artist: Artist }) => {
2022-06-25 13:47:07 +08:00
const navigate = useNavigate()
const to = () => {
navigate(`/artist/${artist.id}`)
}
2022-06-08 00:07:04 +08:00
return (
2022-08-03 23:48:39 +08:00
<div
className='text-center'
onMouseOver={() => prefetchArtist({ id: artist.id })}
>
2022-06-08 00:07:04 +08:00
<Image
2022-06-25 13:47:07 +08:00
onClick={to}
2022-06-08 00:07:04 +08:00
src={resizeImage(artist.img1v1Url, 'md')}
className={cx(
'aspect-square rounded-full',
css`
min-width: 96px;
min-height: 96px;
`
)}
/>
2022-06-25 13:47:07 +08:00
<div
onClick={to}
className='line-clamp-1 mt-2.5 text-12 font-medium text-neutral-700 dark:text-neutral-600 lg:text-14 lg:font-bold'
>
2022-06-08 00:07:04 +08:00
{artist.name}
</div>
</div>
)
}
2022-07-12 22:42:50 +08:00
const Placeholder = ({ row }: { row: number }) => {
return (
<div className='no-scrollbar flex snap-x overflow-x-scroll lg:grid lg:w-auto lg:grid-cols-5 lg:gap-10'>
{[...new Array(row * 5).keys()].map(i => (
<div
className='flex snap-start flex-col items-center px-2.5 lg:px-0'
key={i}
>
<div
className='aspect-square w-full rounded-full bg-white dark:bg-neutral-800'
style={{
minHeight: '96px',
minWidth: '96px',
}}
/>
<div className='line-clamp-1 mt-2.5 w-1/2 rounded-full text-12 font-medium text-transparent dark:bg-neutral-800 lg:text-14 lg:font-bold'>
NAME
</div>
</div>
))}
</div>
)
}
2022-05-29 17:53:27 +08:00
const ArtistRow = ({
artists,
title,
className,
2022-06-08 00:07:04 +08:00
placeholderRow,
2022-05-29 17:53:27 +08:00
}: {
artists: Artist[] | undefined
title?: string
className?: string
2022-06-08 00:07:04 +08:00
placeholderRow?: number
2022-05-29 17:53:27 +08:00
}) => {
return (
<div className={className}>
{/* Title */}
{title && (
2022-08-03 23:48:39 +08:00
<h4 className='mx-2.5 mb-6 text-12 font-medium uppercase dark:text-neutral-300 lg:mx-0 lg:text-14 lg:font-bold'>
2022-05-29 17:53:27 +08:00
{title}
</h4>
)}
{/* Artists */}
2022-06-08 00:07:04 +08:00
{artists && (
2022-08-03 23:48:39 +08:00
<div className='no-scrollbar flex snap-x overflow-x-scroll lg:grid lg:w-auto lg:grid-cols-5 lg:gap-x-10 lg:gap-y-8'>
2022-06-08 00:07:04 +08:00
{artists.map(artist => (
2022-06-09 20:16:05 +08:00
<div className='snap-start px-2.5 lg:px-0' key={artist.id}>
2022-06-08 00:07:04 +08:00
<Artist artist={artist} key={artist.id} />
2022-05-29 17:53:27 +08:00
</div>
2022-06-08 00:07:04 +08:00
))}
</div>
)}
{/* Placeholder */}
2022-07-12 22:42:50 +08:00
{placeholderRow && !artists && <Placeholder row={placeholderRow} />}
2022-05-29 17:53:27 +08:00
</div>
)
}
2022-06-14 23:23:34 +08:00
const memoizedArtistRow = memo(ArtistRow)
memoizedArtistRow.displayName = 'ArtistRow'
export default memoizedArtistRow