feat: add pitch-deck service to core infrastructure
Migrated pitch-deck from breakpilot-pwa to breakpilot-core. Container: bp-core-pitch-deck on port 3012. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
59
pitch-deck/components/ui/KPICard.tsx
Normal file
59
pitch-deck/components/ui/KPICard.tsx
Normal file
@@ -0,0 +1,59 @@
|
||||
'use client'
|
||||
|
||||
import { motion } from 'framer-motion'
|
||||
import { TrendingUp, TrendingDown } from 'lucide-react'
|
||||
import AnimatedCounter from './AnimatedCounter'
|
||||
|
||||
interface KPICardProps {
|
||||
label: string
|
||||
value: number
|
||||
prefix?: string
|
||||
suffix?: string
|
||||
decimals?: number
|
||||
trend?: 'up' | 'down' | 'neutral'
|
||||
color?: string
|
||||
delay?: number
|
||||
subLabel?: string
|
||||
}
|
||||
|
||||
export default function KPICard({
|
||||
label,
|
||||
value,
|
||||
prefix = '',
|
||||
suffix = '',
|
||||
decimals = 0,
|
||||
trend = 'neutral',
|
||||
color = '#6366f1',
|
||||
delay = 0,
|
||||
subLabel,
|
||||
}: KPICardProps) {
|
||||
return (
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.5, delay }}
|
||||
className="relative overflow-hidden bg-white/[0.06] backdrop-blur-xl border border-white/10 rounded-2xl p-4"
|
||||
>
|
||||
{/* Glow effect */}
|
||||
<div
|
||||
className="absolute -top-8 -right-8 w-24 h-24 rounded-full blur-3xl opacity-20"
|
||||
style={{ backgroundColor: color }}
|
||||
/>
|
||||
|
||||
<p className="text-[10px] uppercase tracking-wider text-white/40 mb-1">{label}</p>
|
||||
<div className="flex items-end gap-2">
|
||||
<p className="text-2xl font-bold text-white leading-none">
|
||||
<AnimatedCounter target={value} prefix={prefix} suffix={suffix} duration={1200} decimals={decimals} />
|
||||
</p>
|
||||
{trend !== 'neutral' && (
|
||||
<span className={`flex items-center gap-0.5 text-xs pb-0.5 ${trend === 'up' ? 'text-emerald-400' : 'text-red-400'}`}>
|
||||
{trend === 'up' ? <TrendingUp className="w-3 h-3" /> : <TrendingDown className="w-3 h-3" />}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
{subLabel && (
|
||||
<p className="text-[10px] text-white/30 mt-1">{subLabel}</p>
|
||||
)}
|
||||
</motion.div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user