/** biome-ignore-all lint/correctness/useExhaustiveDependencies: <> */ import type { IssueResponse, OrganisationResponse, ProjectResponse, UserRecord } from "@issue/shared"; import { useEffect, useRef, useState } from "react"; import { Link } from "react-router-dom"; import { CreateIssue } from "@/components/create-issue"; import { CreateOrganisation } from "@/components/create-organisation"; import { CreateProject } from "@/components/create-project"; import { IssueDetailPane } from "@/components/issue-detail-pane"; import { IssuesTable } from "@/components/issues-table"; import LogOutButton from "@/components/log-out-button"; import SmallUserDisplay from "@/components/small-user-display"; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu"; import { Select, SelectContent, SelectItem, SelectSeparator, SelectTrigger, SelectValue, } from "@/components/ui/select"; import { getAuthHeaders } from "@/lib/utils"; import { Button } from "./components/ui/button"; import { ResizablePanel, ResizablePanelGroup, ResizableSeparator } from "./components/ui/resizable"; function Index() { const serverURL = import.meta.env.VITE_SERVER_URL?.trim() || "http://localhost:3000"; const user = JSON.parse(localStorage.getItem("user") || "{}") as UserRecord; const organisationsRef = useRef(false); const [organisations, setOrganisations] = useState([]); const [organisationSelectOpen, setOrganisationSelectOpen] = useState(false); const [selectedOrganisation, setSelectedOrganisation] = useState(null); const [projects, setProjects] = useState([]); const [projectSelectOpen, setProjectSelectOpen] = useState(false); const [selectedProject, setSelectedProject] = useState(null); const [issues, setIssues] = useState([]); const [selectedIssue, setSelectedIssue] = useState(null); const refetchOrganisations = async (options?: { selectOrganisationId?: number }) => { try { const res = await fetch(`${serverURL}/organisation/by-user?userId=${user.id}`, { headers: getAuthHeaders(), }); const data = (await res.json()) as Array; setOrganisations(data); // select newly created organisation if (options?.selectOrganisationId) { const created = data.find((o) => o.Organisation.id === options.selectOrganisationId); if (created) { setSelectedOrganisation(created); return; } } // preserve previously selected organisation setSelectedOrganisation((prev) => { if (!prev) return data[0] || null; const stillExists = data.find((o) => o.Organisation.id === prev.Organisation.id); return stillExists || data[0] || null; }); } catch (err) { console.error("error fetching organisations:", err); } }; useEffect(() => { if (organisationsRef.current) return; organisationsRef.current = true; void refetchOrganisations(); }, [user.id]); useEffect(() => { setSelectedOrganisation((prev) => prev || organisations[0] || null); }, [organisations]); const refetchProjects = async (organisationId: number, options?: { selectProjectId?: number }) => { try { const res = await fetch( `${serverURL}/projects/by-organisation?organisationId=${organisationId}`, { headers: getAuthHeaders(), }, ); const data = (await res.json()) as ProjectResponse[]; setProjects(data); // select newly created project if (options?.selectProjectId) { const created = data.find((p) => p.Project.id === options.selectProjectId); if (created) { setSelectedProject(created); return; } } // preserve previously selected project setSelectedProject((prev) => { if (!prev) return data[0] || null; const stillExists = data.find((p) => p.Project.id === prev.Project.id); return stillExists || data[0] || null; }); } catch (err) { console.error("error fetching projects:", err); setProjects([]); } }; // fetch projects when organisation is selected useEffect(() => { setProjects([]); setSelectedProject(null); setSelectedIssue(null); setIssues([]); if (!selectedOrganisation) { return; } void refetchProjects(selectedOrganisation.Organisation.id); }, [selectedOrganisation]); useEffect(() => { setSelectedProject((prev) => prev || projects[0] || null); }, [projects]); const refetchIssues = async (projectKey: string) => { try { const res = await fetch(`${serverURL}/issues/${projectKey}`, { headers: getAuthHeaders(), }); const data = (await res.json()) as IssueResponse[]; setIssues(data); } catch (err) { console.error("error fetching issues:", err); setIssues([]); } }; // fetch issues when project is selected useEffect(() => { if (!selectedProject) return; void refetchIssues(selectedProject.Project.key); }, [selectedProject]); return (
{/* header area */}
{/* organisation selection */} {/* project selection - only shown when organisation is selected */} {selectedOrganisation && ( )} {selectedOrganisation && selectedProject && ( { if (!selectedProject) return; await refetchIssues(selectedProject.Project.key); }} /> )}
Settings My Account My Organisations
{/* main body */}
{selectedProject && issues.length > 0 && ( {/* issues list (table) */} {/* issue detail pane */} {selectedIssue && ( <>
setSelectedIssue(null)} />
)}
)}
{/* */}
); } export default Index;