import { useEffect, useState } from 'react'; import { Play, X, Trash2, ListPlus } from 'lucide-react'; import { useTranslation } from 'react-i18next'; import { getPlaylists, deletePlaylist } from '@/lib/api/subsonicPlaylists'; import type { SubsonicPlaylist } from '@/lib/api/subsonicTypes'; interface Props { onClose: () => void; onLoad: (id: string, name: string, mode: 'replace' | 'append') => void; } export function LoadPlaylistModal({ onClose, onLoad }: Props) { const { t } = useTranslation(); const [playlists, setPlaylists] = useState([]); const [loading, setLoading] = useState(true); const [filter, setFilter] = useState(''); const [confirmDelete, setConfirmDelete] = useState<{ id: string; name: string } | null>(null); const fetchPlaylists = () => { setLoading(true); getPlaylists().then(data => { setPlaylists(data); setLoading(false); }).catch(e => { console.error(e); setLoading(false); }); }; useEffect(() => { // React Compiler set-state-in-effect rule: state set from an async result resolved in this effect. // eslint-disable-next-line react-hooks/set-state-in-effect fetchPlaylists(); }, []); const handleDelete = async (id: string, name: string) => { setConfirmDelete({ id, name }); }; const confirmDeletePlaylist = async () => { if (!confirmDelete) return; await deletePlaylist(confirmDelete.id); setConfirmDelete(null); fetchPlaylists(); }; return ( <>
e.stopPropagation()} style={{ maxWidth: '560px', width: '90vw' }}>

{t('queue.loadPlaylist')}

{!loading && playlists.length > 0 && ( setFilter(e.target.value)} autoFocus style={{ width: '100%', marginBottom: '0.75rem', padding: '8px 14px' }} /> )} {loading ? (

{t('queue.loading')}

) : playlists.length === 0 ? (

{t('queue.noPlaylists')}

) : (
{playlists.filter(p => p.name.toLowerCase().includes(filter.toLowerCase())).map(p => (
{p.name}
))}
)}
{confirmDelete && (
setConfirmDelete(null)} role="dialog" aria-modal="true">
e.stopPropagation()} style={{ maxWidth: '360px' }}>

{t('queue.delete')}

{t('queue.deleteConfirm', { name: confirmDelete.name })}

)} ); }