"use client"; import Link from "next/link"; import { useEffect, useMemo, useState } from "react"; import { api } from "@/lib/api"; import type { Issue, Project } from "@/lib/types"; import { PROJECT_STATUS_META } from "@/lib/meta"; import { formatShortDate, percent } from "@/lib/format"; import { useReferenceLookups, useWorkflowStates } from "@/lib/store"; import { AppShell } from "@/components/layout/AppShell"; import { Avatar } from "@/components/ui/Avatar"; import { EmptyState } from "@/components/ui/EmptyState"; import { ProgressBar } from "@/components/ui/ProgressBar"; /** * Listado de proyectos con su progreso calculado a partir de los issues * completados sobre el total. */ export default function ProjectsPage() { const [projects, setProjects] = useState([]); const [issues, setIssues] = useState([]); const [loading, setLoading] = useState(true); const { userById } = useReferenceLookups(); const { doneKeys } = useWorkflowStates(); useEffect(() => { let cancelled = false; void Promise.all([api.listProjects(), api.listIssues()]).then(([projectData, issueData]) => { if (!cancelled) { setProjects(projectData); setIssues(issueData); setLoading(false); } }); return () => { cancelled = true; }; }, []); const progressByProject = useMemo(() => { const map = new Map(); for (const issue of issues) { if (!issue.projectId) continue; const entry = map.get(issue.projectId) ?? { total: 0, done: 0 }; entry.total += 1; if (doneKeys.has(issue.status)) entry.done += 1; map.set(issue.projectId, entry); } return map; }, [issues]); return ( {loading && (
{Array.from({ length: 3 }).map((_, index) => (
))}
)} {!loading && projects.length === 0 && ( )} {!loading && (
{projects.map((project) => { const progress = progressByProject.get(project.id) ?? { total: 0, done: 0 }; const lead = project.leadId ? userById.get(project.leadId) : undefined; const meta = PROJECT_STATUS_META[project.status]; return (
{project.name} {project.key} {meta.label} {progress.done}/{progress.total}

{project.description}

{project.targetDate && ( {formatShortDate(project.targetDate)} )}
); })}
)} ); }