"use client"; import { Suspense, useMemo, useCallback } from "react"; import { useSearchParams, useRouter } from "next/navigation"; import { useWorkSessions } from "@/hooks/use-work-sessions"; import { WorkSessionStatus } from "@/types"; import { OfflineState } from "@/components/ui/offline-state"; import { WorkSessionTable, WorkSessionFilters } from "@/components/work-sessions"; import { Button } from "@/components/ui/button"; import { Skeleton } from "@/components/ui/skeleton"; import { RefreshCw } from "lucide-react"; function WorkSessionsPageContent() { const router = useRouter(); const searchParams = useSearchParams(); // Read state from URL params const searchQuery = searchParams.get("q") || ""; const statusParam = searchParams.get("status"); const statusFilter = useMemo( () => (statusParam?.split(",").filter(Boolean) as WorkSessionStatus[]) || [], [statusParam] ); // Update URL params const updateParams = useCallback( (updates: Record) => { const params = new URLSearchParams(searchParams.toString()); Object.entries(updates).forEach(([key, value]) => { if (value) { params.set(key, value); } else { params.delete(key); } }); const query = params.toString(); router.push(query ? `/work-sessions?${query}` : "/work-sessions"); }, [router, searchParams] ); const handleSearchChange = useCallback( (value: string) => { updateParams({ q: value || null }); }, [updateParams] ); const handleStatusChange = useCallback( (value: WorkSessionStatus[]) => { updateParams({ status: value.length > 0 ? value.join(",") : null }); }, [updateParams] ); // Fetch work sessions const { data: sessions, isLoading, error, refetch } = useWorkSessions(); // Filter sessions client-side for search and multi-select status filter const filteredSessions = useMemo(() => { if (!sessions) return []; return sessions.filter((session) => { // Search filter - match branch name if ( searchQuery && !session.branch_name.toLowerCase().includes(searchQuery.toLowerCase()) ) { return false; } // Status filter (if any selected, session must match one of them) if (statusFilter.length > 0 && !statusFilter.includes(session.status)) { return false; } return true; }); }, [sessions, searchQuery, statusFilter]); // Check if it's a connection error (backend not running) const isOffline = error && (error.message?.includes("Network Error") || error.message?.includes("ECONNREFUSED") || (error as { code?: string })?.code === "ERR_NETWORK"); return (
{/* Header */}

Work Sessions

Track git branches and pull requests for active work

{/* Filters - Sticky */}
{/* Content */} {isOffline ? ( refetch()} /> ) : ( )}
); } // Wrap in Suspense for useSearchParams export default function WorkSessionsPage() { return (
} >
); }