turash/bugulma/frontend/components/admin/ChartCard.tsx
2025-12-15 10:06:41 +01:00

72 lines
2.0 KiB
TypeScript

import React from 'react';
import { clsx } from 'clsx';
import { Download, RefreshCw } from 'lucide-react';
import { Card, CardContent, CardHeader, CardTitle, CardDescription } from '@/components/ui/Card';
import { Button } from '@/components/ui';
export interface ChartCardProps {
title: string;
description?: string;
children: React.ReactNode;
onExport?: () => void;
onRefresh?: () => void;
isLoading?: boolean;
className?: string;
actions?: React.ReactNode;
}
/**
* Chart card wrapper component
*/
export const ChartCard = ({
title,
description,
children,
onExport,
onRefresh,
isLoading = false,
className,
actions,
}: ChartCardProps) => {
return (
<Card className={clsx('h-full', className)}>
<CardHeader>
<div className="flex items-start justify-between">
<div className="flex-1">
<CardTitle>{title}</CardTitle>
{description && <CardDescription className="mt-1">{description}</CardDescription>}
</div>
<div className="flex items-center gap-2">
{onRefresh && (
<Button
variant="ghost"
size="sm"
onClick={onRefresh}
disabled={isLoading}
aria-label="Refresh chart"
>
<RefreshCw className={clsx('h-4 w-4', { 'animate-spin': isLoading })} />
</Button>
)}
{onExport && (
<Button variant="ghost" size="sm" onClick={onExport} aria-label="Export chart">
<Download className="h-4 w-4" />
</Button>
)}
{actions}
</div>
</div>
</CardHeader>
<CardContent>
{isLoading ? (
<div className="flex items-center justify-center h-64">
<div className="animate-spin rounded-full h-8 w-8 border-b-2 border-primary" />
</div>
) : (
children
)}
</CardContent>
</Card>
);
};