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:
@@ -0,0 +1,101 @@
|
||||
import { ROLES } from '../context/AuthContext';
|
||||
|
||||
export const PERMISSIONS = {
|
||||
// Admin / Owner Capabilities
|
||||
VIEW_ALL_PROJECTS: 'VIEW_ALL_PROJECTS',
|
||||
VIEW_ALL_PERSONNEL: 'VIEW_ALL_PERSONNEL',
|
||||
VIEW_FINANCIALS: 'VIEW_FINANCIALS',
|
||||
VIEW_SENSITIVE_DATA: 'VIEW_SENSITIVE_DATA', // SSN, Bank Accounts
|
||||
MANAGE_USERS: 'MANAGE_USERS',
|
||||
APPROVE_DOCUMENTS: 'APPROVE_DOCUMENTS',
|
||||
|
||||
// Contractor / Vendor Capabilities
|
||||
VIEW_ASSIGNED_PROJECTS: 'VIEW_ASSIGNED_PROJECTS',
|
||||
UPLOAD_DOCUMENTS: 'UPLOAD_DOCUMENTS',
|
||||
SUBMIT_INVOICES: 'SUBMIT_INVOICES',
|
||||
MANAGE_OWN_CREW: 'MANAGE_OWN_CREW',
|
||||
|
||||
// Subcontractor Capabilities
|
||||
VIEW_ASSIGNED_TASKS: 'VIEW_ASSIGNED_TASKS',
|
||||
UPDATE_TASK_STATUS: 'UPDATE_TASK_STATUS'
|
||||
};
|
||||
|
||||
const ROLE_PERMISSIONS = {
|
||||
[ROLES.OWNER]: [
|
||||
PERMISSIONS.VIEW_ALL_PROJECTS,
|
||||
PERMISSIONS.VIEW_ALL_PERSONNEL,
|
||||
PERMISSIONS.VIEW_FINANCIALS,
|
||||
PERMISSIONS.VIEW_SENSITIVE_DATA,
|
||||
PERMISSIONS.MANAGE_USERS,
|
||||
PERMISSIONS.APPROVE_DOCUMENTS
|
||||
],
|
||||
[ROLES.ADMIN]: [
|
||||
PERMISSIONS.VIEW_ALL_PROJECTS,
|
||||
PERMISSIONS.VIEW_ALL_PERSONNEL,
|
||||
PERMISSIONS.VIEW_FINANCIALS,
|
||||
PERMISSIONS.MANAGE_USERS,
|
||||
PERMISSIONS.APPROVE_DOCUMENTS
|
||||
// Note: Admin might NOT have VIEW_SENSITIVE_DATA by default without extra auth
|
||||
],
|
||||
[ROLES.CONTRACTOR]: [
|
||||
PERMISSIONS.VIEW_ASSIGNED_PROJECTS,
|
||||
PERMISSIONS.UPLOAD_DOCUMENTS,
|
||||
PERMISSIONS.SUBMIT_INVOICES,
|
||||
PERMISSIONS.MANAGE_OWN_CREW
|
||||
],
|
||||
[ROLES.SUBCONTRACTOR]: [
|
||||
PERMISSIONS.VIEW_ASSIGNED_TASKS,
|
||||
PERMISSIONS.UPDATE_TASK_STATUS
|
||||
],
|
||||
[ROLES.FIELD_AGENT]: [
|
||||
// Standard CRM permissions
|
||||
],
|
||||
[ROLES.CUSTOMER]: [
|
||||
// Portal permissions
|
||||
]
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks if a user has a specific permission.
|
||||
* @param {Object} user - The user object from AuthContext
|
||||
* @param {String} permission - The permission key to check
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
export const hasPermission = (user, permission) => {
|
||||
if (!user || !user.role) return false;
|
||||
const userPermissions = ROLE_PERMISSIONS[user.role] || [];
|
||||
return userPermissions.includes(permission);
|
||||
};
|
||||
|
||||
/**
|
||||
* Filters a list of projects based on user role.
|
||||
* @param {Object} user - The user object
|
||||
* @param {Array} projects - Array of project objects
|
||||
* @returns {Array} - Filtered projects
|
||||
*/
|
||||
export const filterProjectsForUser = (user, projects) => {
|
||||
if (!user) return [];
|
||||
|
||||
if (user.role === ROLES.OWNER || user.role === ROLES.ADMIN) {
|
||||
return projects;
|
||||
}
|
||||
|
||||
if (user.role === ROLES.CONTRACTOR) {
|
||||
return projects.filter(p => p.contractorId === user.id);
|
||||
}
|
||||
|
||||
if (user.role === ROLES.SUBCONTRACTOR) {
|
||||
return projects.filter(p => p.subcontractorIds?.includes(user.id));
|
||||
}
|
||||
|
||||
return [];
|
||||
};
|
||||
|
||||
/**
|
||||
* Determines if sensitive data should be masked.
|
||||
* @param {Object} user - The viewer
|
||||
* @returns {Boolean} - True if data should be visible (NOT masked), False if it should be masked.
|
||||
*/
|
||||
export const canViewSensitiveData = (user) => {
|
||||
return hasPermission(user, PERMISSIONS.VIEW_SENSITIVE_DATA);
|
||||
};
|
||||
Reference in New Issue
Block a user