Skip to content

Dashboard System

Comprehensive dashboard featuring KPI metrics, data visualization, responsive grid layouts, and interactive components built with React 19 and ApexCharts.

StatCard Components ApexCharts Integration Grid Layout

Modular dashboard components with responsive grid layouts and centralized data management:

Core Components

  • StatCard - KPI metrics with trend indicators
  • RecentOrders - Data tables with actions
  • Charts - ApexCharts data visualizations
  • Grid Layout - Responsive 8-column system

Key Features

  • Mock data simulation for development
  • Interactive tooltips and dropdowns
  • Theme-aware chart components
  • Mobile-first responsive design

The dashboard uses an 8-column responsive grid system to organize KPI cards and visualization components:

Dashboard Layout
// Dashboard main structure
export default function Dashboard() {
const cardDataList: StatCardData[] = [
{
name: 'Page Views',
value: 12450,
iconName: 'lucide:eye',
description: 'Total page visits within selected timeframe',
percentage: '0.4%',
isMoney: false,
percentageType: 'down',
},
{
name: 'Total Revenue',
value: 9863,
iconName: 'material-symbols:monetization-on-outline-rounded',
description: 'Aggregated revenue from all channels',
percentage: '13.5%',
isMoney: true,
percentageType: 'up',
}
// Additional cards...
]
return (
<div className="grid grid-cols-4 xl:grid-cols-8 gap-6 items-start">
{cardDataList.map((item) => (
<StatCard
key={item.name}
data={item}
className="col-span-4 sm:col-span-2"
/>
))}
<RecentOrders className="col-span-4 xl:col-span-5" />
<TopReferralSources className="col-span-4 lg:col-span-2 xl:col-span-3" />
<MonthlyRevenueComparison className="col-span-4 xl:col-span-5" />
</div>
)
}

KPI metric cards with interactive tooltips and trend indicators:

Key Features:

  • Iconify icon integration for visual indicators
  • Interactive tooltips with detailed descriptions
  • Trend visualization with color-coded percentages
  • Money formatting support with currency symbols
  • Dark mode compatibility
StatCard Structure
// StatCard interface and key props
export interface StatCardData {
name: string
value: number | string
iconName: string
description: string
percentage: string
isMoney: boolean
percentageType: 'up' | 'down'
}
// StatCard with tooltip and trend indicator
export default function StatCard({ data, className }: StatCardProps) {
return (
<Card className={cn('p-5', className)}>
<div className="flex items-center">
<span className="bg-gray-100 dark:bg-gray-500/50 p-1 rounded-sm">
<Icon className="text-sm" icon={data.iconName} />
</span>
<span className="ps-2">{data.name}</span>
{/* Interactive tooltip with description */}
<TooltipProvider>
<Tooltip>
<TooltipTrigger className="ms-auto">
<Icon icon="majesticons:exclamation-circle-line" />
</TooltipTrigger>
<TooltipContent className="max-w-70">
{data.description}
</TooltipContent>
</Tooltip>
</TooltipProvider>
</div>
{/* Value and percentage display */}
<div className="text-2xl font-medium flex items-center">
<span>
{data.isMoney && '$'}{formatNumber(data.value)}
</span>
<TrendBadge percentage={data.percentage} type={data.percentageType} />
</div>
</Card>
)
}

Recent Orders table with avatar integration and action dropdowns:

Table Features:

  • Customer avatars from external service
  • Interactive dropdown menus for actions
  • Responsive table layout with truncated text
  • Styled table headers with background colors
Recent Orders Table
// Recent Orders table component
export default function RecentOrders({ className }) {
const tableDataList = [
{ id: '#1044', customer: 'Daniel Zhang', amount: '$199.00', date: 'Jul 23' },
{ id: '#1043', customer: 'Emma Watson', amount: '$59.99', date: 'Jul 23' },
// Additional orders...
]
return (
<Card className={className}>
<CardHeader className="flex flex-row items-center justify-between">
<CardTitle>Recent Orders</CardTitle>
<div className="cursor-pointer text-muted-foreground hover:text-gray-700">
See All <Icon icon="formkit:right" />
</div>
</CardHeader>
<CardContent>
<Table>
<TableHeader className="bg-gray-100 dark:bg-gray-800">
<TableRow className="border-none">
<TableHead>Order ID</TableHead>
<TableHead>Customer</TableHead>
<TableHead>Amount</TableHead>
<TableHead>Date</TableHead>
<TableHead></TableHead>
</TableRow>
</TableHeader>
<TableBody>
{tableDataList.map((item, index) => (
<TableRow key={item.id} className="border-dashed">
<TableCell>{item.id}</TableCell>
<TableCell>
<div className="flex items-center">
<Avatar className="size-7 me-1">
<AvatarImage
src={`https://vertaui.com/avatar/cartoon/${index + 5}.png`}
/>
</Avatar>
<span className="max-w-40 truncate">{item.customer}</span>
</div>
</TableCell>
<TableCell>{item.amount}</TableCell>
<TableCell>{item.date}</TableCell>
<TableCell>
<ActionsDropdown item={item} />
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</CardContent>
</Card>
)
}

Interactive area chart with year selection and data comparison:

Chart Features:

  • Dynamic data generation based on selected year
  • Memoized chart options and series for performance
  • Interactive year selector with current year awareness
  • Legend with color indicators and totals
  • Responsive chart sizing
Revenue Chart Implementation
// Monthly Revenue Chart with ApexCharts
export default function MonthlyRevenueComparison({ className }) {
const [selectedYear, setSelectedYear] = useState('2025')
// Generate mock data based on selected year
const generateYearlyData = (year: number) => {
const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
const currentYear = new Date().getFullYear()
const endMonth = year === currentYear ? new Date().getMonth() : 11
return Array.from({ length: endMonth + 1 }, (_, i) => ({
month: months[i],
actual: Math.floor(Math.random() * 5000) + 5000,
target: Math.floor(Math.random() * 3000) + 5000,
}))
}
// Memoized data and chart configuration
const dataList = useMemo(() => generateYearlyData(+selectedYear), [selectedYear])
const chartOptions = useMemo(() => ({
xaxis: { categories: dataList.map(item => item.month) },
}), [dataList])
const chartSeries = useMemo(() => [
{ name: 'Actual', data: dataList.map(item => item.actual) },
{ name: 'Target', data: dataList.map(item => item.target) },
], [dataList])
return (
<Card className={className}>
<CardHeader className="flex flex-row items-center justify-between">
<CardTitle>Monthly Revenue Comparison</CardTitle>
<Select value={selectedYear} onValueChange={setSelectedYear}>
<SelectTrigger className="w-30">
<SelectValue placeholder="Select year" />
</SelectTrigger>
<SelectContent>
<SelectItem value="2024">2024</SelectItem>
<SelectItem value="2025">2025</SelectItem>
</SelectContent>
</Select>
</CardHeader>
<CardContent>
{/* Chart legend with totals */}
<div className="flex items-center gap-x-6 pt-3">
<LegendItem
color="bg-primary"
label="Total actual"
value={formatCompactNumber(totalActual)}
/>
<LegendItem
color="bg-chart-1"
label="Total target"
value={formatCompactNumber(totalTarget)}
/>
</div>
<AreaChart className="h-85" options={chartOptions} series={chartSeries} />
</CardContent>
</Card>
)
}
  1. Dashboard Grid Layout Create responsive 8-column grid system using Tailwind CSS classes

  2. StatCard Components Implement KPI cards with Iconify icons, tooltips, and trend indicators

  3. Data Table Components Build tables with avatars, dropdown actions, and styled headers

  4. ApexCharts Integration Add interactive charts with memoized options and dynamic data

  5. Responsive Breakpoints Configure mobile-first responsive behavior across device sizes

Flexible 8-column grid with mobile-first breakpoints:

  • col-span-4 - Full width KPI cards
  • Single column stack layout
  • Touch-optimized table interactions
  • Simplified chart views

Dashboard components use structured mock data for development and testing:

Data Structures
// Dashboard data structure
const cardDataList: StatCardData[] = [
{
name: 'Page Views',
value: 12450,
iconName: 'lucide:eye',
description: 'Total page visits within selected timeframe',
percentage: '0.4%',
isMoney: false,
percentageType: 'down',
},
{
name: 'Total Revenue',
value: 9863,
iconName: 'material-symbols:monetization-on-outline-rounded',
description: 'Aggregated revenue from all channels',
percentage: '13.5%',
isMoney: true,
percentageType: 'up',
}
// Additional metrics...
]
// Table mock data
const tableDataList = [
{ id: '#1044', customer: 'Daniel Zhang', amount: '$199.00', date: 'Jul 23' },
{ id: '#1043', customer: 'Emma Watson', amount: '$59.99', date: 'Jul 23' }
// Additional orders...
]

Dynamic chart data with year-aware generation logic:

Chart Data Generation
// Dynamic chart data generation
const generateYearlyData = (year: number) => {
const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
const currentYear = new Date().getFullYear()
const currentMonth = new Date().getMonth()
const endMonth = year === currentYear ? currentMonth : 11
const data = []
for (let i = 0; i <= endMonth; i++) {
data.push({
month: months[i],
actual: Math.floor(Math.random() * 5000) + 5000,
target: Math.floor(Math.random() * 3000) + 5000,
})
}
return data
}
// Memoized usage in components
const dataList = useMemo(() => generateYearlyData(+selectedYear), [selectedYear])
const totalActual = useMemo(() =>
dataList.reduce((sum, item) => sum + item.actual, 0), [dataList]
)

Optimized rendering with strategic memoization:

Memoization Strategies
// Memoized chart configuration
const chartOptions: ApexOptions = useMemo(() => ({
xaxis: {
categories: dataList.map((item) => item.month),
},
}), [dataList])
const chartSeries = useMemo(() => [
{ name: 'Actual', data: dataList.map((item) => item.actual) },
{ name: 'Target', data: dataList.map((item) => item.target) },
], [dataList])
// Memoized calculations
const totalActual = useMemo(() =>
dataList.reduce((sum, item) => sum + item.actual, 0), [dataList]
)
const totalTarget = useMemo(() =>
dataList.reduce((sum, item) => sum + item.target, 0), [dataList]
)
// Component memoization for stable props
const StatCard = memo(({ data, className }: StatCardProps) => {
return (
<Card className={cn('p-5', className)}>
{/* Component content */}
</Card>
)
})

Contextual help tooltips with backdrop blur effects:

Tooltip Implementation
// Enhanced tooltip with backdrop blur
<TooltipProvider>
<Tooltip>
<TooltipTrigger className="ms-auto text-muted-foreground">
<Icon icon="majesticons:exclamation-circle-line" />
</TooltipTrigger>
<TooltipContent
className="max-w-70 bg-foreground/85 backdrop-blur-[2px]"
side="left"
>
{data.description}
</TooltipContent>
</Tooltip>
</TooltipProvider>

External avatar service integration with fallback handling:

Avatar Components
// Avatar with external service
<Avatar className="size-7 me-1 inline-block">
<AvatarImage
src={`https://vertaui.com/avatar/cartoon/${index + 5}.png?id=1`}
alt="avatar"
/>
<AvatarFallback>
{customer.split(' ').map(n => n[0]).join('').toUpperCase()}
</AvatarFallback>
</Avatar>
  • TypeScript interfaces for all data structures and props
  • Modular design with reusable StatCard and table components
  • Responsive grid system using Tailwind CSS classes
  • Memoization for expensive calculations and chart configurations
  • Use useMemo for chart options and data calculations
  • Implement React.memo for components with stable props
  • Optimize re-renders with strategic memoization
  • Leverage external avatar services for user images
  • Interactive tooltips for contextual information
  • Loading states and smooth transitions
  • Responsive design across all device sizes
  • Accessible keyboard navigation and ARIA labels

The dashboard provides a solid foundation for data-rich admin interfaces with modern React patterns and performance optimizations.