189 lines
6.3 KiB
TypeScript
189 lines
6.3 KiB
TypeScript
'use client'
|
|
|
|
import { useState } from 'react'
|
|
import { useInfrastructureSummary } from '@/lib/hooks/useInfrastructureData'
|
|
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
|
|
import { Button } from '@/components/ui/button'
|
|
import { GlobalSearch } from './GlobalSearch'
|
|
import Link from 'next/link'
|
|
import { Network, Shield, Calendar, DollarSign, Search } from 'lucide-react'
|
|
|
|
export function DocsDashboard() {
|
|
const { summary, loading, error } = useInfrastructureSummary()
|
|
const [searchOpen, setSearchOpen] = useState(false)
|
|
|
|
const cards = [
|
|
{
|
|
title: 'Network Topology',
|
|
description: 'View and edit regional network topology diagrams',
|
|
icon: Network,
|
|
href: '/infrastructure/docs/topology',
|
|
color: 'text-blue-400',
|
|
bgColor: 'bg-blue-500/10',
|
|
stats: summary
|
|
? {
|
|
label: 'Regions',
|
|
value: summary.totalRegions,
|
|
}
|
|
: null,
|
|
},
|
|
{
|
|
title: 'Compliance Mapping',
|
|
description: 'Track compliance requirements by country and region',
|
|
icon: Shield,
|
|
href: '/infrastructure/docs/compliance',
|
|
color: 'text-green-400',
|
|
bgColor: 'bg-green-500/10',
|
|
stats: summary
|
|
? {
|
|
label: 'Countries',
|
|
value: summary.totalCountries,
|
|
}
|
|
: null,
|
|
},
|
|
{
|
|
title: 'Deployment Timeline',
|
|
description: 'Manage infrastructure deployment milestones and schedules',
|
|
icon: Calendar,
|
|
href: '/infrastructure/docs/timeline',
|
|
color: 'text-purple-400',
|
|
bgColor: 'bg-purple-500/10',
|
|
stats: summary
|
|
? {
|
|
label: 'In Progress',
|
|
value: summary.deploymentProgress.inProgress,
|
|
}
|
|
: null,
|
|
},
|
|
{
|
|
title: 'Cost Estimates',
|
|
description: 'View and manage cost estimates by region and category',
|
|
icon: DollarSign,
|
|
href: '/infrastructure/docs/costs',
|
|
color: 'text-yellow-400',
|
|
bgColor: 'bg-yellow-500/10',
|
|
stats: summary
|
|
? {
|
|
label: 'Total Annual',
|
|
value: `$${(summary.totalCost / 1000000).toFixed(1)}M`,
|
|
}
|
|
: null,
|
|
},
|
|
]
|
|
|
|
if (loading) {
|
|
return (
|
|
<div className="grid gap-6 md:grid-cols-2 lg:grid-cols-4">
|
|
{cards.map((card) => (
|
|
<Card key={card.title} className="animate-pulse">
|
|
<CardHeader>
|
|
<div className="h-6 w-32 bg-studio-medium rounded" />
|
|
<div className="h-4 w-48 bg-studio-medium rounded mt-2" />
|
|
</CardHeader>
|
|
<CardContent>
|
|
<div className="h-8 w-16 bg-studio-medium rounded" />
|
|
</CardContent>
|
|
</Card>
|
|
))}
|
|
</div>
|
|
)
|
|
}
|
|
|
|
if (error) {
|
|
return (
|
|
<Card>
|
|
<CardHeader>
|
|
<CardTitle>Error Loading Dashboard</CardTitle>
|
|
<CardDescription>{error.message}</CardDescription>
|
|
</CardHeader>
|
|
</Card>
|
|
)
|
|
}
|
|
|
|
return (
|
|
<div className="space-y-6">
|
|
<div className="flex items-center justify-between">
|
|
<div>
|
|
<h1 className="text-3xl font-bold text-studio-light">Infrastructure Documentation</h1>
|
|
<p className="text-studio-medium mt-2">
|
|
Manage network topology, compliance, deployment timelines, and cost estimates
|
|
</p>
|
|
</div>
|
|
<Button variant="outline" onClick={() => setSearchOpen(true)}>
|
|
<Search className="h-4 w-4 mr-2" />
|
|
Search
|
|
</Button>
|
|
</div>
|
|
|
|
<div className="grid gap-6 md:grid-cols-2 lg:grid-cols-4">
|
|
{cards.map((card) => {
|
|
const Icon = card.icon
|
|
return (
|
|
<Link key={card.title} href={card.href} className="block">
|
|
<Card className="hover:border-studio-light transition-colors cursor-pointer h-full">
|
|
<CardHeader>
|
|
<div className="flex items-center justify-between">
|
|
<Icon className={`h-8 w-8 ${card.color}`} />
|
|
<div className={`h-12 w-12 rounded-lg ${card.bgColor} flex items-center justify-center`}>
|
|
<Icon className={`h-6 w-6 ${card.color}`} />
|
|
</div>
|
|
</div>
|
|
<CardTitle className="mt-4">{card.title}</CardTitle>
|
|
<CardDescription>{card.description}</CardDescription>
|
|
</CardHeader>
|
|
{card.stats && (
|
|
<CardContent>
|
|
<div className="mt-4">
|
|
<div className="text-2xl font-bold text-studio-light">{card.stats.value}</div>
|
|
<div className="text-sm text-studio-medium">{card.stats.label}</div>
|
|
</div>
|
|
</CardContent>
|
|
)}
|
|
</Card>
|
|
</Link>
|
|
)
|
|
})}
|
|
</div>
|
|
|
|
{summary && (
|
|
<div className="grid gap-6 md:grid-cols-3">
|
|
<Card>
|
|
<CardHeader>
|
|
<CardTitle>Deployment Progress</CardTitle>
|
|
</CardHeader>
|
|
<CardContent>
|
|
<div className="space-y-2">
|
|
<div className="flex justify-between">
|
|
<span className="text-studio-medium">Planned</span>
|
|
<span className="font-semibold">{summary.deploymentProgress.planned}</span>
|
|
</div>
|
|
<div className="flex justify-between">
|
|
<span className="text-studio-medium">In Progress</span>
|
|
<span className="font-semibold text-yellow-400">
|
|
{summary.deploymentProgress.inProgress}
|
|
</span>
|
|
</div>
|
|
<div className="flex justify-between">
|
|
<span className="text-studio-medium">Complete</span>
|
|
<span className="font-semibold text-green-400">
|
|
{summary.deploymentProgress.complete}
|
|
</span>
|
|
</div>
|
|
<div className="flex justify-between">
|
|
<span className="text-studio-medium">Blocked</span>
|
|
<span className="font-semibold text-red-400">
|
|
{summary.deploymentProgress.blocked}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
</div>
|
|
)}
|
|
|
|
<GlobalSearch open={searchOpen} onOpenChange={setSearchOpen} />
|
|
</div>
|
|
)
|
|
}
|
|
|