"use client"; import { useState, useEffect, useCallback } from "react"; import { ChatSession } from "../../../lib/types"; import Link from "next/link"; // Placeholder for a SessionListItem component to be created later // For now, we'll display some basic info directly. // import SessionListItem from "../../../components/SessionListItem"; // TODO: Consider moving filter/sort types to lib/types.ts if they become complex interface FilterOptions { categories: string[]; languages: string[]; } export default function SessionsPage() { const [sessions, setSessions] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [searchTerm, setSearchTerm] = useState(""); // Filter states const [filterOptions, setFilterOptions] = useState({ categories: [], languages: [], }); const [selectedCategory, setSelectedCategory] = useState(""); const [selectedLanguage, setSelectedLanguage] = useState(""); const [startDate, setStartDate] = useState(""); const [endDate, setEndDate] = useState(""); // Sort states const [sortKey, setSortKey] = useState("startTime"); // Default sort key const [sortOrder, setSortOrder] = useState<"asc" | "desc">("desc"); // Default sort order // Debounce search term to avoid excessive API calls const [debouncedSearchTerm, setDebouncedSearchTerm] = useState(searchTerm); useEffect(() => { const timerId = setTimeout(() => { setDebouncedSearchTerm(searchTerm); }, 500); // 500ms delay return () => { clearTimeout(timerId); }; }, [searchTerm]); const fetchFilterOptions = useCallback(async () => { // TODO: Implement API endpoint to fetch distinct categories and languages // For now, using placeholder data or deriving from fetched sessions if possible // This should ideally be a separate API call: GET /api/dashboard/session-filter-options try { // Simulating fetching filter options. Replace with actual API call. // const response = await fetch('/api/dashboard/session-filter-options'); // if (!response.ok) { // throw new Error('Failed to fetch filter options'); // } // const data = await response.json(); // setFilterOptions(data); // Placeholder - In a real scenario, fetch these from the backend // For now, we can extract from all sessions once fetched, but this is not ideal for initial load. // This will be improved when the backend endpoint is ready. if (sessions.length > 0) { const categories = Array.from( new Set(sessions.map((s) => s.category).filter(Boolean)) ) as string[]; const languages = Array.from( new Set(sessions.map((s) => s.language).filter(Boolean)) ) as string[]; setFilterOptions({ categories, languages }); } } catch { // setError("Failed to load filter options"); // Optionally set an error state } }, [sessions]); // Re-fetch if sessions change, for placeholder logic. const fetchSessions = useCallback(async () => { setLoading(true); setError(null); try { const params = new URLSearchParams(); if (debouncedSearchTerm) params.append("searchTerm", debouncedSearchTerm); if (selectedCategory) params.append("category", selectedCategory); if (selectedLanguage) params.append("language", selectedLanguage); if (startDate) params.append("startDate", startDate); if (endDate) params.append("endDate", endDate); if (sortKey) params.append("sortKey", sortKey); if (sortOrder) params.append("sortOrder", sortOrder); const response = await fetch( `/api/dashboard/sessions?${params.toString()}` ); if (!response.ok) { throw new Error(`Failed to fetch sessions: ${response.statusText}`); } const data = await response.json(); setSessions(data.sessions || []); // After fetching sessions, update filter options (temporary solution) if (data.sessions && data.sessions.length > 0) { const categories = Array.from( new Set( data.sessions.map((s: ChatSession) => s.category).filter(Boolean) ) ) as string[]; const languages = Array.from( new Set( data.sessions.map((s: ChatSession) => s.language).filter(Boolean) ) ) as string[]; setFilterOptions({ categories, languages }); } } catch (err) { setError( err instanceof Error ? err.message : "An unknown error occurred" ); setSessions([]); } finally { setLoading(false); } }, [ debouncedSearchTerm, selectedCategory, selectedLanguage, startDate, endDate, sortKey, sortOrder, ]); useEffect(() => { fetchSessions(); }, [fetchSessions]); // Fetch initial filter options (or update if sessions change - placeholder) useEffect(() => { // This is a placeholder. Ideally, filter options are fetched once, // or if they are dynamic and dependent on other filters, fetched accordingly. // For now, this re-runs if sessions data changes, which is not optimal. fetchFilterOptions(); }, [fetchFilterOptions]); return (

Chat Sessions

{/* Search Input */}
setSearchTerm(e.target.value)} />
{/* Filter and Sort Controls */}
{/* Category Filter */}
{/* Language Filter */}
{/* Start Date Filter */}
setStartDate(e.target.value)} />
{/* End Date Filter */}
setEndDate(e.target.value)} />
{/* Sort Key */}
{/* Sort Order */}
{loading &&

Loading sessions...

} {error &&

Error: {error}

} {!loading && !error && sessions.length === 0 && (

{debouncedSearchTerm ? `No sessions found for "${debouncedSearchTerm}".` : "No sessions found."}

)} {!loading && !error && sessions.length > 0 && (
{sessions.map((session) => (

Session ID: {session.sessionId || session.id}

Start Time: {new Date(session.startTime).toLocaleString()}

{session.category && (

Category:{" "} {session.category}

)} {session.language && (

Language:{" "} {session.language.toUpperCase()}

)} {session.initialMsg && (

Initial Message: {session.initialMsg}

)} View Details
))}
)} {/* TODO: Add pagination controls (e.g., using a library or custom component) */} {/* TODO: Implement advanced filtering (by date range, category, language, etc.) - Partially done, needs backend support for filter options and robust date filtering */} {/* TODO: Implement sorting options for the session list (e.g., by start time, sentiment) - Partially done, needs backend support */}
); }