Finance
Dividend Calendar Card - Dividend Tracking
Monitor dividend payments and schedules. Track dividend history and investor returns.
Finance Dividend Calendar Card
The Finance Dividend Calendar Card displays upcoming dividend payment dates and amounts, helping investors manage their dividend income.
Preview
Installation
npx shadcn@latest add https://vectormotion.vercel.app/registry/finance-dividend-calendar-card.jsonFinance Dividend Calendar Card
'use client'import React from 'react';import { Calendar, CheckCircle2, Clock } from 'lucide-react';import { motion } from 'motion/react';import { clsx, type ClassValue } from "clsx"import { twMerge } from "tailwind-merge"import { ResponsiveContainer, BarChart, Bar, XAxis, Tooltip, Cell } from 'recharts';function cn(...inputs: ClassValue[]) { return twMerge(clsx(inputs))}interface DividendDate { id: number; symbol: string; amount: string; payDate: string; status: string;}interface ChartData { name: string; value: number;}interface DividendCalendarCardProps { isInteractive?: boolean; className?: string; title?: string; totalPayout?: string; payoutLabel?: string; dividends?: DividendDate[]; chartData?: ChartData[];}const DEFAULT_TITLE = "Dividends";const DEFAULT_TOTAL_PAYOUT = "$145.2";const DEFAULT_PAYOUT_LABEL = "Est. Payout";const DEFAULT_DIVIDENDS: DividendDate[] = [ { id: 1, symbol: 'AAPL', amount: '$0.24', payDate: 'Nov 16', status: 'confirmed' }, { id: 2, symbol: 'MSFT', amount: '$0.68', payDate: 'Dec 08', status: 'confirmed' }, { id: 3, symbol: 'KO', amount: '$0.46', payDate: 'Dec 15', status: 'pending' },];const DEFAULT_CHART_DATA: ChartData[] = [ { name: 'Nov', value: 45 }, { name: 'Dec', value: 68 }, { name: 'Jan', value: 52 }, { name: 'Feb', value: 38 },];const container = { hidden: { opacity: 0 }, show: { opacity: 1, transition: { staggerChildren: 0.1 } }};const item = { hidden: { x: -10, opacity: 0 }, show: { x: 0, opacity: 1 }};export const DividendCalendarCard: React.FC<DividendCalendarCardProps> = ({ isInteractive = true, className = "", title = DEFAULT_TITLE, totalPayout = DEFAULT_TOTAL_PAYOUT, payoutLabel = DEFAULT_PAYOUT_LABEL, dividends = DEFAULT_DIVIDENDS, chartData = DEFAULT_CHART_DATA,}) => { const index = 19; 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">{totalPayout}</span> <span className="text-xs text-muted-foreground">{payoutLabel}</span> </div> </div> <div className="rounded-lg bg-emerald-500/10 p-2 text-emerald-500"> <Calendar className="h-5 w-5" /> </div> </div> <div className="relative z-0 h-16 w-full mb-2"> <ResponsiveContainer width="100%" height="100%"> <BarChart data={chartData}> <Tooltip cursor={{ fill: 'transparent' }} contentStyle={{ borderRadius: '8px', border: 'none', backgroundColor: 'var(--tooltip-bg)', color: 'var(--tooltip-text)' }} /> <Bar dataKey="value" radius={[4, 4, 0, 0]} barSize={32}> {chartData.map((entry, index) => ( <Cell key={`cell-${index}`} fill={index === 1 ? '#10b981' : '#e4e4e7'} className={index === 1 ? "fill-emerald-500" : "fill-zinc-200 dark:fill-zinc-700"} /> ))} </Bar> </BarChart> </ResponsiveContainer> </div> <div className="relative z-10 flex-1"> <motion.div className="space-y-2" variants={container} initial="hidden" animate="show" > {dividends.map((div) => ( <motion.div key={div.id} variants={item} whileHover={{ x: 4 }} className="flex items-center justify-between p-1.5 rounded-lg hover:bg-zinc-50 dark:hover:bg-zinc-800/50 transition-colors" > <div className="flex items-center gap-3"> <div className="h-7 w-7 rounded-full bg-zinc-100 dark:bg-zinc-800 flex items-center justify-center font-bold text-[10px] text-foreground"> {div.symbol[0]} </div> <div> <p className="text-xs font-bold text-foreground">{div.symbol}</p> <p className="text-[10px] text-muted-foreground flex items-center gap-1"> {div.status === 'confirmed' ? <CheckCircle2 className="h-2.5 w-2.5 text-emerald-500" /> : <Clock className="h-2.5 w-2.5 text-amber-500" />} {div.payDate} </p> </div> </div> <div className="text-right"> <p className="text-xs font-medium text-foreground">{div.amount}</p> </div> </motion.div> ))} </motion.div> </div> </motion.div> );};Props
Prop
Type