mirror of
https://github.com/woodchen-ink/nezha-dash-v1.git
synced 2025-07-18 17:41:56 +08:00
80 lines
3.0 KiB
TypeScript
80 lines
3.0 KiB
TypeScript
import { formatBytes } from "@/lib/format"
|
|
import { cn } from "@/lib/utils"
|
|
import React from "react"
|
|
import { useTranslation } from "react-i18next"
|
|
|
|
interface CycleTransferStatsClientProps {
|
|
name: string
|
|
from: string
|
|
to: string
|
|
max: number
|
|
serverStats: Array<{
|
|
serverId: string
|
|
serverName: string
|
|
transfer: number
|
|
nextUpdate: string
|
|
}>
|
|
className?: string
|
|
}
|
|
|
|
export const CycleTransferStatsClient: React.FC<CycleTransferStatsClientProps> = ({ name, from, to, max, serverStats, className }) => {
|
|
const { t } = useTranslation()
|
|
const customBackgroundImage = (window.CustomBackgroundImage as string) !== "" ? window.CustomBackgroundImage : undefined
|
|
return (
|
|
<div
|
|
className={cn(
|
|
"w-full bg-white px-4 py-3.5 rounded-lg border bg-card text-card-foreground hover:shadow-sm transition-all duration-200 dark:shadow-none",
|
|
className,
|
|
{
|
|
"bg-card/70": customBackgroundImage,
|
|
},
|
|
)}
|
|
>
|
|
{serverStats.map(({ serverId, serverName, transfer, nextUpdate }) => {
|
|
const progress = (transfer / max) * 100
|
|
|
|
return (
|
|
<div key={serverId} className="space-y-3">
|
|
{/* Header */}
|
|
<div className="flex items-center justify-between">
|
|
<span className="text-sm font-medium text-neutral-800 dark:text-neutral-200">{serverName}</span>
|
|
<div className="bg-emerald-500/10 text-emerald-600 dark:text-emerald-400 px-2 py-0.5 rounded text-xs font-medium">{name}</div>
|
|
</div>
|
|
|
|
{/* Progress Section */}
|
|
<div className="space-y-1.5">
|
|
<div className="flex items-center justify-between">
|
|
<div className="flex items-baseline gap-1">
|
|
<span className="text-sm font-medium text-neutral-800 dark:text-neutral-200">{formatBytes(transfer)}</span>
|
|
<span className="text-xs text-neutral-500 dark:text-neutral-400">/ {formatBytes(max)}</span>
|
|
</div>
|
|
<span className="text-xs font-medium text-neutral-600 dark:text-neutral-300">{progress.toFixed(1)}%</span>
|
|
</div>
|
|
|
|
<div className="relative h-1.5">
|
|
<div className="absolute inset-0 bg-neutral-100 dark:bg-neutral-800 rounded-full" />
|
|
<div
|
|
className="absolute inset-0 bg-emerald-500 rounded-full transition-all duration-300"
|
|
style={{ width: `${Math.min(progress, 100)}%` }}
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Footer */}
|
|
<div className="flex items-center justify-between text-[11px] text-neutral-500 dark:text-neutral-400">
|
|
<span>
|
|
{new Date(from).toLocaleDateString()} - {new Date(to).toLocaleDateString()}
|
|
</span>
|
|
<span>
|
|
{t("cycleTransfer.nextUpdate")}: {new Date(nextUpdate).toLocaleString()}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
)
|
|
})}
|
|
</div>
|
|
)
|
|
}
|
|
|
|
export default CycleTransferStatsClient
|