Refactor: clients → companies schema v2

This commit is contained in:
Krao Hasanee
2026-03-26 23:42:06 -04:00
commit 719209fa25
61 changed files with 8192 additions and 0 deletions
+122
View File
@@ -0,0 +1,122 @@
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';
export default function MyRequests() {
const { currentUser } = useAuth();
const [projects, setProjects] = useState([]);
const [tasks, setTasks] = useState([]);
const [submissions, setSubmissions] = useState([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
async function load() {
// Only fetch tasks where current user was the original submitter
const { data: mySubs } = await supabase
.from('submissions')
.select('task_id, submitted_by_name, version_number, type')
.eq('submitted_by', currentUser.id)
.eq('type', 'initial');
if (!mySubs || mySubs.length === 0) { setLoading(false); return; }
const myTaskIds = mySubs.map(s => s.task_id);
const { data: t } = await supabase
.from('tasks').select('*, project:projects(id, name, created_at, status)')
.in('id', myTaskIds);
setTasks(t || []);
// Also fetch all submissions for these tasks (to show revision history)
const { data: allSubs } = await supabase
.from('submissions')
.select('task_id, submitted_by_name, version_number, type')
.in('task_id', myTaskIds)
.order('version_number');
setSubmissions(allSubs || []);
// Group tasks by project
const projectMap = {};
(t || []).forEach(task => {
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();
}, [currentUser.id]);
if (loading) return <Layout><p style={{ padding: 24, color: 'var(--text-muted)' }}>Loading...</p></Layout>;
return (
<Layout>
<div className="page-header">
<div>
<div className="page-title">My Requests</div>
<div className="page-subtitle">Requests you have submitted.</div>
</div>
<Link to="/new-request" className="btn btn-primary">+ New Request</Link>
</div>
{projects.length === 0 ? (
<div className="empty-state">
<div className="empty-state-icon">📋</div>
<h3>No requests yet</h3>
<p>Submit a new request to get started.</p>
<Link to="/new-request" className="btn btn-primary" style={{ marginTop: 16 }}>Submit Request</Link>
</div>
) : (
projects.map(project => {
const projectTasks = tasks.filter(t => t.project?.id === project.id);
return (
<div key={project.id} className="request-card">
<div className="request-card-header">
<div>
<div className="request-card-title">{project.name}</div>
<div className="request-card-meta">
Started {new Date(project.created_at).toLocaleDateString()} · {projectTasks.length} job{projectTasks.length !== 1 ? 's' : ''}
</div>
</div>
<StatusBadge status={project.status} />
</div>
<div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
{projectTasks.map(task => {
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 = taskSubs.length > 1 && latestSub?.submitted_by_name !== initialSub?.submitted_by_name;
return (
<div key={task.id} style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: '10px 14px', background: 'var(--bg)', borderRadius: 8 }}>
<div>
<span style={{ fontWeight: 600, fontSize: 13 }}>
{task.title}{' '}
<span style={{ fontWeight: 400, color: 'var(--text-muted)' }}>
{'v' + String(task.current_version).padStart(2, '0')}
</span>
</span>
<div style={{ fontSize: 11, color: 'var(--text-muted)', marginTop: 2 }}>
Submitted by {initialSub?.submitted_by_name || 'Unknown'}
{hasRevision && ` · Last updated by ${latestSub.submitted_by_name}`}
</div>
</div>
<div className="flex items-center gap-3">
<StatusBadge status={task.status} />
<Link to={`/my-requests/${task.id}`} className="btn btn-outline btn-sm">Details</Link>
</div>
</div>
);
})}
</div>
</div>
);
})
)}
</Layout>
);
}