diff --git a/src/components/player/Player.tsx b/src/components/player/Player.tsx index 3e41019..809915a 100644 --- a/src/components/player/Player.tsx +++ b/src/components/player/Player.tsx @@ -504,7 +504,7 @@ export function Player({ className, onPlayerModeChange }: PlayerProps) { {/* Main Player Area */}
{/* Large Album Art */} -
+
{state.current_sound?.thumbnail ? ( (null) const [trackStatistics, setTrackStatistics] = useState(null) const [loading, setLoading] = useState(true) const [error, setError] = useState(null) + + // Top sounds state + const [topSounds, setTopSounds] = useState([]) + const [topSoundsLoading, setTopSoundsLoading] = useState(false) + const [soundType, setSoundType] = useState('SDB') + const [period, setPeriod] = useState('all_time') + const [limit, setLimit] = useState(5) + + const fetchTopSounds = async () => { + try { + setTopSoundsLoading(true) + const response = await fetch( + `/api/v1/dashboard/top-sounds?sound_type=${soundType}&period=${period}&limit=${limit}`, + { credentials: 'include' } + ) + + if (!response.ok) { + throw new Error('Failed to fetch top sounds') + } + + const data = await response.json() + setTopSounds(data) + } catch (err) { + console.error('Failed to fetch top sounds:', err) + } finally { + setTopSoundsLoading(false) + } + } useEffect(() => { const fetchStatistics = async () => { @@ -52,6 +90,10 @@ export function DashboardPage() { fetchStatistics() }, []) + + useEffect(() => { + fetchTopSounds() + }, [soundType, period, limit]) if (loading) { return ( @@ -268,6 +310,108 @@ export function DashboardPage() {
+ + {/* Top Sounds Section */} +
+ + +
+
+ + Top Sounds +
+
+
+ Type: + +
+
+ Period: + +
+
+ Count: + +
+
+
+
+ + {topSoundsLoading ? ( +
+ + Loading top sounds... +
+ ) : topSounds.length === 0 ? ( +
+ +

No sounds found for the selected criteria

+
+ ) : ( +
+ {topSounds.map((sound, index) => ( +
+
+ {index + 1} +
+ +
+
{sound.name}
+
+ + + {sound.play_count} plays + + {sound.duration && ( + + + {formatDuration(sound.duration)} + + )} + + {sound.type} + +
+
+
+ ))} +
+ )} +
+
+
diff --git a/src/pages/PlaylistEditPage.tsx b/src/pages/PlaylistEditPage.tsx index 04455d2..79bad7d 100644 --- a/src/pages/PlaylistEditPage.tsx +++ b/src/pages/PlaylistEditPage.tsx @@ -606,25 +606,17 @@ export function PlaylistEditPage() { // If it's an EXT sound and we're in add mode, add it back to available sounds if (isAddMode && removedSound.type === 'EXT') { - // Convert PlaylistSound back to Sound format for available list - const soundToAddBack = { - id: removedSound.id, - name: removedSound.name, - filename: removedSound.filename, - duration: removedSound.duration, - size: removedSound.size, - hash: removedSound.hash, - type: removedSound.type, - play_count: removedSound.play_count, - is_normalized: removedSound.is_normalized, - normalized_filename: removedSound.normalized_filename, - normalized_duration: removedSound.normalized_duration, - normalized_size: removedSound.normalized_size, - normalized_hash: removedSound.normalized_hash, - created_at: removedSound.created_at, - updated_at: removedSound.updated_at + // Fetch the complete sound data to add back to available sounds + try { + const allExtSounds = await soundsService.getSoundsByType('EXT') + const soundToAddBack = allExtSounds.find(s => s.id === soundId) + if (soundToAddBack) { + setAvailableSounds(prev => [...prev, soundToAddBack].sort((a, b) => a.name.localeCompare(b.name))) + } + } catch { + // If we can't fetch the sound data, just refresh the available sounds + await fetchAvailableSounds() } - setAvailableSounds(prev => [...prev, soundToAddBack].sort((a, b) => a.name.localeCompare(b.name))) } // Optimistically update playlist stats