team management feature in Owners Box

This commit is contained in:
Satyam-Rastogi
2026-05-12 19:29:52 +05:30
parent 91392bebcb
commit 17c3dc7307
3 changed files with 873 additions and 3 deletions
+77 -1
View File
@@ -2066,6 +2066,13 @@ const MOCK_PROJECTS = [
{ name: 'Scope of Work - Roof Replacement', url: '#', type: 'contract' },
{ name: 'Permit #26-0401', url: '#', type: 'permit' },
{ name: 'Material Order PO-2604', url: '#', type: 'invoice' }
],
teamMembers: [
{ id: 'jtm_001_1', userId: 'p1', name: 'Jesus Gonzales', email: 'jesus@lynkeduppro.com', orgRole: 'W2_EMPLOYEE', jobRole: 'Sales Rep', status: 'active', jobCommission: { type: 'percent_gross', rate: 12 } },
{ id: 'jtm_001_2', userId: 'con_001', name: 'Mike Contractor', email: 'mike@texasbuilders.com', orgRole: 'CONTRACTOR', jobRole: 'Lead Installer', status: 'active', jobCommission: null },
{ id: 'jtm_001_3', userId: 'sub_001', name: 'Carlos Subcontractor', email: 'carlos@electricpro.com', orgRole: 'SUBCONTRACTOR', jobRole: 'Subcontractor', status: 'active', jobCommission: null },
{ id: 'jtm_001_4', userId: 'e1', name: 'Frank Agent', email: 'agent1@plano.com', orgRole: 'FIELD_AGENT', jobRole: 'Canvasser', status: 'active', jobCommission: null },
{ id: 'jtm_001_5', userId: 'p2', name: 'Sarah Sales', email: 'sarah@lynkeduppro.com', orgRole: '1099_SALES_REP', jobRole: 'Estimator', status: 'pending', jobCommission: null }
]
},
@@ -2115,6 +2122,10 @@ const MOCK_PROJECTS = [
{ name: 'Completion Certificate', url: '#', type: 'certificate' },
{ name: 'Final Invoice Package', url: '#', type: 'invoice' },
{ name: 'Warranty Registration', url: '#', type: 'warranty' }
],
teamMembers: [
{ id: 'jtm_002_1', userId: 'p1', name: 'Jesus Gonzales', email: 'jesus@lynkeduppro.com', orgRole: 'W2_EMPLOYEE', jobRole: 'Sales Rep', status: 'active', jobCommission: null },
{ id: 'jtm_002_2', userId: 'con_001', name: 'Mike Contractor', email: 'mike@texasbuilders.com', orgRole: 'CONTRACTOR', jobRole: 'Lead Installer', status: 'active', jobCommission: null }
]
},
@@ -2190,6 +2201,11 @@ const MOCK_PROJECTS = [
{ name: 'HVAC Design Plans', url: '#', type: 'plans' },
{ name: 'Mechanical Permit #26-0187', url: '#', type: 'permit' },
{ name: 'Equipment Spec Sheets', url: '#', type: 'specification' }
],
teamMembers: [
{ id: 'jtm_003_1', userId: 'p2', name: 'Sarah Sales', email: 'sarah@lynkeduppro.com', orgRole: '1099_SALES_REP', jobRole: 'Sales Rep', status: 'active', jobCommission: { type: 'flat', rate: 2000 } },
{ id: 'jtm_003_2', userId: 'con_001', name: 'Mike Contractor', email: 'mike@texasbuilders.com', orgRole: 'CONTRACTOR', jobRole: 'Project Manager', status: 'active', jobCommission: null },
{ id: 'jtm_003_3', userId: 'sub_001', name: 'Carlos Subcontractor', email: 'carlos@electricpro.com', orgRole: 'SUBCONTRACTOR', jobRole: 'Subcontractor', status: 'active', jobCommission: null }
]
},
@@ -2276,6 +2292,11 @@ const MOCK_PROJECTS = [
{ name: 'Change Order #1 - Scope Expansion', url: '#', type: 'change_order' },
{ name: 'Change Order #2 - Material Upgrade', url: '#', type: 'change_order' },
{ name: 'Asbestos Abatement Report', url: '#', type: 'report' }
],
teamMembers: [
{ id: 'jtm_004_1', userId: 'p1', name: 'Jesus Gonzales', email: 'jesus@lynkeduppro.com', orgRole: 'W2_EMPLOYEE', jobRole: 'Project Manager', status: 'active', jobCommission: { type: 'percent_net', rate: 8 } },
{ id: 'jtm_004_2', userId: 'con_001', name: 'Mike Contractor', email: 'mike@texasbuilders.com', orgRole: 'CONTRACTOR', jobRole: 'Lead Installer', status: 'active', jobCommission: null },
{ id: 'jtm_004_3', userId: 'e2', name: 'Fiona Field', email: 'agent2@plano.com', orgRole: 'FIELD_AGENT', jobRole: 'Inspector', status: 'active', jobCommission: null }
]
},
@@ -2349,6 +2370,10 @@ const MOCK_PROJECTS = [
{ name: 'Dispute Notice - Material Defect', url: '#', type: 'dispute' },
{ name: 'Manufacturer Warranty Claim', url: '#', type: 'warranty' },
{ name: 'Site Photos - Defective Panels', url: '#', type: 'photos' }
],
teamMembers: [
{ id: 'jtm_005_1', userId: 'p2', name: 'Sarah Sales', email: 'sarah@lynkeduppro.com', orgRole: '1099_SALES_REP', jobRole: 'Sales Rep', status: 'active', jobCommission: null },
{ id: 'jtm_005_2', userId: 'con_001', name: 'Mike Contractor', email: 'mike@texasbuilders.com', orgRole: 'CONTRACTOR', jobRole: 'Lead Installer', status: 'active', jobCommission: null }
]
},
@@ -2396,6 +2421,10 @@ const MOCK_PROJECTS = [
{ name: 'Electrical Upgrade Proposal', url: '#', type: 'contract' },
{ name: 'Electrical Permit #26-0223', url: '#', type: 'permit' },
{ name: 'Load Calculation Report', url: '#', type: 'report' }
],
teamMembers: [
{ id: 'jtm_006_1', userId: 'p1', name: 'Jesus Gonzales', email: 'jesus@lynkeduppro.com', orgRole: 'W2_EMPLOYEE', jobRole: 'Sales Rep', status: 'active', jobCommission: null },
{ id: 'jtm_006_2', userId: 'sub_001', name: 'Carlos Subcontractor', email: 'carlos@electricpro.com', orgRole: 'SUBCONTRACTOR', jobRole: 'Lead Installer', status: 'active', jobCommission: null }
]
},
@@ -2495,6 +2524,12 @@ const MOCK_PROJECTS = [
{ name: 'TPO Manufacturer Spec', url: '#', type: 'specification' },
{ name: 'Roof Survey Report', url: '#', type: 'report' },
{ name: 'Safety Plan - Fall Protection', url: '#', type: 'safety' }
],
teamMembers: [
{ id: 'jtm_007_1', userId: 'p1', name: 'Jesus Gonzales', email: 'jesus@lynkeduppro.com', orgRole: 'W2_EMPLOYEE', jobRole: 'Project Manager', status: 'active', jobCommission: { type: 'percent_gross', rate: 5 } },
{ id: 'jtm_007_2', userId: 'con_001', name: 'Mike Contractor', email: 'mike@texasbuilders.com', orgRole: 'CONTRACTOR', jobRole: 'Lead Installer', status: 'active', jobCommission: null },
{ id: 'jtm_007_3', userId: 'sub_001', name: 'Carlos Subcontractor', email: 'carlos@electricpro.com', orgRole: 'SUBCONTRACTOR', jobRole: 'Subcontractor', status: 'active', jobCommission: null },
{ id: 'jtm_007_4', userId: 'e4', name: 'Felicity Fast', email: 'agent4@plano.com', orgRole: 'FIELD_AGENT', jobRole: 'Canvasser', status: 'active', jobCommission: null }
]
},
@@ -2550,6 +2585,10 @@ const MOCK_PROJECTS = [
{ name: 'Change Order #1 - Additional Piers', url: '#', type: 'change_order' },
{ name: 'Change Order #2 - Plumbing Reroute', url: '#', type: 'change_order' },
{ name: 'Soil Analysis Report', url: '#', type: 'report' }
],
teamMembers: [
{ id: 'jtm_008_1', userId: 'p2', name: 'Sarah Sales', email: 'sarah@lynkeduppro.com', orgRole: '1099_SALES_REP', jobRole: 'Sales Rep', status: 'active', jobCommission: null },
{ id: 'jtm_008_2', userId: 'con_001', name: 'Mike Contractor', email: 'mike@texasbuilders.com', orgRole: 'CONTRACTOR', jobRole: 'Lead Installer', status: 'active', jobCommission: null }
]
},
@@ -2598,6 +2637,10 @@ const MOCK_PROJECTS = [
{ name: 'Window Replacement Agreement', url: '#', type: 'contract' },
{ name: 'Custom Window Order Confirmation', url: '#', type: 'purchase_order' },
{ name: 'Energy Rating Certificates', url: '#', type: 'certificate' }
],
teamMembers: [
{ id: 'jtm_009_1', userId: 'p1', name: 'Jesus Gonzales', email: 'jesus@lynkeduppro.com', orgRole: 'W2_EMPLOYEE', jobRole: 'Sales Rep', status: 'active', jobCommission: null },
{ id: 'jtm_009_2', userId: 'e2', name: 'Fiona Field', email: 'agent2@plano.com', orgRole: 'FIELD_AGENT', jobRole: 'Inspector', status: 'active', jobCommission: null }
]
},
@@ -2646,6 +2689,11 @@ const MOCK_PROJECTS = [
{ name: 'Completion Certificate', url: '#', type: 'certificate' },
{ name: 'ADA Compliance Verification', url: '#', type: 'report' },
{ name: 'Final Payment Release', url: '#', type: 'invoice' }
],
teamMembers: [
{ id: 'jtm_010_1', userId: 'p2', name: 'Sarah Sales', email: 'sarah@lynkeduppro.com', orgRole: '1099_SALES_REP', jobRole: 'Estimator', status: 'active', jobCommission: { type: 'flat', rate: 1500 } },
{ id: 'jtm_010_2', userId: 'con_001', name: 'Mike Contractor', email: 'mike@texasbuilders.com', orgRole: 'CONTRACTOR', jobRole: 'Lead Installer', status: 'active', jobCommission: null },
{ id: 'jtm_010_3', userId: 'e5', name: 'Felix Fixer', email: 'agent5@plano.com', orgRole: 'FIELD_AGENT', jobRole: 'Canvasser', status: 'pending', jobCommission: null }
]
},
@@ -2702,6 +2750,10 @@ const MOCK_PROJECTS = [
{ name: 'Dispute Filing - Scope Disagreement', url: '#', type: 'dispute' },
{ name: 'RFI #1 - Original vs Current Scope', url: '#', type: 'rfi' },
{ name: 'RFI #2 - Waterproofing Method', url: '#', type: 'rfi' }
],
teamMembers: [
{ id: 'jtm_011_1', userId: 'p1', name: 'Jesus Gonzales', email: 'jesus@lynkeduppro.com', orgRole: 'W2_EMPLOYEE', jobRole: 'Project Manager', status: 'active', jobCommission: null },
{ id: 'jtm_011_2', userId: 'con_001', name: 'Mike Contractor', email: 'mike@texasbuilders.com', orgRole: 'CONTRACTOR', jobRole: 'Lead Installer', status: 'active', jobCommission: null }
]
},
@@ -2752,6 +2804,10 @@ const MOCK_PROJECTS = [
{ name: 'Plumbing Permit #26-0156', url: '#', type: 'permit' },
{ name: 'Scope Hold Notice - Permit Review', url: '#', type: 'notice' },
{ name: 'Material Delivery Receipt', url: '#', type: 'receipt' }
],
teamMembers: [
{ id: 'jtm_012_1', userId: 'p2', name: 'Sarah Sales', email: 'sarah@lynkeduppro.com', orgRole: '1099_SALES_REP', jobRole: 'Sales Rep', status: 'active', jobCommission: null },
{ id: 'jtm_012_2', userId: 'e3', name: 'Fred Flyer', email: 'agent3@plano.com', orgRole: 'FIELD_AGENT', jobRole: 'Canvasser', status: 'active', jobCommission: null }
]
}
];
@@ -4993,7 +5049,7 @@ export const MockStoreProvider = ({ children }) => {
meetings,
salesHistory, // Exported for Leaderboard
// New Owners Box Data
// New Data
owners,
personnel,
vendors,
@@ -5123,6 +5179,26 @@ export const MockStoreProvider = ({ children }) => {
updateProject: (projectId, data) => {
setProjects(prev => prev.map(p => p.id === projectId ? { ...p, ...data } : p));
},
// Team Management (job-scoped)
addJobTeamMember: (projectId, member) => {
setProjects(prev => prev.map(p => {
if (p.id !== projectId) return p;
return { ...p, teamMembers: [...(p.teamMembers || []), { ...member, id: `jtm_${Date.now()}_${Math.random().toString(36).slice(2, 6)}` }] };
}));
},
removeJobTeamMember: (projectId, memberId) => {
setProjects(prev => prev.map(p => {
if (p.id !== projectId) return p;
return { ...p, teamMembers: (p.teamMembers || []).filter(m => m.id !== memberId) };
}));
},
updateJobTeamMember: (projectId, memberId, updates) => {
setProjects(prev => prev.map(p => {
if (p.id !== projectId) return p;
return { ...p, teamMembers: (p.teamMembers || []).map(m => m.id === memberId ? { ...m, ...updates } : m) };
}));
},
}}>
{children}
</MockStoreContext.Provider>