feat: Update Music Storage page to use dark theme

- Update MusicStorage page with dark theme colors (gray.900, gray.800, gray.700)
- Update MusicUpload component with dark theme styling
- Update SongMatching component with dark theme colors
- Match the color scheme of the main browser page
- Use consistent text colors (white, gray.100, gray.400, gray.500)
- Update cards, buttons, and alerts with dark backgrounds
- Improve hover states and visual consistency

The Music Storage page now has a consistent dark theme that matches
the main Rekordbox Reader interface.
This commit is contained in:
Geert Rademakes 2025-08-06 15:01:40 +02:00
parent 7f186c6337
commit 3317a69004
3 changed files with 430 additions and 401 deletions

View File

@ -123,7 +123,7 @@ export const MusicUpload: React.FC<MusicUploadProps> = ({ onUploadComplete }) =>
<Box
{...getRootProps()}
border="2px dashed"
borderColor={isDragActive ? 'blue.400' : 'gray.300'}
borderColor={isDragActive ? 'blue.400' : 'gray.600'}
borderRadius="lg"
p={8}
textAlign="center"
@ -131,19 +131,19 @@ export const MusicUpload: React.FC<MusicUploadProps> = ({ onUploadComplete }) =>
transition="all 0.2s"
_hover={{
borderColor: 'blue.400',
bg: 'blue.50',
bg: 'blue.900',
}}
bg={isDragActive ? 'blue.50' : 'transparent'}
bg={isDragActive ? 'blue.900' : 'gray.800'}
>
<input {...getInputProps()} />
<VStack spacing={3}>
<Icon as={isDragActive ? FiUpload : FiMusic} w={8} h={8} color="blue.500" />
<Text fontSize="lg" fontWeight="medium">
<Icon as={isDragActive ? FiUpload : FiMusic} w={8} h={8} color="blue.400" />
<Text fontSize="lg" fontWeight="medium" color="white">
{isDragActive
? 'Drop the music files here...'
: 'Drag & drop music files here, or click to select'}
</Text>
<Text fontSize="sm" color="gray.600">
<Text fontSize="sm" color="gray.400">
Supports MP3, WAV, FLAC, AAC, OGG, WMA, Opus (max 100MB per file)
</Text>
</VStack>
@ -152,30 +152,30 @@ export const MusicUpload: React.FC<MusicUploadProps> = ({ onUploadComplete }) =>
{uploadProgress.length > 0 && (
<VStack spacing={3} align="stretch">
<HStack justify="space-between">
<Text fontWeight="medium">Upload Progress</Text>
<Button size="sm" variant="ghost" onClick={resetUploads}>
<Text fontWeight="medium" color="white">Upload Progress</Text>
<Button size="sm" variant="ghost" onClick={resetUploads} color="gray.400" _hover={{ bg: "gray.700" }}>
Clear
</Button>
</HStack>
{uploadProgress.map((item, index) => (
<Box key={index} p={3} border="1px" borderColor="gray.200" borderRadius="md">
<Box key={index} p={3} border="1px" borderColor="gray.700" borderRadius="md" bg="gray.800">
<HStack justify="space-between" mb={2}>
<Text fontSize="sm" fontWeight="medium" noOfLines={1}>
<Text fontSize="sm" fontWeight="medium" noOfLines={1} color="white">
{item.fileName}
</Text>
<Icon
as={item.status === 'success' ? FiCheck : item.status === 'error' ? FiX : undefined}
color={item.status === 'success' ? 'green.500' : item.status === 'error' ? 'red.500' : 'gray.400'}
color={item.status === 'success' ? 'green.400' : item.status === 'error' ? 'red.400' : 'gray.400'}
/>
</HStack>
{item.status === 'error' ? (
<Alert status="error" size="sm">
<AlertIcon />
<Alert status="error" size="sm" bg="red.900" borderColor="red.700" color="red.100">
<AlertIcon color="red.300" />
<Box>
<AlertTitle>Upload failed</AlertTitle>
<AlertDescription>{item.error}</AlertDescription>
<AlertTitle color="red.100">Upload failed</AlertTitle>
<AlertDescription color="red.200">{item.error}</AlertDescription>
</Box>
</Alert>
) : (
@ -183,6 +183,7 @@ export const MusicUpload: React.FC<MusicUploadProps> = ({ onUploadComplete }) =>
value={item.progress}
colorScheme={item.status === 'success' ? 'green' : 'blue'}
size="sm"
bg="gray.700"
/>
)}
</Box>
@ -191,11 +192,11 @@ export const MusicUpload: React.FC<MusicUploadProps> = ({ onUploadComplete }) =>
)}
{isUploading && (
<Alert status="info">
<AlertIcon />
<Alert status="info" bg="blue.900" borderColor="blue.700" color="blue.100">
<AlertIcon color="blue.300" />
<Box>
<AlertTitle>Uploading files...</AlertTitle>
<AlertDescription>
<AlertTitle color="blue.100">Uploading files...</AlertTitle>
<AlertDescription color="blue.200">
Please wait while your music files are being uploaded and processed.
</AlertDescription>
</Box>

View File

@ -31,6 +31,7 @@ import {
StatHelpText,
IconButton,
Tooltip,
Spinner,
} from '@chakra-ui/react';
import { FiPlay, FiLink, FiSearch, FiZap, FiMusic, FiCheck, FiX } from 'react-icons/fi';
@ -273,98 +274,96 @@ export const SongMatching: React.FC = () => {
}
return (
<Box p={6} maxW="1200px" mx="auto">
<VStack spacing={6} align="stretch">
<Heading size="lg" textAlign="center">
🎵 Song Matching & Linking
</Heading>
{/* Statistics */}
{stats && (
<SimpleGrid columns={{ base: 1, md: 2, lg: 3 }} spacing={4}>
<Card bg="gray.800" borderColor="gray.700" borderWidth="1px">
<CardHeader>
<Heading size="md" color="white">Matching Statistics</Heading>
</CardHeader>
<CardBody>
<SimpleGrid columns={{ base: 2, md: 4 }} spacing={4}>
<Stat>
<StatLabel>Total Songs</StatLabel>
<StatNumber>{stats.totalSongs}</StatNumber>
<StatHelpText>In Rekordbox library</StatHelpText>
<StatLabel color="gray.400">Total Songs</StatLabel>
<StatNumber color="white">{stats.totalSongs}</StatNumber>
</Stat>
<Stat>
<StatLabel>Music Files</StatLabel>
<StatNumber>{stats.totalMusicFiles}</StatNumber>
<StatHelpText>Uploaded to S3</StatHelpText>
<StatLabel color="gray.400">Music Files</StatLabel>
<StatNumber color="white">{stats.totalMusicFiles}</StatNumber>
</Stat>
<Stat>
<StatLabel>Match Rate</StatLabel>
<StatNumber>{stats.matchRate}%</StatNumber>
<StatHelpText>{stats.matchedMusicFiles} of {stats.totalMusicFiles} linked</StatHelpText>
<StatLabel color="gray.400">Match Rate</StatLabel>
<StatNumber color="green.400">{stats.matchRate}</StatNumber>
<StatHelpText color="gray.500">
{stats.matchedMusicFiles} of {stats.totalMusicFiles} files matched
</StatHelpText>
</Stat>
<Stat>
<StatLabel color="gray.400">Unmatched</StatLabel>
<StatNumber color="orange.400">{stats.unmatchedMusicFiles}</StatNumber>
<StatHelpText color="gray.500">
{stats.songsWithoutMusicFiles} songs without files
</StatHelpText>
</Stat>
</SimpleGrid>
</CardBody>
</Card>
)}
{/* Auto-linking */}
<Card>
<CardHeader>
<HStack justify="space-between">
<Heading size="md">Auto-Linking</Heading>
{/* Auto-Link Button */}
<Card bg="gray.800" borderColor="gray.700" borderWidth="1px">
<CardBody>
<VStack spacing={4}>
<Text color="gray.300" textAlign="center">
Automatically match and link music files to songs in your Rekordbox library
</Text>
<Button
leftIcon={<FiZap />}
colorScheme="blue"
size="lg"
onClick={handleAutoLink}
isLoading={autoLinking}
loadingText="Auto-linking..."
loadingText="Auto-Linking..."
_hover={{ bg: "blue.700" }}
>
Auto-Link Files
</Button>
</HStack>
</CardHeader>
<CardBody>
<Text color="gray.600">
Automatically match and link music files to songs in your Rekordbox library.
This will attempt to find matches based on filename, title, artist, and other metadata.
Original file paths are preserved and S3 information is added alongside.
</Text>
</VStack>
</CardBody>
</Card>
{/* Unmatched Music Files */}
<Card>
<Card bg="gray.800" borderColor="gray.700" borderWidth="1px">
<CardHeader>
<Heading size="md">Unmatched Music Files ({unmatchedMusicFiles.length})</Heading>
<Heading size="md" color="white">Unmatched Music Files ({unmatchedMusicFiles.length})</Heading>
</CardHeader>
<CardBody>
{unmatchedMusicFiles.length === 0 ? (
<Text color="gray.500" textAlign="center">
All music files have been matched! 🎉
All music files are matched! 🎉
</Text>
) : (
<VStack spacing={3} align="stretch">
{unmatchedMusicFiles.slice(0, 10).map((musicFile) => (
{unmatchedMusicFiles.slice(0, 10).map((file) => (
<Box
key={musicFile._id}
key={file._id}
p={3}
border="1px"
borderColor="gray.200"
borderColor="gray.700"
borderRadius="md"
bg="gray.900"
>
<HStack justify="space-between">
<VStack align="start" spacing={1} flex={1}>
<Text fontWeight="bold" fontSize="sm">
{musicFile.title || musicFile.originalName}
<Text fontWeight="bold" fontSize="sm" color="white">
{file.title || file.originalName}
</Text>
{musicFile.artist && (
<Text fontSize="xs" color="gray.600">
{musicFile.artist}
<Text fontSize="xs" color="gray.400">
{file.artist}
</Text>
)}
{musicFile.album && (
<Text fontSize="xs" color="gray.500">
{musicFile.album}
{file.album}
</Text>
)}
<HStack spacing={2} fontSize="xs" color="gray.500">
<Text>{formatDuration(musicFile.duration || 0)}</Text>
<Text></Text>
<Text>{musicFile.format?.toUpperCase()}</Text>
</HStack>
</VStack>
<HStack spacing={2}>
<Tooltip label="Get matching suggestions">
@ -373,7 +372,9 @@ export const SongMatching: React.FC = () => {
icon={<FiSearch />}
size="sm"
variant="ghost"
onClick={() => handleGetSuggestions(musicFile)}
colorScheme="blue"
onClick={() => handleGetSuggestions(file)}
_hover={{ bg: "blue.900" }}
/>
</Tooltip>
<Tooltip label="Play music file">
@ -382,7 +383,8 @@ export const SongMatching: React.FC = () => {
icon={<FiPlay />}
size="sm"
variant="ghost"
colorScheme="blue"
colorScheme="green"
_hover={{ bg: "green.900" }}
/>
</Tooltip>
</HStack>
@ -400,62 +402,54 @@ export const SongMatching: React.FC = () => {
</Card>
{/* Matched Music Files */}
<Card>
<Card bg="gray.800" borderColor="gray.700" borderWidth="1px">
<CardHeader>
<Heading size="md">Matched Music Files ({matchedMusicFiles.length})</Heading>
<Heading size="md" color="white">Matched Music Files ({matchedMusicFiles.length})</Heading>
</CardHeader>
<CardBody>
{matchedMusicFiles.length === 0 ? (
<Text color="gray.500" textAlign="center">
No music files have been matched yet.
No music files are matched yet.
</Text>
) : (
<VStack spacing={3} align="stretch">
{matchedMusicFiles.slice(0, 10).map((musicFile) => (
{matchedMusicFiles.slice(0, 10).map((file) => (
<Box
key={musicFile._id}
key={file._id}
p={3}
border="1px"
borderColor="green.200"
borderColor="green.700"
borderRadius="md"
bg="green.50"
bg="green.900"
>
<HStack justify="space-between">
<VStack align="start" spacing={1} flex={1}>
<HStack spacing={2}>
<Text fontWeight="bold" fontSize="sm">
{musicFile.title || musicFile.originalName}
<Text fontWeight="bold" fontSize="sm" color="white">
{file.title || file.originalName}
</Text>
<Badge colorScheme="green" size="sm">
<Badge colorScheme="green" size="sm" bg="green.800" color="green.200">
<FiCheck style={{ marginRight: '4px' }} />
Linked
Matched
</Badge>
</HStack>
{musicFile.artist && (
<Text fontSize="xs" color="gray.600">
{musicFile.artist}
<Text fontSize="xs" color="gray.300">
{file.artist}
</Text>
)}
{musicFile.songId && (
<Text fontSize="xs" color="blue.600">
{musicFile.songId.title} by {musicFile.songId.artist}
<Text fontSize="xs" color="gray.400">
{file.album}
</Text>
)}
{musicFile.songId?.location && (
<Text fontSize="xs" color="gray.500">
📁 {musicFile.songId.location}
</Text>
)}
</VStack>
<HStack spacing={2}>
<Tooltip label="Unlink from song">
<Tooltip label="Unlink music file">
<IconButton
aria-label="Unlink"
icon={<FiX />}
size="sm"
variant="ghost"
colorScheme="red"
onClick={() => handleUnlinkMusicFile(musicFile.songId._id)}
onClick={() => handleUnlinkMusicFile(file.songId)}
_hover={{ bg: "red.900" }}
/>
</Tooltip>
<Tooltip label="Play music file">
@ -465,6 +459,7 @@ export const SongMatching: React.FC = () => {
size="sm"
variant="ghost"
colorScheme="blue"
_hover={{ bg: "blue.900" }}
/>
</Tooltip>
</HStack>
@ -482,9 +477,9 @@ export const SongMatching: React.FC = () => {
</Card>
{/* Songs with Music Files */}
<Card>
<Card bg="gray.800" borderColor="gray.700" borderWidth="1px">
<CardHeader>
<Heading size="md">Songs with Music Files ({songsWithMusicFiles.length})</Heading>
<Heading size="md" color="white">Songs with Music Files ({songsWithMusicFiles.length})</Heading>
</CardHeader>
<CardBody>
{songsWithMusicFiles.length === 0 ? (
@ -498,31 +493,31 @@ export const SongMatching: React.FC = () => {
key={song._id}
p={3}
border="1px"
borderColor="blue.200"
borderColor="blue.700"
borderRadius="md"
bg="blue.50"
bg="blue.900"
>
<HStack justify="space-between">
<VStack align="start" spacing={1} flex={1}>
<HStack spacing={2}>
<Text fontWeight="bold" fontSize="sm">
<Text fontWeight="bold" fontSize="sm" color="white">
{song.title}
</Text>
<Badge colorScheme="blue" size="sm">
<Badge colorScheme="blue" size="sm" bg="blue.800" color="blue.200">
<FiMusic style={{ marginRight: '4px' }} />
Has S3 File
</Badge>
</HStack>
<Text fontSize="xs" color="gray.600">
<Text fontSize="xs" color="gray.300">
{song.artist}
</Text>
{song.location && (
<Text fontSize="xs" color="gray.500">
<Text fontSize="xs" color="gray.400">
📁 {song.location}
</Text>
)}
{song.s3File?.streamingUrl && (
<Text fontSize="xs" color="green.600">
<Text fontSize="xs" color="green.400">
🎵 S3: {song.s3File.s3Key}
</Text>
)}
@ -536,6 +531,7 @@ export const SongMatching: React.FC = () => {
variant="ghost"
colorScheme="red"
onClick={() => handleUnlinkMusicFile(song._id)}
_hover={{ bg: "red.900" }}
/>
</Tooltip>
<Tooltip label="Play music file">
@ -545,6 +541,7 @@ export const SongMatching: React.FC = () => {
size="sm"
variant="ghost"
colorScheme="blue"
_hover={{ bg: "blue.800" }}
/>
</Tooltip>
</HStack>
@ -564,63 +561,73 @@ export const SongMatching: React.FC = () => {
{/* Suggestions Modal */}
<Modal isOpen={isOpen} onClose={onClose} size="xl">
<ModalOverlay />
<ModalContent>
<ModalHeader>
<ModalContent bg="gray.800" borderColor="gray.700" borderWidth="1px">
<ModalHeader color="white">
Matching Suggestions for "{selectedMusicFile?.title || selectedMusicFile?.originalName}"
</ModalHeader>
<ModalCloseButton />
<ModalCloseButton color="gray.400" />
<ModalBody>
{loadingSuggestions ? (
<Progress size="xs" isIndeterminate />
<VStack spacing={4}>
<Spinner size="lg" color="blue.400" />
<Text color="gray.400">Finding matching songs...</Text>
</VStack>
) : suggestions.length === 0 ? (
<Text color="gray.500" textAlign="center">
No matching suggestions found.
No matching songs found. You can manually link this file later.
</Text>
) : (
<VStack spacing={3} align="stretch">
{suggestions.map((match, index) => (
{suggestions.map((suggestion, index) => (
<Box
key={index}
p={3}
border="1px"
borderColor="gray.200"
borderColor="gray.700"
borderRadius="md"
bg="gray.900"
>
<HStack justify="space-between">
<VStack align="start" spacing={1} flex={1}>
<HStack spacing={2}>
<Text fontWeight="bold" fontSize="sm">
{match.song.title}
<Text fontWeight="bold" fontSize="sm" color="white">
{suggestion.song.title}
</Text>
<Badge colorScheme={getConfidenceColor(match.confidence)} size="sm">
{(match.confidence * 100).toFixed(0)}%
<Badge
colorScheme={getConfidenceColor(suggestion.confidence)}
size="sm"
bg={`${getConfidenceColor(suggestion.confidence)}.900`}
color={`${getConfidenceColor(suggestion.confidence)}.200`}
>
{Math.round(suggestion.confidence * 100)}%
</Badge>
</HStack>
<Text fontSize="xs" color="gray.600">
{match.song.artist}
<Text fontSize="xs" color="gray.400">
{suggestion.song.artist}
</Text>
{match.song.album && (
{suggestion.song.location && (
<Text fontSize="xs" color="gray.500">
{match.song.album}
📁 {suggestion.song.location}
</Text>
)}
{match.song.location && (
<Text fontSize="xs" color="gray.500">
📁 {match.song.location}
</Text>
)}
<Text fontSize="xs" color="gray.500">
{match.matchReason}
<Text fontSize="xs" color="blue.400">
{suggestion.matchReason}
</Text>
</VStack>
<Button
leftIcon={<FiLink />}
<Tooltip label="Link this song">
<IconButton
aria-label="Link"
icon={<FiLink />}
size="sm"
variant="ghost"
colorScheme="blue"
onClick={() => handleLinkMusicFile(match.musicFile._id, match.song._id)}
>
Link
</Button>
onClick={() => {
handleLinkMusicFile(selectedMusicFile._id, suggestion.song._id);
onClose();
}}
_hover={{ bg: "blue.900" }}
/>
</Tooltip>
</HStack>
</Box>
))}
@ -628,13 +635,12 @@ export const SongMatching: React.FC = () => {
)}
</ModalBody>
<ModalFooter>
<Button variant="ghost" onClick={onClose}>
<Button variant="ghost" onClick={onClose} color="gray.400" _hover={{ bg: "gray.700" }}>
Close
</Button>
</ModalFooter>
</ModalContent>
</Modal>
</VStack>
</Box>
);
};

View File

@ -171,40 +171,55 @@ export const MusicStorage: React.FC = () => {
};
return (
<Box p={6} maxW="1200px" mx="auto">
<Box
p={6}
maxW="1200px"
mx="auto"
minH="100vh"
bg="gray.900"
color="gray.100"
>
<VStack spacing={6} align="stretch">
<Heading size="lg" textAlign="center">
<Heading size="lg" textAlign="center" color="white">
🎵 Music Storage & Playback
</Heading>
<Alert status="info">
<AlertIcon />
<Alert status="info" bg="blue.900" borderColor="blue.700" color="blue.100">
<AlertIcon color="blue.300" />
<Box>
<Text fontWeight="bold">S3 Storage Feature</Text>
<Text fontSize="sm">
<Text fontWeight="bold" color="blue.100">S3 Storage Feature</Text>
<Text fontSize="sm" color="blue.200">
Upload your music files to S3-compatible storage (MinIO) and stream them directly in the browser.
Supports MP3, WAV, FLAC, AAC, OGG, WMA, and Opus formats.
</Text>
</Box>
</Alert>
<Tabs variant="enclosed">
<TabList>
<Tab>Upload Music</Tab>
<Tab>Music Library</Tab>
<Tab>Song Matching</Tab>
<Tab>Player</Tab>
<Tabs variant="enclosed" colorScheme="blue">
<TabList bg="gray.800" borderColor="gray.700">
<Tab color="gray.300" _selected={{ bg: "gray.700", color: "white", borderColor: "gray.600" }}>
Upload Music
</Tab>
<Tab color="gray.300" _selected={{ bg: "gray.700", color: "white", borderColor: "gray.600" }}>
Music Library
</Tab>
<Tab color="gray.300" _selected={{ bg: "gray.700", color: "white", borderColor: "gray.600" }}>
Song Matching
</Tab>
<Tab color="gray.300" _selected={{ bg: "gray.700", color: "white", borderColor: "gray.600" }}>
Player
</Tab>
</TabList>
<TabPanels>
{/* Upload Tab */}
<TabPanel>
<TabPanel bg="gray.900">
<VStack spacing={6} align="stretch">
<Box>
<Heading size="md" mb={4}>
<Heading size="md" mb={4} color="white">
Upload Music Files
</Heading>
<Text color="gray.600" mb={4}>
<Text color="gray.400" mb={4}>
Drag and drop your music files here or click to select. Files will be uploaded to S3 storage
and metadata will be automatically extracted.
</Text>
@ -214,21 +229,23 @@ export const MusicStorage: React.FC = () => {
</TabPanel>
{/* Library Tab */}
<TabPanel>
<TabPanel bg="gray.900">
<VStack spacing={4} align="stretch">
<HStack justify="space-between">
<Heading size="md">Music Library</Heading>
<Heading size="md" color="white">Music Library</Heading>
<HStack spacing={2}>
<Text color="gray.600">
<Text color="gray.400">
{musicFiles.length} file{musicFiles.length !== 1 ? 's' : ''}
</Text>
<Button
leftIcon={isSyncing ? <Spinner size="sm" /> : <FiRefreshCw />}
size="sm"
variant="outline"
colorScheme="blue"
onClick={handleSyncS3}
isLoading={isSyncing}
loadingText="Syncing..."
_hover={{ bg: "blue.900", borderColor: "blue.400" }}
>
Sync S3
</Button>
@ -250,6 +267,8 @@ export const MusicStorage: React.FC = () => {
onClick={handleSyncS3}
isLoading={isSyncing}
loadingText="Syncing..."
colorScheme="blue"
_hover={{ bg: "blue.700" }}
>
Sync S3 Bucket
</Button>
@ -257,10 +276,10 @@ export const MusicStorage: React.FC = () => {
) : (
<SimpleGrid columns={{ base: 1, md: 2, lg: 3 }} spacing={4}>
{musicFiles.map((file) => (
<Card key={file._id} size="sm">
<Card key={file._id} size="sm" bg="gray.800" borderColor="gray.700" borderWidth="1px">
<CardHeader pb={2}>
<HStack justify="space-between">
<Badge colorScheme="blue" variant="subtle">
<Badge colorScheme="blue" variant="subtle" bg="blue.900" color="blue.200">
{file.format?.toUpperCase() || 'AUDIO'}
</Badge>
<IconButton
@ -270,16 +289,17 @@ export const MusicStorage: React.FC = () => {
variant="ghost"
colorScheme="red"
onClick={() => handleDeleteFile(file._id)}
_hover={{ bg: "red.900" }}
/>
</HStack>
</CardHeader>
<CardBody pt={0}>
<VStack spacing={2} align="stretch">
<Text fontWeight="bold" fontSize="sm" noOfLines={1}>
<Text fontWeight="bold" fontSize="sm" noOfLines={1} color="white">
{file.title || file.originalName}
</Text>
{file.artist && (
<Text fontSize="xs" color="gray.600" noOfLines={1}>
<Text fontSize="xs" color="gray.400" noOfLines={1}>
{file.artist}
</Text>
)}
@ -293,7 +313,7 @@ export const MusicStorage: React.FC = () => {
<Text>{formatFileSize(file.size)}</Text>
</HStack>
{file.songId && (
<Badge colorScheme="green" size="sm" alignSelf="start">
<Badge colorScheme="green" size="sm" alignSelf="start" bg="green.900" color="green.200">
Linked to Rekordbox
</Badge>
)}
@ -303,6 +323,7 @@ export const MusicStorage: React.FC = () => {
size="sm"
colorScheme="blue"
onClick={() => setSelectedFile(file)}
_hover={{ bg: "blue.700" }}
/>
</VStack>
</CardBody>
@ -314,14 +335,14 @@ export const MusicStorage: React.FC = () => {
</TabPanel>
{/* Song Matching Tab */}
<TabPanel>
<TabPanel bg="gray.900">
<SongMatching />
</TabPanel>
{/* Player Tab */}
<TabPanel>
<TabPanel bg="gray.900">
<VStack spacing={4} align="stretch">
<Heading size="md">Music Player</Heading>
<Heading size="md" color="white">Music Player</Heading>
{selectedFile ? (
<MusicPlayer
musicFile={selectedFile}
@ -339,9 +360,10 @@ export const MusicStorage: React.FC = () => {
p={8}
textAlign="center"
border="2px dashed"
borderColor="gray.300"
borderColor="gray.600"
borderRadius="lg"
color="gray.500"
bg="gray.800"
>
<FiMusic size={48} style={{ margin: '0 auto 16px' }} />
<Text>Select a music file from the library to start playing</Text>