abbashkyt-creator 7d8ce0e322 V0.1
2026-03-14 04:02:22 +03:00

147 lines
4.8 KiB
TypeScript

'use client'
import { motion } from 'framer-motion'
import { cn } from '@/lib/utils'
interface Props {
scanned: number
alerts: number
keywords: number
uptime: string
}
const CARDS = [
{
id: 'scanned',
label: 'Lots Scanned',
sub: 'Processed this session',
gradFrom: '#00e87b',
gradTo: '#06b6d4',
icon: (
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
<circle cx="11" cy="11" r="8"/><path d="m21 21-4.35-4.35"/>
</svg>
),
},
{
id: 'alerts',
label: 'Alerts Fired',
sub: 'Qualifying matches',
gradFrom: '#fbbf24',
gradTo: '#f59e0b',
icon: (
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
<path d="M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9"/><path d="M13.73 21a2 2 0 0 1-3.46 0"/>
</svg>
),
},
{
id: 'keywords',
label: 'Active Targets',
sub: 'Keyword strategies',
gradFrom: '#a78bfa',
gradTo: '#3b82f6',
icon: (
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
<path d="M20.59 13.41l-7.17 7.17a2 2 0 0 1-2.83 0L2 12V2h10l8.59 8.59a2 2 0 0 1 0 2.82z"/><line x1="7" y1="7" x2="7.01" y2="7"/>
</svg>
),
},
{
id: 'uptime',
label: 'Engine Uptime',
sub: 'Continuous runtime',
gradFrom: '#3b82f6',
gradTo: '#06b6d4',
icon: (
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
<circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/>
</svg>
),
},
]
export default function StatsGrid({ scanned, alerts, keywords, uptime }: Props) {
const values: Record<string, string | number> = {
scanned: String(scanned),
alerts: alerts,
keywords: keywords,
uptime: uptime,
}
return (
<div className="grid grid-cols-2 xl:grid-cols-4 gap-4">
{CARDS.map((card, i) => {
const val = values[card.id]
const isAlert = card.id === 'alerts' && alerts > 0
const accentColor = isAlert ? card.gradFrom : undefined
return (
<motion.div
key={card.id}
initial={{ opacity: 1, y: 18, scale: 0.97 }}
animate={{ opacity: 1, y: 0, scale: 1 }}
transition={{ duration: 0.55, delay: i * 0.07, ease: [0.22, 1, 0.36, 1] }}
className="g-card-glow p-5 flex flex-col gap-3.5 group cursor-default select-none"
>
{/* Top row: label + icon */}
<div className="relative z-10 flex items-start justify-between gap-2">
<span className="text-[10px] font-bold uppercase tracking-[0.14em] text-g-faint leading-none mt-0.5">
{card.label}
</span>
<div
className="shrink-0 w-7 h-7 rounded-lg flex items-center justify-center transition-all duration-300 group-hover:scale-110"
style={{
background: `linear-gradient(135deg, ${card.gradFrom}18, ${card.gradTo}10)`,
border: `1px solid ${card.gradFrom}25`,
color: card.gradFrom,
boxShadow: `0 0 12px ${card.gradFrom}15`,
}}
>
{card.icon}
</div>
</div>
{/* Value */}
<div className="relative z-10">
<span
className={cn(
'g-stat-num transition-colors duration-300',
isAlert ? 'text-g-amber' : 'text-g-text',
)}
style={accentColor ? {} : {}}
>
{val}
</span>
</div>
{/* Sub */}
<p className="relative z-10 text-[10px] text-g-faint/50 leading-none font-medium">
{card.sub}
</p>
{/* Bottom gradient line */}
<div
className="absolute bottom-0 left-0 right-0 h-px opacity-20 group-hover:opacity-40 transition-opacity"
style={{
background: `linear-gradient(90deg, transparent, ${card.gradFrom}80, ${card.gradTo}50, transparent)`,
}}
/>
{/* Alert pulse ring for alerts card when active */}
{isAlert && (
<div
className="absolute top-4 right-4 w-1.5 h-1.5 rounded-full"
style={{
background: card.gradFrom,
boxShadow: `0 0 6px ${card.gradFrom}`,
animation: 'pulse-ring 2s ease-out infinite',
}}
/>
)}
</motion.div>
)
})}
</div>
)
}