Add company/user filters to Requests, move Companies to bottom of nav
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -8,9 +8,9 @@ function TeamNav({ onNav }) {
|
|||||||
<div className="sidebar-section-label">Main</div>
|
<div className="sidebar-section-label">Main</div>
|
||||||
{[
|
{[
|
||||||
{ to: '/dashboard', label: 'Dashboard' },
|
{ to: '/dashboard', label: 'Dashboard' },
|
||||||
{ to: '/companies', label: 'Companies' },
|
|
||||||
{ to: '/requests', label: 'Requests' },
|
{ to: '/requests', label: 'Requests' },
|
||||||
{ to: '/invoices', label: 'Invoices' },
|
{ to: '/invoices', label: 'Invoices' },
|
||||||
|
{ to: '/companies', label: 'Companies' },
|
||||||
].map(({ to, label }) => (
|
].map(({ to, label }) => (
|
||||||
<NavLink key={to} to={to} onClick={onNav} className={({ isActive }) => `sidebar-link${isActive ? ' active' : ''}`}>
|
<NavLink key={to} to={to} onClick={onNav} className={({ isActive }) => `sidebar-link${isActive ? ' active' : ''}`}>
|
||||||
{label}
|
{label}
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ export default function Requests() {
|
|||||||
const [projects, setProjects] = useState([]);
|
const [projects, setProjects] = useState([]);
|
||||||
const [companies, setCompanies] = useState([]);
|
const [companies, setCompanies] = useState([]);
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
|
const [filterCompany, setFilterCompany] = useState('');
|
||||||
|
const [filterUser, setFilterUser] = useState('');
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
async function load() {
|
async function load() {
|
||||||
@@ -39,6 +41,34 @@ export default function Requests() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div style={{ display: 'flex', gap: 10, marginBottom: 20, flexWrap: 'wrap' }}>
|
||||||
|
<select
|
||||||
|
value={filterCompany}
|
||||||
|
onChange={e => setFilterCompany(e.target.value)}
|
||||||
|
style={{ minWidth: 160 }}
|
||||||
|
>
|
||||||
|
<option value="">All Companies</option>
|
||||||
|
{companies.map(co => (
|
||||||
|
<option key={co.id} value={co.id}>{co.name}</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
<select
|
||||||
|
value={filterUser}
|
||||||
|
onChange={e => setFilterUser(e.target.value)}
|
||||||
|
style={{ minWidth: 160 }}
|
||||||
|
>
|
||||||
|
<option value="">All Users</option>
|
||||||
|
{[...new Set(submissions.map(s => s.submitted_by_name).filter(Boolean))].sort().map(name => (
|
||||||
|
<option key={name} value={name}>{name}</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
{(filterCompany || filterUser) && (
|
||||||
|
<button className="btn btn-outline btn-sm" onClick={() => { setFilterCompany(''); setFilterUser(''); }}>
|
||||||
|
Clear Filters
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
{submissions.length === 0 ? (
|
{submissions.length === 0 ? (
|
||||||
<div className="empty-state">
|
<div className="empty-state">
|
||||||
<h3>No requests yet</h3>
|
<h3>No requests yet</h3>
|
||||||
@@ -53,8 +83,15 @@ export default function Requests() {
|
|||||||
groupMap[key].push(sub);
|
groupMap[key].push(sub);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Sort groups by latest submitted_at descending
|
// Sort groups by latest submitted_at descending, then apply filters
|
||||||
const groups = Object.values(groupMap).sort((a, b) => {
|
const groups = Object.values(groupMap).filter(group => {
|
||||||
|
const primary = group.find(s => s.type !== 'amendment') || group[0];
|
||||||
|
const task = tasks.find(t => t.id === primary.task_id);
|
||||||
|
const project = projects.find(p => p.id === task?.project_id);
|
||||||
|
if (filterCompany && project?.company_id !== filterCompany) return false;
|
||||||
|
if (filterUser && !group.some(s => s.submitted_by_name === filterUser)) return false;
|
||||||
|
return true;
|
||||||
|
}).sort((a, b) => {
|
||||||
const aMax = Math.max(...a.map(s => new Date(s.submitted_at)));
|
const aMax = Math.max(...a.map(s => new Date(s.submitted_at)));
|
||||||
const bMax = Math.max(...b.map(s => new Date(s.submitted_at)));
|
const bMax = Math.max(...b.map(s => new Date(s.submitted_at)));
|
||||||
return bMax - aMax;
|
return bMax - aMax;
|
||||||
|
|||||||
Reference in New Issue
Block a user