← Components/Finance

CryptoTicker

cryptoticker-1779379195773.tsx
'use client'
import { useState, useEffect } from 'react'

const BASE_PRICES: Record<string, { price: number; change: number; cap: string; icon: string; color: string }> = {
  BTC: { price: 67420, change: 2.4, cap: '1.32T', icon: '₿', color: '#f59e0b' },
  ETH: { price: 3180, change: -1.2, cap: '382B', icon: 'Ξ', color: '#6366f1' },
  SOL: { price: 142, change: 5.8, cap: '63B', icon: '◎', color: '#22c55e' },
  USDC: { price: 1.00, change: 0.01, cap: '32B', icon: '$', color: '#2775ca' },
}

function randomize(v: number, pct = 0.002): number {
  return v * (1 + (Math.random() - 0.5) * pct)
}

export default function CryptoTicker() {
  const [prices, setPrices] = useState(BASE_PRICES)
  const [alerts, setAlerts] = useState<Record<string, boolean>>({})

  useEffect(() => {
    const t = setInterval(() => {
      setPrices(p => Object.fromEntries(
        Object.entries(p).map(([k, v]) => [k, { ...v, price: randomize(v.price), change: v.change + (Math.random() - 0.5) * 0.05 }])
      ))
    }, 2000)
    return () => clearInterval(t)
  }, [])

  return (
    <div style={{ background: '#0D0D0D', border: '1px solid rgba(255,255,255,0.06)', borderRadius: 16, overflow: 'hidden' }}>
      <div style={{ padding: '14px 20px', borderBottom: '1px solid rgba(255,255,255,0.06)', display: 'flex', justifyContent: 'space-between' }}>
        <div style={{ color: '#F5F5F0', fontSize: 15, fontWeight: 600 }}>Crypto Markets</div>
        <div style={{ display: 'flex', alignItems: 'center', gap: 4 }}>
          <span style={{ width: 6, height: 6, borderRadius: '50%', background: '#22c55e', display: 'inline-block', animation: 'pulse 2s infinite' }} />
          <span style={{ color: 'rgba(255,255,255,0.35)', fontSize: 12 }}>Live</span>
        </div>
      </div>

      {Object.entries(prices).map(([symbol, data]) => (
        <div key={symbol} style={{ display: 'flex', alignItems: 'center', padding: '14px 20px', borderBottom: '1px solid rgba(255,255,255,0.04)' }}>
          <div style={{ width: 36, height: 36, borderRadius: '50%', background: data.color + '18', border: `1px solid ${data.color}30`, display: 'flex', alignItems: 'center', justifyContent: 'center', color: data.color, fontWeight: 800, fontSize: 15, marginRight: 12, flexShrink: 0 }}>
            {data.icon}
          </div>
          <div style={{ flex: 1, minWidth: 0 }}>
            <div style={{ color: '#F5F5F0', fontSize: 14, fontWeight: 600 }}>{symbol}</div>
            <div style={{ color: 'rgba(255,255,255,0.35)', fontSize: 11 }}>Market cap: ${data.cap}</div>
          </div>
          <div style={{ textAlign: 'right', marginRight: 14 }}>
            <div style={{ color: '#F5F5F0', fontSize: 15, fontWeight: 700, fontVariantNumeric: 'tabular-nums' }}>
              ${symbol === 'USDC' ? data.price.toFixed(2) : data.price >= 1000 ? data.price.toLocaleString('en', { maximumFractionDigits: 0 }) : data.price.toFixed(2)}
            </div>
            <div style={{ color: data.change >= 0 ? '#22c55e' : '#ef4444', fontSize: 12, fontWeight: 600 }}>
              {data.change >= 0 ? '+' : ''}{data.change.toFixed(2)}%
            </div>
          </div>
          <button onClick={() => setAlerts(a => ({ ...a, [symbol]: !a[symbol] }))}
            style={{ background: alerts[symbol] ? 'rgba(201,168,76,0.12)' : 'rgba(255,255,255,0.04)', border: '1px solid', borderColor: alerts[symbol] ? 'rgba(201,168,76,0.25)' : 'rgba(255,255,255,0.08)', borderRadius: 6, padding: '4px 8px', cursor: 'pointer', fontSize: 14 }}>
            {alerts[symbol] ? '🔔' : '🔕'}
          </button>
        </div>
      ))}
      <style>{`@keyframes pulse { 0%,100% { opacity:1 } 50% { opacity:0.3 } }`}</style>
    </div>
  )
}

Component info

CategoryFinance
Frameworkreact
TierFREE
Views0
Copies0

About

Live crypto price ticker with sparklines, price alerts, percentage changes, and market cap