chore(matching): remove heavy matched/songs-with-files lists from SongMatching to streamline UI

This commit is contained in:
Geert Rademakes 2025-08-13 16:47:51 +02:00
parent 58eaa50bd2
commit 1560e614dc

View File

@ -29,7 +29,7 @@ import {
Tooltip, Tooltip,
Spinner, Spinner,
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import { FiPlay, FiLink, FiSearch, FiZap, FiMusic, FiCheck, FiX } from 'react-icons/fi'; import { FiPlay, FiLink, FiSearch, FiZap } from 'react-icons/fi';
interface MatchResult { interface MatchResult {
song: any; song: any;
@ -52,8 +52,7 @@ interface MatchingStats {
export const SongMatching: React.FC = () => { export const SongMatching: React.FC = () => {
const [stats, setStats] = useState<MatchingStats | null>(null); const [stats, setStats] = useState<MatchingStats | null>(null);
const [unmatchedMusicFiles, setUnmatchedMusicFiles] = useState<any[]>([]); const [unmatchedMusicFiles, setUnmatchedMusicFiles] = useState<any[]>([]);
const [matchedMusicFiles, setMatchedMusicFiles] = useState<any[]>([]); // Removed matched and songs-with-files lists to reduce load
const [songsWithMusicFiles, setSongsWithMusicFiles] = useState<any[]>([]);
const [isLoading, setIsLoading] = useState(false); const [isLoading, setIsLoading] = useState(false);
const [autoLinking, setAutoLinking] = useState(false); const [autoLinking, setAutoLinking] = useState(false);
const [selectedMusicFile, setSelectedMusicFile] = useState<any>(null); const [selectedMusicFile, setSelectedMusicFile] = useState<any>(null);
@ -70,11 +69,9 @@ export const SongMatching: React.FC = () => {
const loadData = async () => { const loadData = async () => {
setIsLoading(true); setIsLoading(true);
try { try {
const [statsRes, unmatchedRes, matchedRes, songsWithRes] = await Promise.all([ const [statsRes, unmatchedRes] = await Promise.all([
fetch('/api/matching/stats'), fetch('/api/matching/stats'),
fetch('/api/matching/unmatched-music-files?limit=200'), fetch('/api/matching/unmatched-music-files?limit=200')
fetch('/api/matching/matched-music-files?limit=200'),
fetch('/api/matching/songs-with-music-files?limit=200')
]); ]);
if (statsRes.ok) { if (statsRes.ok) {
@ -87,15 +84,7 @@ export const SongMatching: React.FC = () => {
setUnmatchedMusicFiles(unmatchedData.musicFiles); setUnmatchedMusicFiles(unmatchedData.musicFiles);
} }
if (matchedRes.ok) { // Matched and songs-with-files lists are omitted
const matchedData = await matchedRes.json();
setMatchedMusicFiles(matchedData.musicFiles);
}
if (songsWithRes.ok) {
const songsData = await songsWithRes.json();
setSongsWithMusicFiles(songsData.songs);
}
} catch (error) { } catch (error) {
console.error('Error loading data:', error); console.error('Error loading data:', error);
toast({ toast({
@ -209,35 +198,7 @@ export const SongMatching: React.FC = () => {
} }
}; };
const handleUnlinkMusicFile = async (songId: string) => { // Unlink handler removed with matched/songs-with-files lists
try {
const response = await fetch(`/api/matching/unlink/${songId}`, {
method: 'DELETE',
});
if (response.ok) {
toast({
title: 'Success',
description: 'Music file unlinked from song successfully',
status: 'success',
duration: 3000,
isClosable: true,
});
loadData(); // Refresh data
} else {
throw new Error('Failed to unlink music file');
}
} catch (error) {
console.error('Error unlinking music file:', error);
toast({
title: 'Error',
description: 'Failed to unlink music file from song',
status: 'error',
duration: 3000,
isClosable: true,
});
}
};
const getConfidenceColor = (confidence: number) => { const getConfidenceColor = (confidence: number) => {
if (confidence >= 0.9) return 'green'; if (confidence >= 0.9) return 'green';
@ -386,162 +347,7 @@ export const SongMatching: React.FC = () => {
</CardBody> </CardBody>
</Card> </Card>
{/* Matched Music Files */} {/* Removed Matched Music Files and Songs with Music Files lists to streamline UI */}
<Card bg="gray.800" borderColor="gray.700" borderWidth="1px">
<CardHeader>
<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 are matched yet.
</Text>
) : (
<VStack spacing={3} align="stretch">
{matchedMusicFiles.slice(0, 10).map((file) => (
<Box
key={file._id}
p={3}
border="1px"
borderColor="green.700"
borderRadius="md"
bg="green.900"
>
<HStack justify="space-between">
<VStack align="start" spacing={1} flex={1}>
<HStack spacing={2}>
<Text fontWeight="bold" fontSize="sm" color="white">
{file.title || file.originalName}
</Text>
<Badge colorScheme="green" size="sm" bg="green.800" color="green.200">
<FiCheck style={{ marginRight: '4px' }} />
Matched
</Badge>
</HStack>
<Text fontSize="xs" color="gray.300">
{file.artist}
</Text>
<Text fontSize="xs" color="gray.400">
{file.album}
</Text>
</VStack>
<HStack spacing={2}>
<Tooltip label="Unlink music file">
<IconButton
aria-label="Unlink"
icon={<FiX />}
size="sm"
variant="ghost"
colorScheme="red"
onClick={() => handleUnlinkMusicFile(file.songId)}
_hover={{ bg: "red.900" }}
/>
</Tooltip>
<Tooltip label="Play music file">
<IconButton
aria-label="Play"
icon={<FiPlay />}
size="sm"
variant="ghost"
colorScheme="blue"
_hover={{ bg: "blue.900" }}
/>
</Tooltip>
</HStack>
</HStack>
</Box>
))}
{matchedMusicFiles.length > 10 && (
<Text fontSize="sm" color="gray.500" textAlign="center">
Showing first 10 of {matchedMusicFiles.length} matched files
</Text>
)}
</VStack>
)}
</CardBody>
</Card>
{/* Songs with Music Files */}
<Card bg="gray.800" borderColor="gray.700" borderWidth="1px">
<CardHeader>
<Heading size="md" color="white">Songs with Music Files ({songsWithMusicFiles.length})</Heading>
</CardHeader>
<CardBody>
{songsWithMusicFiles.length === 0 ? (
<Text color="gray.500" textAlign="center">
No songs have music files linked yet.
</Text>
) : (
<VStack spacing={3} align="stretch">
{songsWithMusicFiles.slice(0, 10).map((song) => (
<Box
key={song._id}
p={3}
border="1px"
borderColor="blue.700"
borderRadius="md"
bg="blue.900"
>
<HStack justify="space-between">
<VStack align="start" spacing={1} flex={1}>
<HStack spacing={2}>
<Text fontWeight="bold" fontSize="sm" color="white">
{song.title}
</Text>
<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.300">
{song.artist}
</Text>
{song.location && (
<Text fontSize="xs" color="gray.400">
📁 {song.location}
</Text>
)}
{song.s3File?.streamingUrl && (
<Text fontSize="xs" color="green.400">
🎵 S3: {song.s3File.s3Key}
</Text>
)}
</VStack>
<HStack spacing={2}>
<Tooltip label="Unlink music file">
<IconButton
aria-label="Unlink"
icon={<FiX />}
size="sm"
variant="ghost"
colorScheme="red"
onClick={() => handleUnlinkMusicFile(song._id)}
_hover={{ bg: "red.900" }}
/>
</Tooltip>
<Tooltip label="Play music file">
<IconButton
aria-label="Play"
icon={<FiPlay />}
size="sm"
variant="ghost"
colorScheme="blue"
_hover={{ bg: "blue.800" }}
/>
</Tooltip>
</HStack>
</HStack>
</Box>
))}
{songsWithMusicFiles.length > 10 && (
<Text fontSize="sm" color="gray.500" textAlign="center">
Showing first 10 of {songsWithMusicFiles.length} songs with music files
</Text>
)}
</VStack>
)}
</CardBody>
</Card>
{/* Suggestions Modal */} {/* Suggestions Modal */}
<Modal isOpen={isOpen} onClose={onClose} size="xl"> <Modal isOpen={isOpen} onClose={onClose} size="xl">