Add dedicated New Project page for clients

Route /new-project: name + company selector → creates project, redirects
to project detail. My Projects buttons now link there instead of new-request.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Krao Hasanee
2026-05-13 11:35:42 -04:00
parent 572c290f48
commit 1b7c53b810
3 changed files with 161 additions and 24 deletions
+3 -3
View File
@@ -104,7 +104,7 @@ function ProjectGroup({ project, tasks, submissions, currentUserId, filter }) {
)}
<div style={{ padding: '10px 16px', borderTop: filteredTasks.length > 0 ? '1px solid var(--border)' : 'none' }}>
<Link
to={`/new-request?project=${encodeURIComponent(project.name)}`}
to={`/new-project?project=${encodeURIComponent(project.name)}`}
className="btn btn-outline btn-sm"
>
+ Add Request to {project.name}
@@ -169,7 +169,7 @@ export default function MyProjects() {
<div className="page-title">Projects</div>
<div className="page-subtitle">All work for your company.</div>
</div>
<Link to="/new-request" className="btn btn-primary">+ New Project</Link>
<Link to="/new-project" className="btn btn-primary">+ New Project</Link>
</div>
<div className="card page-toolbar">
@@ -199,7 +199,7 @@ export default function MyProjects() {
<div className="empty-state">
<h3>No projects yet</h3>
<p>Submit a request and a project will be created automatically.</p>
<Link to="/new-request" className="btn btn-primary" style={{ marginTop: 16 }}>+ New Project</Link>
<Link to="/new-project" className="btn btn-primary" style={{ marginTop: 16 }}>+ New Project</Link>
</div>
) : (
projects.map(project => (
+109
View File
@@ -0,0 +1,109 @@
import { useState } from 'react';
import { useNavigate } from 'react-router-dom';
import Layout from '../../components/Layout';
import { supabase } from '../../lib/supabase';
import { useAuth } from '../../context/AuthContext';
export default function NewProject() {
const { currentUser } = useAuth();
const navigate = useNavigate();
const companyOptions = currentUser.companies?.length
? currentUser.companies
: (currentUser.company ? [currentUser.company] : []);
const [selectedCompanyId, setSelectedCompanyId] = useState(companyOptions[0]?.id || '');
const [name, setName] = useState('');
const [saving, setSaving] = useState(false);
const [error, setError] = useState(null);
if (!companyOptions.length) {
return (
<Layout>
<div style={{ maxWidth: 480, margin: '0 auto', textAlign: 'center', paddingTop: 48 }}>
<h2 style={{ fontSize: 20, fontWeight: 700, marginBottom: 8 }}>Account Not Yet Active</h2>
<p style={{ color: 'var(--text-secondary)', fontSize: 14 }}>
Your account hasn't been linked to a company yet. Please contact the Fourge team to get set up.
</p>
</div>
</Layout>
);
}
const handleSubmit = async (e) => {
e.preventDefault();
if (saving) return;
const trimmedName = name.trim();
if (!trimmedName) return;
setSaving(true);
setError(null);
const { data, error: insertError } = await supabase
.from('projects')
.insert({ company_id: selectedCompanyId, name: trimmedName })
.select('id')
.single();
if (insertError) {
setError(insertError.message);
setSaving(false);
return;
}
navigate(`/my-projects/${data.id}`);
};
return (
<Layout>
<div className="page-header">
<div>
<div className="page-title">New Project</div>
<div className="page-subtitle">Create a project to organise your work.</div>
</div>
</div>
<div className="card" style={{ maxWidth: 480 }}>
<form onSubmit={handleSubmit}>
{companyOptions.length > 1 && (
<div className="form-group">
<label>Company *</label>
<select
value={selectedCompanyId}
onChange={e => setSelectedCompanyId(e.target.value)}
required
>
{companyOptions.map(c => <option key={c.id} value={c.id}>{c.name}</option>)}
</select>
</div>
)}
<div className="form-group">
<label>Project Name *</label>
<input
type="text"
placeholder="e.g. Brand Refresh 2026"
value={name}
onChange={e => setName(e.target.value)}
autoFocus
required
/>
</div>
{error && (
<div className="notification notification-error" style={{ marginBottom: 16 }}>
{error}
</div>
)}
<div className="action-buttons">
<button type="submit" className="btn btn-primary btn-lg" disabled={saving || !name.trim()}>
{saving ? 'Creating...' : 'Create Project'}
</button>
<button type="button" className="btn btn-outline" onClick={() => navigate('/my-projects')}>
Cancel
</button>
</div>
</form>
</div>
</Layout>
);
}