WorkoutCard
workoutcard-1779394643348.tsx
'use client'
import { useState, useEffect } from 'react'
const EXERCISES = [
{ name:'Push-ups', sets:3, reps:15, rest:60, emoji:'💪' },
{ name:'Squats', sets:4, reps:12, rest:90, emoji:'🦵' },
{ name:'Plank', sets:3, reps:1, rest:60, emoji:'🏋️', duration:60 },
]
export default function WorkoutCard({ exercises = EXERCISES }) {
const [current, setCurrent] = useState(0)
const [completedSets, setCompletedSets] = useState({})
const [resting, setResting] = useState(false)
const [restTimer, setRestTimer] = useState(0)
const ex = exercises[current]
const done = completedSets[current] || 0
const completeSet = () => {
const next = done + 1
setCompletedSets(c => ({ ...c, [current]:next }))
if (next < ex.sets) { setResting(true); setRestTimer(ex.rest) }
else if (current < exercises.length-1) setTimeout(() => setCurrent(c => c+1), 500)
}
useEffect(() => {
if (!resting) return
const t = setInterval(() => setRestTimer(r => { if (r<=1){ setResting(false); return 0 } return r-1 }), 1000)
return () => clearInterval(t)
}, [resting])
const allDone = current === exercises.length-1 && done >= ex.sets
return (
<div style={{ background:'#1e1e2e', borderRadius:'20px', padding:'24px', maxWidth:'320px', color:'#fff' }}>
<div style={{ display:'flex', justifyContent:'space-between', alignItems:'center', marginBottom:'20px' }}>
<div style={{ fontSize:'12px', color:'#94a3b8' }}>Exercise {current+1}/{exercises.length}</div>
<div style={{ display:'flex', gap:'4px' }}>
{exercises.map((_,i)=>(
<div key={i} style={{ width:'8px', height:'8px', borderRadius:'50%', background:i<current?'#10b981':i===current?'#6d28d9':'#2d2d3d' }}/>
))}
</div>
</div>
{allDone ? (
<div style={{ textAlign:'center', padding:'20px 0' }}>
<div style={{ fontSize:'48px', marginBottom:'12px' }}>🏆</div>
<h3 style={{ margin:'0 0 6px', color:'#f59e0b' }}>Workout Complete!</h3>
<p style={{ color:'#94a3b8', fontSize:'13px', margin:0 }}>Great job! {exercises.length} exercises done.</p>
</div>
) : resting ? (
<div style={{ textAlign:'center', padding:'10px 0 20px' }}>
<div style={{ fontSize:'48px', marginBottom:'8px' }}>⏱️</div>
<div style={{ fontSize:'40px', fontWeight:900, color:'#a78bfa', marginBottom:'6px' }}>{restTimer}s</div>
<div style={{ color:'#94a3b8', fontSize:'13px' }}>Rest time...</div>
</div>
) : (
<>
<div style={{ textAlign:'center', marginBottom:'20px' }}>
<div style={{ fontSize:'48px', marginBottom:'8px' }}>{ex.emoji}</div>
<h3 style={{ margin:'0 0 4px', fontSize:'20px', fontWeight:700 }}>{ex.name}</h3>
<div style={{ color:'#94a3b8', fontSize:'13px' }}>{ex.sets} sets × {ex.reps} {ex.duration?'sec':'reps'}</div>
</div>
<div style={{ display:'flex', gap:'6px', marginBottom:'20px', justifyContent:'center' }}>
{Array.from({length:ex.sets}).map((_,i)=>(
<div key={i} style={{ width:'32px', height:'32px', borderRadius:'8px', background:i<done?'#10b981':i===done?'#6d28d9':'#2d2d3d', display:'flex', alignItems:'center', justifyContent:'center', fontSize:'14px' }}>{i<done?'✓':i+1}</div>
))}
</div>
<button onClick={completeSet} disabled={done>=ex.sets} style={{
width:'100%', padding:'14px', border:'none', borderRadius:'12px', fontWeight:700, cursor:'pointer', fontSize:'16px',
background:done>=ex.sets?'#2d2d3d':'linear-gradient(135deg,#6d28d9,#2563eb)', color:'#fff',
}}>Complete Set {done+1}</button>
</>
)}
</div>
)
}Component info
CategoryHealth
Frameworkreact
TierFREE
Views0
Copies0
About
Exercise/workout card with sets, reps, timer and completion tracking
More from Health
'use client'
import { useState } from 'react'
const METRICS = [
{ label: 'Steps', value: 8432, goal: 10000, unit: 'steps', color: '#22c55e', icon: '👟' },
{ label: 'Calories', value: 1840, goal: 2200, unit: 'kcal', color: '#f59e0b', icon: '🔥' }HealthDashboard
Health
'use client';
import { useEffect, useState } from 'react';
export default function HeatRingChart() {
const [progress, setProgress] = useState([0, 0, 0]);
const goals = [
{ label: 'Move', value: 78, goal: 100, color: '#ef4444' },
{ label:HeatRingChart
Health
'use client'
import { useState } from 'react'
function Ring({ value, max, color, size = 80, label, sublabel }) {
const R = size/2-8, C = 2*Math.PI*R
const pct = Math.min(value/max, 1)
return (
<div style={{ textAlign:'center' }}>
<svHealthMetrics
Health