refactor: improve layout and styling of Playlist component for better readability

This commit is contained in:
JSC
2025-08-09 21:13:50 +02:00
parent 5ca8c8bf15
commit f65ed660ef

View File

@@ -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 */}
<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'
)}>
{sound.thumbnail ? (
<img
src={filesService.getThumbnailUrl(sound.id)}
alt={sound.name}
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'
)}
/>
{/* Thumbnail - 1 column */}
<div className="col-span-1">
<div className={cn(
'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=""
className="w-full h-full object-cover"
/>
) : (
<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>