From dc8254772c8a0ddad1bd4488c49c6eb832acb80c Mon Sep 17 00:00:00 2001 From: Geert Rademakes Date: Fri, 15 Aug 2025 13:38:45 +0200 Subject: [PATCH] feat(ux): improve song details panel UX - hide panel by default, show only when song selected, add close button with X icon --- packages/frontend/src/App.tsx | 9 +++-- .../frontend/src/components/SongDetails.tsx | 35 +++++++++++++------ 2 files changed, 32 insertions(+), 12 deletions(-) diff --git a/packages/frontend/src/App.tsx b/packages/frontend/src/App.tsx index b36f486..70751f4 100644 --- a/packages/frontend/src/App.tsx +++ b/packages/frontend/src/App.tsx @@ -83,6 +83,11 @@ const RekordboxReader: React.FC = () => { setSelectedSong(song); }, []); + // Handle closing the song details panel + const handleCloseSongDetails = useCallback(() => { + setSelectedSong(null); + }, []); + // Handle playing a song from the main view const handlePlaySong = useCallback((song: Song) => { // Check if song has S3 file @@ -685,7 +690,7 @@ const RekordboxReader: React.FC = () => { {/* Details Panel */} - {!isMobile && ( + {!isMobile && selectedSong && ( { '&::-webkit-scrollbar-track': { backgroundColor: 'var(--chakra-colors-gray-900)' }, }} > - + )} diff --git a/packages/frontend/src/components/SongDetails.tsx b/packages/frontend/src/components/SongDetails.tsx index 14aa670..31844c2 100644 --- a/packages/frontend/src/components/SongDetails.tsx +++ b/packages/frontend/src/components/SongDetails.tsx @@ -1,10 +1,12 @@ import React, { useMemo, memo } from "react"; -import { Box, VStack, Text, Divider } from "@chakra-ui/react"; +import { Box, VStack, Text, Divider, IconButton, HStack } from "@chakra-ui/react"; +import { CloseIcon } from "@chakra-ui/icons"; import { Song } from "../types/interfaces"; import { formatDuration } from '../utils/formatters'; interface SongDetailsProps { song: Song | null; + onClose?: () => void; } const calculateBitrate = (size: string, totalTime: string): number | null => { @@ -22,7 +24,7 @@ const calculateBitrate = (size: string, totalTime: string): number | null => { return Math.round(bits / seconds / 1000); }; -export const SongDetails: React.FC = memo(({ song }) => { +export const SongDetails: React.FC = memo(({ song, onClose }) => { // Memoize expensive calculations const songDetails = useMemo(() => { if (!song) return null; @@ -72,14 +74,27 @@ export const SongDetails: React.FC = memo(({ song }) => { return ( - - - {song.title} - - - {song.artist} - - + + + + {song.title} + + + {song.artist} + + + {onClose && ( + } + onClick={onClose} + aria-label="Close details" + color="gray.400" + _hover={{ bg: "gray.700", color: "white" }} + /> + )} + {songDetails.details.map(({ label, value }) => (