Rename client project buttons to '+ New Project'

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Krao Hasanee
2026-05-13 11:33:01 -04:00
parent 8f8b2090f6
commit 572c290f48
+57 -34
View File
@@ -4,8 +4,9 @@ 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';
const vLabel = (v) => 'v' + String(v || 0).padStart(2, '0'); const rLabel = (v) => 'R' + String(v || 0).padStart(2, '0');
function ProjectGroup({ project, tasks, submissions, currentUserId, filter }) { function ProjectGroup({ project, tasks, submissions, currentUserId, filter }) {
const [open, setOpen] = useState(true); const [open, setOpen] = useState(true);
@@ -20,9 +21,10 @@ function ProjectGroup({ project, tasks, submissions, currentUserId, filter }) {
if (filter === 'mine' && filteredTasks.length === 0) return null; if (filter === 'mine' && filteredTasks.length === 0) return null;
return ( return (
<div style={{ border: '1px solid var(--border)', borderRadius: 8, overflow: 'hidden', marginBottom: 8 }}> <div className="interactive-surface" style={{ border: '1px solid var(--border)', borderRadius: 8, overflow: 'hidden', marginBottom: 8 }}>
{/* Project header — clickable to collapse */} {/* Project header — clickable to collapse */}
<button <button
className="interactive-panel-toggle"
onClick={() => setOpen(o => !o)} onClick={() => setOpen(o => !o)}
style={{ style={{
width: '100%', display: 'flex', alignItems: 'center', width: '100%', display: 'flex', alignItems: 'center',
@@ -68,6 +70,7 @@ function ProjectGroup({ project, tasks, submissions, currentUserId, filter }) {
<Link <Link
key={task.id} key={task.id}
to={`/my-requests/${task.id}`} to={`/my-requests/${task.id}`}
className="interactive-row"
style={{ style={{
display: 'flex', alignItems: 'center', justifyContent: 'space-between', display: 'flex', alignItems: 'center', justifyContent: 'space-between',
padding: '12px 16px', padding: '12px 16px',
@@ -81,7 +84,7 @@ function ProjectGroup({ project, tasks, submissions, currentUserId, filter }) {
{task.title} {task.title}
</span> </span>
<span style={{ fontSize: 12, color: 'var(--text-muted)' }}> <span style={{ fontSize: 12, color: 'var(--text-muted)' }}>
{vLabel(task.current_version)} {rLabel(task.current_version)}
</span> </span>
{isMine && ( {isMine && (
<span style={{ fontSize: 11, background: 'rgba(245,165,35,0.15)', color: 'var(--accent)', padding: '1px 7px', borderRadius: 4, fontWeight: 600 }}> <span style={{ fontSize: 11, background: 'rgba(245,165,35,0.15)', color: 'var(--accent)', padding: '1px 7px', borderRadius: 4, fontWeight: 600 }}>
@@ -123,23 +126,36 @@ export default function MyProjects() {
useEffect(() => { useEffect(() => {
async function load() { async function load() {
const [{ data: p }, { data: t }] = await Promise.all([ try {
supabase.from('projects').select('*').order('created_at', { ascending: false }), const [{ data: p }, { data: t }] = await withTimeout(Promise.all([
supabase.from('tasks').select('*').order('submitted_at', { ascending: false }), supabase.from('projects').select('*').order('created_at', { ascending: false }),
]); supabase.from('tasks').select('*').order('submitted_at', { ascending: false }),
setProjects(p || []); ]), 12000, 'Projects load');
setTasks(t || []); setProjects(p || []);
setTasks(t || []);
if (t && t.length > 0) { if (t && t.length > 0) {
const { data: subs } = await supabase const { data: subs } = await withTimeout(
.from('submissions') supabase
.select('id, task_id, submitted_by, submitted_by_name, version_number, type') .from('submissions')
.in('task_id', t.map(task => task.id)) .select('id, task_id, submitted_by, submitted_by_name, version_number, type')
.order('version_number'); .in('task_id', t.map(task => task.id))
setSubmissions(subs || []); .order('version_number'),
12000,
'Project submissions load'
);
setSubmissions(subs || []);
} else {
setSubmissions([]);
}
} catch (error) {
console.error('MyProjects load failed:', error);
setProjects([]);
setTasks([]);
setSubmissions([]);
} finally {
setLoading(false);
} }
setLoading(false);
} }
load(); load();
}, []); }, []);
@@ -153,30 +169,37 @@ export default function MyProjects() {
<div className="page-title">Projects</div> <div className="page-title">Projects</div>
<div className="page-subtitle">All work for your company.</div> <div className="page-subtitle">All work for your company.</div>
</div> </div>
<Link to="/new-request" className="btn btn-primary">+ New Request</Link> <Link to="/new-request" className="btn btn-primary">+ New Project</Link>
</div> </div>
{/* Filter toggle */} <div className="card page-toolbar">
<div style={{ display: 'flex', gap: 8, marginBottom: 20 }}> <div className="page-toolbar-grid">
<button <div className="page-toolbar-section">
className={`btn btn-sm ${filter === 'all' ? 'btn-primary' : 'btn-outline'}`} <div className="card-title" style={{ marginBottom: 10 }}>Filter</div>
onClick={() => setFilter('all')} <div className="page-toolbar-filters">
> <button
All Requests className={`btn btn-sm ${filter === 'all' ? 'btn-primary' : 'btn-outline'}`}
</button> onClick={() => setFilter('all')}
<button >
className={`btn btn-sm ${filter === 'mine' ? 'btn-primary' : 'btn-outline'}`} All Requests
onClick={() => setFilter('mine')} </button>
> <button
Mine Only className={`btn btn-sm ${filter === 'mine' ? 'btn-primary' : 'btn-outline'}`}
</button> onClick={() => setFilter('mine')}
>
Mine Only
</button>
</div>
</div>
</div>
</div> </div>
{projects.length === 0 ? ( {projects.length === 0 ? (
<div className="empty-state"> <div className="empty-state">
<h3>No projects yet</h3> <h3>No projects yet</h3>
<p>Submit a request and a project will be created automatically.</p> <p>Submit a request and a project will be created automatically.</p>
<Link to="/new-request" className="btn btn-primary" style={{ marginTop: 16 }}>Submit Request</Link> <Link to="/new-request" className="btn btn-primary" style={{ marginTop: 16 }}>+ New Project</Link>
</div> </div>
) : ( ) : (
projects.map(project => ( projects.map(project => (