feat: add TTS statistics to DashboardPage and StatisticsGrid components

This commit is contained in:
JSC
2025-09-27 21:38:07 +02:00
parent 79d9bd7f76
commit d17dc5558c
2 changed files with 79 additions and 6 deletions

View File

@@ -2,7 +2,7 @@ import { StatisticCard } from '@/components/dashboard/StatisticCard'
import { NumberFlowDuration } from '@/components/ui/number-flow-duration'
import { NumberFlowSize } from '@/components/ui/number-flow-size'
import NumberFlow from '@number-flow/react'
import { Clock, HardDrive, Music, Play, Volume2 } from 'lucide-react'
import { Clock, HardDrive, Music, Play, Volume2, MessageSquare } from 'lucide-react'
interface SoundboardStatistics {
sound_count: number
@@ -18,12 +18,20 @@ interface TrackStatistics {
total_size: number
}
interface TTSStatistics {
sound_count: number
total_play_count: number
total_duration: number
total_size: number
}
interface StatisticsGridProps {
soundboardStatistics: SoundboardStatistics
trackStatistics: TrackStatistics
ttsStatistics: TTSStatistics
}
export function StatisticsGrid({ soundboardStatistics, trackStatistics }: StatisticsGridProps) {
export function StatisticsGrid({ soundboardStatistics, trackStatistics, ttsStatistics }: StatisticsGridProps) {
return (
<div className="space-y-6">
<div>
@@ -109,6 +117,48 @@ export function StatisticsGrid({ soundboardStatistics, trackStatistics }: Statis
/>
</div>
</div>
<div>
<h2 className="text-lg font-semibold mb-3 text-muted-foreground">
TTS Statistics
</h2>
<div className="grid gap-4 md:grid-cols-2 lg:grid-cols-4">
<StatisticCard
title="Total TTS"
icon={MessageSquare}
value={<NumberFlow value={ttsStatistics.sound_count} />}
description="Text-to-speech audio files"
/>
<StatisticCard
title="Total Plays"
icon={Play}
value={<NumberFlow value={ttsStatistics.total_play_count} />}
description="All-time play count"
/>
<StatisticCard
title="Total Duration"
icon={Clock}
value={
<NumberFlowDuration
duration={ttsStatistics.total_duration}
variant="wordy"
/>
}
description="Combined TTS duration"
/>
<StatisticCard
title="Total Size"
icon={HardDrive}
value={
<NumberFlowSize
size={ttsStatistics.total_size}
binary={true}
/>
}
description="Original + normalized files"
/>
</div>
</div>
</div>
)
}

View File

@@ -19,6 +19,13 @@ interface TrackStatistics {
total_size: number
}
interface TTSStatistics {
sound_count: number
total_play_count: number
total_duration: number
total_size: number
}
interface TopSound {
id: number
name: string
@@ -33,6 +40,8 @@ export function DashboardPage() {
useState<SoundboardStatistics | null>(null)
const [trackStatistics, setTrackStatistics] =
useState<TrackStatistics | null>(null)
const [ttsStatistics, setTtsStatistics] =
useState<TTSStatistics | null>(null)
const [loading, setLoading] = useState(true)
const [error, setError] = useState<string | null>(null)
@@ -74,6 +83,19 @@ export function DashboardPage() {
const trackData = await trackResponse.json()
setTrackStatistics(trackData)
// Fetch TTS statistics separately to avoid Promise.all failures
const ttsResponse = await fetch('/api/v1/dashboard/tts-statistics', {
credentials: 'include'
})
if (!ttsResponse.ok) {
const errorText = await ttsResponse.text()
throw new Error(`Failed to fetch TTS statistics: ${errorText}`)
}
const ttsData = await ttsResponse.json()
setTtsStatistics(ttsData)
} catch (err) {
console.error('Dashboard statistics error:', err)
setError(err instanceof Error ? err.message : 'An error occurred')
@@ -174,13 +196,13 @@ export function DashboardPage() {
useEffect(() => {
const interval = setInterval(() => {
// Only auto-refresh if not currently loading or in error state
if (!loading && !refreshing && (!error || (soundboardStatistics && trackStatistics))) {
if (!loading && !refreshing && (!error || (soundboardStatistics && trackStatistics && ttsStatistics))) {
refreshAll()
}
}, 30000) // Increased to 30 seconds
return () => clearInterval(interval)
}, [refreshAll, loading, refreshing, error, soundboardStatistics, trackStatistics])
}, [refreshAll, loading, refreshing, error, soundboardStatistics, trackStatistics, ttsStatistics])
useEffect(() => {
fetchTopSounds(true) // Show loading on initial load and filter changes
@@ -190,7 +212,7 @@ export function DashboardPage() {
return <LoadingSkeleton />
}
if (error && (!soundboardStatistics || !trackStatistics)) {
if (error && (!soundboardStatistics || !trackStatistics || !ttsStatistics)) {
return <ErrorState error={error} onRetry={retryFromError} />
}
@@ -204,10 +226,11 @@ export function DashboardPage() {
<DashboardHeader onRefresh={refreshAll} isRefreshing={refreshing} />
<div className="space-y-6">
{soundboardStatistics && trackStatistics && (
{soundboardStatistics && trackStatistics && ttsStatistics && (
<StatisticsGrid
soundboardStatistics={soundboardStatistics}
trackStatistics={trackStatistics}
ttsStatistics={ttsStatistics}
/>
)}