import { Box, Button, Flex, Input, Modal, ModalBody, ModalCloseButton, ModalContent, ModalFooter, ModalHeader, ModalOverlay, useDisclosure, VStack, Menu, MenuButton, MenuList, MenuItem, IconButton, Collapse, MenuDivider, MenuGroup, Icon } from "@chakra-ui/react"; import { ChevronDownIcon, DeleteIcon, ChevronRightIcon, AddIcon, ViewIcon } from "@chakra-ui/icons"; 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; } const getButtonStyles = (isSelected: boolean) => ({ width: "100%", display: "flex", alignItems: "center", justifyContent: "space-between", bg: isSelected ? "blue.800" : "transparent", color: isSelected ? "white" : "gray.100", fontWeight: isSelected ? "600" : "normal", borderRadius: "md", px: 4, py: 2, cursor: "pointer", transition: "all 0.2s", _hover: { bg: isSelected ? "blue.600" : "whiteAlpha.200", transform: "translateX(2px)", }, _active: { bg: isSelected ? "blue.700" : "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 }[]; } const PlaylistItem: React.FC = ({ node, level, selectedItem, onPlaylistSelect, onPlaylistDelete, onPlaylistMove, allFolders, }) => { const [isOpen, setIsOpen] = useState(true); const indent = level * 10; 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 ); }; export const PlaylistManager: React.FC = ({ playlists, selectedItem, onPlaylistCreate, onPlaylistSelect, onPlaylistDelete, onFolderCreate, onPlaylistMove, }) => { 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 ( {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", }} /> ); };