diff --git a/src/pages/owner/OwnerProjectList.jsx b/src/pages/owner/OwnerProjectList.jsx index cc03fad..9eec28a 100644 --- a/src/pages/owner/OwnerProjectList.jsx +++ b/src/pages/owner/OwnerProjectList.jsx @@ -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 = () => { )} + {/* ── Owner's Box — Team Management ── */} + {selectedProject && ( +
+
+

+ + Team Management +

+
+ + +
+
+ + + +
+ )} + igotsar.matyas | LynkedUpPro - Turns out roofing CRMs don't build themselves. Who knew?