โ† Components/Health

HealthDashboard

healthdashboard-1779379195787.tsx
'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: '๐Ÿ”ฅ' },
  { label: 'Water', value: 1.8, goal: 2.5, unit: 'L', color: '#3b82f6', icon: '๐Ÿ’ง' },
  { label: 'Sleep', value: 7.2, goal: 8, unit: 'hrs', color: '#8b5cf6', icon: '๐Ÿ˜ด' },
]

const WEEK = ['M','T','W','T','F','S','S']
const STEPS_WEEK = [6200, 9100, 7800, 10200, 8400, 11000, 8432]

function Ring({ value, goal, color, size = 80 }: { value: number; goal: number; color: string; size?: number }) {
  const r = (size - 12) / 2, circ = 2 * Math.PI * r
  const pct = Math.min(value / goal, 1)
  return (
    <svg width={size} height={size} viewBox={`0 0 ${size} ${size}`}>
      <circle cx={size/2} cy={size/2} r={r} fill="none" stroke="rgba(255,255,255,0.06)" strokeWidth={6} />
      <circle cx={size/2} cy={size/2} r={r} fill="none" stroke={color} strokeWidth={6}
        strokeDasharray={circ} strokeDashoffset={circ * (1 - pct)} strokeLinecap="round" transform={`rotate(-90 ${size/2} ${size/2})`}
        style={{ transition: 'stroke-dashoffset 0.6s ease' }} />
    </svg>
  )
}

export default function HealthDashboard() {
  const [day, setDay] = useState(6)
  const maxStep = Math.max(...STEPS_WEEK)

  return (
    <div style={{ background: '#080808', padding: 24, display: 'flex', flexDirection: 'column', gap: 16 }}>
      {/* Rings */}
      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 10 }}>
        {METRICS.map(m => (
          <div key={m.label} style={{ background: '#0F0F0F', border: '1px solid rgba(255,255,255,0.06)', borderRadius: 14, padding: 16, display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 8 }}>
            <div style={{ position: 'relative', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
              <Ring value={m.value} goal={m.goal} color={m.color} />
              <span style={{ position: 'absolute', fontSize: 18 }}>{m.icon}</span>
            </div>
            <div style={{ textAlign: 'center' }}>
              <div style={{ color: '#F5F5F0', fontSize: 15, fontWeight: 700 }}>{m.value < 10 ? m.value.toFixed(1) : Math.round(m.value).toLocaleString()}</div>
              <div style={{ color: 'rgba(255,255,255,0.3)', fontSize: 10 }}>{m.label} ยท {m.unit}</div>
              <div style={{ color: m.color, fontSize: 10, marginTop: 2 }}>{Math.round(m.value / m.goal * 100)}%</div>
            </div>
          </div>
        ))}
      </div>

      {/* Weekly Steps */}
      <div style={{ background: '#0F0F0F', border: '1px solid rgba(255,255,255,0.06)', borderRadius: 14, padding: 20 }}>
        <div style={{ color: '#F5F5F0', fontSize: 14, fontWeight: 600, marginBottom: 16 }}>Weekly Steps</div>
        <div style={{ display: 'flex', gap: 8, alignItems: 'flex-end', height: 80 }}>
          {STEPS_WEEK.map((v, i) => (
            <div key={i} onClick={() => setDay(i)} style={{ flex: 1, display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 4, cursor: 'pointer' }}>
              <div style={{ width: '100%', background: day === i ? '#22c55e' : v >= 10000 ? 'rgba(34,197,94,0.3)' : 'rgba(255,255,255,0.08)', borderRadius: '4px 4px 0 0', height: `${(v / maxStep) * 64}px`, transition: 'background 0.2s' }} />
              <span style={{ color: day === i ? '#22c55e' : 'rgba(255,255,255,0.3)', fontSize: 11 }}>{WEEK[i]}</span>
            </div>
          ))}
        </div>
        {day !== null && (
          <div style={{ marginTop: 12, color: 'rgba(255,255,255,0.5)', fontSize: 12, textAlign: 'center' }}>
            {WEEK[day]}day: <strong style={{ color: '#F5F5F0' }}>{STEPS_WEEK[day].toLocaleString()}</strong> steps {STEPS_WEEK[day] >= 10000 ? '๐ŸŽฏ' : ''}
          </div>
        )}
      </div>
    </div>
  )
}

Component info

CategoryHealth
Frameworkreact
TierFREE
Views0
Copies0

About

Health metrics dashboard with circular progress rings, weekly trend chart, and goal tracking