← Components/Health

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' }}>
      <sv
HealthMetrics
Health