Team Members section added in Projects List page

This commit is contained in:
Satyam Rastogi
2026-05-13 19:59:37 +05:30
parent 2299cda11d
commit 46605fd31e
+69 -2
View File
@@ -3,9 +3,10 @@ import { useNavigate } from 'react-router-dom';
import { useAuth } from '../../context/AuthContext';
import { useMockStore } from '../../data/mockStore';
import { SpotlightCard } from '../../components/SpotlightCard';
import TeamManagementPanel from '../../components/owner/TeamManagementPanel';
import {
Search, ChevronRight, ArrowUpDown, Briefcase, LayoutGrid,
CheckCircle, Clock, AlertTriangle, PauseCircle, ShieldAlert, User
CheckCircle, Clock, AlertTriangle, PauseCircle, ShieldAlert, User, Users, ChevronDown
} from 'lucide-react';
const statusConfig = {
@@ -49,7 +50,12 @@ function getPipelineHealth(lead) {
const OwnerProjectList = () => {
const { user } = useAuth();
const { projects, vendors, kanbanLeads, kanbanColumns } = useMockStore();
const {
projects, vendors, kanbanLeads, kanbanColumns,
users, personnel, orgCommissionDefaults, userCommissionOverrides,
roleCommissionOverrides, orgMembers,
addJobTeamMember, removeJobTeamMember, updateJobTeamMember,
} = useMockStore();
const navigate = useNavigate();
const [activeSection, setActiveSection] = useState('construction'); // 'construction' | 'pipeline'
@@ -69,6 +75,23 @@ const OwnerProjectList = () => {
projects.filter(p => p.ownerId === user?.id)
, [projects, user]);
// ── Team Management ──
const [selectedProjectId, setSelectedProjectId] = useState(null);
const selectedProject = useMemo(() => {
const id = selectedProjectId || ownerProjects.find(p => p.status === 'active')?.id;
return ownerProjects.find(p => p.id === id) || ownerProjects[0] || null;
}, [selectedProjectId, ownerProjects]);
const teamFinancials = useMemo(() => {
if (!selectedProject) return { totalReceived: 0, grossProfit: 0 };
const paid = (selectedProject.paymentSchedule || [])
.filter(ps => ps.status === 'paid')
.reduce((s, ps) => s + (ps.amount || 0), 0);
const totalReceived = paid || (selectedProject.budget || 0);
const totalCosts = Number(selectedProject.actualCost ?? selectedProject.spent) || 0;
return { totalReceived, grossProfit: totalReceived - totalCosts };
}, [selectedProject]);
// Apply filters
const filteredProjects = useMemo(() => {
return ownerProjects.filter(p => {
@@ -635,6 +658,50 @@ const OwnerProjectList = () => {
</SpotlightCard>
</>)}
{/* ── Owner's Box — Team Management ── */}
{selectedProject && (
<section>
<div className="flex items-center justify-between mb-4 flex-wrap gap-3">
<h2 className="text-xl font-bold text-zinc-900 dark:text-white/90 flex items-center">
<span className="w-2 h-8 bg-violet-500 rounded-full mr-3"></span>
Team Management
</h2>
<div className="relative">
<select
value={selectedProject.id}
onChange={e => setSelectedProjectId(e.target.value)}
className="appearance-none pl-3 pr-8 py-2 text-sm font-semibold rounded-xl bg-zinc-100 dark:bg-white/5 border border-zinc-200 dark:border-white/10 text-zinc-900 dark:text-white outline-none focus:border-violet-500 transition-colors cursor-pointer"
>
{ownerProjects.map(p => (
<option key={p.id} value={p.id}>
{p.projectType} {p.address?.split(',')[0] || p.id}
</option>
))}
</select>
<ChevronDown size={14} className="absolute right-2.5 top-1/2 -translate-y-1/2 text-zinc-400 pointer-events-none" />
</div>
</div>
<SpotlightCard className="p-5 lg:p-6" spotlightColor="rgba(139, 92, 246, 0.06)">
<TeamManagementPanel
project={selectedProject}
teamMembers={selectedProject.teamMembers || []}
allUsers={users}
personnel={personnel}
userRole={user?.role}
orgCommissionDefaults={orgCommissionDefaults}
userCommissionOverrides={userCommissionOverrides}
roleCommissionOverrides={roleCommissionOverrides}
orgMembers={orgMembers}
totalReceived={teamFinancials.totalReceived}
grossProfit={teamFinancials.grossProfit}
onAddMember={addJobTeamMember}
onRemoveMember={removeJobTeamMember}
onUpdateMember={updateJobTeamMember}
/>
</SpotlightCard>
</section>
)}
</div>
<span className="attribution-ghost">igotsar.matyas | LynkedUpPro - Turns out roofing CRMs don't build themselves. Who knew?</span>
</div>