feat: add NumberFlowSize component and integrate it into DashboardPage for improved size display
This commit is contained in:
22
src/components/ui/number-flow-size.tsx
Normal file
22
src/components/ui/number-flow-size.tsx
Normal file
@@ -0,0 +1,22 @@
|
||||
import NumberFlow from '@number-flow/react'
|
||||
import { formatSizeObject } from '@/utils/format-size'
|
||||
|
||||
interface NumberFlowSizeProps {
|
||||
size: number
|
||||
binary?: boolean
|
||||
className?: string
|
||||
}
|
||||
|
||||
export function NumberFlowSize({
|
||||
size,
|
||||
binary = true,
|
||||
className
|
||||
}: NumberFlowSizeProps) {
|
||||
const sizeObj = formatSizeObject(size, binary)
|
||||
|
||||
return (
|
||||
<span className={className}>
|
||||
<NumberFlow value={sizeObj.value} /> {sizeObj.unit}
|
||||
</span>
|
||||
)
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
/**
|
||||
* Utility functions for formatting data for display
|
||||
*/
|
||||
|
||||
export function formatDuration(durationMs: number): string {
|
||||
if (!durationMs) return "0s"
|
||||
|
||||
const totalSeconds = Math.floor(durationMs / 1000)
|
||||
const hours = Math.floor(totalSeconds / 3600)
|
||||
const minutes = Math.floor((totalSeconds % 3600) / 60)
|
||||
const seconds = totalSeconds % 60
|
||||
|
||||
if (hours > 0) {
|
||||
return `${hours}h ${minutes}m ${seconds}s`
|
||||
}
|
||||
if (minutes > 0) {
|
||||
return `${minutes}m ${seconds}s`
|
||||
}
|
||||
return `${seconds}s`
|
||||
}
|
||||
|
||||
export function formatFileSize(sizeBytes: number): string {
|
||||
if (!sizeBytes) return "0 B"
|
||||
|
||||
const units = ["B", "KB", "MB", "GB", "TB"]
|
||||
let size = sizeBytes
|
||||
let unitIndex = 0
|
||||
|
||||
while (size >= 1024 && unitIndex < units.length - 1) {
|
||||
size /= 1024
|
||||
unitIndex++
|
||||
}
|
||||
|
||||
if (unitIndex === 0) {
|
||||
return `${Math.floor(size)} ${units[unitIndex]}`
|
||||
}
|
||||
return `${size.toFixed(1)} ${units[unitIndex]}`
|
||||
}
|
||||
@@ -4,10 +4,9 @@ import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { Volume2, Play, Clock, HardDrive, Music, Trophy, Loader2, RefreshCw } from 'lucide-react'
|
||||
import { formatDuration } from '@/lib/format'
|
||||
import NumberFlow from '@number-flow/react'
|
||||
import { formatSizeObject } from '@/utils/format-size'
|
||||
import { NumberFlowDuration } from '@/components/ui/number-flow-duration'
|
||||
import { NumberFlowSize } from '@/components/ui/number-flow-size'
|
||||
|
||||
interface SoundboardStatistics {
|
||||
sound_count: number
|
||||
@@ -315,14 +314,7 @@ export function DashboardPage() {
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="text-2xl font-bold">
|
||||
{(() => {
|
||||
const sizeObj = formatSizeObject(soundboardStatistics.total_size, true)
|
||||
return (
|
||||
<>
|
||||
<NumberFlow value={sizeObj.value} /> {sizeObj.unit}
|
||||
</>
|
||||
)
|
||||
})()}
|
||||
<NumberFlowSize size={soundboardStatistics.total_size} binary={true} />
|
||||
</div>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
Original + normalized files
|
||||
@@ -384,14 +376,7 @@ export function DashboardPage() {
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="text-2xl font-bold">
|
||||
{(() => {
|
||||
const sizeObj = formatSizeObject(trackStatistics.total_size, true)
|
||||
return (
|
||||
<>
|
||||
<NumberFlow value={sizeObj.value} /> {sizeObj.unit}
|
||||
</>
|
||||
)
|
||||
})()}
|
||||
<NumberFlowSize size={trackStatistics.total_size} binary={true} />
|
||||
</div>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
Original + normalized files
|
||||
|
||||
Reference in New Issue
Block a user