/** * Public Transparency Portal * * A public-facing dashboard showing all transparency metrics * for LocalGreenChain platform operations. */ import { useState, useEffect } from 'react'; import Head from 'next/head'; interface SystemHealth { status: 'healthy' | 'degraded' | 'unhealthy'; uptime: number; lastCheck: string; components: Record; } interface DashboardData { generatedAt: string; systemHealth: SystemHealth; audit: { totalEntries: number; entriesLast24h: number; entriesLast7d: number; errorRate24h: number; }; events: { totalEvents: number; eventsLast24h: number; activeSubscriptions: number; activeWebhooks: number; }; plants: { totalPlantsRegistered: number; plantsRegisteredToday: number; plantsRegisteredThisWeek: number; totalClones: number; averageLineageDepth: number; topVarieties: Array<{ variety: string; count: number }>; }; blockchain: { totalBlocks: number; chainValid: boolean; difficulty: number; lastBlockTime: string | null; }; environmental: { totalCarbonSavedKg: number; waterSavedLiters: number; foodMilesReduced: number; sustainabilityScore: number; }; agents: { totalAgents: number; activeAgents: number; totalTasksCompleted: number; }; alerts: Array<{ id: string; type: string; title: string; message: string; timestamp: string; }>; } const StatusBadge = ({ status }: { status: string }) => { const colors: Record = { healthy: 'bg-green-500', up: 'bg-green-500', degraded: 'bg-yellow-500', unhealthy: 'bg-red-500', down: 'bg-red-500' }; return ( {status.toUpperCase()} ); }; const MetricCard = ({ title, value, subtitle, icon }: { title: string; value: string | number; subtitle?: string; icon?: string; }) => (

{title}

{value}

{subtitle &&

{subtitle}

}
{icon && {icon}}
); const SectionHeader = ({ title, subtitle }: { title: string; subtitle?: string }) => (

{title}

{subtitle &&

{subtitle}

}
); export default function TransparencyPortal() { const [data, setData] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [lastUpdated, setLastUpdated] = useState(null); const [autoRefresh, setAutoRefresh] = useState(true); const fetchDashboard = async () => { try { const response = await fetch('/api/transparency/dashboard'); const result = await response.json(); if (result.success) { setData(result.data); setLastUpdated(new Date()); setError(null); } else { setError(result.error || 'Failed to load dashboard'); } } catch (err) { setError('Failed to connect to transparency API'); } finally { setLoading(false); } }; useEffect(() => { fetchDashboard(); // Auto-refresh every 30 seconds if enabled let interval: NodeJS.Timeout; if (autoRefresh) { interval = setInterval(fetchDashboard, 30000); } return () => { if (interval) clearInterval(interval); }; }, [autoRefresh]); const formatUptime = (ms: number) => { const hours = Math.floor(ms / 3600000); const minutes = Math.floor((ms % 3600000) / 60000); return `${hours}h ${minutes}m`; }; if (loading) { return (

Loading transparency data...

); } if (error) { return (
!

{error}

); } return ( <> Transparency Portal | LocalGreenChain
{/* Header */}

Transparency Portal

Real-time visibility into LocalGreenChain operations

{data?.systemHealth && ( )}
{lastUpdated && (

Last updated: {lastUpdated.toLocaleTimeString()}

)}
{/* System Health Section */}
{data?.systemHealth.components && Object.entries(data.systemHealth.components).map(([name, component]) => (
{name}

Errors (24h): {component.errorCount24h}

))}
{data?.systemHealth && (

Uptime: {formatUptime(data.systemHealth.uptime)}

)}
{/* Key Metrics Section */}
{/* Environmental Impact Section */}
{/* Plant Registry Section */}

Registration Stats

Total Plants {data?.plants.totalPlantsRegistered || 0}
This Week {data?.plants.plantsRegisteredThisWeek || 0}
Total Clones {data?.plants.totalClones || 0}
Avg Lineage Depth {data?.plants.averageLineageDepth?.toFixed(1) || 0}

Top Varieties

{data?.plants.topVarieties && data.plants.topVarieties.length > 0 ? (
{data.plants.topVarieties.slice(0, 5).map((v, i) => (
{v.variety} {v.count}
))}
) : (

No varieties registered yet

)}
{/* Blockchain Section */}

Total Blocks

{data?.blockchain.totalBlocks || 0}

Chain Integrity

{data?.blockchain.chainValid ? ( Valid ) : ( Invalid )}

Difficulty

{data?.blockchain.difficulty || 4}

Last Block

{data?.blockchain.lastBlockTime ? new Date(data.blockchain.lastBlockTime).toLocaleString() : 'N/A'}

{/* Agents Section */}

{data?.agents.totalAgents || 10}

Total Agents

{data?.agents.activeAgents || 0}

Active

{data?.agents.totalTasksCompleted || 0}

Tasks Completed

{/* Alerts Section */} {data?.alerts && data.alerts.length > 0 && (
{data.alerts.map(alert => (

{alert.title}

{alert.message}

{new Date(alert.timestamp).toLocaleTimeString()}
))}
)} {/* Export Section */}
{/* Footer */}
); }