AI/ML
Training Progress Card - ML Model Training
Track machine learning model training progress, epochs, and convergence. Monitor training loss and validation metrics in real-time.
Training Progress Card
The Training Progress Card displays real-time training progress including epochs, loss, and estimated time remaining.
Preview
Installation
npx shadcn@latest add https://vectormotion.vercel.app/registry/training-progress-card.jsonTraining Progress Card
'use client'import React from 'react';import { Loader2, Timer, TrendingDown } from 'lucide-react';import { motion } from 'motion/react';import { clsx, type ClassValue } from "clsx"import { twMerge } from "tailwind-merge"import { ResponsiveContainer, PieChart, Pie, Cell, Tooltip } from 'recharts';function cn(...inputs: ClassValue[]) { return twMerge(clsx(inputs))}interface ProgressData { name: string; value: number; fill: string; [key: string]: any;}interface TrainingProgressCardProps { className?: string; title?: string; status?: string; epochLabel?: string; data?: ProgressData[]; progressValue?: string; lossValue?: string; elapsedTime?: string; remainingTime?: string;}const DEFAULT_DATA: ProgressData[] = [ { name: 'Completed', value: 42, fill: '#3b82f6' }, // Blue-500 { name: 'Remaining', value: 58, fill: '#e4e4e7' }, // Zinc-200];const DEFAULT_TITLE = "Training";const DEFAULT_STATUS = "Running";const DEFAULT_EPOCH_LABEL = "Epoch 42/100";const DEFAULT_PROGRESS_VALUE = "42%";const DEFAULT_LOSS_VALUE = "0.34";const DEFAULT_ELAPSED_TIME = "2h 14m";const DEFAULT_REMAINING_TIME = "~3h 05m";export const TrainingProgressCard: React.FC<TrainingProgressCardProps> = ({ className = "", title = DEFAULT_TITLE, status = DEFAULT_STATUS, epochLabel = DEFAULT_EPOCH_LABEL, data = DEFAULT_DATA, progressValue = DEFAULT_PROGRESS_VALUE, lossValue = DEFAULT_LOSS_VALUE, elapsedTime = DEFAULT_ELAPSED_TIME, remainingTime = DEFAULT_REMAINING_TIME,}) => { return ( <motion.div initial={{ opacity: 0, y: 20 }} animate={{ opacity: 1, y: 0 }} transition={{ duration: 0.5, delay: 0.1 }} className={cn( "relative overflow-hidden rounded-2xl border border-border bg-card text-card-foreground shadow-sm transition-all hover:border-blue-300 dark:hover:border-blue-700 hover:shadow-md flex flex-col h-full", className )} > <div className="p-5 flex flex-col h-full relative z-10"> <div className="mb-2 flex items-start justify-between"> <div> <div className="flex items-center gap-2 mb-1"> <span className="inline-flex items-center gap-1.5 px-2 py-0.5 rounded-full text-xs font-medium bg-blue-50 text-blue-600 dark:bg-blue-900/20 dark:text-blue-400 border border-blue-100 dark:border-blue-800"> <Loader2 className="w-3 h-3 animate-spin" /> {status} </span> </div> <h3 className="font-bold text-lg text-foreground"> {title} </h3> <p className="text-sm text-muted-foreground font-medium"> {epochLabel} </p> </div> <div className="rounded-lg border-2 border-blue-100 dark:border-blue-800 p-2 text-blue-500 dark:text-blue-400 flex items-center justify-center"> <Timer className="h-5 w-5" /> </div> </div> <div className="flex-1 w-full min-h-[140px] relative"> <ResponsiveContainer width="100%" height="100%"> <PieChart> <Pie data={data} cx="50%" cy="50%" innerRadius={45} outerRadius={65} startAngle={90} endAngle={-270} paddingAngle={0} dataKey="value" stroke="none" cornerRadius={5} > {data.map((entry, index) => ( <Cell key={`cell-${index}`} fill={entry.fill} /> ))} </Pie> <Tooltip cursor={false} content={() => null} /> </PieChart> </ResponsiveContainer> <div className="absolute inset-0 flex flex-col items-center justify-center pointer-events-none"> <span className="text-3xl font-bold text-foreground">{progressValue}</span> <div className="flex items-center gap-0.5 text-xs text-muted-foreground"> <span>Loss: {lossValue}</span> <TrendingDown className="w-3 h-3 text-emerald-500" /> </div> </div> </div> <div className="mt-2 grid grid-cols-2 gap-2"> <div className="p-2 rounded bg-muted border border-border text-center"> <div className="text-[10px] text-muted-foreground text-left">Elapsed</div> <div className="text-sm font-bold text-foreground text-left">{elapsedTime}</div> <div className="w-full h-1 bg-zinc-200 dark:bg-zinc-700 rounded-full mt-1 overflow-hidden"> <div className="h-full bg-blue-400 w-1/2" /> </div> </div> <div className="p-2 rounded bg-muted border border-border text-center"> <div className="text-[10px] text-muted-foreground text-left">Remaining</div> <div className="text-sm font-bold text-foreground text-left">{remainingTime}</div> <div className="w-full h-1 bg-zinc-200 dark:bg-zinc-700 rounded-full mt-1 overflow-hidden"> <div className="h-full bg-zinc-400 w-3/4" /> </div> </div> </div> <div className="absolute -bottom-4 -right-4 z-0 opacity-5 pointer-events-none"> <Loader2 className="w-40 h-40 text-blue-500" /> </div> </div> </motion.div> );};Props
Prop
Type
Usage
This component is a demo card displaying training progress with animated visualizations and dark mode support.