"use client" import { useState, useEffect } from "react" import { useRouter } from "next/navigation" import { Button } from "@/components/ui/button" import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card" import { Plus, Loader2, AlertCircle, TrendingUp, MapPin as MapPinIcon, BarChart3, AlertTriangle, RectangleHorizontal } from "lucide-react" import { SidebarNavigation } from "@/components/sidebar-navigation" import { GradientStatsCard } from "@/components/dashboard/gradient-stats-card" import { CompactProjectSelector } from "@/components/dashboard/compact-project-selector" import { DetectionDonutChart } from "@/components/dashboard/detection-donut-chart" import { LocationBarChart } from "@/components/dashboard/location-bar-chart" import { DashboardMap } from "@/components/dashboard/dashboard-map" import { fetchProjects, type Project } from "@/lib/api" const API_URL = process.env.NEXT_PUBLIC_API_URL || "http://127.0.0.1:8000/api/v1" interface ProjectSummary { project: { id: string name: string corridor_name: string | null state: string | null } packages: { [key: string]: { package_id: string region: string | null locations: { [key: string]: { location_id: string chainage: string | null detection_count: number detections: Array<{ id: number type: string class: string confidence: number latitude: number longitude: number }> } } } } } interface DetectionStats { totalPotholes: number totalSignboards: number totalDetections: number locationData: Array<{ name: string potholes: number signboards: number total: number }> } function calculateStats(summary: ProjectSummary | null): DetectionStats { if (!summary) { return { totalPotholes: 0, totalSignboards: 0, totalDetections: 0, locationData: [] } } let totalPotholes = 0 let totalSignboards = 0 const locationData: DetectionStats["locationData"] = [] for (const pkg of Object.values(summary.packages || {})) { for (const [locName, loc] of Object.entries(pkg.locations || {})) { let locPotholes = 0 let locSignboards = 0 for (const detection of loc.detections || []) { if (detection.type.toLowerCase().includes("pothole")) { locPotholes++ totalPotholes++ } else { locSignboards++ totalSignboards++ } } if (locPotholes > 0 || locSignboards > 0) { const shortName = locName.length > 20 ? locName.substring(0, 20) + "..." : locName locationData.push({ name: shortName, potholes: locPotholes, signboards: locSignboards, total: locPotholes + locSignboards }) } } } return { totalPotholes, totalSignboards, totalDetections: totalPotholes + totalSignboards, locationData } } export default function DashboardPage() { const router = useRouter() const [isLoading, setIsLoading] = useState(true) const [projects, setProjects] = useState([]) const [selectedProjectId, setSelectedProjectId] = useState(null) const [projectSummary, setProjectSummary] = useState(null) const [stats, setStats] = useState({ totalPotholes: 0, totalSignboards: 0, totalDetections: 0, locationData: [] }) const [error, setError] = useState(null) // Load projects on mount useEffect(() => { const loadProjects = async () => { try { setIsLoading(true) setError(null) const projectsData = await fetchProjects() setProjects(projectsData) if (projectsData.length > 0) { setSelectedProjectId(projectsData[0].id) } } catch (err) { console.error("Failed to load projects:", err) setError("Failed to load projects. Please check if the backend is running.") } finally { setIsLoading(false) } } loadProjects() }, []) // Load project summary when project changes useEffect(() => { if (!selectedProjectId) { setProjectSummary(null) setStats({ totalPotholes: 0, totalSignboards: 0, totalDetections: 0, locationData: [] }) return } const loadProjectSummary = async () => { try { setIsLoading(true) setError(null) const response = await fetch(`${API_URL}/summary/projects/${selectedProjectId}`, { headers: { "Content-Type": "application/json", "ngrok-skip-browser-warning": "true" } }) if (!response.ok) { throw new Error(`API Error: ${response.status}`) } const summary: ProjectSummary = await response.json() setProjectSummary(summary) setStats(calculateStats(summary)) } catch (err) { console.error("Failed to load project summary:", err) setError("Failed to load project summary.") setProjectSummary(null) setStats({ totalPotholes: 0, totalSignboards: 0, totalDetections: 0, locationData: [] }) } finally { setIsLoading(false) } } loadProjectSummary() }, [selectedProjectId]) const handleNewAnalysis = () => { router.push("/") } const selectedProject = projects.find(p => p.id === selectedProjectId) return (
{/* Sidebar Navigation */} {/* Main Content - offset by sidebar width */}
{/* Header */}

VisionRoad Analytics Dashboard

A Comprehensive Overview Of Your Road Infrastructure Analysis

{/* Error Display */} {error && (

{error}

)} {/* Stats Cards - Top Row */}
{/* Project Selector - Above main content */}
{/* Main Content Grid - Map Left, Charts Right */}
{/* Left Side - Map */}
{/* Right Side - Stacked Charts */}
{/* Detection Distribution */}
Detection Distribution
{/* Location Bar Chart */}
Detections by Location
{/* Footer */}

Sentient Geeks Pvt. Ltd.

) }