feat(owner-dash): Expand project command center with mock data, modals, and recharts fixes

This commit is contained in:
Satyam
2026-02-22 03:00:38 +05:30
parent b8a20144d3
commit b6f899afd2
3 changed files with 887 additions and 308 deletions
+103
View File
@@ -0,0 +1,103 @@
import React, { useEffect, useState } from 'react';
import { createPortal } from 'react-dom';
import { X } from 'lucide-react';
const CreateItemModal = ({ isOpen, onClose, title, icon: Icon, iconColor = "text-[#00f0ff]", iconBg = "bg-blue-500/10", fields, onSubmit, submitLabel = "Submit", submitColor = "bg-blue-500/20 text-[#00f0ff] border-blue-500/30" }) => {
const [formData, setFormData] = useState({});
useEffect(() => {
const handleEsc = (e) => { if (e.key === 'Escape') onClose(); };
if (isOpen) window.addEventListener('keydown', handleEsc);
return () => window.removeEventListener('keydown', handleEsc);
}, [isOpen, onClose]);
if (!isOpen) return null;
const handleSubmit = (e) => {
e.preventDefault();
onSubmit(formData);
setFormData({});
onClose();
};
return createPortal(
<div className="fixed inset-0 z-[9999] flex items-center justify-center p-4" role="dialog" aria-modal="true">
<div className="absolute inset-0 bg-black/60 backdrop-blur-sm" onClick={onClose} />
<div className="relative w-full max-w-md bg-[#121214] rounded-2xl shadow-[0_0_40px_rgba(0,0,0,0.8)] border border-white/10 overflow-hidden animate-in zoom-in-95 duration-200">
{/* Header */}
<div className="px-6 py-5 border-b border-white/10 flex justify-between items-center bg-white/5">
<div className="flex items-center gap-3">
{Icon && (
<div className={`p-2 rounded-xl ${iconBg} ${iconColor}`}>
<Icon size={20} />
</div>
)}
<h2 className="text-lg font-bold text-white tracking-widest uppercase">{title}</h2>
</div>
<button onClick={onClose} className="p-2 rounded-lg hover:bg-white/10 text-zinc-500 hover:text-white transition-colors">
<X size={18} />
</button>
</div>
{/* Content */}
<form onSubmit={handleSubmit} className="p-6 space-y-5">
{fields.map((field, i) => (
<div key={i} className="space-y-1.5">
<label className="text-xs font-bold uppercase tracking-wider text-zinc-400">{field.label}</label>
{field.type === 'textarea' ? (
<textarea
className="w-full bg-[#18181b] border border-white/10 rounded-xl px-4 py-3 text-sm text-white placeholder-zinc-600 focus:outline-none focus:border-[#00f0ff] focus:ring-1 focus:ring-[#00f0ff] transition-all"
rows={4}
placeholder={field.placeholder || ''}
required={field.required}
value={formData[field.name] || ''}
onChange={e => setFormData({ ...formData, [field.name]: e.target.value })}
/>
) : field.type === 'select' ? (
<select
className="w-full bg-[#18181b] border border-white/10 rounded-xl px-4 py-3 text-sm text-white focus:outline-none focus:border-[#00f0ff] focus:ring-1 focus:ring-[#00f0ff] transition-all"
required={field.required}
value={formData[field.name] || ''}
onChange={e => setFormData({ ...formData, [field.name]: e.target.value })}
>
<option value="" disabled>Select {field.label}</option>
{field.options.map(o => <option key={o.value} value={o.value}>{o.label}</option>)}
</select>
) : field.type === 'file' ? (
<input
type="file"
accept={field.accept}
className="w-full text-sm text-zinc-400 file:mr-4 file:py-2.5 file:px-4 file:rounded-xl file:border file:border-white/10 file:text-sm file:font-bold file:bg-[#18181b] file:text-white hover:file:bg-white/5 transition-all"
required={field.required}
onChange={e => setFormData({ ...formData, [field.name]: e.target.files[0] })}
/>
) : (
<input
type={field.type || 'text'}
className="w-full bg-[#18181b] border border-white/10 rounded-xl px-4 py-3 text-sm text-white placeholder-zinc-600 focus:outline-none focus:border-[#00f0ff] focus:ring-1 focus:ring-[#00f0ff] transition-all"
placeholder={field.placeholder || ''}
required={field.required}
value={formData[field.name] || ''}
onChange={e => setFormData({ ...formData, [field.name]: e.target.value })}
/>
)}
</div>
))}
{/* Footer */}
<div className="pt-4 flex justify-end gap-3">
<button type="button" onClick={onClose} className="px-5 py-2.5 text-sm font-bold text-zinc-400 hover:text-white transition-colors">
Cancel
</button>
<button type="submit" className={`px-6 py-2.5 text-sm font-bold rounded-xl border ${submitColor} hover:brightness-110 transition-all shadow-[0_0_15px_rgba(0,0,0,0.5)]`}>
{submitLabel}
</button>
</div>
</form>
</div>
</div>,
document.body
);
};
export default CreateItemModal;
+84 -3
View File
@@ -2132,7 +2132,7 @@ const MOCK_PROJECTS = [
completionPercentage: 42,
healthScore: 58,
openRFIs: 1,
changeOrderCount: 0,
changeOrderCount: 2,
pendingInvoiceCount: 2,
// TODO: cross-reference — Contractor: Texas Builders LLC, Vendors: North Texas HVAC Solutions, ABC Supply Co.
milestones: [
@@ -2143,11 +2143,37 @@ const MOCK_PROJECTS = [
{ id: 'ms_003_5', name: 'Electrical Hookup', dueDate: '2026-02-14', status: 'pending', assignedTo: 'sub_001' },
{ id: 'ms_003_6', name: 'System Test and Commissioning', dueDate: '2026-02-25', status: 'pending', assignedTo: 'v6' }
],
budgetBreakdown: [
{ category: 'Equipment & Materials', allocated: 15000, committed: 15000, actual: 12500 },
{ category: 'Labor - HVAC', allocated: 8000, committed: 8000, actual: 4000 },
{ category: 'Labor - Electrical', allocated: 3000, committed: 3000, actual: 0 },
{ category: 'Permits & Fees', allocated: 1000, committed: 1000, actual: 950 },
{ category: 'Contingency', allocated: 5000, committed: 1200, actual: 950 }
],
invoices: [
{ id: 'inv_003_1', amount: 8200, submittedBy: 'con_001', status: 'paid', dueDate: '2026-01-15', datePaid: '2026-01-16' },
{ id: 'inv_003_2', amount: 10500.25, submittedBy: 'v6', status: 'pending', dueDate: '2026-02-19' },
{ id: 'inv_003_3', amount: 3400, submittedBy: 'v2', status: 'pending', dueDate: '2026-02-22' }
],
changeOrders: [
{ id: 'CO-003-01', title: 'Upsize Return Ducts', amount: 1200, status: 'approved', dateSubmitted: '2026-01-22', description: 'Increase return duct size for better airflow in master bedroom.' },
{ id: 'CO-003-02', title: 'Smart Thermostat Upgrade', amount: 450, status: 'pending', dateSubmitted: '2026-02-18', description: 'Upgrade to Ecobee Premium thermostats per owner request.' }
],
rfis: [
{ id: 'RFI-003-01', subject: 'Condenser Pad Location', status: 'closed', submittedBy: 'North Texas HVAC', dateOpened: '2026-01-12', dateClosed: '2026-01-14' },
{ id: 'RFI-003-02', subject: 'Duct Routing Conflict in Attic', status: 'open', submittedBy: 'Texas Builders LLC', dateOpened: '2026-02-15' }
],
riskLog: [
{ id: 'risk_003_1', description: 'Equipment backorder from manufacturer', severity: 'High', likelihood: 'Likely', mitigation: 'Source equivalent unit from secondary distributor', status: 'open' }
],
issueLog: [
{ id: 'issue_003_1', title: 'Failed framing inspection for duct clearance', priority: 'High', status: 'open', assignedTo: 'Texas Builders LLC', dateReported: '2026-02-14' }
],
activityTimeline: [
{ date: '2026-02-15', action: 'RFI Submitted', user: 'Site Supervisor', details: 'Duct routing conflict in attic' },
{ date: '2026-02-14', action: 'Inspection Failed', user: 'City Inspector', details: 'Framing clearance insufficient for 12" ducts' },
{ date: '2026-01-30', action: 'Milestone Completed', user: 'North Texas HVAC', details: 'Equipment Delivery phase finished' }
],
documents: [
{ name: 'HVAC Design Plans', url: '#', type: 'plans' },
{ name: 'Mechanical Permit #26-0187', url: '#', type: 'permit' },
@@ -2177,7 +2203,7 @@ const MOCK_PROJECTS = [
endDate: '2026-02-28',
completionPercentage: 78,
healthScore: 35,
openRFIs: 0,
openRFIs: 1,
changeOrderCount: 2,
pendingInvoiceCount: 2,
// TODO: cross-reference — Contractor: Texas Builders LLC, Vendors: ABC Supply Co., Texas Roofing Crew A, Sparky Electric
@@ -2190,6 +2216,37 @@ const MOCK_PROJECTS = [
{ id: 'ms_004_6', name: 'Flooring and Trim', dueDate: '2026-02-18', status: 'in_progress', assignedTo: 'con_001' },
{ id: 'ms_004_7', name: 'Final Punch List', dueDate: '2026-02-25', status: 'pending', assignedTo: 'con_001' }
],
budgetBreakdown: [
{ category: 'Demolition', allocated: 5000, committed: 5500, actual: 5500 },
{ category: 'Framing & Structural', allocated: 8000, committed: 8500, actual: 8500 },
{ category: 'Electrical', allocated: 7000, committed: 7000, actual: 4800 },
{ category: 'Plumbing', allocated: 6000, committed: 6500, actual: 6500 },
{ category: 'Drywall & Paint', allocated: 9000, committed: 10000, actual: 10000 },
{ category: 'Flooring & Trim', allocated: 12000, committed: 15500, actual: 15500 },
{ category: 'Contingency', allocated: 8000, committed: 9300, actual: 11500 }
],
changeOrders: [
{ id: 'CO-004-01', title: 'Scope Expansion - Kitchen Island', amount: 4500, status: 'approved', dateSubmitted: '2026-01-10', description: 'Add a custom 6ft island with quartz countertop and built-in microwave.' },
{ id: 'CO-004-02', title: 'Hardwood Flooring Upgrade', amount: 2800, status: 'approved', dateSubmitted: '2026-01-25', description: 'Upgrade from LVP to engineered hardwood in living areas.' }
],
rfis: [
{ id: 'RFI-004-01', subject: 'Load-bearing wall clarification', status: 'closed', submittedBy: 'Texas Builders LLC', dateOpened: '2025-12-15', dateClosed: '2025-12-16' },
{ id: 'RFI-004-02', subject: 'Paint finish in bathrooms', status: 'open', submittedBy: 'Texas Builders LLC', dateOpened: '2026-02-02' }
],
riskLog: [
{ id: 'risk_004_1', description: 'Flooring shipment delayed at port', severity: 'High', likelihood: 'Likely', mitigation: 'Source alternative matching material from local distributor', status: 'open' },
{ id: 'risk_004_2', description: 'Paint color mismatch between batches', severity: 'Medium', likelihood: 'Possible', mitigation: 'Verify batch numbers before final coat', status: 'mitigated' }
],
issueLog: [
{ id: 'issue_004_1', title: 'Drywall texturing inconsistent in hallway', priority: 'Medium', status: 'open', assignedTo: 'Texas Builders LLC', dateReported: '2026-02-16' },
{ id: 'issue_004_2', title: 'Plumbing rough-in failed initial inspection', priority: 'High', status: 'resolved', assignedTo: 'Lone Star Plumbing', dateReported: '2026-01-16' }
],
activityTimeline: [
{ date: '2026-02-16', action: 'Issue Reported', user: 'Site Supervisor', details: 'Drywall texture inconsistent in main hallway' },
{ date: '2026-02-05', action: 'Milestone Completed', user: 'Texas Builders LLC', details: 'Drywall and Paint phase finished' },
{ date: '2026-01-22', action: 'Payment Released', user: 'Marcus Whitfield', details: 'Truss and framing payment - $12,800' },
{ date: '2026-01-18', action: 'Inspection Passed', user: 'City Inspector', details: 'Plumbing rough-in re-inspection passed' }
],
invoices: [
{ id: 'inv_004_1', amount: 18000, submittedBy: 'con_001', status: 'paid', dueDate: '2025-12-15', datePaid: '2025-12-16' },
{ id: 'inv_004_2', amount: 15500, submittedBy: 'con_001', status: 'paid', dueDate: '2026-01-10', datePaid: '2026-01-12' },
@@ -2230,7 +2287,7 @@ const MOCK_PROJECTS = [
completionPercentage: 38,
healthScore: 42,
openRFIs: 0,
changeOrderCount: 0,
changeOrderCount: 1,
pendingInvoiceCount: 1,
// TODO: cross-reference — Contractor: Texas Builders LLC, Vendors: ABC Supply Co.
milestones: [
@@ -2240,11 +2297,35 @@ const MOCK_PROJECTS = [
{ id: 'ms_005_4', name: 'New Siding Install', dueDate: '2026-02-05', status: 'pending', assignedTo: 'con_001' },
{ id: 'ms_005_5', name: 'Trim and Caulking', dueDate: '2026-02-15', status: 'pending', assignedTo: 'con_001' }
],
budgetBreakdown: [
{ category: 'Materials - Siding', allocated: 12000, committed: 12000, actual: 8000 },
{ category: 'Labor - Prep & Install', allocated: 9000, committed: 9000, actual: 3500 },
{ category: 'Equipment Rental', allocated: 2000, committed: 2000, actual: 1500 },
{ category: 'Structural Repairs (CO)', allocated: 0, committed: 850, actual: 850 },
{ category: 'Contingency', allocated: 5000, committed: 5000, actual: 350 }
],
invoices: [
{ id: 'inv_005_1', amount: 8400, submittedBy: 'con_001', status: 'paid', dueDate: '2026-01-12', datePaid: '2026-01-13' },
{ id: 'inv_005_2', amount: 5800, submittedBy: 'v3', status: 'paid', dueDate: '2026-01-20', datePaid: '2026-01-21' },
{ id: 'inv_005_3', amount: 6500, submittedBy: 'con_001', status: 'pending', dueDate: '2026-02-10' }
],
changeOrders: [
{ id: 'CO-005-01', title: 'Rotten Fascia Board Replacement', amount: 850, status: 'approved', dateSubmitted: '2026-01-18', description: 'Replace 40 linear feet of rotted fascia discovered during tear-off.' }
],
rfis: [
{ id: 'RFI-005-01', subject: 'Vapor Barrier Specification', status: 'closed', submittedBy: 'Texas Builders LLC', dateOpened: '2026-01-20', dateClosed: '2026-01-21' }
],
riskLog: [
{ id: 'risk_005_1', description: 'Water damage hidden behind existing siding', severity: 'High', likelihood: 'Certain', mitigation: 'Halt work, assess rot, submit change order for structural repair.', status: 'realized' }
],
issueLog: [
{ id: 'issue_005_1', title: 'Defective siding panels delivered', priority: 'Critical', status: 'open', assignedTo: 'ABC Supply Co.', dateReported: '2026-02-04' }
],
activityTimeline: [
{ date: '2026-02-06', action: 'Project Paused', user: 'System', details: 'Status changed to On Hold due to material dispute' },
{ date: '2026-02-04', action: 'Issue Reported', user: 'Site Supervisor', details: 'Batch of siding panels showed unacceptable warping' },
{ date: '2026-01-22', action: 'Milestone Completed', user: 'Texas Builders LLC', details: 'Moisture Barrier Install finished' }
],
documents: [
{ name: 'Siding Replacement Contract', url: '#', type: 'contract' },
{ name: 'Dispute Notice - Material Defect', url: '#', type: 'dispute' },
File diff suppressed because it is too large Load Diff