import { Box, Button, Flex, Input, Modal, ModalBody, ModalCloseButton, ModalContent, ModalFooter, ModalHeader, ModalOverlay, useDisclosure, VStack, Menu, MenuButton, MenuList, MenuItem, Text, // HStack, Collapse, MenuDivider, MenuGroup, Icon, Badge } from "@chakra-ui/react"; import { ChevronRightIcon, AddIcon, ViewIcon, DeleteIcon } from "@chakra-ui/icons"; import { FiMoreHorizontal } from 'react-icons/fi'; import React, { useState, useCallback } from "react"; import { PlaylistNode } from "../types/interfaces"; interface PlaylistManagerProps { playlists: PlaylistNode[]; selectedItem: string | null; onPlaylistCreate: (name: string) => void; onPlaylistSelect: (name: string | null) => void; onPlaylistDelete: (name: string) => void; onFolderCreate: (name: string) => void; onPlaylistMove: (playlistName: string, targetFolderName: string | null) => void; onDropSongs?: (playlistName: string, songIds: string[]) => void; } // Memoized button styles to prevent unnecessary re-renders const selectedButtonStyles = { width: "100%", display: "flex", alignItems: "center", justifyContent: "space-between", bg: "blue.800", color: "white", fontWeight: "600", borderRadius: "md", px: 4, py: 2, cursor: "pointer", transition: "all 0.2s", _hover: { bg: "blue.600", transform: "translateX(2px)", }, _active: { bg: "blue.700", }, }; const unselectedButtonStyles = { width: "100%", display: "flex", alignItems: "center", justifyContent: "space-between", bg: "transparent", color: "gray.100", fontWeight: "normal", borderRadius: "md", px: 4, py: 2, cursor: "pointer", transition: "all 0.2s", _hover: { bg: "whiteAlpha.200", transform: "translateX(2px)", }, _active: { bg: "whiteAlpha.300", }, }; interface PlaylistItemProps { node: PlaylistNode; level: number; selectedItem: string | null; onPlaylistSelect: (name: string | null) => void; onPlaylistDelete: (name: string) => void; onPlaylistMove: (playlistName: string, targetFolderName: string | null) => void; allFolders: { name: string }[]; onDropSongs?: (playlistName: string, songIds: string[]) => void; } const PlaylistItem: React.FC = React.memo(({ node, level, selectedItem, onPlaylistSelect, onPlaylistDelete, onPlaylistMove, allFolders, onDropSongs, }) => { const [isOpen, setIsOpen] = useState(false); const [isDragOver, setIsDragOver] = useState(false); // Memoize click handlers to prevent recreation const handlePlaylistClick = useCallback(() => { onPlaylistSelect(node.name); }, [onPlaylistSelect, node.name]); const handleFolderToggle = useCallback(() => { setIsOpen(prev => !prev); }, []); const indent = level * 10; // Reverted back to 10px per level if (node.type === 'folder') { return ( {node.children?.map((child, index) => ( ))} ); } return ( onPlaylistMove(node.name, null)} > Root level {allFolders.map((folder) => ( onPlaylistMove(node.name, folder.name)} > {folder.name} ))} } onClick={() => onPlaylistDelete(node.name)} > Delete Playlist ); }); const PlaylistManagerComponent: React.FC = ({ playlists, selectedItem, onPlaylistCreate, onPlaylistSelect, onPlaylistDelete, onFolderCreate, onPlaylistMove, onDropSongs, }) => { const { isOpen: isPlaylistModalOpen, onOpen: onPlaylistModalOpen, onClose: onPlaylistModalClose } = useDisclosure(); const { isOpen: isFolderModalOpen, onOpen: onFolderModalOpen, onClose: onFolderModalClose } = useDisclosure(); const [newPlaylistName, setNewPlaylistName] = useState(""); const [newFolderName, setNewFolderName] = useState(""); // Helper function to get all folders from the playlist tree const getAllFolders = useCallback((nodes: PlaylistNode[]): { name: string }[] => { let result: { name: string }[] = []; for (const node of nodes) { if (node.type === 'folder') { result.push({ name: node.name }); if (node.children) { result = result.concat(getAllFolders(node.children)); } } } return result; }, []); const allFolders = getAllFolders(playlists); const handleCreatePlaylist = () => { if (newPlaylistName.trim()) { onPlaylistCreate(newPlaylistName); setNewPlaylistName(""); onPlaylistModalClose(); } }; const handleCreateFolder = () => { if (newFolderName.trim()) { onFolderCreate(newFolderName); setNewFolderName(""); onFolderModalClose(); } }; return ( {/* Add Playlist and Folder buttons at the top */} {playlists.map((node, index) => ( ))} {/* New Playlist Modal */} Create New Playlist setNewPlaylistName(e.target.value)} placeholder="Enter playlist name" bg="gray.700" border="none" color="white" _placeholder={{ color: "gray.400" }} _focus={{ boxShadow: "0 0 0 1px blue.500", borderColor: "blue.500", }} /> {/* New Folder Modal */} Create New Folder setNewFolderName(e.target.value)} placeholder="Enter folder name" bg="gray.700" border="none" color="white" _placeholder={{ color: "gray.400" }} _focus={{ boxShadow: "0 0 0 1px teal.500", borderColor: "teal.500", }} /> ); }; export const PlaylistManager = React.memo(PlaylistManagerComponent);