krishnasales_mobile/src/components/reusable/AnalyticsChart.tsx
Bhanu Prakash Sai Potteri 73850d6e0a Krishna Sales mobile PWA
Mobile PWA port of the desktop console: bottom-sheet modals, card-list
record views, bottom tab nav, vite-plugin-pwa (manifest, service worker,
icons). API layer, workflow UIDs, and design tokens reused verbatim.
2026-07-08 11:27:35 +05:30

88 lines
2.8 KiB
TypeScript

import { Card } from './Card';
import {
BarChart,
Bar,
XAxis,
YAxis,
CartesianGrid,
Tooltip,
ResponsiveContainer
} from 'recharts';
export interface ChartRow {
dimension: string;
value: number;
}
export interface ChartConfig {
chart_uid: string;
key: string;
rows: ChartRow[];
}
export interface AnalyticsChartProps {
data?: unknown[];
}
export function AnalyticsChart({ data }: AnalyticsChartProps) {
if (!data || !Array.isArray(data) || data.length === 0) return null;
const charts = data as ChartConfig[];
const colors = ['#3B82F6', '#10B981', '#F59E0B', '#8B5CF6', '#EC4899', '#14B8A6'];
return (
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6 w-full">
{charts.map((chart, idx) => {
const title = (chart.key || `Chart ${idx + 1}`)
.replace(/_/g, ' ')
.replace(/\b\w/g, c => c.toUpperCase());
// Safely format dimension string (fallbacks for empty strings)
const formattedRows = (chart.rows || []).map(r => ({
...r,
dimension: String(r.dimension || '').trim() || 'Unknown'
}));
if (formattedRows.length === 0) return null;
return (
<Card key={chart.chart_uid || idx} title={title} className="shadow-sm border-t-4 border-t-indigo-500">
<div className="h-[320px] w-full mt-4">
<ResponsiveContainer width="100%" height="100%">
<BarChart data={formattedRows} margin={{ top: 10, right: 10, left: -20, bottom: 0 }}>
<CartesianGrid strokeDasharray="3 3" vertical={false} stroke="#E2E8F0" />
<XAxis
dataKey="dimension"
axisLine={false}
tickLine={false}
tick={{ fontSize: 12, fill: '#64748B' }}
dy={10}
/>
<YAxis
axisLine={false}
tickLine={false}
tick={{ fontSize: 12, fill: '#64748B' }}
allowDecimals={false}
/>
<Tooltip
cursor={{ fill: '#F8FAFC' }}
contentStyle={{ borderRadius: '8px', border: '1px solid #E2E8F0', boxShadow: '0 4px 6px -1px rgb(0 0 0 / 0.1)', fontSize: '14px', fontFamily: 'inherit' }}
labelStyle={{ fontWeight: 'bold', color: '#0F172A', marginBottom: '4px' }}
/>
<Bar
dataKey="value"
name="Value"
fill={colors[idx % colors.length]}
radius={[4, 4, 0, 0]}
maxBarSize={40}
/>
</BarChart>
</ResponsiveContainer>
</div>
</Card>
);
})}
</div>
);
}