From 42792a82ca91c16c708fdfb0139a16a62c33274e Mon Sep 17 00:00:00 2001 From: Satyam Rastogi Date: Fri, 29 May 2026 19:31:26 +0530 Subject: [PATCH] feat(data): expand subcontractor task state machine constants + add category/assignedDate; audit cancel --- src/data/mockStore.jsx | 57 +++++++++++++++++++++++++++++++----------- 1 file changed, 42 insertions(+), 15 deletions(-) diff --git a/src/data/mockStore.jsx b/src/data/mockStore.jsx index 0ee6495..72e7e6e 100644 --- a/src/data/mockStore.jsx +++ b/src/data/mockStore.jsx @@ -6834,16 +6834,19 @@ export const SUBCONTRACTOR_TASK_PRIORITIES = [ ]; export const SUBCONTRACTOR_TASK_STATUSES = [ - 'Assigned', - 'In Progress', - 'On Hold', - 'Completed', - 'Cancelled', + 'Assigned', 'Pre-Work Inspection', 'In Progress', 'On Hold', + 'Post-Work Review', 'Rework Needed', 'Completed', 'Cancelled', +]; +// Statuses a subcontractor can set themselves (no review gate, no cancel): +export const SUBCONTRACTOR_SELF_STATUSES = [ + 'Assigned', 'Pre-Work Inspection', 'In Progress', 'On Hold', 'Post-Work Review', +]; +// Owner/admin-only transitions (the review gate + cancel): +export const SUBCONTRACTOR_REVIEW_STATUSES = ['Completed', 'Rework Needed', 'Cancelled']; +// Task categories (for the owner table + assignment): +export const SUBCONTRACTOR_TASK_CATEGORIES = [ + 'Roofing', 'Electrical', 'Plumbing', 'Siding', 'Gutters', 'Windows', 'Painting', 'Inspection', 'General', ]; - -// Statuses the subcontractor themselves can set from the Task Detail page. -// Owner / admin can still flip a task to Cancelled from the admin page. -export const SUBCONTRACTOR_SELF_STATUSES = ['Assigned', 'In Progress', 'On Hold', 'Completed']; export const SUBCONTRACTOR_EXPENSE_CATEGORIES = [ 'Materials', @@ -6948,6 +6951,8 @@ const MOCK_SUBCONTRACTOR_TASKS = [ description: 'Two ridge cap shingles missing on the south slope after wind storm. Replace with matching tile and seal. Inspect adjacent tiles for hairline cracks while you are up there.', dueDate: '2026-05-25', priority: 'high', + category: 'Roofing', + assignedDate: '2026-05-15T09:12:00Z', status: 'In Progress', photos: [ { id: 'sct_001_p1', name: 'Roof_Damage.jpg', url: '/assets/images/properties/Hail_Damaged_Shingles.jpg', annotation: 'Repair this corner' }, @@ -7039,6 +7044,8 @@ const MOCK_SUBCONTRACTOR_TASKS = [ description: 'Outdated 100A panel — upgrade to 200A. Permit pulled, materials staged on site. Coordinate Oncor disconnect for the morning of installation.', dueDate: '2026-05-22', priority: 'medium', + category: 'Electrical', + assignedDate: '2026-05-10T15:40:00Z', status: 'In Progress', photos: [ { id: 'sct_002_p1', name: 'Old_Panel.jpg', url: '/assets/images/properties/Beige_Two_Story_House.jpg', annotation: 'Existing 100A panel — disconnect and remove' }, @@ -7131,6 +7138,8 @@ const MOCK_SUBCONTRACTOR_TASKS = [ description: 'Front fascia and side trim need fresh coat after siding repair. Match existing Sherwin-Williams color.', dueDate: '2026-05-18', priority: 'low', + category: 'Painting', + assignedDate: '2026-05-05T11:00:00Z', status: 'Completed', photos: [ { id: 'sct_003_p1', name: 'Before.jpg', url: '/assets/images/properties/Brick_Front_Porch_Home.jpg', annotation: 'Before' }, @@ -7149,6 +7158,7 @@ const MOCK_SUBCONTRACTOR_TASKS = [ fees: [ { id: 'sct_003_f1', description: 'Touch-up paint labour', type: 'Labour / Service Fee', amount: 180, createdAt: '2026-05-14T17:35:00Z' }, ], + activities: [], projectId: 'PRJ-2026-006', paymentStatus: 'Paid', paymentRequestedAt: '2026-05-14T17:35:00Z', @@ -7173,6 +7183,8 @@ const MOCK_SUBCONTRACTOR_TASKS = [ description: 'Hailstorm overnight; 3–4 ft section of decking exposed near chimney. Tarp ASAP to prevent further water intrusion. Permanent repair will be scheduled after insurance scope.', dueDate: '2026-05-19', priority: 'high', + category: 'Roofing', + assignedDate: '2026-05-18T22:40:00Z', status: 'Assigned', photos: [ { id: 'sct_004_p1', name: 'Storm_Damage.jpg', url: '/assets/images/properties/Broken_Roof_Surface.jpg', annotation: 'Exposed decking near chimney' }, @@ -7188,6 +7200,7 @@ const MOCK_SUBCONTRACTOR_TASKS = [ ], expenses: [], fees: [], + activities: [], projectId: 'PRJ-2026-001', paymentStatus: 'Unpaid', paymentRequestedAt: null, @@ -7211,6 +7224,8 @@ const MOCK_SUBCONTRACTOR_TASKS = [ description: 'Customer reports unusually high attic temps. Check ridge vent, soffit airflow, and intake/exhaust balance. Recommend remediation.', dueDate: '2026-05-30', priority: 'medium', + category: 'Inspection', + assignedDate: '2026-05-12T10:00:00Z', status: 'On Hold', photos: [ { id: 'sct_005_p1', name: 'Attic_View.jpg', url: '/assets/images/properties/Roof_Inspection_Angle.jpg', annotation: 'Access from south gable' }, @@ -7280,6 +7295,8 @@ const MOCK_SUBCONTRACTOR_TASKS = [ description: '30 ft section of K-style gutter — pulling away from fascia after storm. Replace with new 6" oversized gutter, match existing bronze color.', dueDate: '2026-06-02', priority: 'low', + category: 'Gutters', + assignedDate: '2026-05-17T14:00:00Z', status: 'Assigned', photos: [], statusHistory: [ @@ -7288,6 +7305,7 @@ const MOCK_SUBCONTRACTOR_TASKS = [ thread: [], expenses: [], fees: [], + activities: [], projectId: 'PRJ-2026-009', paymentStatus: 'Unpaid', paymentRequestedAt: null, @@ -7311,6 +7329,8 @@ const MOCK_SUBCONTRACTOR_TASKS = [ description: 'Sheathing soft in two ~2x2 ft areas. Cut out, replace with matching OSB, re-felt and re-shingle.', dueDate: '2026-05-08', priority: 'high', + category: 'Roofing', + assignedDate: '2026-05-01T09:00:00Z', status: 'Completed', photos: [ { id: 'sct_007_p1', name: 'Deck_Repair.jpg', url: '/assets/images/properties/Cracked_Asphalt_Shingles.jpg', annotation: 'Soft section, top right' }, @@ -7331,6 +7351,7 @@ const MOCK_SUBCONTRACTOR_TASKS = [ fees: [ { id: 'sct_007_f1', description: 'Labour — deck repair (2 days)', type: 'Labour / Service Fee', amount: 920, createdAt: '2026-05-07T16:50:00Z' }, ], + activities: [], projectId: 'PRJ-2026-001', paymentStatus: 'Paid', paymentRequestedAt: '2026-05-07T16:50:00Z', @@ -7355,6 +7376,8 @@ const MOCK_SUBCONTRACTOR_TASKS = [ description: 'Replace 4 standard receptacles with GFCI: 2 kitchen counter outlets (left of sink + island), 1 master bath vanity, 1 powder room vanity. Code update required as part of insurance work. Use Leviton SmartlockPro 20A devices. Test all branches with plug-in tester before signing off.', dueDate: '2026-05-26', priority: 'medium', + category: 'Electrical', + assignedDate: '2026-05-16T13:00:00Z', status: 'In Progress', photos: [ { id: 'sct_008_p1', name: 'Kitchen_Outlet.jpg', url: '/assets/images/properties/Modern_White_Suburban_Home.jpg', annotation: 'Kitchen — left of sink, current standard receptacle' }, @@ -7437,6 +7460,8 @@ const MOCK_SUBCONTRACTOR_TASKS = [ description: 'Homeowner purchased a Tesla Wall Connector. Run a dedicated 60A 240V circuit from the main panel to the garage wall. Coordinate with homeowner for outage window. Permit required.', dueDate: '2026-05-29', priority: 'medium', + category: 'Electrical', + assignedDate: '2026-05-20T09:00:00Z', status: 'Assigned', photos: [ { id: 'sct_010_p1', name: 'Garage_Wall.jpg', url: '/assets/images/properties/Modern_White_Suburban_Home.jpg', annotation: 'Wall Connector mounting location' }, @@ -7474,6 +7499,8 @@ const MOCK_SUBCONTRACTOR_TASKS = [ description: 'New ADU build — bathroom rough-in. Coordinate with framing inspection.', dueDate: '2026-06-15', priority: 'medium', + category: 'Plumbing', + assignedDate: '2026-05-09T10:00:00Z', status: 'On Hold', photos: [], statusHistory: [ @@ -7483,6 +7510,7 @@ const MOCK_SUBCONTRACTOR_TASKS = [ thread: [], expenses: [], fees: [], + activities: [], projectId: null, paymentStatus: 'Unpaid', paymentRequestedAt: null, @@ -8102,6 +8130,8 @@ export const MockStoreProvider = ({ children }) => { description: input.description || '', dueDate: input.dueDate, priority: input.priority || 'medium', + category: input.category || 'General', + assignedDate: now, status: 'Assigned', photos: (input.photos || []).map((p, i) => ({ id: p.id || `${Date.now()}_${i}`, @@ -8120,6 +8150,7 @@ export const MockStoreProvider = ({ children }) => { thread: [], expenses: [], fees: [], + activities: [], createdAt: now, updatedAt: now, }; @@ -8401,12 +8432,8 @@ export const MockStoreProvider = ({ children }) => { toast.success('Task updated'); }; - const cancelSubcontractorTask = (taskId) => { - setSubcontractorTasks(prev => prev.map(t => t.id === taskId - ? { ...t, status: 'Cancelled', updatedAt: new Date().toISOString() } - : t, - )); - toast.success('Task cancelled'); + const cancelSubcontractorTask = (taskId, comment = 'Task cancelled', actor) => { + setSubcontractorTaskStatus(taskId, 'Cancelled', comment, actor); }; const reassignSubcontractorTask = (taskId, newSubcontractorId) => {