import { Outlet, Link, useLocation, useNavigate } from 'react-router-dom'
import { useState, Fragment } from 'react'
import { Menu, Transition } from '@headlessui/react'
import {
HomeIcon,
MapIcon,
DocumentTextIcon,
BellAlertIcon,
BuildingLibraryIcon,
Cog6ToothIcon,
ChartBarIcon,
MagnifyingGlassIcon,
BookOpenIcon,
UserGroupIcon,
AcademicCapIcon,
Bars3Icon,
XMarkIcon,
UserCircleIcon,
ArrowRightOnRectangleIcon,
ChevronDownIcon,
MapPinIcon,
HeartIcon,
CodeBracketIcon,
XCircleIcon,
} from '@heroicons/react/24/outline'
import { useAuth } from '../contexts/AuthContext'
import { useLocation as useLocationContext } from '../contexts/LocationContext'
const navigation = [
{ name: 'Home', href: '/', icon: HomeIcon },
{ name: 'Explore Data', href: '/explore', icon: MagnifyingGlassIcon },
{ name: 'Search', href: '/search', icon: MagnifyingGlassIcon },
{ name: 'Jurisdictions', href: '/jurisdictions', icon: MapPinIcon },
{
section: 'Families & Individuals',
items: [
{ name: 'Community Events', href: '/events', icon: BookOpenIcon },
{ name: 'Services & Resources', href: '/services', icon: HeartIcon },
]
},
{
section: 'Policy & Government',
items: [
{ name: 'Policy Decisions', href: '/documents', icon: DocumentTextIcon },
{ name: 'Budget Analysis', href: '/analytics', icon: ChartBarIcon },
{ name: 'Elected Officials', href: '/people', icon: UserGroupIcon },
{ name: 'Policy Map', href: '/policy-map', icon: MapIcon },
]
},
{
section: 'Community & Advocacy',
items: [
{ name: 'Nonprofits', href: '/nonprofits', icon: BuildingLibraryIcon },
{ name: 'Advocacy Topics', href: '/advocacy-topics', icon: BellAlertIcon },
{ name: 'Fact-Checking', href: '/fact-checking', icon: AcademicCapIcon },
]
},
{
section: 'Developers',
items: [
{ name: 'Open Source', href: '/opensource', icon: CodeBracketIcon },
{ name: 'Hackathons', href: '/hackathons', icon: AcademicCapIcon },
]
},
{ name: 'Settings', href: '/settings', icon: Cog6ToothIcon },
]
export default function Layout() {
const location = useLocation()
const navigate = useNavigate()
const [searchQuery, setSearchQuery] = useState('')
const [mobileMenuOpen, setMobileMenuOpen] = useState(false)
const [showLoginMenu, setShowLoginMenu] = useState(false)
const { user, isAuthenticated, login, logout, isLoading, authError, clearAuthError } = useAuth()
const { location: userLocation, hasLocation } = useLocationContext()
// Environment-aware URLs
const docsUrl = import.meta.env.PROD ? 'https://www.communityone.com/docs/intro' : 'http://localhost:3000/docs/intro'
const apiDocsUrl = import.meta.env.PROD ? 'https://www.communityone.com/api/docs' : 'http://localhost:8000/docs'
const handleSearch = (e: React.FormEvent) => {
e.preventDefault()
if (searchQuery.trim()) {
navigate(`/search?q=${encodeURIComponent(searchQuery)}`)
}
}
return (
{/* Top Header Bar */}
{/* Mobile menu button */}
Open Navigator
{/* Global Search - Hidden on home page and mobile */}
{location.pathname !== '/' && (
)}
{/* Header Actions */}
{/* Location Banner - Compact */}
{hasLocation && userLocation && (
{userLocation.city}, {userLocation.state}
{userLocation.county && (
{userLocation.county}
)}
)}
{/* Authentication */}
{isLoading ? (
) : isAuthenticated && user ? (
) : (
{showLoginMenu && (
)}
)}
Docs
e.currentTarget.style.backgroundColor = '#2e4346'}
onMouseLeave={(e) => e.currentTarget.style.backgroundColor = '#354F52'}
>
API
{/* Sidebar */}
{/* Sidebar Footer */}
Open Data Sources
• 925 Jurisdictions
• 43,726 Nonprofits
• 6,913 Meeting Pages
• 362 Officials
📍 Request Jurisdiction Coverage
{/* Mobile menu overlay */}
{mobileMenuOpen && (
setMobileMenuOpen(false)}
/>
)}
{/* Main content */}
{/* Auth Error Banner - Mobile Friendly */}
{authError && (
)}
)
}