import { useState, useEffect } from 'react'; import { Link } from 'react-router-dom'; import Layout from '../../components/Layout'; import StatusBadge from '../../components/StatusBadge'; import { supabase } from '../../lib/supabase'; import { useAuth } from '../../context/AuthContext'; const vLabel = (v) => 'v' + String(v).padStart(2, '0'); function ProjectGroup({ project, tasks, submissions, currentUserId, filter }) { const [open, setOpen] = useState(true); const filteredTasks = filter === 'mine' ? tasks.filter(task => { const initial = submissions.find(s => s.task_id === task.id && s.type === 'initial'); return initial?.submitted_by === currentUserId; }) : tasks; if (filter === 'mine' && filteredTasks.length === 0) return null; return (
{/* Project header — clickable to collapse */} {open && (
{filteredTasks.length === 0 ? (
No requests in this project yet.
) : ( filteredTasks.map((task, i) => { const taskSubs = submissions.filter(s => s.task_id === task.id); const initialSub = taskSubs.find(s => s.type === 'initial') || taskSubs[0]; const latestSub = taskSubs[taskSubs.length - 1]; const hasRevision = latestSub && initialSub && latestSub.id !== initialSub.id && latestSub.submitted_by_name !== initialSub.submitted_by_name; const isMine = initialSub?.submitted_by === currentUserId; return (
{task.title} {vLabel(task.current_version)} {isMine && ( Mine )}
{initialSub?.submitted_by_name && <>By {initialSub.submitted_by_name}} {hasRevision && <> · Updated by {latestSub.submitted_by_name}}
Details
); }) )}
0 ? '1px solid var(--border)' : 'none' }}> + Add Request to {project.name}
)}
); } export default function MyProjects() { const { currentUser } = useAuth(); const [projects, setProjects] = useState([]); const [tasks, setTasks] = useState([]); const [submissions, setSubmissions] = useState([]); const [loading, setLoading] = useState(true); const [filter, setFilter] = useState('all'); // 'all' | 'mine' useEffect(() => { async function load() { const { data: p } = await supabase .from('projects').select('*').order('created_at', { ascending: false }); setProjects(p || []); if (!p || p.length === 0) { setLoading(false); return; } const { data: t } = await supabase .from('tasks').select('*').in('project_id', p.map(pr => pr.id)) .order('submitted_at', { ascending: false }); setTasks(t || []); if (t && t.length > 0) { const { data: subs } = await supabase .from('submissions') .select('id, task_id, submitted_by, submitted_by_name, version_number, type') .in('task_id', t.map(task => task.id)) .order('version_number'); setSubmissions(subs || []); } setLoading(false); } load(); }, []); if (loading) return

Loading...

; return (
Projects
All work for your company.
+ New Request
{/* Filter toggle */}
{projects.length === 0 ? (

No projects yet

Submit a request and a project will be created automatically.

Submit Request
) : ( projects.map(project => ( t.project_id === project.id)} submissions={submissions} currentUserId={currentUser.id} filter={filter} /> )) )}
); }