feat: Multi-role platform expansion, mobile nav redesign, and UI polish

- Add Owner, Contractor, Vendor, Subcontractor dashboards and role-based routing
- Owner now has superuser access to all Admin pages (dashboard, schedule, leaderboard)
- Redesign landing page mobile menu as slide-in sidebar (replaces broken Framer Motion overlay)
- Add body scroll lock to app sidebar for mobile consistency
- Fix Team Schedule to match Admin Dashboard design language (ambient glows, gradient header, SpotlightCard, zinc palette)
- Fix login page tab overflow — use abbreviated labels and grid layout for 6 role tabs
- Fix Recharts ResponsiveContainer warnings — replace height="100%" with fixed pixel heights
- Fix lightbox image viewer — unified nav bar, touch swipe support, no more overlapping text
- Add AI Assistant page, People/Vendor/Document management for Owner role
- Expand mock data store with contractor, vendor, and subcontractor data
This commit is contained in:
Satyam
2026-02-17 01:19:41 +05:30
parent 35cbdeb33c
commit 2eaac6b84a
44 changed files with 6857 additions and 662 deletions
+617 -1
View File
@@ -662,7 +662,73 @@ const MOCK_USERS = [
// Admins (3 Admins)
{ id: 'a1', type: 'employee', empId: 'ADM01', email: 'admin@plano.com', password: 'password', role: 'ADMIN', name: 'Adam Admin' },
{ id: 'a2', type: 'employee', empId: 'ADM02', email: 'admin2@plano.com', password: 'password', role: 'ADMIN', name: 'Amanda Manager' },
{ id: 'a3', type: 'employee', empId: 'ADM03', email: 'admin3@plano.com', password: 'password', role: 'ADMIN', name: 'Arthur Director' }
{ id: 'a3', type: 'employee', empId: 'ADM03', email: 'admin3@plano.com', password: 'password', role: 'ADMIN', name: 'Arthur Director' },
// --- NEW ROLES (Owners Box) ---
// Owner
{
id: 'own_001',
type: 'owner',
username: 'justin', // For login
email: 'justin@lynkeduppro.com',
password: 'password', // Keeping simple for dev
role: 'OWNER',
name: 'Justin Owner',
companyName: 'LynkedUp Pro',
phone: '972-555-1234'
},
// Contractor
{
id: 'con_001',
type: 'contractor',
username: 'mike',
email: 'mike@texasbuilders.com',
password: 'password',
role: 'CONTRACTOR',
name: 'Mike Contractor',
companyName: 'Texas Builders LLC',
licenseNumber: 'TX-GC-123456',
phone: '214-555-5678'
},
// Subcontractor
{
id: 'sub_001',
type: 'subcontractor',
username: 'carlos',
email: 'carlos@electricpro.com',
password: 'password',
role: 'SUBCONTRACTOR',
name: 'Carlos Subcontractor',
companyName: 'Electric Pro Services',
tradeType: 'electrical',
phone: '469-555-9012'
},
// Vendor (Supplier)
{
id: 'ven_001',
type: 'vendor',
username: 'abc_supply',
email: 'sales@abcsupply.com',
password: 'password',
role: 'VENDOR',
name: 'ABC Supply Co.',
companyName: 'ABC Supply',
tradeType: 'materials',
phone: '972-555-8888'
},
// Vendor (Supplier)
{
id: 'ven_001',
type: 'vendor',
username: 'abc_supply',
email: 'sales@abcsupply.com',
password: 'password',
role: 'VENDOR',
name: 'ABC Supply Co.',
companyName: 'ABC Supply',
tradeType: 'materials',
phone: '972-555-8888'
}
];
// --- NEW MOCK SALES HISTORY FOR LEADERBOARD ---
@@ -821,6 +887,539 @@ function generateMockMeetings() {
const MOCK_MEETINGS = generateMockMeetings();
// --- NEW OWNERS BOX DATA SCHEMAS ---
const MOCK_PERSONNEL = [
{
id: 'p1',
name: 'Jesus Gonzales',
role: 'W2_EMPLOYEE',
email: 'jesus@lynkeduppro.com',
phone: '214-555-0101',
team: 'Sales Team A',
manager: 'Justin Owner',
sensitiveData: {
ssn: '123-45-6789',
bankAccount: '9876543210'
},
compliance: {
w9Signed: true,
payPlanSigned: true,
driverLicense: {
uploaded: true,
expirationDate: '2026-08-15',
status: 'compliant'
}
},
status: 'active'
},
{
id: 'p2',
name: 'Sarah Sales',
role: '1099_SALES_REP',
email: 'sarah@lynkeduppro.com',
phone: '214-555-0102',
team: 'Sales Team A',
manager: 'Jesus Gonzales',
sensitiveData: {
ssn: '987-65-4321',
bankAccount: '1234567890'
},
compliance: {
w9Signed: true,
payPlanSigned: false,
driverLicense: {
uploaded: true,
expirationDate: '2025-12-01',
status: 'expiring'
}
},
status: 'active'
}
];
const MOCK_VENDORS = [
{
id: 'v1',
vendorName: 'Texas Roofing Crew A',
vendorType: 'roofing_crew',
primaryContact: {
name: 'Juan Perez',
email: 'juan@texasroofing.com',
phone: '469-555-0201'
},
sensitiveData: {
ein: '12-3456789',
bankAccount: '1122334455'
},
compliance: {
w9: { uploaded: true, status: 'approved' },
subcontractorAgreement: { uploaded: true, status: 'approved' },
coi: {
uploaded: true,
expirationDate: '2026-06-30',
status: 'compliant'
}
},
spend: {
totalSpend: 154000,
lastPayment: { date: '2026-02-01', amount: 12500 },
ytdSpend: 45000,
pendingInvoices: 2500
},
performance: {
rating: 4.8,
onTimeRate: 0.95,
jobsCompleted: 34,
activeJobs: 2
},
status: 'active'
},
{
id: 'v2',
vendorName: 'Sparky Electric',
vendorType: 'electrical',
primaryContact: {
name: 'Mike Spark',
email: 'mike@sparky.com',
phone: '469-555-0202'
},
sensitiveData: {
ein: '98-7654321',
bankAccount: '5544332211'
},
compliance: {
w9: { uploaded: true, status: 'approved' },
subcontractorAgreement: { uploaded: false, status: 'pending' },
coi: {
uploaded: true,
expirationDate: '2026-01-15',
status: 'expired'
}
},
spend: {
totalSpend: 4500,
lastPayment: { date: '2025-12-15', amount: 800 },
ytdSpend: 0,
pendingInvoices: 0
},
performance: {
rating: 4.2,
onTimeRate: 0.88,
jobsCompleted: 5,
activeJobs: 0
},
status: 'non_compliant'
},
{
id: 'v3',
vendorName: 'ABC Supply Co.',
vendorType: 'material_supplier',
primaryContact: {
name: 'Sales Desk',
email: 'sales@abcsupply.com',
phone: '972-555-8888'
},
sensitiveData: {
ein: '55-4433221',
bankAccount: '9988776655'
},
compliance: {
w9: { uploaded: true, status: 'approved' },
subcontractorAgreement: { uploaded: true, status: 'approved' },
coi: { uploaded: true, status: 'compliant', expirationDate: '2027-01-01' }
},
spend: {
totalSpend: 250000,
lastPayment: { date: '2026-02-10', amount: 15000 },
ytdSpend: 85000,
pendingInvoices: 12000
},
performance: {
rating: 5.0,
onTimeRate: 0.99,
jobsCompleted: 100, // Deliveries
activeJobs: 5
},
status: 'active'
}
];
const MOCK_ORDERS = [
{
id: 'ORD-001',
vendorId: 'v3',
projectId: 'proj_001',
projectAddress: '2604 Dunwick Dr, Plano, TX 75023',
orderDate: '2026-02-10',
dueDate: '2026-02-20',
deliveryDate: null,
status: 'shipped',
items: [
{
id: 'item_001',
description: 'Roofing Shingles - Architectural',
quantity: 50,
unit: 'bundles',
unitPrice: 45.00,
total: 2250.00,
specifications: 'GAF Timberline HDZ, Charcoal'
},
{
id: 'item_002',
description: 'Roofing Underlayment',
quantity: 10,
unit: 'rolls',
unitPrice: 85.00,
total: 850.00,
specifications: 'Synthetic, 10 sq per roll'
}
],
subtotal: 3100.00,
tax: 248.00,
total: 3348.00,
deliveryAddress: {
street: '2604 Dunwick Dr',
city: 'Plano',
state: 'TX',
zip: '75023',
instructions: 'Deliver to side yard, call foreman on arrival'
},
timeline: [
{ date: '2026-02-10', event: 'Order Placed', status: 'completed' },
{ date: '2026-02-11', event: 'Order Confirmed', status: 'completed' },
{ date: '2026-02-15', event: 'Shipped', status: 'completed' },
{ date: '2026-02-20', event: 'Estimated Delivery', status: 'pending' }
],
documents: [
{ id: 'doc_001', type: 'PO', name: 'PO-2604-Dunwick.pdf', url: '#' },
{ id: 'doc_002', type: 'Invoice', name: 'INV-001.pdf', url: '#' }
],
notes: 'Rush order for weather window',
contactPerson: 'John Smith',
contactPhone: '469-555-0123'
},
{
id: 'ORD-002',
vendorId: 'v3',
projectId: 'proj_002',
projectAddress: 'Plano, TX 75023',
orderDate: '2026-02-05',
dueDate: '2026-02-15',
deliveryDate: '2026-02-14',
status: 'delivered',
items: [
{
id: 'item_003',
description: 'Gutter System - Seamless Aluminum',
quantity: 150,
unit: 'linear feet',
unitPrice: 12.50,
total: 1875.00,
specifications: 'White, 5-inch K-style'
}
],
subtotal: 1875.00,
tax: 150.00,
total: 2025.00,
deliveryAddress: {
street: 'Gutter Replacement Project',
city: 'Plano',
state: 'TX',
zip: '75023',
instructions: 'Standard delivery'
},
timeline: [
{ date: '2026-02-05', event: 'Order Placed', status: 'completed' },
{ date: '2026-02-06', event: 'Order Confirmed', status: 'completed' },
{ date: '2026-02-12', event: 'Shipped', status: 'completed' },
{ date: '2026-02-14', event: 'Delivered', status: 'completed' }
],
documents: [
{ id: 'doc_003', type: 'PO', name: 'PO-Gutter-Project.pdf', url: '#' },
{ id: 'doc_004', type: 'Delivery Receipt', name: 'DR-002.pdf', url: '#' }
],
notes: null,
contactPerson: 'Mike Johnson',
contactPhone: '469-555-0456'
},
{
id: 'ORD-003',
vendorId: 'v3',
projectId: 'proj_003',
projectAddress: 'Dallas, TX 75201',
orderDate: '2026-02-12',
dueDate: '2026-02-25',
deliveryDate: null,
status: 'confirmed',
items: [
{
id: 'item_004',
description: 'Roofing Nails - Coil',
quantity: 20,
unit: 'boxes',
unitPrice: 35.00,
total: 700.00,
specifications: '1-1/4 inch, galvanized'
},
{
id: 'item_005',
description: 'Flashing - Step',
quantity: 100,
unit: 'pieces',
unitPrice: 4.50,
total: 450.00,
specifications: 'Aluminum, 8-inch'
}
],
subtotal: 1150.00,
tax: 92.00,
total: 1242.00,
deliveryAddress: {
street: 'Commercial Building',
city: 'Dallas',
state: 'TX',
zip: '75201',
instructions: 'Loading dock access required'
},
timeline: [
{ date: '2026-02-12', event: 'Order Placed', status: 'completed' },
{ date: '2026-02-13', event: 'Order Confirmed', status: 'completed' },
{ date: '2026-02-20', event: 'Estimated Ship Date', status: 'pending' },
{ date: '2026-02-25', event: 'Estimated Delivery', status: 'pending' }
],
documents: [
{ id: 'doc_005', type: 'PO', name: 'PO-Dallas-Commercial.pdf', url: '#' }
],
notes: 'Confirm delivery time 24hrs in advance',
contactPerson: 'Sarah Williams',
contactPhone: '214-555-0789'
}
];
const MOCK_VENDOR_INVOICES = [
{
id: 'INV-2026-001',
vendorId: 'v3',
orderId: 'ORD-002',
projectId: 'proj_002',
project: 'Plano, TX 75023',
invoiceDate: '2026-02-14',
dueDate: '2026-03-01',
amount: 2025.00,
status: 'paid',
paymentTerms: 'Net 15',
description: 'Gutter System Delivery'
},
{
id: 'INV-2026-002',
vendorId: 'v3',
orderId: 'ORD-001',
projectId: 'proj_001',
project: '2604 Dunwick Dr, Plano, TX 75023',
invoiceDate: '2026-02-15',
dueDate: '2026-03-02',
amount: 3348.00,
status: 'pending',
paymentTerms: 'Net 15',
description: 'Roofing Materials Delivery'
},
{
id: 'INV-2026-003',
vendorId: 'v3',
orderId: 'ORD-003',
projectId: 'proj_003',
project: 'Dallas, TX 75201',
invoiceDate: '2026-02-13',
dueDate: '2026-02-28',
amount: 1242.00,
status: 'pending',
paymentTerms: 'Net 15',
description: 'Roofing Accessories'
},
{
id: 'INV-2025-045',
vendorId: 'v3',
orderId: 'ORD-OLD-001',
projectId: 'proj_old_001',
project: 'Frisco, TX 75034',
invoiceDate: '2025-12-20',
dueDate: '2026-01-05',
amount: 4500.00,
status: 'paid',
paymentTerms: 'Net 15',
description: 'Complete Roofing Package'
}
];
const MOCK_DOCUMENTS = [
{
id: 'd1',
entityId: 'p1',
entityType: 'personnel',
entityName: 'Jesus Gonzales',
documentType: 'DL',
fileName: 'JG_DriverLicense.pdf',
fileUrl: '#',
uploadedBy: 'Jesus Gonzales',
uploadedAt: '2025-08-15',
expirationDate: '2026-08-15',
status: 'approved',
aiConfidence: 0.98,
reviewedBy: 'Admin',
reviewedAt: '2025-08-16'
},
{
id: 'd2',
entityId: 'v2',
entityType: 'vendor',
entityName: 'Sparky Electric',
documentType: 'COI',
fileName: 'Sparky_COI_2025.pdf',
fileUrl: '#',
uploadedBy: 'Mike Spark',
uploadedAt: '2025-01-10',
expirationDate: '2026-01-15',
status: 'expired',
aiConfidence: 0.95,
reviewedBy: 'Admin',
reviewedAt: '2025-01-11'
},
{
id: 'd3',
entityId: 'p2',
entityType: 'personnel',
entityName: 'Sarah Sales',
documentType: 'PAY_PLAN',
fileName: 'Sarah_PayPlan_Signed.pdf',
fileUrl: '#',
uploadedBy: 'Sarah Sales',
uploadedAt: '2026-02-14',
expirationDate: null,
status: 'pending_review',
aiConfidence: 0.88,
reviewedBy: null,
reviewedAt: null
}
];
const MOCK_PROJECTS = [
{
id: 'proj_1',
propertyId: 'P-2602',
address: '2604 Dunwick Dr, Plano, TX 75023',
contractorId: 'con_001',
subcontractorIds: ['sub_001'],
projectType: 'Roof Replacement',
status: 'active',
budget: 25000,
spent: 12500,
margin: 0.35,
startDate: '2026-02-01',
endDate: '2026-02-15',
completionPercentage: 65,
milestones: [
{
id: 'ms_1',
name: 'Material Delivery',
dueDate: '2026-02-02',
status: 'completed',
assignedTo: 'ven_001' // Supplier
},
{
id: 'ms_2',
name: 'Roof Tear-off',
dueDate: '2026-02-04',
status: 'completed',
assignedTo: 'con_001'
},
{
id: 'ms_3',
name: 'Dry-In Inspection',
dueDate: '2026-02-06',
status: 'completed',
assignedTo: 'con_001'
},
{
id: 'ms_4',
name: 'Shingle Install',
dueDate: '2026-02-10',
status: 'in_progress',
assignedTo: 'con_001'
},
{
id: 'ms_5',
name: 'Final Inspection',
dueDate: '2026-02-14',
status: 'pending',
assignedTo: 'con_001'
}
],
invoices: [
{
id: 'inv_1',
amount: 10000,
submittedBy: 'con_001',
status: 'paid',
dueDate: '2026-02-05',
datePaid: '2026-02-06'
},
{
id: 'inv_2',
amount: 5000,
submittedBy: 'sub_001',
status: 'pending',
dueDate: '2026-02-10'
},
{
id: 'inv_3',
amount: 12000,
submittedBy: 'ven_001', // ABC Supply
status: 'pending',
dueDate: '2026-02-12'
}
],
documents: [
{ name: 'Scope of Work', url: '#', type: 'contract' },
{ name: 'Permit #22-401', url: '#', type: 'permit' },
{ name: 'Material Order', url: '#', type: 'invoice' }
]
},
{
id: 'proj_2',
propertyId: 'P-2608',
address: '2617 Rothland Ln, Plano, TX 75023',
contractorId: 'con_001',
subcontractorIds: [],
projectType: 'Gutter Replacement',
status: 'scheduled',
budget: 4500,
spent: 0,
margin: 0.40,
startDate: '2026-02-20',
endDate: '2026-02-22',
completionPercentage: 0,
milestones: [
{
id: 'ms_2_1',
name: 'Material Delivery',
dueDate: '2026-02-19',
status: 'pending',
assignedTo: 'ven_001'
},
{
id: 'ms_2_2',
name: 'Installation',
dueDate: '2026-02-20',
status: 'pending',
assignedTo: 'con_001'
}
],
invoices: [],
documents: []
}
];
// --- CONTEXT SETUP ---
const MockStoreContext = createContext();
@@ -831,6 +1430,14 @@ export const MockStoreProvider = ({ children }) => {
const [meetings, setMeetings] = useState(MOCK_MEETINGS);
const [salesHistory, setSalesHistory] = useState(MOCK_SALES_HISTORY);
// New Data States
const [personnel, setPersonnel] = useState(MOCK_PERSONNEL);
const [vendors, setVendors] = useState(MOCK_VENDORS);
const [documents, setDocuments] = useState(MOCK_DOCUMENTS);
const [projects, setProjects] = useState(MOCK_PROJECTS);
const [orders, setOrders] = useState(MOCK_ORDERS);
const [vendorInvoices, setVendorInvoices] = useState(MOCK_VENDOR_INVOICES);
// Initialize properties once
useEffect(() => {
const data = generateProperties();
@@ -908,6 +1515,15 @@ export const MockStoreProvider = ({ children }) => {
users,
meetings,
salesHistory, // Exported for Leaderboard
// New Owners Box Data
personnel,
vendors,
documents,
projects,
orders,
vendorInvoices,
updatePropertyStatus,
addMeeting,
updateUser: (updatedUser) => {