import React, { useState, useMemo } from 'react'; import { Modal, ModalOverlay, ModalContent, ModalHeader, ModalBody, ModalFooter, Button, Input, InputGroup, InputLeftElement, VStack, HStack, Text, Icon, useToast, Box, } from '@chakra-ui/react'; import { SearchIcon } from '@chakra-ui/icons'; import { FiMusic } from 'react-icons/fi'; import type { PlaylistNode } from '../types/interfaces'; interface PlaylistSelectionModalProps { isOpen: boolean; onClose: () => void; playlists: PlaylistNode[]; onPlaylistSelect: (playlistName: string) => void; selectedSongCount: number; } export const PlaylistSelectionModal: React.FC = ({ isOpen, onClose, playlists, onPlaylistSelect, selectedSongCount, }) => { const [searchQuery, setSearchQuery] = useState(''); const toast = useToast(); // Flatten all playlists (including nested ones) for search const allPlaylists = useMemo(() => { const flattenPlaylists = (nodes: PlaylistNode[]): PlaylistNode[] => { const result: PlaylistNode[] = []; for (const node of nodes) { if (node.type === 'playlist') { result.push(node); } else if (node.type === 'folder' && node.children) { result.push(...flattenPlaylists(node.children)); } } return result; }; return flattenPlaylists(playlists); }, [playlists]); // Filter playlists based on search query const filteredPlaylists = useMemo(() => { if (!searchQuery.trim()) return allPlaylists; const query = searchQuery.toLowerCase(); return allPlaylists.filter(playlist => playlist.name.toLowerCase().includes(query) ); }, [allPlaylists, searchQuery]); const handlePlaylistSelect = (playlistName: string) => { onPlaylistSelect(playlistName); onClose(); setSearchQuery(''); toast({ title: 'Songs Added', description: `${selectedSongCount} song${selectedSongCount !== 1 ? 's' : ''} added to "${playlistName}"`, status: 'success', duration: 3000, isClosable: true, }); }; const handleClose = () => { onClose(); setSearchQuery(''); }; return ( Add to Playlist Select a playlist to add {selectedSongCount} song{selectedSongCount !== 1 ? 's' : ''} {/* Search Input */} setSearchQuery(e.target.value)} bg="gray.700" borderColor="gray.600" color="white" _placeholder={{ color: 'gray.400' }} _focus={{ borderColor: 'blue.400', boxShadow: 'none' }} _hover={{ borderColor: 'gray.500' }} /> {/* Playlist List */} {filteredPlaylists.length === 0 ? ( {searchQuery ? 'No playlists found' : 'No playlists available'} ) : ( {filteredPlaylists.map((playlist) => ( handlePlaylistSelect(playlist.name)} transition="background-color 0.2s" > {playlist.name} {playlist.trackCount || playlist.tracks?.length || 0} tracks ))} )} ); };