mirror of
https://github.com/elisiariocouto/leggen.git
synced 2025-12-29 02:49:13 +00:00
- Install and configure TanStack Router for type-safe routing - Create route structure with __root.tsx layout and individual route files - Implement mobile-responsive sidebar with collapse functionality - Add clickable logo in sidebar that navigates to overview page - Extract Header and Sidebar components from Dashboard for reusability - Configure Vite with TanStack Router plugin for development - Update main.tsx to use RouterProvider instead of direct App rendering - Maintain existing TanStack Query integration seamlessly - Add proper TypeScript types for all route components - Implement responsive design with mobile overlay and hamburger menu This replaces the tab-based navigation with URL-based routing while maintaining the same user experience and adding powerful features like: - Bookmarkable URLs (/transactions, /analytics, /notifications) - Browser back/forward button support - Direct linking capabilities - Mobile-responsive sidebar with smooth animations - Type-safe navigation with auto-completion
71 lines
2.2 KiB
TypeScript
71 lines
2.2 KiB
TypeScript
import { useLocation } from "@tanstack/react-router";
|
|
import { Menu, Activity, Wifi, WifiOff } from "lucide-react";
|
|
import { useQuery } from "@tanstack/react-query";
|
|
import { apiClient } from "../lib/api";
|
|
|
|
const navigation = [
|
|
{ name: "Overview", to: "/" },
|
|
{ name: "Transactions", to: "/transactions" },
|
|
{ name: "Analytics", to: "/analytics" },
|
|
{ name: "Notifications", to: "/notifications" },
|
|
];
|
|
|
|
interface HeaderProps {
|
|
setSidebarOpen: (open: boolean) => void;
|
|
}
|
|
|
|
export default function Header({ setSidebarOpen }: HeaderProps) {
|
|
const location = useLocation();
|
|
const currentPage =
|
|
navigation.find((item) => item.to === location.pathname)?.name ||
|
|
"Dashboard";
|
|
|
|
const {
|
|
data: healthStatus,
|
|
isLoading: healthLoading,
|
|
isError: healthError,
|
|
} = useQuery({
|
|
queryKey: ["health"],
|
|
queryFn: apiClient.getHealth,
|
|
refetchInterval: 30000,
|
|
});
|
|
|
|
return (
|
|
<header className="bg-white shadow-sm border-b border-gray-200">
|
|
<div className="flex items-center justify-between h-16 px-6">
|
|
<div className="flex items-center">
|
|
<button
|
|
onClick={() => setSidebarOpen(true)}
|
|
className="lg:hidden p-1 rounded-md text-gray-400 hover:text-gray-500"
|
|
>
|
|
<Menu className="h-6 w-6" />
|
|
</button>
|
|
<h2 className="text-lg font-semibold text-gray-900 lg:ml-0 ml-4">
|
|
{currentPage}
|
|
</h2>
|
|
</div>
|
|
<div className="flex items-center space-x-2">
|
|
<div className="flex items-center space-x-1">
|
|
{healthLoading ? (
|
|
<>
|
|
<Activity className="h-4 w-4 text-yellow-500 animate-pulse" />
|
|
<span className="text-sm text-gray-600">Checking...</span>
|
|
</>
|
|
) : healthError || healthStatus?.status !== "healthy" ? (
|
|
<>
|
|
<WifiOff className="h-4 w-4 text-red-500" />
|
|
<span className="text-sm text-red-500">Disconnected</span>
|
|
</>
|
|
) : (
|
|
<>
|
|
<Wifi className="h-4 w-4 text-green-500" />
|
|
<span className="text-sm text-gray-600">Connected</span>
|
|
</>
|
|
)}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</header>
|
|
);
|
|
}
|