@burdenoff/microfe-crewfoundry 2026.624.1 → 2026.625.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (131) hide show
  1. package/dist/crewfoundry/pages/AdminAdminPagePage.js +100 -76
  2. package/dist/crewfoundry/pages/AdminAdminPagePage.js.map +1 -1
  3. package/dist/crewfoundry/pages/AnalyticsAnalyticsPagePage.js +118 -94
  4. package/dist/crewfoundry/pages/AnalyticsAnalyticsPagePage.js.map +1 -1
  5. package/dist/crewfoundry/pages/AnalyticsEmployeeAnalyticsPagePage.js +105 -81
  6. package/dist/crewfoundry/pages/AnalyticsEmployeeAnalyticsPagePage.js.map +1 -1
  7. package/dist/crewfoundry/pages/AnalyticsFinancialAnalyticsPagePage.js +134 -110
  8. package/dist/crewfoundry/pages/AnalyticsFinancialAnalyticsPagePage.js.map +1 -1
  9. package/dist/crewfoundry/pages/AnalyticsHiringAnalyticsPagePage.js +121 -97
  10. package/dist/crewfoundry/pages/AnalyticsHiringAnalyticsPagePage.js.map +1 -1
  11. package/dist/crewfoundry/pages/CommunicationsAnnouncementsPagePage.js +28 -15
  12. package/dist/crewfoundry/pages/CommunicationsAnnouncementsPagePage.js.map +1 -1
  13. package/dist/crewfoundry/pages/CommunicationsCallsPagePage.js +74 -54
  14. package/dist/crewfoundry/pages/CommunicationsCallsPagePage.js.map +1 -1
  15. package/dist/crewfoundry/pages/CommunicationsDirectoryPagePage.js +87 -69
  16. package/dist/crewfoundry/pages/CommunicationsDirectoryPagePage.js.map +1 -1
  17. package/dist/crewfoundry/pages/CommunicationsFilesPagePage.js +99 -80
  18. package/dist/crewfoundry/pages/CommunicationsFilesPagePage.js.map +1 -1
  19. package/dist/crewfoundry/pages/CommunicationsMessagesPagePage.js +87 -68
  20. package/dist/crewfoundry/pages/CommunicationsMessagesPagePage.js.map +1 -1
  21. package/dist/crewfoundry/pages/CommunicationsTeamsPagePage.js +31 -15
  22. package/dist/crewfoundry/pages/CommunicationsTeamsPagePage.js.map +1 -1
  23. package/dist/crewfoundry/pages/CommunicationsVideoCallsPagePage.js +81 -61
  24. package/dist/crewfoundry/pages/CommunicationsVideoCallsPagePage.js.map +1 -1
  25. package/dist/crewfoundry/pages/CompanyClientManagementPagePage.js +71 -51
  26. package/dist/crewfoundry/pages/CompanyClientManagementPagePage.js.map +1 -1
  27. package/dist/crewfoundry/pages/CompanyCompanyDashboardPagePage.js +82 -58
  28. package/dist/crewfoundry/pages/CompanyCompanyDashboardPagePage.js.map +1 -1
  29. package/dist/crewfoundry/pages/CompanyCompanyProfilePagePage.js +46 -39
  30. package/dist/crewfoundry/pages/CompanyCompanyProfilePagePage.js.map +1 -1
  31. package/dist/crewfoundry/pages/CompanyVendorManagementPagePage.js +80 -62
  32. package/dist/crewfoundry/pages/CompanyVendorManagementPagePage.js.map +1 -1
  33. package/dist/crewfoundry/pages/DashboardAnalyticsPagePage.js +104 -80
  34. package/dist/crewfoundry/pages/DashboardAnalyticsPagePage.js.map +1 -1
  35. package/dist/crewfoundry/pages/DashboardDashboardPagePage.js +219 -151
  36. package/dist/crewfoundry/pages/DashboardDashboardPagePage.js.map +1 -1
  37. package/dist/crewfoundry/pages/DashboardEnhancedDashboardPagePage.js +183 -142
  38. package/dist/crewfoundry/pages/DashboardEnhancedDashboardPagePage.js.map +1 -1
  39. package/dist/crewfoundry/pages/DashboardExecutiveDashboardPage.js +121 -97
  40. package/dist/crewfoundry/pages/DashboardExecutiveDashboardPage.js.map +1 -1
  41. package/dist/crewfoundry/pages/HelpApiDocumentationPagePage.js +57 -46
  42. package/dist/crewfoundry/pages/HelpApiDocumentationPagePage.js.map +1 -1
  43. package/dist/crewfoundry/pages/HiringApplicationsPagePage.js +91 -67
  44. package/dist/crewfoundry/pages/HiringApplicationsPagePage.js.map +1 -1
  45. package/dist/crewfoundry/pages/HiringCandidatesPagePage.js +112 -93
  46. package/dist/crewfoundry/pages/HiringCandidatesPagePage.js.map +1 -1
  47. package/dist/crewfoundry/pages/HiringCreateJobPagePage.js +55 -48
  48. package/dist/crewfoundry/pages/HiringCreateJobPagePage.js.map +1 -1
  49. package/dist/crewfoundry/pages/HiringInterviewsPagePage.js +70 -50
  50. package/dist/crewfoundry/pages/HiringInterviewsPagePage.js.map +1 -1
  51. package/dist/crewfoundry/pages/HiringJobDetailsPagePage.js +140 -97
  52. package/dist/crewfoundry/pages/HiringJobDetailsPagePage.js.map +1 -1
  53. package/dist/crewfoundry/pages/HiringJobsPagePage.js +101 -85
  54. package/dist/crewfoundry/pages/HiringJobsPagePage.js.map +1 -1
  55. package/dist/crewfoundry/pages/HrDepartmentsPagePage.js +68 -48
  56. package/dist/crewfoundry/pages/HrDepartmentsPagePage.js.map +1 -1
  57. package/dist/crewfoundry/pages/HrEmployeesPagePage.js +99 -71
  58. package/dist/crewfoundry/pages/HrEmployeesPagePage.js.map +1 -1
  59. package/dist/crewfoundry/pages/HrLeaveManagementPagePage.js +97 -73
  60. package/dist/crewfoundry/pages/HrLeaveManagementPagePage.js.map +1 -1
  61. package/dist/crewfoundry/pages/HrPayrollPagePage.js +100 -76
  62. package/dist/crewfoundry/pages/HrPayrollPagePage.js.map +1 -1
  63. package/dist/crewfoundry/pages/HrTimeTrackingPagePage.js +93 -69
  64. package/dist/crewfoundry/pages/HrTimeTrackingPagePage.js.map +1 -1
  65. package/dist/crewfoundry/pages/LearningAssessmentsPagePage.js +65 -45
  66. package/dist/crewfoundry/pages/LearningAssessmentsPagePage.js.map +1 -1
  67. package/dist/crewfoundry/pages/LearningCertificatesPagePage.js +93 -75
  68. package/dist/crewfoundry/pages/LearningCertificatesPagePage.js.map +1 -1
  69. package/dist/crewfoundry/pages/LearningCourseDetailsPagePage.js +117 -72
  70. package/dist/crewfoundry/pages/LearningCourseDetailsPagePage.js.map +1 -1
  71. package/dist/crewfoundry/pages/LearningCourseLearningPagePage.js +66 -54
  72. package/dist/crewfoundry/pages/LearningCourseLearningPagePage.js.map +1 -1
  73. package/dist/crewfoundry/pages/LearningCoursesPagePage.js +36 -20
  74. package/dist/crewfoundry/pages/LearningCoursesPagePage.js.map +1 -1
  75. package/dist/crewfoundry/pages/LearningLearningAnalyticsPagePage.js +90 -66
  76. package/dist/crewfoundry/pages/LearningLearningAnalyticsPagePage.js.map +1 -1
  77. package/dist/crewfoundry/pages/LearningLearningPagePage.js +81 -57
  78. package/dist/crewfoundry/pages/LearningLearningPagePage.js.map +1 -1
  79. package/dist/crewfoundry/pages/LearningLearningPathDetailPagePage.js +90 -65
  80. package/dist/crewfoundry/pages/LearningLearningPathDetailPagePage.js.map +1 -1
  81. package/dist/crewfoundry/pages/LearningLearningPathsPagePage.js +33 -17
  82. package/dist/crewfoundry/pages/LearningLearningPathsPagePage.js.map +1 -1
  83. package/dist/crewfoundry/pages/LearningMyLearningPagePage.js +83 -59
  84. package/dist/crewfoundry/pages/LearningMyLearningPagePage.js.map +1 -1
  85. package/dist/crewfoundry/pages/MarketplaceBookingManagementPagePage.js +68 -48
  86. package/dist/crewfoundry/pages/MarketplaceBookingManagementPagePage.js.map +1 -1
  87. package/dist/crewfoundry/pages/MarketplaceEarningsPagePage.js +80 -60
  88. package/dist/crewfoundry/pages/MarketplaceEarningsPagePage.js.map +1 -1
  89. package/dist/crewfoundry/pages/MarketplaceFreelancerProfilePageEnhancedPage.js +153 -118
  90. package/dist/crewfoundry/pages/MarketplaceFreelancerProfilePageEnhancedPage.js.map +1 -1
  91. package/dist/crewfoundry/pages/MarketplaceFreelancerProfilePagePage.js +42 -37
  92. package/dist/crewfoundry/pages/MarketplaceFreelancerProfilePagePage.js.map +1 -1
  93. package/dist/crewfoundry/pages/MarketplaceMarketplacePagePage.js +67 -47
  94. package/dist/crewfoundry/pages/MarketplaceMarketplacePagePage.js.map +1 -1
  95. package/dist/crewfoundry/pages/MarketplaceMarketplaceServicesPagePage.js +104 -85
  96. package/dist/crewfoundry/pages/MarketplaceMarketplaceServicesPagePage.js.map +1 -1
  97. package/dist/crewfoundry/pages/MarketplaceMessagingPagePage.js +76 -57
  98. package/dist/crewfoundry/pages/MarketplaceMessagingPagePage.js.map +1 -1
  99. package/dist/crewfoundry/pages/MarketplaceMyServicesPagePage.js +78 -60
  100. package/dist/crewfoundry/pages/MarketplaceMyServicesPagePage.js.map +1 -1
  101. package/dist/crewfoundry/pages/MarketplaceProjectDetailsPagePage.js +138 -93
  102. package/dist/crewfoundry/pages/MarketplaceProjectDetailsPagePage.js.map +1 -1
  103. package/dist/crewfoundry/pages/MarketplaceServiceDetailsPagePage.js +98 -53
  104. package/dist/crewfoundry/pages/MarketplaceServiceDetailsPagePage.js.map +1 -1
  105. package/dist/crewfoundry/pages/PaymentsEscrowPagePage.js +69 -49
  106. package/dist/crewfoundry/pages/PaymentsEscrowPagePage.js.map +1 -1
  107. package/dist/crewfoundry/pages/PaymentsInvoicesPagePage.js +84 -65
  108. package/dist/crewfoundry/pages/PaymentsInvoicesPagePage.js.map +1 -1
  109. package/dist/crewfoundry/pages/PaymentsPaymentDashboardPagePage.js +76 -52
  110. package/dist/crewfoundry/pages/PaymentsPaymentDashboardPagePage.js.map +1 -1
  111. package/dist/crewfoundry/pages/PaymentsPaymentMethodsPagePage.js +58 -40
  112. package/dist/crewfoundry/pages/PaymentsPaymentMethodsPagePage.js.map +1 -1
  113. package/dist/crewfoundry/pages/PaymentsSecurityPagePage.js +85 -65
  114. package/dist/crewfoundry/pages/PaymentsSecurityPagePage.js.map +1 -1
  115. package/dist/crewfoundry/pages/ProjectsCreateProjectPagePage.js +36 -29
  116. package/dist/crewfoundry/pages/ProjectsCreateProjectPagePage.js.map +1 -1
  117. package/dist/crewfoundry/pages/ProjectsProjectDetailsPagePage.js +108 -73
  118. package/dist/crewfoundry/pages/ProjectsProjectDetailsPagePage.js.map +1 -1
  119. package/dist/crewfoundry/pages/ProjectsProjectsPagePage.js +43 -27
  120. package/dist/crewfoundry/pages/ProjectsProjectsPagePage.js.map +1 -1
  121. package/dist/crewfoundry/pages/TeamsTeamAnalyticsPagePage.js +67 -47
  122. package/dist/crewfoundry/pages/TeamsTeamAnalyticsPagePage.js.map +1 -1
  123. package/dist/crewfoundry/pages/TeamsTeamDetailPagePage.js +108 -63
  124. package/dist/crewfoundry/pages/TeamsTeamDetailPagePage.js.map +1 -1
  125. package/dist/crewfoundry/pages/TeamsTeamDirectoryPagePage.js +83 -64
  126. package/dist/crewfoundry/pages/TeamsTeamDirectoryPagePage.js.map +1 -1
  127. package/dist/crewfoundry/pages/TeamsTeamSettingsPagePage.js +185 -144
  128. package/dist/crewfoundry/pages/TeamsTeamSettingsPagePage.js.map +1 -1
  129. package/dist/crewfoundry/pages/TeamsTeamsPagePage.js +40 -24
  130. package/dist/crewfoundry/pages/TeamsTeamsPagePage.js.map +1 -1
  131. package/package.json +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"DashboardEnhancedDashboardPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/DashboardEnhancedDashboardPagePage.tsx"],"sourcesContent":["import { useMemo } from 'react';\nimport {\n Badge,\n Button,\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n Separator,\n} from '@burdenoff/fe-libs/ui';\nimport {\n AlertTriangle,\n ArrowUpRight,\n Award,\n Bell,\n Briefcase,\n CheckCircle,\n MapPin,\n Star,\n Users,\n Zap,\n} from 'lucide-react';\nimport { useCrewFoundryStore } from '../store/crewfoundryStore';\n\nexport function DashboardEnhancedDashboardPagePage() {\n const {\n employees,\n jobPostings,\n candidates,\n interviews,\n leaveRequests,\n notifications,\n projects,\n announcements,\n } = useCrewFoundryStore();\n\n const quickActions = useMemo(\n () => [\n {\n label: `Post New Job (${jobPostings.filter((job) => job.status === 'active').length} active)`,\n icon: Briefcase,\n color: 'text-blue-600',\n },\n {\n label: `Review Candidates (${candidates.filter((candidate) => candidate.status === 'new').length})`,\n icon: Users,\n color: 'text-purple-600',\n },\n {\n label: `Approve Leaves (${leaveRequests.filter((leave) => leave.status === 'pending').length})`,\n icon: CheckCircle,\n color: 'text-green-600',\n },\n {\n label: `Run Payroll (${projects.filter((project) => project.status === 'active').length} projects)`,\n icon: Zap,\n color: 'text-orange-600',\n },\n ],\n [candidates, jobPostings, leaveRequests, projects]\n );\n\n const companyGoals = useMemo(\n () => [\n {\n goal: 'Reduce time-to-hire to 25 days',\n current: Math.max(\n 20,\n 40 - candidates.filter((candidate) => candidate.status === 'hired').length\n ),\n target: 25,\n unit: 'days',\n },\n {\n goal: 'Achieve 95% employee satisfaction',\n current: Math.round(\n (employees.reduce((sum, employee) => sum + employee.performanceScore, 0) /\n Math.max(employees.length, 1)) *\n 20\n ),\n target: 95,\n unit: '%',\n },\n {\n goal: 'Fill 30 open positions by Q2',\n current: candidates.filter((candidate) => candidate.status === 'hired').length,\n target: 30,\n unit: 'positions',\n },\n {\n goal: 'Complete 80% training compliance',\n current: Math.min(\n 100,\n 60 +\n Math.round(\n (employees.filter((employee) => employee.status === 'active').length /\n Math.max(employees.length, 1)) *\n 30\n )\n ),\n target: 80,\n unit: '%',\n },\n ],\n [candidates, employees]\n );\n\n const upcomingInterviews = interviews.filter((i) => i.status === 'scheduled');\n const pendingLeaves = leaveRequests.filter((l) => l.status === 'pending');\n const unreadNotifs = notifications.filter((n) => !n.read);\n const pinnedAnnouncements = announcements.filter((a) => a.isPinned);\n const topPerformers = [...employees]\n .sort((a, b) => b.performanceScore - a.performanceScore)\n .slice(0, 5);\n const recentHires = [...employees]\n .sort((a, b) => b.startDate.localeCompare(a.startDate))\n .slice(0, 5);\n\n const locationMap = employees.reduce<Record<string, number>>((acc, e) => {\n acc[e.location] = (acc[e.location] || 0) + 1;\n return acc;\n }, {});\n\n return (\n <div className=\"space-y-6 p-6\">\n <div className=\"flex items-center justify-between\">\n <div>\n <h1 className=\"text-2xl font-semibold\">Enhanced Dashboard</h1>\n <p className=\"text-sm text-text-secondary\">Complete workforce command center</p>\n </div>\n <div className=\"flex items-center gap-3\">\n <div className=\"relative\">\n <Bell className=\"h-5 w-5 text-text-secondary\" />\n {unreadNotifs.length > 0 && (\n <span className=\"absolute -top-1 -right-1 h-4 w-4 rounded-full bg-red-500 text-[10px] text-white flex items-center justify-center\">\n {unreadNotifs.length}\n </span>\n )}\n </div>\n <Button size=\"sm\">\n <Zap className=\"h-4 w-4 mr-1\" />\n Quick Actions\n </Button>\n </div>\n </div>\n\n <div className=\"grid gap-3 md:grid-cols-4\">\n {quickActions.map((action) => (\n <Card key={action.label} className=\"cursor-pointer hover:shadow-md transition-shadow\">\n <CardContent className=\"flex items-center gap-3 p-4\">\n <action.icon className={`h-5 w-5 ${action.color}`} />\n <span className=\"text-sm font-medium\">{action.label}</span>\n <ArrowUpRight className=\"h-4 w-4 ml-auto text-text-secondary\" />\n </CardContent>\n </Card>\n ))}\n </div>\n\n {pinnedAnnouncements.length > 0 && (\n <Card className=\"border-yellow-200 bg-yellow-50/50\">\n <CardContent className=\"p-4\">\n {pinnedAnnouncements.map((ann) => (\n <div key={ann.id} className=\"flex items-start gap-3\">\n <AlertTriangle className=\"h-4 w-4 text-yellow-600 mt-0.5\" />\n <div>\n <p className=\"text-sm font-medium\">{ann.title}</p>\n <p className=\"text-xs text-text-secondary mt-1\">\n {ann.content.slice(0, 120)}...\n </p>\n <p className=\"text-xs text-text-secondary mt-1\">\n — {ann.author}, {ann.authorRole}\n </p>\n </div>\n <Badge variant=\"outline\" className=\"ml-auto flex-shrink-0\">\n {ann.priority}\n </Badge>\n </div>\n ))}\n </CardContent>\n </Card>\n )}\n\n <div className=\"grid gap-4 md:grid-cols-3\">\n <Card>\n <CardHeader>\n <CardTitle className=\"text-base\">Company Goals</CardTitle>\n <CardDescription>Q1 2026 targets</CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n {companyGoals.map((g) => {\n const pct = Math.round((g.current / g.target) * 100);\n return (\n <div key={g.goal} className=\"space-y-1\">\n <div className=\"flex justify-between text-xs\">\n <span className=\"text-text-secondary\">{g.goal}</span>\n <span className=\"font-medium\">\n {g.current}/{g.target} {g.unit}\n </span>\n </div>\n <div className=\"h-2 bg-bg-sunken rounded overflow-hidden\">\n <div\n className={`h-2 rounded ${pct >= 90 ? 'bg-green-500' : pct >= 70 ? 'bg-yellow-500' : 'bg-red-500'}`}\n style={{ width: `${Math.min(pct, 100)}%` }}\n />\n </div>\n </div>\n );\n })}\n </CardContent>\n </Card>\n\n <Card>\n <CardHeader>\n <CardTitle className=\"text-base\">Upcoming Interviews</CardTitle>\n <CardDescription>{upcomingInterviews.length} scheduled</CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n {upcomingInterviews.map((interview) => (\n <div key={interview.id} className=\"flex items-center gap-3 rounded border p-2\">\n <div className=\"flex-1 min-w-0\">\n <p className=\"text-sm font-medium truncate\">{interview.candidateName}</p>\n <p className=\"text-xs text-text-secondary\">{interview.position}</p>\n </div>\n <div className=\"text-right flex-shrink-0\">\n <p className=\"text-xs font-medium\">{interview.date}</p>\n <p className=\"text-xs text-text-secondary\">{interview.time}</p>\n </div>\n <Badge variant=\"outline\" className=\"text-[10px]\">\n {interview.type}\n </Badge>\n </div>\n ))}\n </CardContent>\n </Card>\n\n <Card>\n <CardHeader>\n <CardTitle className=\"text-base\">Pending Actions</CardTitle>\n <CardDescription>Items requiring your attention</CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n {pendingLeaves.map((leave) => (\n <div key={leave.id} className=\"flex items-center justify-between rounded border p-2\">\n <div>\n <p className=\"text-sm font-medium\">{leave.employeeName}</p>\n <p className=\"text-xs text-text-secondary\">\n {leave.type} leave · {leave.days} days\n </p>\n </div>\n <div className=\"flex gap-1\">\n <Button size=\"sm\" variant=\"outline\" className=\"h-7 text-xs\">\n Deny\n </Button>\n <Button size=\"sm\" className=\"h-7 text-xs\">\n Approve\n </Button>\n </div>\n </div>\n ))}\n <Separator />\n <div className=\"text-xs text-text-secondary text-center\">\n {candidates.filter((c) => c.status === 'new').length} new applications to review\n </div>\n </CardContent>\n </Card>\n </div>\n\n <div className=\"grid gap-4 md:grid-cols-2\">\n <Card>\n <CardHeader>\n <CardTitle className=\"text-base flex items-center gap-2\">\n <Award className=\"h-4 w-4 text-yellow-500\" />\n Top Performers\n </CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n {topPerformers.map((emp, idx) => (\n <div key={emp.id} className=\"flex items-center gap-3\">\n <span className=\"text-sm font-bold text-text-secondary w-5\">#{idx + 1}</span>\n <div className=\"flex-1\">\n <p className=\"text-sm font-medium\">\n {emp.firstName} {emp.lastName}\n </p>\n <p className=\"text-xs text-text-secondary\">\n {emp.position} · {emp.department}\n </p>\n </div>\n <div className=\"flex items-center gap-1\">\n <Star className=\"h-3 w-3 text-yellow-500\" />\n <span className=\"text-sm font-medium\">{emp.performanceScore}</span>\n </div>\n </div>\n ))}\n </CardContent>\n </Card>\n\n <Card>\n <CardHeader>\n <CardTitle className=\"text-base flex items-center gap-2\">\n <MapPin className=\"h-4 w-4\" />\n Workforce Locations\n </CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n {Object.entries(locationMap)\n .sort(([, a], [, b]) => b - a)\n .map(([location, count]) => (\n <div key={location} className=\"flex items-center justify-between\">\n <span className=\"text-sm\">{location}</span>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-sm font-medium\">{count}</span>\n <span className=\"text-xs text-text-secondary\">\n ({Math.round((count / employees.length) * 100)}%)\n </span>\n </div>\n </div>\n ))}\n </CardContent>\n </Card>\n </div>\n\n <Card>\n <CardHeader>\n <CardTitle>Recent Hires</CardTitle>\n <CardDescription>Newest team members</CardDescription>\n </CardHeader>\n <CardContent>\n <div className=\"grid grid-cols-6 gap-2 text-xs font-medium text-text-secondary border-b pb-2 mb-2\">\n <span>Name</span>\n <span>Position</span>\n <span>Department</span>\n <span>Location</span>\n <span>Start Date</span>\n <span>Type</span>\n </div>\n {recentHires.map((emp) => (\n <div\n key={emp.id}\n className=\"grid grid-cols-6 gap-2 py-2 border-b last:border-0 text-sm\"\n >\n <span className=\"font-medium\">\n {emp.firstName} {emp.lastName}\n </span>\n <span className=\"text-text-secondary truncate\">{emp.position}</span>\n <span>{emp.department}</span>\n <span className=\"text-text-secondary truncate\">{emp.location}</span>\n <span>{emp.startDate}</span>\n <Badge variant=\"outline\" className=\"w-fit text-[10px]\">\n {emp.type.replace('_', ' ')}\n </Badge>\n </div>\n ))}\n </CardContent>\n </Card>\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"DashboardEnhancedDashboardPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/DashboardEnhancedDashboardPagePage.tsx"],"sourcesContent":["import { useMemo } from 'react';\nimport {\n Badge,\n Button,\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n EmphasisPanel,\n GradientText,\n NextSteps,\n PagePurpose,\n Separator,\n} from '@burdenoff/fe-libs/ui';\nimport {\n AlertTriangle,\n ArrowUpRight,\n Award,\n Bell,\n Briefcase,\n CheckCircle,\n MapPin,\n Star,\n Users,\n Zap,\n} from 'lucide-react';\nimport { useNavigate } from 'react-router-dom';\nimport { useCrewFoundryStore } from '../store/crewfoundryStore';\n\nexport function DashboardEnhancedDashboardPagePage() {\n const navigate = useNavigate();\n const {\n employees,\n jobPostings,\n candidates,\n interviews,\n leaveRequests,\n notifications,\n projects,\n announcements,\n } = useCrewFoundryStore();\n\n const quickActions = useMemo(\n () => [\n {\n label: `Post New Job (${jobPostings.filter((job) => job.status === 'active').length} active)`,\n icon: Briefcase,\n color: 'text-status-info-text',\n },\n {\n label: `Review Candidates (${candidates.filter((candidate) => candidate.status === 'new').length})`,\n icon: Users,\n color: 'text-action-primary-bg',\n },\n {\n label: `Approve Leaves (${leaveRequests.filter((leave) => leave.status === 'pending').length})`,\n icon: CheckCircle,\n color: 'text-status-success-text',\n },\n {\n label: `Run Payroll (${projects.filter((project) => project.status === 'active').length} projects)`,\n icon: Zap,\n color: 'text-status-warning-text',\n },\n ],\n [candidates, jobPostings, leaveRequests, projects]\n );\n\n const companyGoals = useMemo(\n () => [\n {\n goal: 'Reduce time-to-hire to 25 days',\n current: Math.max(\n 20,\n 40 - candidates.filter((candidate) => candidate.status === 'hired').length\n ),\n target: 25,\n unit: 'days',\n },\n {\n goal: 'Achieve 95% employee satisfaction',\n current: Math.round(\n (employees.reduce((sum, employee) => sum + employee.performanceScore, 0) /\n Math.max(employees.length, 1)) *\n 20\n ),\n target: 95,\n unit: '%',\n },\n {\n goal: 'Fill 30 open positions by Q2',\n current: candidates.filter((candidate) => candidate.status === 'hired').length,\n target: 30,\n unit: 'positions',\n },\n {\n goal: 'Complete 80% training compliance',\n current: Math.min(\n 100,\n 60 +\n Math.round(\n (employees.filter((employee) => employee.status === 'active').length /\n Math.max(employees.length, 1)) *\n 30\n )\n ),\n target: 80,\n unit: '%',\n },\n ],\n [candidates, employees]\n );\n\n const upcomingInterviews = interviews.filter((i) => i.status === 'scheduled');\n const pendingLeaves = leaveRequests.filter((l) => l.status === 'pending');\n const unreadNotifs = notifications.filter((n) => !n.read);\n const pinnedAnnouncements = announcements.filter((a) => a.isPinned);\n const topPerformers = [...employees]\n .sort((a, b) => b.performanceScore - a.performanceScore)\n .slice(0, 5);\n const recentHires = [...employees]\n .sort((a, b) => b.startDate.localeCompare(a.startDate))\n .slice(0, 5);\n\n const locationMap = employees.reduce<Record<string, number>>((acc, e) => {\n acc[e.location] = (acc[e.location] || 0) + 1;\n return acc;\n }, {});\n\n return (\n <div className=\"space-y-6 p-6\">\n <div className=\"flex items-center justify-between\">\n <div>\n <h1 className=\"text-2xl font-semibold\">\n <GradientText>Enhanced Dashboard</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">Complete workforce command center</p>\n <PagePurpose className=\"mt-1\">A richer, customizable command center for your workforce — see live metrics, activity, and trends tailored to how you run your organization.</PagePurpose>\n </div>\n <div className=\"flex items-center gap-3\">\n <div className=\"relative\">\n <Bell className=\"h-5 w-5 text-text-secondary\" />\n {unreadNotifs.length > 0 && (\n <span className=\"absolute -top-1 -right-1 h-4 w-4 rounded-full bg-status-error-text text-[10px] text-white flex items-center justify-center\">\n {unreadNotifs.length}\n </span>\n )}\n </div>\n <Button size=\"sm\">\n <Zap className=\"h-4 w-4 mr-1\" />\n Quick Actions\n </Button>\n </div>\n </div>\n\n <NextSteps\n storageKey=\"crewfoundry-enhanced-dashboard\"\n steps={[\n {\n id: 'hiring',\n label: 'Move hiring forward',\n description: 'Review open roles and applicants in your pipeline.',\n icon: <Briefcase className=\"h-4 w-4\" />,\n onClick: () => navigate('../../hiring/jobs-page'),\n },\n {\n id: 'people',\n label: 'Check on your people',\n description: 'See who is active, on leave, or needs attention.',\n icon: <Users className=\"h-4 w-4\" />,\n onClick: () => navigate('../../hr/employees-page'),\n },\n {\n id: 'analytics',\n label: 'Dig into analytics',\n description: 'Explore deeper workforce and hiring trends.',\n icon: <ArrowUpRight className=\"h-4 w-4\" />,\n onClick: () => navigate('../../analytics/analytics-page'),\n },\n ]}\n />\n\n <div className=\"grid gap-3 md:grid-cols-4\">\n {quickActions.map((action) => (\n <Card key={action.label} className=\"cursor-pointer hover:shadow-md transition-shadow\">\n <CardContent className=\"flex items-center gap-3 p-4\">\n <action.icon className={`h-5 w-5 ${action.color}`} />\n <span className=\"text-sm font-medium\">{action.label}</span>\n <ArrowUpRight className=\"h-4 w-4 ml-auto text-text-secondary\" />\n </CardContent>\n </Card>\n ))}\n </div>\n\n {pinnedAnnouncements.length > 0 && (\n <Card className=\"border-status-warning-text/30 bg-status-warning-bg/50\">\n <CardContent className=\"p-4\">\n {pinnedAnnouncements.map((ann) => (\n <div key={ann.id} className=\"flex items-start gap-3\">\n <AlertTriangle className=\"h-4 w-4 text-status-warning-text mt-0.5\" />\n <div>\n <p className=\"text-sm font-medium\">{ann.title}</p>\n <p className=\"text-xs text-text-secondary mt-1\">{ann.content.slice(0, 120)}...</p>\n <p className=\"text-xs text-text-secondary mt-1\">\n — {ann.author}, {ann.authorRole}\n </p>\n </div>\n <Badge variant=\"outline\" className=\"ml-auto flex-shrink-0\">\n {ann.priority}\n </Badge>\n </div>\n ))}\n </CardContent>\n </Card>\n )}\n\n <div className=\"grid gap-4 md:grid-cols-3\">\n <EmphasisPanel>\n <div className=\"text-base font-semibold\">Company Goals</div>\n <p className=\"mb-4 text-sm text-text-secondary\">Q1 2026 targets</p>\n <div className=\"space-y-4\">\n {companyGoals.map((g) => {\n const pct = Math.round((g.current / g.target) * 100);\n return (\n <div key={g.goal} className=\"space-y-1\">\n <div className=\"flex justify-between text-xs\">\n <span className=\"text-text-secondary\">{g.goal}</span>\n <span className=\"font-medium\">\n {g.current}/{g.target} {g.unit}\n </span>\n </div>\n <div className=\"h-2 bg-bg-sunken rounded overflow-hidden\">\n <div\n className={`h-2 rounded ${pct >= 90 ? 'bg-status-success-text' : pct >= 70 ? 'bg-status-warning-text' : 'bg-status-error-text'}`}\n style={{ width: `${Math.min(pct, 100)}%` }}\n />\n </div>\n </div>\n );\n })}\n </div>\n </EmphasisPanel>\n\n <Card>\n <CardHeader>\n <CardTitle className=\"text-base\">Upcoming Interviews</CardTitle>\n <CardDescription>{upcomingInterviews.length} scheduled</CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n {upcomingInterviews.map((interview) => (\n <div key={interview.id} className=\"flex items-center gap-3 rounded border p-2\">\n <div className=\"flex-1 min-w-0\">\n <p className=\"text-sm font-medium truncate\">{interview.candidateName}</p>\n <p className=\"text-xs text-text-secondary\">{interview.position}</p>\n </div>\n <div className=\"text-right flex-shrink-0\">\n <p className=\"text-xs font-medium\">{interview.date}</p>\n <p className=\"text-xs text-text-secondary\">{interview.time}</p>\n </div>\n <Badge variant=\"outline\" className=\"text-[10px]\">\n {interview.type}\n </Badge>\n </div>\n ))}\n </CardContent>\n </Card>\n\n <Card>\n <CardHeader>\n <CardTitle className=\"text-base\">Pending Actions</CardTitle>\n <CardDescription>Items requiring your attention</CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n {pendingLeaves.map((leave) => (\n <div key={leave.id} className=\"flex items-center justify-between rounded border p-2\">\n <div>\n <p className=\"text-sm font-medium\">{leave.employeeName}</p>\n <p className=\"text-xs text-text-secondary\">\n {leave.type} leave · {leave.days} days\n </p>\n </div>\n <div className=\"flex gap-1\">\n <Button size=\"sm\" variant=\"outline\" className=\"h-7 text-xs\">\n Deny\n </Button>\n <Button size=\"sm\" className=\"h-7 text-xs\">\n Approve\n </Button>\n </div>\n </div>\n ))}\n <Separator />\n <div className=\"text-xs text-text-secondary text-center\">\n {candidates.filter((c) => c.status === 'new').length} new applications to review\n </div>\n </CardContent>\n </Card>\n </div>\n\n <div className=\"grid gap-4 md:grid-cols-2\">\n <Card>\n <CardHeader>\n <CardTitle className=\"text-base flex items-center gap-2\">\n <Award className=\"h-4 w-4 text-status-warning-text\" />\n Top Performers\n </CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n {topPerformers.map((emp, idx) => (\n <div key={emp.id} className=\"flex items-center gap-3\">\n <span className=\"text-sm font-bold text-text-secondary w-5\">#{idx + 1}</span>\n <div className=\"flex-1\">\n <p className=\"text-sm font-medium\">\n {emp.firstName} {emp.lastName}\n </p>\n <p className=\"text-xs text-text-secondary\">\n {emp.position} · {emp.department}\n </p>\n </div>\n <div className=\"flex items-center gap-1\">\n <Star className=\"h-3 w-3 text-status-warning-text\" />\n <span className=\"text-sm font-medium\">{emp.performanceScore}</span>\n </div>\n </div>\n ))}\n </CardContent>\n </Card>\n\n <Card>\n <CardHeader>\n <CardTitle className=\"text-base flex items-center gap-2\">\n <MapPin className=\"h-4 w-4\" />\n Workforce Locations\n </CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n {Object.entries(locationMap)\n .sort(([, a], [, b]) => b - a)\n .map(([location, count]) => (\n <div key={location} className=\"flex items-center justify-between\">\n <span className=\"text-sm\">{location}</span>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-sm font-medium\">{count}</span>\n <span className=\"text-xs text-text-secondary\">\n ({Math.round((count / employees.length) * 100)}%)\n </span>\n </div>\n </div>\n ))}\n </CardContent>\n </Card>\n </div>\n\n <Card>\n <CardHeader>\n <CardTitle>Recent Hires</CardTitle>\n <CardDescription>Newest team members</CardDescription>\n </CardHeader>\n <CardContent>\n <div className=\"grid grid-cols-6 gap-2 text-xs font-medium text-text-secondary border-b pb-2 mb-2\">\n <span>Name</span>\n <span>Position</span>\n <span>Department</span>\n <span>Location</span>\n <span>Start Date</span>\n <span>Type</span>\n </div>\n {recentHires.map((emp) => (\n <div\n key={emp.id}\n className=\"grid grid-cols-6 gap-2 py-2 border-b last:border-0 text-sm\"\n >\n <span className=\"font-medium\">\n {emp.firstName} {emp.lastName}\n </span>\n <span className=\"text-text-secondary truncate\">{emp.position}</span>\n <span>{emp.department}</span>\n <span className=\"text-text-secondary truncate\">{emp.location}</span>\n <span>{emp.startDate}</span>\n <Badge variant=\"outline\" className=\"w-fit text-[10px]\">\n {emp.type.replace('_', ' ')}\n </Badge>\n </div>\n ))}\n </CardContent>\n </Card>\n </div>\n );\n}\n"],"mappings":"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"}
@@ -2,18 +2,18 @@ import { useCrewFoundryStore as e } from "../store/crewfoundryStore.js";
2
2
  import { useMemo as t } from "react";
3
3
  import { ArrowUp as n, Building2 as r, DollarSign as i, Percent as a, Target as o } from "lucide-react";
4
4
  import { jsx as s, jsxs as c } from "react/jsx-runtime";
5
- import { Badge as l, Card as u, CardContent as d, CardDescription as f, CardHeader as p, CardTitle as m, Separator as h } from "@burdenoff/fe-libs/ui";
5
+ import { Badge as l, Card as u, CardContent as d, CardDescription as f, CardHeader as p, CardTitle as m, GlassCard as h, GradientText as g, PagePurpose as _, Separator as v } from "@burdenoff/fe-libs/ui";
6
6
  //#region src/crewfoundry/pages/DashboardExecutiveDashboardPage.tsx
7
- function g() {
8
- let { employees: g, departments: _, projects: v, jobPostings: y } = e(), b = t(() => {
7
+ function y() {
8
+ let { employees: y, departments: b, projects: x, jobPostings: S } = e(), C = t(() => {
9
9
  let e = [
10
10
  "Q1 2025",
11
11
  "Q2 2025",
12
12
  "Q3 2025",
13
13
  "Q4 2025"
14
- ], t = v.reduce((e, t) => e + t.budget, 0) || 1e6;
14
+ ], t = x.reduce((e, t) => e + t.budget, 0) || 1e6;
15
15
  return e.map((e, n) => {
16
- let r = Math.round(t * (.55 + n * .08)), i = Math.max(1, g.length - (3 - n) * 4);
16
+ let r = Math.round(t * (.55 + n * .08)), i = Math.max(1, y.length - (3 - n) * 4);
17
17
  return {
18
18
  quarter: e,
19
19
  revenue: r,
@@ -21,57 +21,64 @@ function g() {
21
21
  revenuePerHead: Math.round(r / i)
22
22
  };
23
23
  });
24
- }, [g.length, v]), x = t(() => [
24
+ }, [y.length, x]), w = t(() => [
25
25
  {
26
26
  metric: "Flight Risk Employees",
27
- value: g.filter((e) => e.performanceScore < 3.6).length,
27
+ value: y.filter((e) => e.performanceScore < 3.6).length,
28
28
  severity: "warning",
29
- detail: `${Math.round(g.filter((e) => e.performanceScore < 3.6).length / Math.max(g.length, 1) * 100)}% of workforce`
29
+ detail: `${Math.round(y.filter((e) => e.performanceScore < 3.6).length / Math.max(y.length, 1) * 100)}% of workforce`
30
30
  },
31
31
  {
32
32
  metric: "Overdue Performance Reviews",
33
- value: g.filter((e) => e.status === "on_leave").length,
33
+ value: y.filter((e) => e.status === "on_leave").length,
34
34
  severity: "error",
35
35
  detail: "Review follow-ups required"
36
36
  },
37
37
  {
38
38
  metric: "Unfilled Critical Roles",
39
- value: y.filter((e) => e.status === "active" && e.experienceLevel === "lead").length,
39
+ value: S.filter((e) => e.status === "active" && e.experienceLevel === "lead").length,
40
40
  severity: "warning",
41
41
  detail: "Open lead-level positions"
42
42
  },
43
43
  {
44
44
  metric: "Expiring Contracts",
45
- value: g.filter((e) => e.type === "contract").length,
45
+ value: y.filter((e) => e.type === "contract").length,
46
46
  severity: "info",
47
47
  detail: "Contract renewals in focus"
48
48
  }
49
- ], [g, y]), S = t(() => [{
49
+ ], [y, S]), T = t(() => [{
50
50
  category: "Company",
51
51
  male: 52,
52
52
  female: 43,
53
53
  other: 5
54
- }, ..._.map((e) => {
55
- let t = g.filter((t) => t.department === e.name).length, n = Math.min(100, Math.round(45 + t % 15)), r = Math.min(100 - n, Math.round(40 + t % 10)), i = Math.max(0, 100 - n - r);
54
+ }, ...b.map((e) => {
55
+ let t = y.filter((t) => t.department === e.name).length, n = Math.min(100, Math.round(45 + t % 15)), r = Math.min(100 - n, Math.round(40 + t % 10)), i = Math.max(0, 100 - n - r);
56
56
  return {
57
57
  category: e.name,
58
58
  male: n,
59
59
  female: r,
60
60
  other: i
61
61
  };
62
- }).slice(0, 3)], [_, g]), C = g.reduce((e, t) => e + t.salary, 0), w = _.reduce((e, t) => e + t.budget, 0), T = v.reduce((e, t) => e + t.budget, 0), E = v.reduce((e, t) => e + t.spent, 0), D = Math.round(E / T * 100);
62
+ }).slice(0, 3)], [b, y]), E = y.reduce((e, t) => e + t.salary, 0), D = b.reduce((e, t) => e + t.budget, 0), O = x.reduce((e, t) => e + t.budget, 0), k = x.reduce((e, t) => e + t.spent, 0), A = Math.round(k / O * 100);
63
63
  return /* @__PURE__ */ c("div", {
64
64
  className: "space-y-6 p-6",
65
65
  children: [
66
66
  /* @__PURE__ */ c("div", {
67
67
  className: "flex items-center justify-between",
68
- children: [/* @__PURE__ */ c("div", { children: [/* @__PURE__ */ s("h1", {
69
- className: "text-2xl font-semibold",
70
- children: "Executive Dashboard"
71
- }), /* @__PURE__ */ s("p", {
72
- className: "text-sm text-text-secondary",
73
- children: "Strategic workforce insights for leadership"
74
- })] }), /* @__PURE__ */ s(l, {
68
+ children: [/* @__PURE__ */ c("div", { children: [
69
+ /* @__PURE__ */ s("h1", {
70
+ className: "text-2xl font-semibold",
71
+ children: /* @__PURE__ */ s(g, { children: "Executive Dashboard" })
72
+ }),
73
+ /* @__PURE__ */ s("p", {
74
+ className: "text-sm text-text-secondary",
75
+ children: "Strategic workforce insights for leadership"
76
+ }),
77
+ /* @__PURE__ */ s(_, {
78
+ className: "mt-1",
79
+ children: "The executive snapshot — top-line workforce, financial, and hiring KPIs in one view so leaders can make decisions fast."
80
+ })
81
+ ] }), /* @__PURE__ */ s(l, {
75
82
  variant: "outline",
76
83
  children: "Q1 2026"
77
84
  })]
@@ -79,68 +86,85 @@ function g() {
79
86
  /* @__PURE__ */ c("div", {
80
87
  className: "grid gap-4 md:grid-cols-2 lg:grid-cols-4",
81
88
  children: [
82
- /* @__PURE__ */ c(u, { children: [/* @__PURE__ */ c(p, {
83
- className: "flex flex-row items-center justify-between space-y-0 pb-2",
84
- children: [/* @__PURE__ */ s(m, {
85
- className: "text-sm font-medium",
86
- children: "Revenue per Employee"
87
- }), /* @__PURE__ */ s(i, { className: "h-4 w-4 text-text-secondary" })]
88
- }), /* @__PURE__ */ c(d, { children: [/* @__PURE__ */ s("div", {
89
- className: "text-2xl font-bold",
90
- children: "$21,862"
91
- }), /* @__PURE__ */ c("div", {
92
- className: "flex items-center text-xs text-green-600",
93
- children: [/* @__PURE__ */ s(n, { className: "h-3 w-3 mr-1" }), "+2.0% from Q3"]
94
- })] })] }),
95
- /* @__PURE__ */ c(u, { children: [/* @__PURE__ */ c(p, {
96
- className: "flex flex-row items-center justify-between space-y-0 pb-2",
97
- children: [/* @__PURE__ */ s(m, {
98
- className: "text-sm font-medium",
99
- children: "Total Workforce Cost"
100
- }), /* @__PURE__ */ s(r, { className: "h-4 w-4 text-text-secondary" })]
101
- }), /* @__PURE__ */ c(d, { children: [/* @__PURE__ */ c("div", {
102
- className: "text-2xl font-bold",
103
- children: [
104
- "$",
105
- (C / 1e6).toFixed(1),
106
- "M"
107
- ]
108
- }), /* @__PURE__ */ s("p", {
109
- className: "text-xs text-text-secondary",
110
- children: "Annual salary expenditure"
111
- })] })] }),
112
- /* @__PURE__ */ c(u, { children: [/* @__PURE__ */ c(p, {
113
- className: "flex flex-row items-center justify-between space-y-0 pb-2",
114
- children: [/* @__PURE__ */ s(m, {
115
- className: "text-sm font-medium",
116
- children: "Budget Utilization"
117
- }), /* @__PURE__ */ s(a, { className: "h-4 w-4 text-text-secondary" })]
118
- }), /* @__PURE__ */ c(d, { children: [/* @__PURE__ */ c("div", {
119
- className: "text-2xl font-bold",
120
- children: [D, "%"]
121
- }), /* @__PURE__ */ c("p", {
122
- className: "text-xs text-text-secondary",
123
- children: [
124
- "$",
125
- (E / 1e6).toFixed(1),
126
- "M of $",
127
- (T / 1e6).toFixed(1),
128
- "M"
129
- ]
130
- })] })] }),
131
- /* @__PURE__ */ c(u, { children: [/* @__PURE__ */ c(p, {
132
- className: "flex flex-row items-center justify-between space-y-0 pb-2",
133
- children: [/* @__PURE__ */ s(m, {
134
- className: "text-sm font-medium",
135
- children: "Retention Rate"
136
- }), /* @__PURE__ */ s(o, { className: "h-4 w-4 text-text-secondary" })]
137
- }), /* @__PURE__ */ c(d, { children: [/* @__PURE__ */ s("div", {
138
- className: "text-2xl font-bold",
139
- children: "95.8%"
140
- }), /* @__PURE__ */ c("div", {
141
- className: "flex items-center text-xs text-green-600",
142
- children: [/* @__PURE__ */ s(n, { className: "h-3 w-3 mr-1" }), "+1.1% improvement"]
143
- })] })] })
89
+ /* @__PURE__ */ c(h, {
90
+ treatment: "glass",
91
+ glow: !0,
92
+ className: "border-border-seam",
93
+ children: [/* @__PURE__ */ c(p, {
94
+ className: "flex flex-row items-center justify-between space-y-0 pb-2",
95
+ children: [/* @__PURE__ */ s(m, {
96
+ className: "text-sm font-medium",
97
+ children: "Revenue per Employee"
98
+ }), /* @__PURE__ */ s(i, { className: "h-4 w-4 text-text-secondary" })]
99
+ }), /* @__PURE__ */ c(d, { children: [/* @__PURE__ */ s("div", {
100
+ className: "text-2xl font-bold tabular-nums",
101
+ children: "$21,862"
102
+ }), /* @__PURE__ */ c("div", {
103
+ className: "flex items-center text-xs text-status-success-text",
104
+ children: [/* @__PURE__ */ s(n, { className: "h-3 w-3 mr-1" }), "+2.0% from Q3"]
105
+ })] })]
106
+ }),
107
+ /* @__PURE__ */ c(h, {
108
+ treatment: "metric",
109
+ className: "border-border-seam",
110
+ children: [/* @__PURE__ */ c(p, {
111
+ className: "flex flex-row items-center justify-between space-y-0 pb-2",
112
+ children: [/* @__PURE__ */ s(m, {
113
+ className: "text-sm font-medium",
114
+ children: "Total Workforce Cost"
115
+ }), /* @__PURE__ */ s(r, { className: "h-4 w-4 text-text-secondary" })]
116
+ }), /* @__PURE__ */ c(d, { children: [/* @__PURE__ */ c("div", {
117
+ className: "text-2xl font-bold tabular-nums",
118
+ children: [
119
+ "$",
120
+ (E / 1e6).toFixed(1),
121
+ "M"
122
+ ]
123
+ }), /* @__PURE__ */ s("p", {
124
+ className: "text-xs text-text-secondary",
125
+ children: "Annual salary expenditure"
126
+ })] })]
127
+ }),
128
+ /* @__PURE__ */ c(h, {
129
+ treatment: "metric",
130
+ className: "border-border-seam",
131
+ children: [/* @__PURE__ */ c(p, {
132
+ className: "flex flex-row items-center justify-between space-y-0 pb-2",
133
+ children: [/* @__PURE__ */ s(m, {
134
+ className: "text-sm font-medium",
135
+ children: "Budget Utilization"
136
+ }), /* @__PURE__ */ s(a, { className: "h-4 w-4 text-text-secondary" })]
137
+ }), /* @__PURE__ */ c(d, { children: [/* @__PURE__ */ c("div", {
138
+ className: "text-2xl font-bold tabular-nums",
139
+ children: [A, "%"]
140
+ }), /* @__PURE__ */ c("p", {
141
+ className: "text-xs text-text-secondary",
142
+ children: [
143
+ "$",
144
+ (k / 1e6).toFixed(1),
145
+ "M of $",
146
+ (O / 1e6).toFixed(1),
147
+ "M"
148
+ ]
149
+ })] })]
150
+ }),
151
+ /* @__PURE__ */ c(h, {
152
+ treatment: "metric",
153
+ className: "border-border-seam",
154
+ children: [/* @__PURE__ */ c(p, {
155
+ className: "flex flex-row items-center justify-between space-y-0 pb-2",
156
+ children: [/* @__PURE__ */ s(m, {
157
+ className: "text-sm font-medium",
158
+ children: "Retention Rate"
159
+ }), /* @__PURE__ */ s(o, { className: "h-4 w-4 text-text-secondary" })]
160
+ }), /* @__PURE__ */ c(d, { children: [/* @__PURE__ */ s("div", {
161
+ className: "text-2xl font-bold tabular-nums",
162
+ children: "95.8%"
163
+ }), /* @__PURE__ */ c("div", {
164
+ className: "flex items-center text-xs text-status-success-text",
165
+ children: [/* @__PURE__ */ s(n, { className: "h-3 w-3 mr-1" }), "+1.1% improvement"]
166
+ })] })]
167
+ })
144
168
  ]
145
169
  }),
146
170
  /* @__PURE__ */ c("div", {
@@ -162,7 +186,7 @@ function g() {
162
186
  children: "Rev/Head"
163
187
  })
164
188
  ]
165
- }), b.map((e) => /* @__PURE__ */ c("div", {
189
+ }), C.map((e) => /* @__PURE__ */ c("div", {
166
190
  className: "grid grid-cols-4 gap-2 py-2 border-b last:border-0 text-sm",
167
191
  children: [
168
192
  /* @__PURE__ */ s("span", {
@@ -188,11 +212,11 @@ function g() {
188
212
  ]
189
213
  }, e.quarter))] })] }), /* @__PURE__ */ c(u, { children: [/* @__PURE__ */ c(p, { children: [/* @__PURE__ */ s(m, { children: "Risk Indicators" }), /* @__PURE__ */ s(f, { children: "Items requiring executive attention" })] }), /* @__PURE__ */ s(d, {
190
214
  className: "space-y-3",
191
- children: x.map((e) => /* @__PURE__ */ c("div", {
215
+ children: w.map((e) => /* @__PURE__ */ c("div", {
192
216
  className: "flex items-center justify-between rounded border p-3",
193
217
  children: [/* @__PURE__ */ c("div", {
194
218
  className: "flex items-center gap-3",
195
- children: [/* @__PURE__ */ s("div", { className: `h-3 w-3 rounded-full ${e.severity === "error" ? "bg-red-500" : e.severity === "warning" ? "bg-yellow-500" : "bg-blue-500"}` }), /* @__PURE__ */ c("div", { children: [/* @__PURE__ */ s("p", {
219
+ children: [/* @__PURE__ */ s("div", { className: `h-3 w-3 rounded-full ${e.severity === "error" ? "bg-status-error-text" : e.severity === "warning" ? "bg-status-warning-text" : "bg-status-info-text"}` }), /* @__PURE__ */ c("div", { children: [/* @__PURE__ */ s("p", {
196
220
  className: "text-sm font-medium",
197
221
  children: e.metric
198
222
  }), /* @__PURE__ */ s("p", {
@@ -208,7 +232,7 @@ function g() {
208
232
  }),
209
233
  /* @__PURE__ */ c(u, { children: [/* @__PURE__ */ c(p, { children: [/* @__PURE__ */ s(m, { children: "Diversity & Inclusion Metrics" }), /* @__PURE__ */ s(f, { children: "Gender distribution across organization segments" })] }), /* @__PURE__ */ s(d, { children: /* @__PURE__ */ s("div", {
210
234
  className: "space-y-4",
211
- children: S.map((e) => /* @__PURE__ */ c("div", {
235
+ children: T.map((e) => /* @__PURE__ */ c("div", {
212
236
  className: "space-y-1",
213
237
  children: [/* @__PURE__ */ c("div", {
214
238
  className: "flex justify-between text-sm",
@@ -231,15 +255,15 @@ function g() {
231
255
  className: "flex h-3 rounded overflow-hidden",
232
256
  children: [
233
257
  /* @__PURE__ */ s("div", {
234
- className: "bg-blue-500",
258
+ className: "bg-status-info-text",
235
259
  style: { width: `${e.male}%` }
236
260
  }),
237
261
  /* @__PURE__ */ s("div", {
238
- className: "bg-purple-500",
262
+ className: "bg-action-primary-bg",
239
263
  style: { width: `${e.female}%` }
240
264
  }),
241
265
  /* @__PURE__ */ s("div", {
242
- className: "bg-green-500",
266
+ className: "bg-status-success-text",
243
267
  style: { width: `${e.other}%` }
244
268
  })
245
269
  ]
@@ -266,7 +290,7 @@ function g() {
266
290
  })
267
291
  ]
268
292
  }),
269
- _.map((e) => {
293
+ b.map((e) => {
270
294
  let t = e.employeeCount > 0 ? Math.round(e.budget / e.employeeCount) : 0;
271
295
  return /* @__PURE__ */ c("div", {
272
296
  className: "grid grid-cols-5 gap-2 py-2 border-b last:border-0 text-sm",
@@ -302,7 +326,7 @@ function g() {
302
326
  ]
303
327
  }, e.id);
304
328
  }),
305
- /* @__PURE__ */ s(h, { className: "my-2" }),
329
+ /* @__PURE__ */ s(v, { className: "my-2" }),
306
330
  /* @__PURE__ */ c("div", {
307
331
  className: "grid grid-cols-5 gap-2 text-sm font-bold",
308
332
  children: [
@@ -310,13 +334,13 @@ function g() {
310
334
  /* @__PURE__ */ s("span", {}),
311
335
  /* @__PURE__ */ s("span", {
312
336
  className: "text-right",
313
- children: _.reduce((e, t) => e + t.employeeCount, 0)
337
+ children: b.reduce((e, t) => e + t.employeeCount, 0)
314
338
  }),
315
339
  /* @__PURE__ */ c("span", {
316
340
  className: "text-right",
317
341
  children: [
318
342
  "$",
319
- (w / 1e6).toFixed(1),
343
+ (D / 1e6).toFixed(1),
320
344
  "M"
321
345
  ]
322
346
  }),
@@ -324,7 +348,7 @@ function g() {
324
348
  className: "text-right",
325
349
  children: [
326
350
  "$",
327
- (w / _.reduce((e, t) => e + t.employeeCount, 0) / 1e3).toFixed(0),
351
+ (D / b.reduce((e, t) => e + t.employeeCount, 0) / 1e3).toFixed(0),
328
352
  "K"
329
353
  ]
330
354
  })
@@ -335,6 +359,6 @@ function g() {
335
359
  });
336
360
  }
337
361
  //#endregion
338
- export { g as DashboardExecutiveDashboardPage };
362
+ export { y as DashboardExecutiveDashboardPage };
339
363
 
340
364
  //# sourceMappingURL=DashboardExecutiveDashboardPage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"DashboardExecutiveDashboardPage.js","names":[],"sources":["../../../src/crewfoundry/pages/DashboardExecutiveDashboardPage.tsx"],"sourcesContent":["import {\n Badge,\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n Separator,\n} from '@burdenoff/fe-libs/ui';\nimport { ArrowUp, Building2, DollarSign, Percent, Target } from 'lucide-react';\nimport { useMemo } from 'react';\nimport { useCrewFoundryStore } from '../store/crewfoundryStore';\n\nexport function DashboardExecutiveDashboardPage() {\n const { employees, departments, projects, jobPostings } = useCrewFoundryStore();\n\n const quarterlyRevenue = useMemo(() => {\n const quarters = ['Q1 2025', 'Q2 2025', 'Q3 2025', 'Q4 2025'];\n const base = projects.reduce((sum, project) => sum + project.budget, 0) || 1000000;\n return quarters.map((quarter, index) => {\n const revenue = Math.round(base * (0.55 + index * 0.08));\n const headcount = Math.max(1, employees.length - (3 - index) * 4);\n return {\n quarter,\n revenue,\n headcount,\n revenuePerHead: Math.round(revenue / headcount),\n };\n });\n }, [employees.length, projects]);\n\n const riskIndicators = useMemo(\n () => [\n {\n metric: 'Flight Risk Employees',\n value: employees.filter((employee) => employee.performanceScore < 3.6).length,\n severity: 'warning' as const,\n detail: `${Math.round((employees.filter((employee) => employee.performanceScore < 3.6).length / Math.max(employees.length, 1)) * 100)}% of workforce`,\n },\n {\n metric: 'Overdue Performance Reviews',\n value: employees.filter((employee) => employee.status === 'on_leave').length,\n severity: 'error' as const,\n detail: 'Review follow-ups required',\n },\n {\n metric: 'Unfilled Critical Roles',\n value: jobPostings.filter(\n (posting) => posting.status === 'active' && posting.experienceLevel === 'lead'\n ).length,\n severity: 'warning' as const,\n detail: 'Open lead-level positions',\n },\n {\n metric: 'Expiring Contracts',\n value: employees.filter((employee) => employee.type === 'contract').length,\n severity: 'info' as const,\n detail: 'Contract renewals in focus',\n },\n ],\n [employees, jobPostings]\n );\n\n const diversityMetrics = useMemo(() => {\n const byDepartment = departments.map((department) => {\n const count = employees.filter((employee) => employee.department === department.name).length;\n const male = Math.min(100, Math.round(45 + (count % 15)));\n const female = Math.min(100 - male, Math.round(40 + (count % 10)));\n const other = Math.max(0, 100 - male - female);\n return { category: department.name, male, female, other };\n });\n return [\n {\n category: 'Company',\n male: 52,\n female: 43,\n other: 5,\n },\n ...byDepartment.slice(0, 3),\n ];\n }, [departments, employees]);\n\n const totalSalaryBudget = employees.reduce((sum, e) => sum + e.salary, 0);\n const totalDeptBudget = departments.reduce((sum, d) => sum + d.budget, 0);\n const totalProjectBudget = projects.reduce((sum, p) => sum + p.budget, 0);\n const totalProjectSpent = projects.reduce((sum, p) => sum + p.spent, 0);\n const budgetUtilization = Math.round((totalProjectSpent / totalProjectBudget) * 100);\n\n return (\n <div className=\"space-y-6 p-6\">\n <div className=\"flex items-center justify-between\">\n <div>\n <h1 className=\"text-2xl font-semibold\">Executive Dashboard</h1>\n <p className=\"text-sm text-text-secondary\">\n Strategic workforce insights for leadership\n </p>\n </div>\n <Badge variant=\"outline\">Q1 2026</Badge>\n </div>\n\n <div className=\"grid gap-4 md:grid-cols-2 lg:grid-cols-4\">\n <Card>\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Revenue per Employee</CardTitle>\n <DollarSign className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold\">$21,862</div>\n <div className=\"flex items-center text-xs text-green-600\">\n <ArrowUp className=\"h-3 w-3 mr-1\" />\n +2.0% from Q3\n </div>\n </CardContent>\n </Card>\n <Card>\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Total Workforce Cost</CardTitle>\n <Building2 className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold\">${(totalSalaryBudget / 1000000).toFixed(1)}M</div>\n <p className=\"text-xs text-text-secondary\">Annual salary expenditure</p>\n </CardContent>\n </Card>\n <Card>\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Budget Utilization</CardTitle>\n <Percent className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold\">{budgetUtilization}%</div>\n <p className=\"text-xs text-text-secondary\">\n ${(totalProjectSpent / 1000000).toFixed(1)}M of $\n {(totalProjectBudget / 1000000).toFixed(1)}M\n </p>\n </CardContent>\n </Card>\n <Card>\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Retention Rate</CardTitle>\n <Target className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold\">95.8%</div>\n <div className=\"flex items-center text-xs text-green-600\">\n <ArrowUp className=\"h-3 w-3 mr-1\" />\n +1.1% improvement\n </div>\n </CardContent>\n </Card>\n </div>\n\n <div className=\"grid gap-4 md:grid-cols-2\">\n <Card>\n <CardHeader>\n <CardTitle>Revenue & Headcount Trend</CardTitle>\n <CardDescription>Quarterly performance metrics</CardDescription>\n </CardHeader>\n <CardContent>\n <div className=\"grid grid-cols-4 gap-2 text-xs font-medium text-text-secondary border-b pb-2 mb-2\">\n <span>Quarter</span>\n <span className=\"text-right\">Revenue</span>\n <span className=\"text-right\">Headcount</span>\n <span className=\"text-right\">Rev/Head</span>\n </div>\n {quarterlyRevenue.map((q) => (\n <div\n key={q.quarter}\n className=\"grid grid-cols-4 gap-2 py-2 border-b last:border-0 text-sm\"\n >\n <span className=\"font-medium\">{q.quarter}</span>\n <span className=\"text-right\">${(q.revenue / 1000000).toFixed(1)}M</span>\n <span className=\"text-right\">{q.headcount}</span>\n <span className=\"text-right font-medium\">${q.revenuePerHead.toLocaleString()}</span>\n </div>\n ))}\n </CardContent>\n </Card>\n\n <Card>\n <CardHeader>\n <CardTitle>Risk Indicators</CardTitle>\n <CardDescription>Items requiring executive attention</CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n {riskIndicators.map((risk) => (\n <div\n key={risk.metric}\n className=\"flex items-center justify-between rounded border p-3\"\n >\n <div className=\"flex items-center gap-3\">\n <div\n className={`h-3 w-3 rounded-full ${\n risk.severity === 'error'\n ? 'bg-red-500'\n : risk.severity === 'warning'\n ? 'bg-yellow-500'\n : 'bg-blue-500'\n }`}\n />\n <div>\n <p className=\"text-sm font-medium\">{risk.metric}</p>\n <p className=\"text-xs text-text-secondary\">{risk.detail}</p>\n </div>\n </div>\n <span className=\"text-lg font-bold\">{risk.value}</span>\n </div>\n ))}\n </CardContent>\n </Card>\n </div>\n\n <Card>\n <CardHeader>\n <CardTitle>Diversity & Inclusion Metrics</CardTitle>\n <CardDescription>Gender distribution across organization segments</CardDescription>\n </CardHeader>\n <CardContent>\n <div className=\"space-y-4\">\n {diversityMetrics.map((d) => (\n <div key={d.category} className=\"space-y-1\">\n <div className=\"flex justify-between text-sm\">\n <span className=\"font-medium\">{d.category}</span>\n <span className=\"text-xs text-text-secondary\">\n M: {d.male}% · F: {d.female}% · Other: {d.other}%\n </span>\n </div>\n <div className=\"flex h-3 rounded overflow-hidden\">\n <div className=\"bg-blue-500\" style={{ width: `${d.male}%` }} />\n <div className=\"bg-purple-500\" style={{ width: `${d.female}%` }} />\n <div className=\"bg-green-500\" style={{ width: `${d.other}%` }} />\n </div>\n </div>\n ))}\n </div>\n </CardContent>\n </Card>\n\n <Card>\n <CardHeader>\n <CardTitle>Department Budget Status</CardTitle>\n <CardDescription>Annual budget allocation and headcount</CardDescription>\n </CardHeader>\n <CardContent>\n <div className=\"grid grid-cols-5 gap-2 text-xs font-medium text-text-secondary border-b pb-2 mb-2\">\n <span>Department</span>\n <span>Head</span>\n <span className=\"text-right\">Headcount</span>\n <span className=\"text-right\">Budget</span>\n <span className=\"text-right\">Cost/Employee</span>\n </div>\n {departments.map((dept) => {\n const costPerEmp =\n dept.employeeCount > 0 ? Math.round(dept.budget / dept.employeeCount) : 0;\n return (\n <div\n key={dept.id}\n className=\"grid grid-cols-5 gap-2 py-2 border-b last:border-0 text-sm\"\n >\n <span className=\"font-medium\">{dept.name}</span>\n <span className=\"text-text-secondary\">{dept.headName}</span>\n <span className=\"text-right\">{dept.employeeCount}</span>\n <span className=\"text-right\">${(dept.budget / 1000000).toFixed(1)}M</span>\n <span className=\"text-right\">${(costPerEmp / 1000).toFixed(0)}K</span>\n </div>\n );\n })}\n <Separator className=\"my-2\" />\n <div className=\"grid grid-cols-5 gap-2 text-sm font-bold\">\n <span>Total</span>\n <span />\n <span className=\"text-right\">\n {departments.reduce((s, d) => s + d.employeeCount, 0)}\n </span>\n <span className=\"text-right\">${(totalDeptBudget / 1000000).toFixed(1)}M</span>\n <span className=\"text-right\">\n $\n {(\n totalDeptBudget /\n departments.reduce((s, d) => s + d.employeeCount, 0) /\n 1000\n ).toFixed(0)}\n K\n </span>\n </div>\n </CardContent>\n </Card>\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"DashboardExecutiveDashboardPage.js","names":[],"sources":["../../../src/crewfoundry/pages/DashboardExecutiveDashboardPage.tsx"],"sourcesContent":["import {\n Badge,\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n GlassCard,\n GradientText,\n PagePurpose,\n Separator,\n} from '@burdenoff/fe-libs/ui';\nimport { ArrowUp, Building2, DollarSign, Percent, Target } from 'lucide-react';\nimport { useMemo } from 'react';\nimport { useCrewFoundryStore } from '../store/crewfoundryStore';\n\nexport function DashboardExecutiveDashboardPage() {\n const { employees, departments, projects, jobPostings } = useCrewFoundryStore();\n\n const quarterlyRevenue = useMemo(() => {\n const quarters = ['Q1 2025', 'Q2 2025', 'Q3 2025', 'Q4 2025'];\n const base = projects.reduce((sum, project) => sum + project.budget, 0) || 1000000;\n return quarters.map((quarter, index) => {\n const revenue = Math.round(base * (0.55 + index * 0.08));\n const headcount = Math.max(1, employees.length - (3 - index) * 4);\n return {\n quarter,\n revenue,\n headcount,\n revenuePerHead: Math.round(revenue / headcount),\n };\n });\n }, [employees.length, projects]);\n\n const riskIndicators = useMemo(\n () => [\n {\n metric: 'Flight Risk Employees',\n value: employees.filter((employee) => employee.performanceScore < 3.6).length,\n severity: 'warning' as const,\n detail: `${Math.round((employees.filter((employee) => employee.performanceScore < 3.6).length / Math.max(employees.length, 1)) * 100)}% of workforce`,\n },\n {\n metric: 'Overdue Performance Reviews',\n value: employees.filter((employee) => employee.status === 'on_leave').length,\n severity: 'error' as const,\n detail: 'Review follow-ups required',\n },\n {\n metric: 'Unfilled Critical Roles',\n value: jobPostings.filter(\n (posting) => posting.status === 'active' && posting.experienceLevel === 'lead'\n ).length,\n severity: 'warning' as const,\n detail: 'Open lead-level positions',\n },\n {\n metric: 'Expiring Contracts',\n value: employees.filter((employee) => employee.type === 'contract').length,\n severity: 'info' as const,\n detail: 'Contract renewals in focus',\n },\n ],\n [employees, jobPostings]\n );\n\n const diversityMetrics = useMemo(() => {\n const byDepartment = departments.map((department) => {\n const count = employees.filter((employee) => employee.department === department.name).length;\n const male = Math.min(100, Math.round(45 + (count % 15)));\n const female = Math.min(100 - male, Math.round(40 + (count % 10)));\n const other = Math.max(0, 100 - male - female);\n return { category: department.name, male, female, other };\n });\n return [\n {\n category: 'Company',\n male: 52,\n female: 43,\n other: 5,\n },\n ...byDepartment.slice(0, 3),\n ];\n }, [departments, employees]);\n\n const totalSalaryBudget = employees.reduce((sum, e) => sum + e.salary, 0);\n const totalDeptBudget = departments.reduce((sum, d) => sum + d.budget, 0);\n const totalProjectBudget = projects.reduce((sum, p) => sum + p.budget, 0);\n const totalProjectSpent = projects.reduce((sum, p) => sum + p.spent, 0);\n const budgetUtilization = Math.round((totalProjectSpent / totalProjectBudget) * 100);\n\n return (\n <div className=\"space-y-6 p-6\">\n <div className=\"flex items-center justify-between\">\n <div>\n <h1 className=\"text-2xl font-semibold\">\n <GradientText>Executive Dashboard</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">Strategic workforce insights for leadership</p>\n <PagePurpose className=\"mt-1\">The executive snapshot — top-line workforce, financial, and hiring KPIs in one view so leaders can make decisions fast.</PagePurpose>\n </div>\n <Badge variant=\"outline\">Q1 2026</Badge>\n </div>\n\n <div className=\"grid gap-4 md:grid-cols-2 lg:grid-cols-4\">\n <GlassCard treatment=\"glass\" glow className=\"border-border-seam\">\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Revenue per Employee</CardTitle>\n <DollarSign className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">$21,862</div>\n <div className=\"flex items-center text-xs text-status-success-text\">\n <ArrowUp className=\"h-3 w-3 mr-1\" />\n +2.0% from Q3\n </div>\n </CardContent>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"border-border-seam\">\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Total Workforce Cost</CardTitle>\n <Building2 className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">\n ${(totalSalaryBudget / 1000000).toFixed(1)}M\n </div>\n <p className=\"text-xs text-text-secondary\">Annual salary expenditure</p>\n </CardContent>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"border-border-seam\">\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Budget Utilization</CardTitle>\n <Percent className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">{budgetUtilization}%</div>\n <p className=\"text-xs text-text-secondary\">\n ${(totalProjectSpent / 1000000).toFixed(1)}M of $\n {(totalProjectBudget / 1000000).toFixed(1)}M\n </p>\n </CardContent>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"border-border-seam\">\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Retention Rate</CardTitle>\n <Target className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">95.8%</div>\n <div className=\"flex items-center text-xs text-status-success-text\">\n <ArrowUp className=\"h-3 w-3 mr-1\" />\n +1.1% improvement\n </div>\n </CardContent>\n </GlassCard>\n </div>\n\n <div className=\"grid gap-4 md:grid-cols-2\">\n <Card>\n <CardHeader>\n <CardTitle>Revenue & Headcount Trend</CardTitle>\n <CardDescription>Quarterly performance metrics</CardDescription>\n </CardHeader>\n <CardContent>\n <div className=\"grid grid-cols-4 gap-2 text-xs font-medium text-text-secondary border-b pb-2 mb-2\">\n <span>Quarter</span>\n <span className=\"text-right\">Revenue</span>\n <span className=\"text-right\">Headcount</span>\n <span className=\"text-right\">Rev/Head</span>\n </div>\n {quarterlyRevenue.map((q) => (\n <div\n key={q.quarter}\n className=\"grid grid-cols-4 gap-2 py-2 border-b last:border-0 text-sm\"\n >\n <span className=\"font-medium\">{q.quarter}</span>\n <span className=\"text-right\">${(q.revenue / 1000000).toFixed(1)}M</span>\n <span className=\"text-right\">{q.headcount}</span>\n <span className=\"text-right font-medium\">${q.revenuePerHead.toLocaleString()}</span>\n </div>\n ))}\n </CardContent>\n </Card>\n\n <Card>\n <CardHeader>\n <CardTitle>Risk Indicators</CardTitle>\n <CardDescription>Items requiring executive attention</CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n {riskIndicators.map((risk) => (\n <div\n key={risk.metric}\n className=\"flex items-center justify-between rounded border p-3\"\n >\n <div className=\"flex items-center gap-3\">\n <div\n className={`h-3 w-3 rounded-full ${\n risk.severity === 'error'\n ? 'bg-status-error-text'\n : risk.severity === 'warning'\n ? 'bg-status-warning-text'\n : 'bg-status-info-text'\n }`}\n />\n <div>\n <p className=\"text-sm font-medium\">{risk.metric}</p>\n <p className=\"text-xs text-text-secondary\">{risk.detail}</p>\n </div>\n </div>\n <span className=\"text-lg font-bold\">{risk.value}</span>\n </div>\n ))}\n </CardContent>\n </Card>\n </div>\n\n <Card>\n <CardHeader>\n <CardTitle>Diversity & Inclusion Metrics</CardTitle>\n <CardDescription>Gender distribution across organization segments</CardDescription>\n </CardHeader>\n <CardContent>\n <div className=\"space-y-4\">\n {diversityMetrics.map((d) => (\n <div key={d.category} className=\"space-y-1\">\n <div className=\"flex justify-between text-sm\">\n <span className=\"font-medium\">{d.category}</span>\n <span className=\"text-xs text-text-secondary\">\n M: {d.male}% · F: {d.female}% · Other: {d.other}%\n </span>\n </div>\n <div className=\"flex h-3 rounded overflow-hidden\">\n <div className=\"bg-status-info-text\" style={{ width: `${d.male}%` }} />\n <div className=\"bg-action-primary-bg\" style={{ width: `${d.female}%` }} />\n <div className=\"bg-status-success-text\" style={{ width: `${d.other}%` }} />\n </div>\n </div>\n ))}\n </div>\n </CardContent>\n </Card>\n\n <Card>\n <CardHeader>\n <CardTitle>Department Budget Status</CardTitle>\n <CardDescription>Annual budget allocation and headcount</CardDescription>\n </CardHeader>\n <CardContent>\n <div className=\"grid grid-cols-5 gap-2 text-xs font-medium text-text-secondary border-b pb-2 mb-2\">\n <span>Department</span>\n <span>Head</span>\n <span className=\"text-right\">Headcount</span>\n <span className=\"text-right\">Budget</span>\n <span className=\"text-right\">Cost/Employee</span>\n </div>\n {departments.map((dept) => {\n const costPerEmp =\n dept.employeeCount > 0 ? Math.round(dept.budget / dept.employeeCount) : 0;\n return (\n <div\n key={dept.id}\n className=\"grid grid-cols-5 gap-2 py-2 border-b last:border-0 text-sm\"\n >\n <span className=\"font-medium\">{dept.name}</span>\n <span className=\"text-text-secondary\">{dept.headName}</span>\n <span className=\"text-right\">{dept.employeeCount}</span>\n <span className=\"text-right\">${(dept.budget / 1000000).toFixed(1)}M</span>\n <span className=\"text-right\">${(costPerEmp / 1000).toFixed(0)}K</span>\n </div>\n );\n })}\n <Separator className=\"my-2\" />\n <div className=\"grid grid-cols-5 gap-2 text-sm font-bold\">\n <span>Total</span>\n <span />\n <span className=\"text-right\">\n {departments.reduce((s, d) => s + d.employeeCount, 0)}\n </span>\n <span className=\"text-right\">${(totalDeptBudget / 1000000).toFixed(1)}M</span>\n <span className=\"text-right\">\n $\n {(\n totalDeptBudget /\n departments.reduce((s, d) => s + d.employeeCount, 0) /\n 1000\n ).toFixed(0)}\n K\n </span>\n </div>\n </CardContent>\n </Card>\n </div>\n );\n}\n"],"mappings":"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"}