import React from 'react' import * as z from "zod"; import { ChartContainer, ChartTooltip, ChartTooltipContent, ChartLegend, ChartLegendContent } from "@/components/ui/chart"; import { BarChart, Bar, LineChart, Line, PieChart, Pie, AreaChart, Area, ScatterChart, Scatter, XAxis, YAxis, CartesianGrid, Cell, ResponsiveContainer } from "recharts"; export const layoutId = 'chart-table-slide' export const layoutName = 'Chart + Table Slide' export const layoutDescription = 'A layout for displaying data visualization alongside detailed tabular data for comprehensive analysis.' const chartDataSchema = z.object({ name: z.string().meta({ description: "Data point name" }), value: z.number().meta({ description: "Data point value" }), category: z.string().optional().meta({ description: "Category for grouping" }), x: z.number().optional().meta({ description: "X coordinate for scatter plots" }), y: z.number().optional().meta({ description: "Y coordinate for scatter plots" }), }); const tableRowSchema = z.object({ metric: z.string().meta({ description: "Metric name" }), value: z.string().meta({ description: "Metric value" }), change: z.string().optional().meta({ description: "Change percentage or indicator" }), status: z.string().optional().meta({ description: "Status or category" }), }); const chartTableSlideSchema = z.object({ title: z.string().min(3).max(100).default('Revenue Analysis & Breakdown').meta({ description: "Main title of the slide", }), description: z.string().min(10).max(300).default('This comprehensive analysis combines visual trends with detailed metrics, providing both high-level insights and granular data for informed decision-making.').meta({ description: "Bottom description text", }), chartType: z.enum(['bar', 'line', 'pie', 'area', 'scatter']).default('bar').meta({ description: "Type of chart to display", }), chartData: z.array(chartDataSchema).min(2).max(10).default([ { name: 'Q1', value: 4000 }, { name: 'Q2', value: 3000 }, { name: 'Q3', value: 5000 }, { name: 'Q4', value: 4500 }, ]).meta({ description: "Chart data points", }), tableData: z.array(tableRowSchema).min(3).max(15).default([ { metric: 'Total Revenue', value: '$16.5M', change: '+12.5%', status: 'Growth' }, { metric: 'Q1 Revenue', value: '$4.0M', change: '+8.2%', status: 'Stable' }, { metric: 'Q2 Revenue', value: '$3.0M', change: '-15.3%', status: 'Decline' }, { metric: 'Q3 Revenue', value: '$5.0M', change: '+25.8%', status: 'Growth' }, { metric: 'Q4 Revenue', value: '$4.5M', change: '+18.4%', status: 'Growth' }, { metric: 'Average Deal Size', value: '$125K', change: '+5.2%', status: 'Stable' }, { metric: 'Customer Count', value: '132', change: '+22.1%', status: 'Growth' }, { metric: 'Market Share', value: '18.3%', change: '+3.1%', status: 'Growth' }, { metric: 'Conversion Rate', value: '24.7%', change: '+1.8%', status: 'Stable' }, { metric: 'Customer Churn', value: '5.2%', change: '-2.1%', status: 'Improvement' }, ]).meta({ description: "Table data rows", }), chartColor: z.string().default('#3b82f6').meta({ description: "Primary color for chart elements", }), dataKey: z.string().default('value').meta({ description: "Key field for chart values", }), categoryKey: z.string().default('name').meta({ description: "Key field for chart categories", }), showLegend: z.boolean().default(false).meta({ description: "Whether to show chart legend", }), showTooltip: z.boolean().default(true).meta({ description: "Whether to show chart tooltip", }), }) export const Schema = chartTableSlideSchema export type ChartTableSlideData = z.infer interface ChartTableSlideLayoutProps { data?: Partial } const chartConfig = { value: { label: "Value", }, name: { label: "Name", }, }; const CHART_COLORS = [ '#3b82f6', '#ef4444', '#10b981', '#f59e0b', '#8b5cf6', '#06b6d4', '#84cc16', '#f97316', '#ec4899', '#6366f1' ]; const ChartTableSlideLayout: React.FC = ({ data: slideData }) => { const chartData = slideData?.chartData || []; const tableData = slideData?.tableData || []; const chartType = slideData?.chartType || 'bar'; const chartColor = slideData?.chartColor || '#3b82f6'; const dataKey = slideData?.dataKey || 'value'; const categoryKey = slideData?.categoryKey || 'name'; const showLegend = slideData?.showLegend || false; const showTooltip = slideData?.showTooltip || true; const renderChart = () => { const commonProps = { data: chartData, margin: { top: 20, right: 20, left: 20, bottom: 40 }, }; switch (chartType) { case 'bar': return ( {showTooltip && } />} {showLegend && } />} ); case 'line': return ( {showTooltip && } />} {showLegend && } />} ); case 'area': return ( {showTooltip && } />} {showLegend && } />} ); case 'pie': return ( {showTooltip && } />} {showLegend && } />} `${name} ${(percent * 100).toFixed(0)}%`} > {chartData.map((entry, index) => ( ))} ); case 'scatter': return ( {showTooltip && } />} {showLegend && } />} ); default: return
Unsupported chart type
; } }; const getStatusColor = (status: string) => { switch (status?.toLowerCase()) { case 'growth': return 'text-green-600'; case 'decline': return 'text-red-600'; case 'stable': return 'text-blue-600'; case 'improvement': return 'text-emerald-600'; default: return 'text-gray-600'; } }; return ( <> {/* Import Google Fonts */}
{/* Glass overlay background */}
{/* Header section */}

{slideData?.title || 'Revenue Analysis & Breakdown'}

{/* Chart and Table section */}
{/* Chart section - Left side */}
{renderChart()}
{/* Table section - Right side */}
{tableData.map((row, index) => ( ))}
Metric Value Change Status
{row.metric} {row.value} {row.change} {row.status}
{/* Bottom Description section */}

{slideData?.description || 'This comprehensive analysis combines visual trends with detailed metrics, providing both high-level insights and granular data for informed decision-making.'}

) } export default ChartTableSlideLayout