import React, { useState } from 'react'; import { useNumberCards, useDashboardChart } from '../hooks/useApi'; const ModernDashboard: React.FC = () => { const [activeTab, setActiveTab] = useState<'variation1' | 'variation2'>('variation1'); const { data: numberCards, loading: cardsLoading } = useNumberCards(); // Fetch all charts const { data: upDownChart, error: upDownError } = useDashboardChart('Up & Down Time Chart'); const { data: workOrderChart, error: workOrderError } = useDashboardChart('Work Order Status Chart'); const { data: assetWiseChart, error: assetWiseError } = useDashboardChart('Maintenance - Asset wise Count'); const { data: assigneesChart, error: assigneesError } = useDashboardChart('Asset Maintenance Assignees Status Count'); const { data: frequencyChart, error: frequencyError } = useDashboardChart('Asset Maintenance Frequency Chart'); const { data: ppmStatusChart, error: ppmStatusError } = useDashboardChart('PPM Status'); const { data: ppmTemplateChart, error: ppmTemplateError } = useDashboardChart('PPM Template Counts'); // Log errors for debugging React.useEffect(() => { if (upDownError) console.error('Up & Down Time Chart error:', upDownError); if (workOrderError) console.error('Work Order Status Chart error:', workOrderError); if (assetWiseError) console.error('Maintenance - Asset wise Count error:', assetWiseError); if (assigneesError) console.error('Asset Maintenance Assignees Status Count error:', assigneesError); if (frequencyError) console.error('Asset Maintenance Frequency Chart error:', frequencyError); if (ppmStatusError) console.error('PPM Status error:', ppmStatusError); if (ppmTemplateError) console.error('PPM Template Counts error:', ppmTemplateError); }, [upDownError, workOrderError, assetWiseError, assigneesError, frequencyError, ppmStatusError, ppmTemplateError]); if (cardsLoading) { return (
Loading dashboard...
); } return (
{/* Header */}

Asset Management

Analytics Dashboard

{/* Tabs */} {/*
*/} {/* Number Cards - Matching Frappe Style */}
{/* Quick Links */}
{/* Charts Section */}
{/* Up & Down Time Chart */} {/* Work Order Status Chart */} {/* Maintenance - Asset wise Count */} {/* Asset Maintenance Assignees Status Count */} {/* Asset Maintenance Frequency Chart */} {/* PPM Status */} {/* PPM Template Counts */}
); }; // Number Card Component (Frappe Style) const NumberCard: React.FC<{ title: string; value: number; subtitle: string; color: string }> = ({ title, value, subtitle, color, }) => (
{title}
{value.toLocaleString()}
{subtitle}
); // Quick Link Component const QuickLink: React.FC<{ title: string; icon: string }> = ({ title, icon }) => ( ); // Chart Card Component const ChartCard: React.FC<{ title: string; data: any; type: 'bar' | 'pie' }> = ({ title, data, type }) => { // Log data for debugging React.useEffect(() => { console.log(`${title} data:`, data); }, [title, data]); return (

{title}

{!data || !data.datasets || !data.datasets.length ? (
No chart data available
Check browser console for errors
) : type === 'pie' ? ( ) : ( )}
); }; // Pie Chart Component const PieChart: React.FC<{ data: any }> = ({ data }) => { const labels = data.labels || []; const values = data.datasets[0]?.values || []; const colors = data.datasets[0]?.color ? [data.datasets[0].color] : generateColors(values.length); const total = values.reduce((sum: number, val: number) => sum + val, 0); const radius = 120; const cx = radius + 20; const cy = radius + 20; let cumulative = 0; const slices = values.map((value: number, i: number) => { const startAngle = (cumulative / total) * 2 * Math.PI - Math.PI / 2; cumulative += value; const endAngle = (cumulative / total) * 2 * Math.PI - Math.PI / 2; const largeArc = endAngle - startAngle > Math.PI ? 1 : 0; const x1 = cx + radius * Math.cos(startAngle); const y1 = cy + radius * Math.sin(startAngle); const x2 = cx + radius * Math.cos(endAngle); const y2 = cy + radius * Math.sin(endAngle); return { path: `M ${cx} ${cy} L ${x1} ${y1} A ${radius} ${radius} 0 ${largeArc} 1 ${x2} ${y2} Z`, color: colors[i % colors.length], label: labels[i], value: value, }; }); return (
{slices.map((slice: any, i: number) => ( ))}
{slices.map((slice: any, i: number) => (
{slice.label} {slice.value.toLocaleString()}
))}
); }; // Bar Chart Component const BarChart: React.FC<{ data: any }> = ({ data }) => { const labels = data.labels || []; const datasets = data.datasets || []; if (!datasets.length) { return
No data available
; } // Calculate max value across all datasets const allValues = datasets.flatMap((ds: any) => ds.values || []); const max = Math.max(...allValues, 1); const chartHeight = 300; const barSpacing = 8; const groupWidth = Math.max(60, Math.min(120, (800 - 80) / labels.length)); return (
{/* Y-axis */}
{max.toFixed(0)} {(max * 0.75).toFixed(0)} {(max * 0.5).toFixed(0)} {(max * 0.25).toFixed(0)} 0
{/* Bars */}
{labels.map((label: string, i: number) => { const barWidth = Math.max(20, (groupWidth - barSpacing * (datasets.length + 1)) / datasets.length); return (
{datasets.map((dataset: any, dsIndex: number) => { const value = dataset.values?.[i] || 0; const height = (value / max) * chartHeight; const color = dataset.color || generateColors(datasets.length)[dsIndex]; return (
0 ? '4px' : '0px', }} >
{value.toLocaleString()}
); })}
{label}
); })}
{/* Legend */} {datasets.length > 1 && (
{datasets.map((dataset: any, i: number) => (
{dataset.name}
))}
)}
); }; // Helper: Generate colors function generateColors(count: number): string[] { const colors = [ '#4F46E5', // Indigo '#10B981', // Green '#F59E0B', // Amber '#EF4444', // Red '#8B5CF6', // Purple '#06B6D4', // Cyan '#F97316', // Orange '#EC4899', // Pink '#14B8A6', // Teal '#6366F1', // Violet ]; return Array.from({ length: count }, (_, i) => colors[i % colors.length]); } export default ModernDashboard;