feat: add search functionality to Playlist component for filtering tracks
Some checks failed
Frontend CI / lint (push) Failing after 18s
Frontend CI / build (push) Has been skipped

This commit is contained in:
JSC
2025-10-04 14:09:33 +02:00
parent 53a39126f4
commit adcf9832f4

View File

@@ -1,10 +1,13 @@
import { useState } from 'react'
import { Badge } from '@/components/ui/badge'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { ScrollArea } from '@/components/ui/scroll-area'
import { filesService } from '@/lib/api/services/files'
import { type PlayerPlaylist } from '@/lib/api/services/player'
import { cn } from '@/lib/utils'
import { formatDuration } from '@/utils/format-duration'
import { Music, Play } from 'lucide-react'
import { Music, Play, Search, X } from 'lucide-react'
interface PlaylistProps {
playlist: PlayerPlaylist
@@ -19,6 +22,12 @@ export function Playlist({
onTrackSelect,
variant = 'normal',
}: PlaylistProps) {
const [searchQuery, setSearchQuery] = useState('')
const filteredSounds = playlist.sounds.filter((sound) =>
sound.name.toLowerCase().includes(searchQuery.toLowerCase())
)
return (
<div className="w-full">
{/* Header */}
@@ -29,26 +38,50 @@ export function Playlist({
</Badge>
</div>
{/* Search */}
<div className="relative mb-2">
<Search className="absolute left-2 top-1/2 -translate-y-1/2 h-3.5 w-3.5 text-muted-foreground" />
<Input
type="text"
placeholder="Search tracks..."
value={searchQuery}
onChange={(e) => setSearchQuery(e.target.value)}
className="h-8 pl-8 pr-8 text-xs"
/>
{searchQuery && (
<Button
variant="ghost"
size="icon"
className="absolute right-0 top-1/2 -translate-y-1/2 h-8 w-8"
onClick={() => setSearchQuery('')}
>
<X className="h-3.5 w-3.5" />
</Button>
)}
</div>
{/* Track List */}
<ScrollArea
className={variant === 'maximized' ? 'h-[calc(100vh-230px)]' : 'h-60'}
className={variant === 'maximized' ? 'h-[calc(100vh-280px)]' : 'h-60'}
>
<div className="w-full">
{playlist.sounds.map((sound, index) => (
{filteredSounds.map((sound) => {
const originalIndex = playlist.sounds.findIndex((s) => s.id === sound.id)
return (
<div
key={sound.id}
className={cn(
'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',
currentIndex === originalIndex && 'bg-primary/10 text-primary',
)}
onClick={() => onTrackSelect(index)}
onClick={() => onTrackSelect(originalIndex)}
>
{/* Track number/play icon - 1 column */}
<div className="col-span-1 flex justify-center">
{currentIndex === index ? (
{currentIndex === originalIndex ? (
<Play className="h-3 w-3" />
) : (
<span className="text-muted-foreground">{index + 1}</span>
<span className="text-muted-foreground">{originalIndex + 1}</span>
)}
</div>
@@ -78,7 +111,7 @@ export function Playlist({
className={cn(
'font-medium truncate block',
variant === 'maximized' ? 'text-sm' : 'text-xs',
currentIndex === index ? 'text-primary' : 'text-foreground',
currentIndex === originalIndex ? 'text-primary' : 'text-foreground',
)}
>
{sound.name}
@@ -92,7 +125,7 @@ export function Playlist({
</span>
</div>
</div>
))}
)})}
</div>
</ScrollArea>