refactor: improve layout and styling of Playlist component for better readability
This commit is contained in:
@@ -22,9 +22,10 @@ export function Playlist({
|
||||
const maxHeight = variant === 'maximized' ? 'h-[calc(100vh-200px)]' : 'h-60'
|
||||
|
||||
return (
|
||||
<div className="space-y-2">
|
||||
<div className="flex items-center justify-between">
|
||||
<h4 className="font-medium text-sm">
|
||||
<div className="w-full">
|
||||
{/* Header */}
|
||||
<div className="flex items-center justify-between mb-2">
|
||||
<h4 className="font-medium text-sm truncate">
|
||||
{playlist.name}
|
||||
</h4>
|
||||
<Badge variant="secondary" className="text-xs">
|
||||
@@ -32,98 +33,69 @@ export function Playlist({
|
||||
</Badge>
|
||||
</div>
|
||||
|
||||
<ScrollArea className={cn('w-full', maxHeight)}>
|
||||
<div className="space-y-1">
|
||||
{/* Track List */}
|
||||
<ScrollArea className={maxHeight}>
|
||||
<div className="w-full">
|
||||
{playlist.sounds.map((sound, index) => (
|
||||
<div
|
||||
key={sound.id}
|
||||
className={cn(
|
||||
'flex items-center gap-3 p-2 rounded-lg cursor-pointer transition-colors',
|
||||
'hover:bg-muted/50',
|
||||
currentIndex === index && 'bg-primary/10 border border-primary/20'
|
||||
'grid grid-cols-10 gap-2 items-center py-1.5 px-2 rounded hover:bg-muted/50 cursor-pointer text-xs',
|
||||
currentIndex === index && 'bg-primary/10 text-primary'
|
||||
)}
|
||||
onClick={() => onTrackSelect(index)}
|
||||
>
|
||||
{/* Track Number or Play Icon */}
|
||||
<div className="w-6 h-6 flex items-center justify-center flex-shrink-0">
|
||||
{/* Track number/play icon - 1 column */}
|
||||
<div className="col-span-1 flex justify-center">
|
||||
{currentIndex === index ? (
|
||||
<Play className="h-3 w-3 text-primary" />
|
||||
<Play className="h-3 w-3" />
|
||||
) : (
|
||||
<span className="text-xs text-muted-foreground">
|
||||
{index + 1}
|
||||
</span>
|
||||
<span className="text-muted-foreground">{index + 1}</span>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Thumbnail */}
|
||||
{/* Thumbnail - 1 column */}
|
||||
<div className="col-span-1">
|
||||
<div className={cn(
|
||||
'flex-shrink-0 bg-muted rounded flex items-center justify-center overflow-hidden',
|
||||
variant === 'maximized' ? 'w-10 h-10' : 'w-8 h-8'
|
||||
'bg-muted rounded flex items-center justify-center overflow-hidden',
|
||||
variant === 'maximized' ? 'w-6 h-6' : 'w-5 h-5'
|
||||
)}>
|
||||
{sound.thumbnail ? (
|
||||
<img
|
||||
src={filesService.getThumbnailUrl(sound.id)}
|
||||
alt={sound.name}
|
||||
alt=""
|
||||
className="w-full h-full object-cover"
|
||||
onError={(e) => {
|
||||
// Hide image and show music icon if thumbnail fails to load
|
||||
const target = e.target as HTMLImageElement
|
||||
target.style.display = 'none'
|
||||
const musicIcon = target.nextElementSibling as HTMLElement
|
||||
if (musicIcon) musicIcon.style.display = 'block'
|
||||
}}
|
||||
/>
|
||||
) : null}
|
||||
<Music
|
||||
className={cn(
|
||||
'text-muted-foreground',
|
||||
variant === 'maximized' ? 'h-5 w-5' : 'h-4 w-4',
|
||||
sound.thumbnail ? 'hidden' : 'block'
|
||||
) : (
|
||||
<Music className="h-3 w-3 text-muted-foreground" />
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Track Info */}
|
||||
<div className="flex-1 min-w-0">
|
||||
<p className={cn(
|
||||
'font-medium truncate',
|
||||
{/* Track name - 6 columns (takes most space) */}
|
||||
<div className="col-span-6">
|
||||
<span className={cn(
|
||||
'font-medium truncate block',
|
||||
variant === 'maximized' ? 'text-sm' : 'text-xs',
|
||||
currentIndex === index && 'text-primary'
|
||||
currentIndex === index ? 'text-primary' : 'text-foreground'
|
||||
)}>
|
||||
{sound.name}
|
||||
</p>
|
||||
{/* <p className={cn(
|
||||
'text-muted-foreground truncate',
|
||||
variant === 'maximized' ? 'text-xs' : 'text-[10px]'
|
||||
)}>
|
||||
{sound.filename}
|
||||
</p> */}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{/* Duration and Type */}
|
||||
{/* <div className="flex flex-col items-end gap-1 flex-shrink-0">
|
||||
<span className={cn(
|
||||
'text-muted-foreground',
|
||||
variant === 'maximized' ? 'text-xs' : 'text-[10px]'
|
||||
)}>
|
||||
{/* Duration - 2 columns */}
|
||||
<div className="col-span-2 text-right">
|
||||
<span className="text-muted-foreground text-[10px] whitespace-nowrap">
|
||||
{formatDuration(sound.duration)}
|
||||
</span>
|
||||
<Badge
|
||||
variant="outline"
|
||||
className={cn(
|
||||
variant === 'maximized' ? 'text-[10px] px-1' : 'text-[8px] px-1 py-0'
|
||||
)}
|
||||
>
|
||||
{sound.type}
|
||||
</Badge>
|
||||
</div> */}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</ScrollArea>
|
||||
|
||||
{/* Playlist Stats */}
|
||||
<div className="pt-2 border-t">
|
||||
{/* Footer Stats */}
|
||||
<div className="pt-2 mt-2 border-t">
|
||||
<div className="flex justify-between text-xs text-muted-foreground">
|
||||
<span>{playlist.sounds.length} tracks</span>
|
||||
<span>{formatDuration(playlist.duration)}</span>
|
||||
|
||||
Reference in New Issue
Block a user