import { useState, useEffect, useRef } from "react"; import { debounce } from "lodash"; import type { Project, OrganizationLocation, FilterState, ChatMessage,AvailableFilters } from "./types"; interface Stats { [key: string]: { labels: string[]; values: number[]; }; } export const useAppState = () => { const [projects, setProjects] = useState([]); const [search, setSearch] = useState(""); const [statusFilter, setStatusFilter] = useState(""); const [page, setPage] = useState(0); const [question, setQuestion] = useState(""); const [selectedProject, setSelectedProject] = useState(null); const [stats, setStats] = useState({}); const [filters, setFilters] = useState({ status: "", organization: "", country: "", legalBasis: "", minYear: "2000", maxYear: "2025", minFunding: "0", maxFunding: "10000000", }); const [chatHistory, setChatHistory] = useState([]); const [availableFilters, setAvailableFilters] = useState({ statuses: ["SIGNED", "CLOSED", "TERMINATED"], organizations: [], countries: [], legalBases: [] }); const messagesEndRef = useRef(null); const fetchProjects = () => { fetch(`/api/projects?page=${page}&search=${encodeURIComponent(search)}&status=${statusFilter}`) .then(res => res.json()) .then((data: Project[]) => setProjects(data)) .catch(console.error); }; const fetchStats = debounce((filters: FilterState) => { const params = new URLSearchParams(filters); fetch(`/api/stats?${params.toString()}`) .then(res => res.json()) .then((data: Stats) => setStats(data)) .catch(console.error); }, 500); const fetchAvailableFilters = (filters: FilterState) => { const params = new URLSearchParams(filters); fetch(`/api/filters?${params.toString()}`) .then(res => res.json()) .then((data: Omit) => { setAvailableFilters({ statuses: ["SIGNED", "CLOSED", "TERMINATED"], organizations: data.organizations, countries: data.countries, legalBases: data.legalBases }); }); }; const askChatbot = async () => { if (!question.trim()) return; const newChat: ChatMessage[] = [...chatHistory, { role: "user", content: question }]; setChatHistory(newChat); setQuestion(""); try { const res = await fetch("/api/chat/query", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ question }) }); const data: { answer: string } = await res.json(); setChatHistory([...newChat, { role: "assistant", content: data.answer }]); } catch { setChatHistory([...newChat, { role: "assistant", content: "Something went wrong." }]); } }; useEffect(fetchProjects, [page, search, statusFilter]); useEffect(() => { console.log("Updated filters:", filters); fetchStats(filters); }, [filters]); useEffect(() => fetchAvailableFilters(filters), [filters]); return { selectedProject, dashboardProps: { stats, filters, setFilters, availableFilters }, explorerProps: { projects, search, setSearch, statusFilter, setStatusFilter, page, setPage, setSelectedProject, question, setQuestion, chatHistory, setChatHistory, askChatbot, messagesEndRef }, detailsProps: { project: selectedProject!, question, setQuestion, chatHistory, askChatbot, messagesEndRef } }; };