npm package: @kodeme-io/next-core-analytics
Description: Analytics, charts, dashboards, and reporting for Next.js applications
Author: ABC Food
Latest version: 0.8.4

# @kodeme-io/next-core-analytics

Analytics, charts, dashboards, and reporting components for Next.js applications with TypeScript support and real-time data visualization.

## 🚀 Features

- **📊 KPI Cards** - Display key metrics with trends and comparisons
- **📈 Rich Charts** - Line, bar, pie, donut, area, scatter, radar charts using Recharts
- **🎯 Dashboard Builder** - Create custom, responsive dashboards
- **📁 Export Functionality** - PDF, Excel, CSV, JSON export with real library implementations
- **📊 Data Aggregation** - Sum, avg, min, max, count with grouping
- **⏰ Time Series Analysis** - Time-based data processing and visualization
- **🔄 Real-time Updates** - Live data streaming and WebSocket support
- **♿ Accessible** - WCAG compliant with keyboard navigation
- **🔧 TypeScript Native** - Full type safety and IntelliSense support
- **🌍 Internationalization** - Built-in support for multiple locales and currencies
- **✅ Data Validation** - Zod-powered validation for all data inputs
- **🛡️ Error Boundaries** - Graceful error handling and recovery
- **⚡ Performance Optimized** - React.memo and useMemo optimizations

## 📦 Installation

```bash
npm install @kodeme-io/next-core-analytics
# or
yarn add @kodeme-io/next-core-analytics
# or
pnpm add @kodeme-io/next-core-analytics
```

### Peer Dependencies

```bash
npm install react react-dom recharts date-fns
```

### Dependencies

The package includes the following dependencies:
- `recharts` - Chart rendering
- `date-fns` - Date manipulation
- `jspdf` - PDF export
- `xlsx` - Excel export
- `zod` - Data validation

## 🎯 Quick Start

### Basic Analytics Dashboard

```tsx
'use client'

import {
  KPICard,
  ChartContainer,
  Dashboard,
  useAnalytics,
  type KPIMetric,
  type ChartConfig,
  type DashboardLayout
} from '@kodeme-io/next-core-analytics'

const salesMetrics: KPIMetric[] = [
  {
    id: 'revenue',
    label: 'Total Revenue',
    value: 2500000,
    previousValue: 2100000,
    format: 'currency',
    trend: 'up',
    trendValue: 19.0,
    icon: <div>💰</div>,
    color: 'text-green-600'
  },
  {
    id: 'orders',
    label: 'Total Orders',
    value: 1250,
    previousValue: 1100,
    format: 'number',
    trend: 'up',
    trendValue: 13.6,
    icon: <div>📦</div>,
    color: 'text-blue-600'
  },
  {
    id: 'conversion',
    label: 'Conversion Rate',
    value: 3.2,
    previousValue: 2.8,
    format: 'percentage',
    trend: 'up',
    trendValue: 14.3,
    icon: <div>📈</div>,
    color: 'text-purple-600'
  }
]

const salesChartConfig: ChartConfig = {
  type: 'line',
  data: [
    { name: 'Jan', value: 1800000 },
    { name: 'Feb', value: 2100000 },
    { name: 'Mar', value: 2500000 },
    { name: 'Apr', value: 2300000 },
    { name: 'May', value: 2800000 },
    { name: 'Jun', value: 2500000 }
  ],
  xKey: 'name',
  yKey: 'value',
  colors: ['#3b82f6'],
  title: 'Monthly Revenue Trend',
  subtitle: 'Revenue performance over the last 6 months'
}

const salesDashboard: DashboardLayout = {
  id: 'sales-dashboard',
  name: 'Sales Dashboard',
  widgets: [
    {
      id: 'kpi-row',
      type: 'kpi',
      title: 'Key Metrics',
      config: { metrics: salesMetrics },
      span: { cols: 12, rows: 2 }
    },
    {
      id: 'revenue-chart',
      type: 'chart',
      title: 'Revenue Trend',
      config: salesChartConfig,
      span: { cols: 8, rows: 4 }
    }
  ],
  refreshInterval: 300
}

export default function SalesDashboard() {
  const { data, loading, error, refresh } = useAnalytics({
    endpoint: '/api/analytics/sales',
    params: { period: '6m' },
    refreshInterval: 30000 // 30 seconds
  })

  if (loading) return <div>Loading dashboard...</div>
  if (error) return <div>Error loading dashboard</div>

  return (
    <div className="p-6">
      <div className="flex justify-between items-center mb-6">
        <h1 className="text-3xl font-bold">Sales Analytics</h1>
        <button
          onClick={refresh}
          className="px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600"
        >
          Refresh
        </button>
      </div>

      <Dashboard layout={salesDashboard} data={data} />
    </div>
  )
}
```

## 📚 Core Concepts

### KPI Card Structure

```typescript
interface KPIMetric {
  id: string                    // Unique metric identifier
  label: string                 // Display label
  value: number | string       // Current value
  previousValue?: number       // Previous period value
  format?: 'number' | 'currency' | 'percentage' | 'duration'  // Value formatting
  trend?: 'up' | 'down' | 'neutral'  // Trend direction
  trendValue?: number          // Trend percentage
  icon?: React.ReactNode       // Custom icon
  color?: string              // Custom color class
  prefix?: string             // Value prefix
  suffix?: string             // Value suffix
  // Internationalization options
  locale?: string             // Locale for number formatting (e.g., 'en-US', 'de-DE')
  currency?: string           // Currency code (e.g., 'USD', 'EUR', 'IDR')
  numberFormatOptions?: Intl.NumberFormatOptions  // Custom formatting options
}
```

### Chart Configuration

```typescript
interface ChartConfig {
  type: ChartType              // Chart type (line, bar, area, pie, donut, scatter, radar)
  data: ChartDataPoint[]      // Chart data
  xKey?: string              // X-axis data key
  yKey?: string | string[]   // Y-axis data key(s)
  colors?: string[]          // Custom colors
  legend?: boolean           // Show legend
  grid?: boolean            // Show grid
  tooltip?: boolean          // Show tooltip
  title?: string            // Chart title
  subtitle?: string         // Chart subtitle
}
```

### Dashboard Layout

```typescript
interface DashboardLayout {
  id: string                    // Dashboard identifier
  name: string                 // Dashboard name
  widgets: DashboardWidget[]   // Dashboard widgets
  refreshInterval?: number     // Auto-refresh interval (seconds)
  filters?: DashboardFilter[]  // Dashboard filters
}

interface DashboardWidget {
  id: string                    // Widget identifier
  type: 'chart' | 'kpi' | 'table' | 'custom'  // Widget type
  title: string                 // Widget title
  description?: string          // Widget description
  config: ChartConfig | KPICardConfig | any  // Widget configuration
  span?: {                     // Grid span
    cols?: number              // Column span (1-12)
    rows?: number              // Row span (1-6)
  }
}
```

## 🎨 Components

### KPICard

Display key performance metrics with optional trends and comparisons:

```tsx
<KPICard
  metric={{
    id: 'revenue',
    label: 'Total Revenue',
    value: 1500000,
    previousValue: 1200000,
    format: 'currency',
    trend: 'up',
    trendValue: 25,
    icon: <RevenueIcon />,
    color: 'text-green-600'
  }}
  variant="default"  // 'default' | 'compact' | 'detailed'
  className="custom-kpi-card"
/>
```

**Variants:**
- `default` - Standard card with trend and value
- `compact` - Minimal design for dense layouts
- `detailed` - Extended view with previous values

**Formats:**
- `number` - Formatted with thousand separators
- `currency` - IDR currency format (default)
- `percentage` - Percentage with decimal precision
- `duration` - Hours and minutes format

### ChartContainer

Responsive chart wrapper with loading and error states:

```tsx
<ChartContainer
  config={{
    type: 'line',
    data: salesData,
    xKey: 'month',
    yKey: 'revenue',
    colors: ['#3b82f6'],
    title: 'Monthly Revenue',
    grid: true,
    tooltip: true
  }}
  loading={false}
  error={null}
  className="chart-container"
  height={400}
/>
```

**Chart Types:**
- `line` - Line charts for trends
- `bar` - Bar charts for comparisons
- `area` - Area charts for cumulative data
- `pie` - Pie charts for proportions
- `donut` - Donut charts with center space
- `scatter` - Scatter plots for correlations
- `radar` - Radar charts for multi-dimensional data

### Dashboard

Full dashboard layout with grid system and widgets:

```tsx
<Dashboard
  layout={dashboardLayout}
  data={analyticsData}
  onWidgetClick={(widgetId) => console.log('Widget clicked:', widgetId)}
  onFilterChange={(filters) => console.log('Filters changed:', filters)}
  className="analytics-dashboard"
  loading={false}
  error={null}
/>
```

### ExportButton

Export dashboard or chart data in multiple formats:

```tsx
<ExportButton
  config={{
    format: 'pdf',
    filename: 'sales-report',
    data: chartData,
    title: 'Sales Report',
    includeCharts: true
  }}
  onExportComplete={(filename) => console.log('Exported:', filename)}
  className="export-button"
/>
```

**Export Formats:**
- `pdf` - PDF reports with charts and tables
- `excel` - Excel spreadsheets with multiple sheets
- `csv` - CSV files for data analysis
- `json` - JSON data for integration

## 📊 Data Processing

### Data Aggregation

```tsx
import { aggregateData } from '@kodeme-io/next-core-analytics'

// Aggregate sales data by region
const aggregatedSales = aggregateData(salesData, {
  field: 'revenue',
  type: 'sum',
  groupBy: 'region'
})

// Calculate average order value
const avgOrderValue = aggregateData(orderData, {
  field: 'orderValue',
  type: 'avg'
})
```

**Aggregation Types:**
- `sum` - Sum of values
- `avg` - Average of values
- `min` - Minimum value
- `max` - Maximum value
- `count` - Count of records

### Time Series Processing

```tsx
import { processTimeSeries } from '@kodeme-io/next-core-analytics'

// Process daily sales data into weekly aggregates
const weeklyData = processTimeSeries(dailySales, {
  dateField: 'date',
  valueField: 'revenue',
  granularity: 'week',
  fillGaps: true
})
```

**Time Granularities:**
- `hour` - Hourly aggregation
- `day` - Daily aggregation
- `week` - Weekly aggregation
- `month` - Monthly aggregation
- `quarter` - Quarterly aggregation
- `year` - Yearly aggregation

### Comparison Analysis

```tsx
import { calculateComparison } from '@kodeme-io/next-core-analytics'

// Calculate period-over-period growth
const comparison = calculateComparison({
  currentPeriod: { start: new Date('2024-01-01'), end: new Date('2024-01-31') },
  previousPeriod: { start: new Date('2023-12-01'), end: new Date('2023-12-31') },
  metric: 'revenue',
  data: salesData
})

console.log(`Revenue ${comparison.trend === 'up' ? 'increased' : 'decreased'} by ${comparison.percentChange}%`)
```

## 🔄 Advanced Usage

### Real-time Data

```tsx
function RealTimeDashboard() {
  const { data, subscribe, unsubscribe } = useAnalytics({
    endpoint: '/api/analytics/realtime',
    realtime: true
  })

  useEffect(() => {
    const handleRealtimeUpdate = (newData) => {
      console.log('Real-time data update:', newData)
    }

    subscribe('data-updated', handleRealtimeUpdate)

    return () => {
      unsubscribe('data-updated')
    }
  }, [subscribe, unsubscribe])

  return (
    <Dashboard layout={realtimeLayout} data={data} />
  )
}
```

### Custom Charts

```tsx
import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer } from 'recharts'

function CustomSalesChart({ data }: { data: any[] }) {
  return (
    <ResponsiveContainer width="100%" height={400}>
      <LineChart data={data}>
        <CartesianGrid strokeDasharray="3 3" />
        <XAxis dataKey="month" />
        <YAxis />
        <Tooltip />
        <Line
          type="monotone"
          dataKey="revenue"
          stroke="#3b82f6"
          strokeWidth={2}
          dot={{ fill: '#3b82f6', strokeWidth: 2, r: 4 }}
          activeDot={{ r: 6 }}
        />
      </LineChart>
    </ResponsiveContainer>
  )
}
```

### Multi-series Charts

```tsx
const multiSeriesConfig: ChartConfig = {
  type: 'line',
  data: [
    { month: 'Jan', revenue: 1000000, profit: 200000, expenses: 800000 },
    { month: 'Feb', revenue: 1200000, profit: 250000, expenses: 950000 },
    { month: 'Mar', revenue: 1100000, profit: 180000, expenses: 920000 }
  ],
  xKey: 'month',
  yKey: ['revenue', 'profit', 'expenses'],
  colors: ['#3b82f6', '#10b981', '#ef4444'],
  title: 'Financial Overview',
  legend: true
}
```

### Custom Dashboard Filters

```tsx
const dashboardWithFilters: DashboardLayout = {
  id: 'filtered-dashboard',
  name: 'Filtered Dashboard',
  widgets: [/* ... */],
  filters: [
    {
      id: 'date-range',
      type: 'date',
      label: 'Date Range',
      value: { start: '2024-01-01', end: '2024-12-31' }
    },
    {
      id: 'region',
      type: 'multiselect',
      label: 'Regions',
      value: ['all'],
      options: [
        { label: 'All Regions', value: 'all' },
        { label: 'North America', value: 'na' },
        { label: 'Europe', value: 'eu' },
        { label: 'Asia Pacific', value: 'apac' }
      ]
    },
    {
      id: 'product-category',
      type: 'select',
      label: 'Product Category',
      value: 'all',
      options: [
        { label: 'All Categories', value: 'all' },
        { label: 'Electronics', value: 'electronics' },
        { label: 'Clothing', value: 'clothing' },
        { label: 'Food', value: 'food' }
      ]
    }
  ]
}
```

## 🎨 Styling and Theming

### Custom Color Schemes

```tsx
const customTheme = {
  primary: '#6366f1',
  secondary: '#8b5cf6',
  success: '#10b981',
  warning: '#f59e0b',
  error: '#ef4444',
  neutral: '#6b7280'
}

const themedChartConfig: ChartConfig = {
  type: 'bar',
  data: salesData,
  xKey: 'month',
  yKey: 'revenue',
  colors: [customTheme.primary, customTheme.secondary],
  title: 'Sales by Month'
}
```

### Responsive Design

```tsx
// Responsive grid layout
const responsiveDashboard: DashboardLayout = {
  id: 'responsive-dashboard',
  name: 'Responsive Dashboard',
  widgets: [
    {
      id: 'kpi-cards',
      type: 'kpi',
      title: 'Metrics',
      config: { metrics: kpiMetrics },
      span: { cols: 12, rows: 2 }  // Full width on desktop
    },
    {
      id: 'main-chart',
      type: 'chart',
      title: 'Trends',
      config: chartConfig,
      span: { cols: 8, rows: 4 }   // 8/12 columns
    },
    {
      id: 'secondary-chart',
      type: 'chart',
      title: 'Breakdown',
      config: pieChartConfig,
      span: { cols: 4, rows: 4 }   // 4/12 columns
    }
  ]
}
```

## 🧪 Testing

The package includes comprehensive test coverage:

```bash
# Run tests
npm test

# Run with coverage
npm run test:coverage

# Run tests in watch mode
npm run test:watch
```

### Testing Analytics Components

```tsx
import { render, screen } from '@testing-library/react'
import { KPICard } from '@kodeme-io/next-core-analytics'

test('KPI card renders correctly', () => {
  const metric = {
    id: 'test-metric',
    label: 'Test Metric',
    value: 1000,
    format: 'number' as const,
    trend: 'up' as const,
    trendValue: 10
  }

  render(<KPICard metric={metric} />)

  expect(screen.getByText('Test Metric')).toBeInTheDocument()
  expect(screen.getByText('1.000')).toBeInTheDocument()
  expect(screen.getByText('10%')).toBeInTheDocument()
})
```

## 🌍 Internationalization

### Currency and Number Formatting

The analytics package now supports internationalization out of the box:

```tsx
import { KPICard, currencyFormatters } from '@kodeme-io/next-core-analytics'

// Indonesian Rupiah
<KPICard
  metric={{
    id: 'revenue',
    label: 'Total Revenue',
    value: 1500000,
    format: 'currency',
    locale: 'id-ID',
    currency: 'IDR'
  }}
/>

// Euro with German locale
<KPICard
  metric={{
    id: 'revenue-eur',
    label: 'Revenue (EUR)',
    value: 1500,
    format: 'currency',
    locale: 'de-DE',
    currency: 'EUR'
  }}
/>

// Or use pre-configured formatters
const formattedValue = currencyFormatters.EUR(1500)
```

### Custom Formatters

```tsx
import { createFormatter, formatValue } from '@kodeme-io/next-core-analytics'

const customFormatter = createFormatter({
  format: 'currency',
  currency: 'GBP',
  locale: 'en-GB'
})
```

## ✅ Data Validation

### Built-in Validation

All components include automatic data validation using Zod schemas:

```tsx
import { KPICard, validateKPI, KPIMetricSchema } from '@kodeme-io/next-core-analytics'

// Manual validation
const isValidKPI = validateKPI(kpiData)

// Safe validation with error handling
import { safeValidate } from '@kodeme-io/next-core-analytics'
const result = safeValidate(KPIMetricSchema, metricData)
if (!result.success) {
  console.error('Validation errors:', result.errors)
}
```

### Performance Monitoring

```tsx
import { validationMonitor } from '@kodeme-io/next-core-analytics'

// Get validation statistics
const stats = validationMonitor.getStats()
console.log('Average validation time:', stats.averageValidationTime)
console.log('Success rate:', stats.successRate)
```

## 🛡️ Error Boundaries

### Component-Level Error Handling

```tsx
import {
  AnalyticsErrorBoundary,
  KPIErrorBoundary,
  ChartErrorBoundary,
  DashboardErrorBoundary
} from '@kodeme-io/next-core-analytics'

// Wrap your entire dashboard
<DashboardErrorBoundary>
  <Dashboard layout={dashboardLayout} />
</DashboardErrorBoundary>

// Or specific components
<KPIErrorBoundary>
  <KPICard metric={metric} />
</KPIErrorBoundary>

<ChartErrorBoundary>
  <ChartContainer config={chartConfig} />
</ChartErrorBoundary>
```

### Error Handling Hooks

```tsx
import { useErrorHandler } from '@kodeme-io/next-core-analytics'

function MyComponent() {
  const { error, captureError, resetError } = useErrorHandler()

  if (error) {
    return (
      <div>
        <p>Error: {error.message}</p>
        <button onClick={resetError}>Retry</button>
      </div>
    )
  }

  // Your component logic
}
```

## 🔧 API Reference

### Hooks

```typescript
// Main analytics hook (enhanced with real API support)
export function useAnalytics(options?: {
  endpoint?: string
  params?: Record<string, any>
  refreshInterval?: number
  realtime?: boolean
  method?: 'GET' | 'POST'
  headers?: Record<string, string>
  cache?: RequestCache
}): {
  data: any
  loading: boolean
  error: Error | null
  refresh: () => void
  subscribe: (event: string, callback: Function) => void
  unsubscribe: (event: string) => void
}

// Error handling hook
export function useErrorHandler(): {
  error: Error | null
  captureError: (error: Error) => void
  resetError: () => void
}
```

### Utilities

```typescript
// Data aggregation
export function aggregateData(data: any[], config: AggregationConfig): any[]

// Time series processing
export function processTimeSeries(data: any[], config: TimeSeriesConfig): any[]

// Comparison analysis
export function calculateComparison(config: ComparisonConfig): ComparisonData

// Formatting utilities
export function formatValue(value: number | string, options: FormatValueOptions): string
export function formatTrendValue(value: number, format?: 'percentage' | 'number'): string
export function formatDuration(seconds: number): string

// Validation utilities
export function validateKPI(metric: unknown): KPIMetric
export function validateChartData(data: unknown[]): ChartDataPoint[]
export function validateDashboardLayout(layout: unknown): DashboardLayout
export function safeValidate<T>(schema: z.ZodSchema<T>, data: unknown): ValidationResult<T>
```

### Component Props

```typescript
// KPICard props
export interface KPICardProps {
  metric: KPIMetric
  variant?: 'default' | 'compact' | 'detailed'
  className?: string
}

// ChartContainer props
export interface ChartContainerProps {
  config: ChartConfig
  loading?: boolean
  error?: string | null
  className?: string
  height?: number
}

// Dashboard props
export interface DashboardProps {
  layout: DashboardLayout
  data?: any
  onWidgetClick?: (widgetId: string) => void
  onFilterChange?: (filters: Record<string, any>) => void
  className?: string
  loading?: boolean
  error?: string | null
}
```

## 🔍 Troubleshooting

### Common Issues

1. **Charts Not Rendering**
   - Check if data is properly formatted
   - Verify xKey and yKey match data structure
   - Ensure recharts is installed as a dependency

2. **KPI Values Not Formatting**
   - Verify format type matches value type
   - Check if value is number for numeric formats
   - Ensure locale settings are correct

3. **Export Not Working**
   - Check if export libraries are installed
   - Verify data structure matches export requirements
   - Ensure proper file permissions

### Debug Mode

Enable debug logging:

```tsx
const analytics = useAnalytics({
  endpoint: '/api/analytics',
  debug: true
})
```

## 🚀 Performance Tips

1. **Data Caching** - Cache API responses to reduce network requests
2. **Virtualization** - Use virtual scrolling for large datasets
3. **Lazy Loading** - Load charts and data on demand
4. **Debounced Updates** - Debounce real-time data updates
5. **Component Memoization** - Components are optimized with React.memo
6. **Value Memoization** - Expensive calculations are memoized

```tsx
// Caching example
const cachedAnalytics = useMemo(() => {
  return processAnalyticsData(rawData)
}, [rawData])

// Debounced refresh
const debouncedRefresh = useMemo(
  () => debounce(refresh, 1000),
  [refresh]
)

// Components are already optimized - no manual memoization needed
<KPICard metric={metric} variant="compact" />
<ChartContainer config={chartConfig} />
```

### Performance Monitoring

The package includes built-in performance monitoring:

```tsx
import { validationMonitor } from '@kodeme-io/next-core-analytics'

// Get real-time performance metrics
const stats = validationMonitor.getStats()
console.log({
  totalValidations: stats.totalValidations,
  averageTime: stats.averageValidationTime,
  successRate: stats.successRate
})
```

## 🤝 Contributing

1. Fork the repository
2. Create a feature branch
3. Make your changes
4. Add tests for new functionality
5. Submit a pull request

## 📄 License

MIT License - see LICENSE file for details

## 🔗 Related Packages

- [@kodeme-io/next-core-forms](../forms/README.md) - Form components and validation
- [@kodeme-io/next-core-workflow](../workflow/README.md) - Workflow management
- [@kodeme-io/next-core-ui](../ui/README.md) - UI components

## 📞 Support

- Documentation: [Full documentation](https://docs.abc-food.com/next-core/analytics)
- Issues: [GitHub Issues](https://github.com/abc-food/next-core/issues)
- Discord: [Community Discord](https://discord.gg/abc-food)