import { useMemo, useState } from 'react' import { useQuery } from '@tanstack/react-query' import { MapPin } from 'lucide-react' import { metricsApi, tenantsApi } from '@/lib/api' import { useAuth, isSuperAdmin } from '@/lib/auth' import { LoadingText } from '@/components/ui/skeleton' import { FleetMap } from './FleetMap' export function MapPage() { const { user } = useAuth() const superAdmin = isSuperAdmin(user) const [selectedTenant, setSelectedTenant] = useState('all') // Fetch devices -- super_admin gets cross-tenant, others get their own tenant const { data: devices, isLoading: devicesLoading, error: devicesError, } = useQuery({ queryKey: ['fleet-map', superAdmin ? 'all' : user?.tenant_id], queryFn: () => superAdmin ? metricsApi.fleetSummaryAll() : metricsApi.fleetSummary(user!.tenant_id!), enabled: !!user && (superAdmin || !!user.tenant_id), }) // Fetch tenant list for super_admin filter dropdown const { data: tenants } = useQuery({ queryKey: ['tenants'], queryFn: tenantsApi.list, enabled: superAdmin, }) // Filter devices by selected tenant const filteredDevices = useMemo(() => { if (!devices) return [] if (selectedTenant === 'all') return devices return devices.filter((d) => d.tenant_id === selectedTenant) }, [devices, selectedTenant]) // Count mapped vs total const totalDevices = filteredDevices.length const mappedDevices = filteredDevices.filter( (d) => d.latitude != null && d.longitude != null, ).length // Determine effective tenantId for links in markers const effectiveTenantId = useMemo(() => { if (!superAdmin) return user?.tenant_id ?? '' if (selectedTenant !== 'all') return selectedTenant // For "all" view as super_admin, we pass the device's own tenant_id from the FleetDevice record // The FleetMap component handles this per-device return '' }, [superAdmin, selectedTenant, user]) if (devicesLoading) { return (
) } if (devicesError) { return (

Failed to load fleet data

{devicesError instanceof Error ? devicesError.message : 'Unknown error'}

) } return (
{/* Toolbar */}

Fleet Map

{mappedDevices} of {totalDevices} device{totalDevices !== 1 ? 's' : ''} mapped
{superAdmin && tenants && tenants.length > 0 && ( )}
{/* Map */}
{totalDevices === 0 ? (

No devices found

Add devices with coordinates to see them on the map

) : mappedDevices === 0 ? (

No devices have coordinates

Edit devices and add latitude/longitude to place them on the map

) : ( )}
) } /** * Wrapper that handles tenant routing for markers. * In super_admin "all" mode, each device marker uses its own tenant_id. * Otherwise, the effective tenant is used for all markers. */ function FleetMapWithTenantRouting({ devices, effectiveTenantId, superAdmin, }: { devices: Array<{ latitude: number | null; longitude: number | null; tenant_id: string } & Record> effectiveTenantId: string superAdmin: boolean }) { // For super_admin "all" view we need per-device tenant routing // FleetMap + DeviceMarker handle this by using device.tenant_id when tenantId is empty const tenantId = superAdmin && !effectiveTenantId ? '' : effectiveTenantId return ( ) }