Finance
Security Card - Investment Holdings
Monitor investment securities and holdings. Track security performance and portfolio components.
Finance Security Card
The Finance Security Card displays individual security holdings and performance, helping investors track specific investments.
Preview
Installation
npx shadcn@latest add https://vectormotion.vercel.app/registry/finance-security-card.jsonFinance Security Card
"use client"import React, { useState } from 'react';import { ShieldCheck, Smartphone, Lock } from 'lucide-react';import { motion } from 'motion/react';import { clsx, type ClassValue } from "clsx"import { twMerge } from "tailwind-merge"import { ResponsiveContainer, RadialBarChart, RadialBar, PolarAngleAxis } from 'recharts';function cn(...inputs: ClassValue[]) { return twMerge(clsx(inputs))}interface SecurityData { name: string; value: number; fill: string; [key: string]: any;}interface SecurityCardProps { isInteractive?: boolean; className?: string; title?: string; score?: string; scoreLabel?: string; data?: SecurityData[];}const DEFAULT_TITLE = "Security Status";const DEFAULT_SCORE = "92/100";const DEFAULT_SCORE_LABEL = "Secure";const DEFAULT_DATA: SecurityData[] = [{ name: 'Score', value: 92, fill: '#10b981' }]; // Emeraldexport const SecurityCard: React.FC<SecurityCardProps> = ({ isInteractive = true, className = "", title = DEFAULT_TITLE, score = DEFAULT_SCORE, scoreLabel = DEFAULT_SCORE_LABEL, data = DEFAULT_DATA,}) => { const [enabled, setEnabled] = useState(true); const index = 45; return ( <motion.div layoutId={isInteractive ? `card-${index}-${title}` : undefined} transition={{ duration: 0.4, ease: "easeOut" }} className={cn( "relative overflow-hidden rounded-xl border border-border bg-card text-card-foreground p-5 shadow-sm transition-all flex flex-col h-full group", isInteractive ? "cursor-pointer hover:border-primary/50 hover:shadow-md" : "", className )} > <div className="mb-2 flex items-start justify-between relative z-10"> <div> <h3 className="font-semibold text-lg text-foreground"> {title} </h3> <div className="flex items-center gap-2 mt-1"> <span className="text-2xl font-bold text-foreground">{score}</span> <span className="text-xs text-muted-foreground">{scoreLabel}</span> </div> </div> <div className="rounded-lg bg-emerald-500/10 p-2 text-emerald-500"> <ShieldCheck className="h-5 w-5" /> </div> </div> <div className="relative z-10 flex-1 flex items-center justify-center"> <div className="h-28 w-28 relative"> <ResponsiveContainer width="100%" height="100%"> <RadialBarChart cx="50%" cy="50%" innerRadius="70%" outerRadius="100%" barSize={8} data={data} startAngle={90} endAngle={-270} > <PolarAngleAxis type="number" domain={[0, 100]} angleAxisId={0} tick={false} /> <RadialBar background={{ fill: '#f4f4f5' }} dataKey="value" cornerRadius={10} /> </RadialBarChart> </ResponsiveContainer> <div className="absolute inset-0 flex items-center justify-center pointer-events-none"> <ShieldCheck className="w-8 h-8 text-emerald-500" /> </div> </div> </div> <div className="z-10 mt-2 pt-2 border-t border-border flex items-center justify-between text-xs"> <div className="flex items-center gap-1.5 text-muted-foreground"> <Lock className="w-3 h-3" /> 2FA Enabled </div> <motion.button onClick={() => setEnabled(!enabled)} className={`relative h-4 w-8 rounded-full transition-colors duration-200 ease-in-out focus:outline-none ${enabled ? 'bg-emerald-500' : 'bg-zinc-200 dark:bg-zinc-700'}`} > <motion.span layout transition={{ type: "spring", stiffness: 700, damping: 30 }} className={`pointer-events-none block h-3 w-3 transform rounded-full bg-white shadow ring-0 mt-0.5 ml-0.5 ${enabled ? 'translate-x-4' : 'translate-x-0'}`} /> </motion.button> </div> </motion.div> );};Props
Prop
Type
Usage
This component is a demo card displaying security information with animated visualizations and dark mode support.