Fix MyRequests slow load and stuck spinner

- Parallelize tasks + submissions + invoices + invoice_items (4 serial → 1 parallel batch)
- Wrap with withTimeout (10s/12s) so hung queries don't freeze indefinitely
- Add try/catch + finally to guarantee setLoading(false) on any failure

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Krao Hasanee
2026-05-13 13:02:14 -04:00
parent 03fbed8ccc
commit a89f91c8d1
+33 -36
View File
@@ -4,6 +4,7 @@ import Layout from '../../components/Layout';
import StatusBadge from '../../components/StatusBadge'; import StatusBadge from '../../components/StatusBadge';
import { supabase } from '../../lib/supabase'; import { supabase } from '../../lib/supabase';
import { useAuth } from '../../context/AuthContext'; import { useAuth } from '../../context/AuthContext';
import { withTimeout } from '../../lib/withTimeout';
export default function MyRequests() { export default function MyRequests() {
const { currentUser } = useAuth(); const { currentUser } = useAuth();
@@ -17,47 +18,43 @@ export default function MyRequests() {
useEffect(() => { useEffect(() => {
async function load() { async function load() {
// Only fetch tasks where current user was the original submitter try {
const { data: mySubs } = await supabase const { data: mySubs } = await withTimeout(
.from('submissions') supabase.from('submissions').select('task_id, submitted_by_name, version_number, type').eq('submitted_by', currentUser.id).eq('type', 'initial'),
.select('task_id, submitted_by_name, version_number, type') 10000, 'My submissions'
.eq('submitted_by', currentUser.id) );
.eq('type', 'initial');
if (!mySubs || mySubs.length === 0) { setLoading(false); return; } if (!mySubs || mySubs.length === 0) return;
const myTaskIds = mySubs.map(s => s.task_id); const myTaskIds = mySubs.map(s => s.task_id);
const { data: t } = await supabase const [{ data: t }, { data: allSubs }, { data: inv }, { data: itemRows }] = await withTimeout(
.from('tasks').select('*, project:projects(id, name, created_at, status)') Promise.all([
.in('id', myTaskIds); supabase.from('tasks').select('*, project:projects(id, name, created_at, status)').in('id', myTaskIds),
setTasks(t || []); supabase.from('submissions').select('task_id, submitted_by_name, version_number, type').in('task_id', myTaskIds).order('version_number'),
supabase.from('invoices').select('id, status'),
supabase.from('invoice_items').select('task_id, invoice_id').in('task_id', myTaskIds),
]),
12000, 'My requests data'
);
// Also fetch all submissions for these tasks (to show revision history) const tasks = t || [];
const { data: allSubs } = await supabase setTasks(tasks);
.from('submissions') setSubmissions(allSubs || []);
.select('task_id, submitted_by_name, version_number, type') setInvoices(inv || []);
.in('task_id', myTaskIds) setInvoiceItems(itemRows || []);
.order('version_number');
setSubmissions(allSubs || []);
const [{ data: inv }, { data: itemRows }] = await Promise.all([ const projectMap = {};
supabase.from('invoices').select('id, status'), tasks.forEach(task => {
supabase.from('invoice_items').select('task_id, invoice_id').in('task_id', myTaskIds), const p = task.project;
]); if (p && !projectMap[p.id]) projectMap[p.id] = { ...p, id: p.id };
setInvoices(inv || []); });
setInvoiceItems(itemRows || []); setProjects(Object.values(projectMap));
} catch (err) {
// Group tasks by project console.error('MyRequests load failed:', err);
const projectMap = {}; } finally {
(t || []).forEach(task => { setLoading(false);
const p = task.project; }
if (!p) return;
if (!projectMap[p.id]) projectMap[p.id] = { ...p, id: p.id };
});
setProjects(Object.values(projectMap));
setLoading(false);
} }
load(); load();
}, [currentUser.id]); }, [currentUser.id]);