feat(14-03): replace site detail placeholder with tabbed dashboard

- Add Health Grid, Sectors, Links tabs using useState pattern
- Default tab is Health Grid showing device status cards
- Remove placeholder "Assigned Devices" section
- Site info card and health stats remain above tabs unchanged
This commit is contained in:
Jason Staack
2026-03-19 06:54:01 -05:00
parent d89233bcf5
commit a9db9e4bfe

View File

@@ -1,9 +1,13 @@
import { useState } from 'react'
import { createFileRoute, Link } from '@tanstack/react-router' import { createFileRoute, Link } from '@tanstack/react-router'
import { useQuery } from '@tanstack/react-query' import { useQuery } from '@tanstack/react-query'
import { sitesApi } from '@/lib/api' import { sitesApi } from '@/lib/api'
import { MapPin, ArrowLeft } from 'lucide-react' import { MapPin, ArrowLeft } from 'lucide-react'
import { Button } from '@/components/ui/button' import { Button } from '@/components/ui/button'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
import { SiteHealthGrid } from '@/components/sites/SiteHealthGrid'
import { SiteSectorView } from '@/components/sites/SiteSectorView'
import { SiteLinksTab } from '@/components/sites/SiteLinksTab'
export const Route = createFileRoute('/_authenticated/tenants/$tenantId/sites/$siteId')({ export const Route = createFileRoute('/_authenticated/tenants/$tenantId/sites/$siteId')({
component: SiteDetailPage, component: SiteDetailPage,
@@ -11,6 +15,7 @@ export const Route = createFileRoute('/_authenticated/tenants/$tenantId/sites/$s
function SiteDetailPage() { function SiteDetailPage() {
const { tenantId, siteId } = Route.useParams() const { tenantId, siteId } = Route.useParams()
const [activeTab, setActiveTab] = useState<'health' | 'sectors' | 'links'>('health')
const { data: site, isLoading } = useQuery({ const { data: site, isLoading } = useQuery({
queryKey: ['sites', tenantId, siteId], queryKey: ['sites', tenantId, siteId],
@@ -111,15 +116,28 @@ function SiteDetailPage() {
</div> </div>
</div> </div>
{/* Placeholder for device list -- Phase 14 will add full site dashboard */} {/* Tab bar */}
<div className="rounded-lg border border-border bg-surface p-6"> <div className="flex gap-1 border-b border-border">
<h2 className="text-sm font-semibold mb-2">Assigned Devices</h2> {(['health', 'sectors', 'links'] as const).map((tab) => (
<p className="text-sm text-text-muted"> <button
{site.device_count > 0 key={tab}
? `${site.device_count} device${site.device_count !== 1 ? 's' : ''} assigned to this site. Full device list coming in site dashboard.` onClick={() => setActiveTab(tab)}
: 'No devices assigned to this site yet. Assign devices from the fleet page.'} className={cn(
</p> 'px-4 py-2 text-sm font-medium border-b-2 -mb-px transition-colors',
activeTab === tab
? 'border-accent text-accent'
: 'border-transparent text-text-muted hover:text-text-secondary',
)}
>
{tab === 'health' ? 'Health Grid' : tab === 'sectors' ? 'Sectors' : 'Links'}
</button>
))}
</div> </div>
{/* Tab content */}
{activeTab === 'health' && <SiteHealthGrid tenantId={tenantId} siteId={siteId} />}
{activeTab === 'sectors' && <SiteSectorView tenantId={tenantId} siteId={siteId} />}
{activeTab === 'links' && <SiteLinksTab tenantId={tenantId} siteId={siteId} />}
</div> </div>
) )
} }