@burdenoff/microfe-crewfoundry 2026.703.2 → 2026.704.1

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 (127) hide show
  1. package/dist/crewfoundry/pages/AdminAdminPagePage.js +117 -164
  2. package/dist/crewfoundry/pages/AdminAdminPagePage.js.map +1 -1
  3. package/dist/crewfoundry/pages/AnalyticsAnalyticsPagePage.js +99 -82
  4. package/dist/crewfoundry/pages/AnalyticsAnalyticsPagePage.js.map +1 -1
  5. package/dist/crewfoundry/pages/AnalyticsEmployeeAnalyticsPagePage.js +160 -192
  6. package/dist/crewfoundry/pages/AnalyticsEmployeeAnalyticsPagePage.js.map +1 -1
  7. package/dist/crewfoundry/pages/AnalyticsFinancialAnalyticsPagePage.js +238 -231
  8. package/dist/crewfoundry/pages/AnalyticsFinancialAnalyticsPagePage.js.map +1 -1
  9. package/dist/crewfoundry/pages/AnalyticsHiringAnalyticsPagePage.js +196 -166
  10. package/dist/crewfoundry/pages/AnalyticsHiringAnalyticsPagePage.js.map +1 -1
  11. package/dist/crewfoundry/pages/CommunicationsCallsPagePage.js +45 -147
  12. package/dist/crewfoundry/pages/CommunicationsCallsPagePage.js.map +1 -1
  13. package/dist/crewfoundry/pages/CommunicationsDirectoryPagePage.js +20 -11
  14. package/dist/crewfoundry/pages/CommunicationsDirectoryPagePage.js.map +1 -1
  15. package/dist/crewfoundry/pages/CommunicationsFilesPagePage.js +45 -152
  16. package/dist/crewfoundry/pages/CommunicationsFilesPagePage.js.map +1 -1
  17. package/dist/crewfoundry/pages/CommunicationsMessagesPagePage.js +50 -138
  18. package/dist/crewfoundry/pages/CommunicationsMessagesPagePage.js.map +1 -1
  19. package/dist/crewfoundry/pages/CommunicationsTeamsPagePage.js +149 -67
  20. package/dist/crewfoundry/pages/CommunicationsTeamsPagePage.js.map +1 -1
  21. package/dist/crewfoundry/pages/CommunicationsVideoCallsPagePage.js +50 -201
  22. package/dist/crewfoundry/pages/CommunicationsVideoCallsPagePage.js.map +1 -1
  23. package/dist/crewfoundry/pages/CompanyClientManagementPagePage.js +205 -136
  24. package/dist/crewfoundry/pages/CompanyClientManagementPagePage.js.map +1 -1
  25. package/dist/crewfoundry/pages/CompanyCompanyDashboardPagePage.js +25 -31
  26. package/dist/crewfoundry/pages/CompanyCompanyDashboardPagePage.js.map +1 -1
  27. package/dist/crewfoundry/pages/CompanyCompanyProfilePagePage.js +118 -104
  28. package/dist/crewfoundry/pages/CompanyCompanyProfilePagePage.js.map +1 -1
  29. package/dist/crewfoundry/pages/CompanyVendorManagementPagePage.js +117 -58
  30. package/dist/crewfoundry/pages/CompanyVendorManagementPagePage.js.map +1 -1
  31. package/dist/crewfoundry/pages/DashboardAnalyticsPagePage.js +90 -94
  32. package/dist/crewfoundry/pages/DashboardAnalyticsPagePage.js.map +1 -1
  33. package/dist/crewfoundry/pages/DashboardDashboardPagePage.js +210 -191
  34. package/dist/crewfoundry/pages/DashboardDashboardPagePage.js.map +1 -1
  35. package/dist/crewfoundry/pages/DashboardEnhancedDashboardPagePage.js +213 -180
  36. package/dist/crewfoundry/pages/DashboardEnhancedDashboardPagePage.js.map +1 -1
  37. package/dist/crewfoundry/pages/DashboardExecutiveDashboardPage.js +133 -264
  38. package/dist/crewfoundry/pages/DashboardExecutiveDashboardPage.js.map +1 -1
  39. package/dist/crewfoundry/pages/HelpApiDocumentationPagePage.js +279 -212
  40. package/dist/crewfoundry/pages/HelpApiDocumentationPagePage.js.map +1 -1
  41. package/dist/crewfoundry/pages/HiringApplicationsPagePage.js +131 -105
  42. package/dist/crewfoundry/pages/HiringApplicationsPagePage.js.map +1 -1
  43. package/dist/crewfoundry/pages/HiringCandidatesPagePage.js +167 -148
  44. package/dist/crewfoundry/pages/HiringCandidatesPagePage.js.map +1 -1
  45. package/dist/crewfoundry/pages/HiringCreateJobPagePage.js +3 -3
  46. package/dist/crewfoundry/pages/HiringCreateJobPagePage.js.map +1 -1
  47. package/dist/crewfoundry/pages/HiringInterviewsPagePage.js +13 -5
  48. package/dist/crewfoundry/pages/HiringInterviewsPagePage.js.map +1 -1
  49. package/dist/crewfoundry/pages/HiringJobDetailsPagePage.js +151 -152
  50. package/dist/crewfoundry/pages/HiringJobDetailsPagePage.js.map +1 -1
  51. package/dist/crewfoundry/pages/HiringJobsPagePage.js +38 -21
  52. package/dist/crewfoundry/pages/HiringJobsPagePage.js.map +1 -1
  53. package/dist/crewfoundry/pages/HrDepartmentsPagePage.js +3 -3
  54. package/dist/crewfoundry/pages/HrDepartmentsPagePage.js.map +1 -1
  55. package/dist/crewfoundry/pages/HrEmployeesPagePage.js +134 -127
  56. package/dist/crewfoundry/pages/HrEmployeesPagePage.js.map +1 -1
  57. package/dist/crewfoundry/pages/HrLeaveManagementPagePage.js +163 -132
  58. package/dist/crewfoundry/pages/HrLeaveManagementPagePage.js.map +1 -1
  59. package/dist/crewfoundry/pages/HrPayrollPagePage.js +202 -160
  60. package/dist/crewfoundry/pages/HrPayrollPagePage.js.map +1 -1
  61. package/dist/crewfoundry/pages/HrTimeTrackingPagePage.js +104 -91
  62. package/dist/crewfoundry/pages/HrTimeTrackingPagePage.js.map +1 -1
  63. package/dist/crewfoundry/pages/LearningAssessmentsPagePage.js +29 -147
  64. package/dist/crewfoundry/pages/LearningAssessmentsPagePage.js.map +1 -1
  65. package/dist/crewfoundry/pages/LearningCertificatesPagePage.js +22 -106
  66. package/dist/crewfoundry/pages/LearningCertificatesPagePage.js.map +1 -1
  67. package/dist/crewfoundry/pages/LearningCourseDetailsPagePage.js +74 -74
  68. package/dist/crewfoundry/pages/LearningCourseDetailsPagePage.js.map +1 -1
  69. package/dist/crewfoundry/pages/LearningCourseLearningPagePage.js +101 -97
  70. package/dist/crewfoundry/pages/LearningCourseLearningPagePage.js.map +1 -1
  71. package/dist/crewfoundry/pages/LearningCoursesPagePage.js +64 -47
  72. package/dist/crewfoundry/pages/LearningCoursesPagePage.js.map +1 -1
  73. package/dist/crewfoundry/pages/LearningLearningAnalyticsPagePage.js +111 -121
  74. package/dist/crewfoundry/pages/LearningLearningAnalyticsPagePage.js.map +1 -1
  75. package/dist/crewfoundry/pages/LearningLearningPagePage.js +131 -110
  76. package/dist/crewfoundry/pages/LearningLearningPagePage.js.map +1 -1
  77. package/dist/crewfoundry/pages/LearningLearningPathDetailPagePage.js +65 -64
  78. package/dist/crewfoundry/pages/LearningLearningPathDetailPagePage.js.map +1 -1
  79. package/dist/crewfoundry/pages/LearningLearningPathsPagePage.js +58 -43
  80. package/dist/crewfoundry/pages/LearningLearningPathsPagePage.js.map +1 -1
  81. package/dist/crewfoundry/pages/LearningMyLearningPagePage.js +66 -82
  82. package/dist/crewfoundry/pages/LearningMyLearningPagePage.js.map +1 -1
  83. package/dist/crewfoundry/pages/MarketplaceBookingManagementPagePage.js +38 -88
  84. package/dist/crewfoundry/pages/MarketplaceBookingManagementPagePage.js.map +1 -1
  85. package/dist/crewfoundry/pages/MarketplaceEarningsPagePage.js +59 -65
  86. package/dist/crewfoundry/pages/MarketplaceEarningsPagePage.js.map +1 -1
  87. package/dist/crewfoundry/pages/MarketplaceFreelancerProfilePageEnhancedPage.js +209 -323
  88. package/dist/crewfoundry/pages/MarketplaceFreelancerProfilePageEnhancedPage.js.map +1 -1
  89. package/dist/crewfoundry/pages/MarketplaceFreelancerProfilePagePage.js +175 -220
  90. package/dist/crewfoundry/pages/MarketplaceFreelancerProfilePagePage.js.map +1 -1
  91. package/dist/crewfoundry/pages/MarketplaceMarketplacePagePage.js +74 -59
  92. package/dist/crewfoundry/pages/MarketplaceMarketplacePagePage.js.map +1 -1
  93. package/dist/crewfoundry/pages/MarketplaceMarketplaceServicesPagePage.js +96 -80
  94. package/dist/crewfoundry/pages/MarketplaceMarketplaceServicesPagePage.js.map +1 -1
  95. package/dist/crewfoundry/pages/MarketplaceMessagingPagePage.js +28 -100
  96. package/dist/crewfoundry/pages/MarketplaceMessagingPagePage.js.map +1 -1
  97. package/dist/crewfoundry/pages/MarketplaceMyServicesPagePage.js +27 -20
  98. package/dist/crewfoundry/pages/MarketplaceMyServicesPagePage.js.map +1 -1
  99. package/dist/crewfoundry/pages/MarketplaceProjectDetailsPagePage.js +73 -73
  100. package/dist/crewfoundry/pages/MarketplaceProjectDetailsPagePage.js.map +1 -1
  101. package/dist/crewfoundry/pages/MarketplaceServiceDetailsPagePage.js +62 -56
  102. package/dist/crewfoundry/pages/MarketplaceServiceDetailsPagePage.js.map +1 -1
  103. package/dist/crewfoundry/pages/PaymentsEscrowPagePage.js +40 -138
  104. package/dist/crewfoundry/pages/PaymentsEscrowPagePage.js.map +1 -1
  105. package/dist/crewfoundry/pages/PaymentsInvoicesPagePage.js +126 -93
  106. package/dist/crewfoundry/pages/PaymentsInvoicesPagePage.js.map +1 -1
  107. package/dist/crewfoundry/pages/PaymentsPaymentDashboardPagePage.js +99 -77
  108. package/dist/crewfoundry/pages/PaymentsPaymentDashboardPagePage.js.map +1 -1
  109. package/dist/crewfoundry/pages/PaymentsSecurityPagePage.js +73 -74
  110. package/dist/crewfoundry/pages/PaymentsSecurityPagePage.js.map +1 -1
  111. package/dist/crewfoundry/pages/ProjectsCreateProjectPagePage.js +1 -1
  112. package/dist/crewfoundry/pages/ProjectsCreateProjectPagePage.js.map +1 -1
  113. package/dist/crewfoundry/pages/ProjectsProjectDetailsPagePage.js +122 -122
  114. package/dist/crewfoundry/pages/ProjectsProjectDetailsPagePage.js.map +1 -1
  115. package/dist/crewfoundry/pages/ProjectsProjectsPagePage.js +130 -113
  116. package/dist/crewfoundry/pages/ProjectsProjectsPagePage.js.map +1 -1
  117. package/dist/crewfoundry/pages/TeamsTeamAnalyticsPagePage.js +68 -59
  118. package/dist/crewfoundry/pages/TeamsTeamAnalyticsPagePage.js.map +1 -1
  119. package/dist/crewfoundry/pages/TeamsTeamDetailPagePage.js +73 -62
  120. package/dist/crewfoundry/pages/TeamsTeamDetailPagePage.js.map +1 -1
  121. package/dist/crewfoundry/pages/TeamsTeamDirectoryPagePage.js +82 -58
  122. package/dist/crewfoundry/pages/TeamsTeamDirectoryPagePage.js.map +1 -1
  123. package/dist/crewfoundry/pages/TeamsTeamSettingsPagePage.js +153 -153
  124. package/dist/crewfoundry/pages/TeamsTeamSettingsPagePage.js.map +1 -1
  125. package/dist/crewfoundry/pages/TeamsTeamsPagePage.js +63 -48
  126. package/dist/crewfoundry/pages/TeamsTeamsPagePage.js.map +1 -1
  127. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"HelpApiDocumentationPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/HelpApiDocumentationPagePage.tsx"],"sourcesContent":["import { useMemo, useState } from 'react';\nimport {\n Badge,\n Button,\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n EmphasisPanel,\n GradientText,\n IllustratedEmptyState,\n Input,\n PagePurpose,\n} from '@burdenoff/fe-libs/ui';\nimport {\n BookOpen,\n ChevronRight,\n Code2,\n Copy,\n ExternalLink,\n Lock,\n Search,\n Server,\n Zap,\n} from 'lucide-react';\nimport { useCrewFoundryStore } from '../store/crewfoundryStore';\n\nconst methodColors: Record<string, string> = {\n GET: 'bg-status-success-bg text-status-success-text',\n POST: 'bg-status-info-bg text-status-info-text',\n PATCH: 'bg-status-warning-bg text-status-warning-text',\n DELETE: 'bg-status-error-bg text-status-error-text',\n};\n\nexport function HelpApiDocumentationPagePage() {\n const { employees, jobPostings, candidates, payrollRecords, leaveRequests } =\n useCrewFoundryStore();\n const [search, setSearch] = useState('');\n const [copiedPath, setCopiedPath] = useState<string | null>(null);\n\n const apiSections = useMemo(\n () => [\n {\n name: 'Employees',\n version: 'v2',\n endpoints: [\n {\n method: 'GET',\n path: '/api/v2/employees',\n description: `List all employees (${employees.length} records) with pagination and filters`,\n },\n {\n method: 'POST',\n path: '/api/v2/employees',\n description: 'Create a new employee record',\n },\n {\n method: 'GET',\n path: '/api/v2/employees/:id',\n description: 'Get employee details by ID',\n },\n {\n method: 'PATCH',\n path: '/api/v2/employees/:id',\n description: 'Update employee information',\n },\n {\n method: 'DELETE',\n path: '/api/v2/employees/:id',\n description: 'Deactivate an employee record',\n },\n ],\n },\n {\n name: 'Hiring',\n version: 'v2',\n endpoints: [\n {\n method: 'GET',\n path: '/api/v2/jobs',\n description: `List all job postings (${jobPostings.length} total)`,\n },\n { method: 'POST', path: '/api/v2/jobs', description: 'Create a new job posting' },\n {\n method: 'GET',\n path: '/api/v2/candidates',\n description: `List candidates (${candidates.length}) with pipeline filters`,\n },\n {\n method: 'POST',\n path: '/api/v2/candidates',\n description: 'Add a new candidate to the pipeline',\n },\n ],\n },\n {\n name: 'Payroll',\n version: 'v1',\n endpoints: [\n {\n method: 'GET',\n path: '/api/v1/payroll/records',\n description: `List payroll records by period (${payrollRecords.length} loaded)`,\n },\n {\n method: 'POST',\n path: '/api/v1/payroll/run',\n description: 'Trigger payroll processing',\n },\n {\n method: 'GET',\n path: '/api/v1/payroll/reports',\n description: 'Generate payroll reports',\n },\n ],\n },\n {\n name: 'Leave',\n version: 'v2',\n endpoints: [\n {\n method: 'GET',\n path: '/api/v2/leave/requests',\n description: `List leave requests with status filters (${leaveRequests.length} total)`,\n },\n {\n method: 'POST',\n path: '/api/v2/leave/requests',\n description: 'Submit a new leave request',\n },\n {\n method: 'PATCH',\n path: '/api/v2/leave/requests/:id/approve',\n description: 'Approve a leave request',\n },\n ],\n },\n ],\n [\n candidates.length,\n employees.length,\n jobPostings.length,\n leaveRequests.length,\n payrollRecords.length,\n ]\n );\n\n const handleCopy = (path: string) => {\n setCopiedPath(path);\n setTimeout(() => setCopiedPath(null), 1500);\n };\n\n const filteredSections = apiSections\n .map((section) => ({\n ...section,\n endpoints: section.endpoints.filter(\n (ep) =>\n ep.path.toLowerCase().includes(search.toLowerCase()) ||\n ep.description.toLowerCase().includes(search.toLowerCase())\n ),\n }))\n .filter((s) => s.endpoints.length > 0);\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>API Documentation</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">\n CrewFoundry REST API reference for integrations\n </p>\n <PagePurpose className=\"mt-1\">Browse the CrewFoundry API reference — use it to find endpoints, understand request formats, and integrate CrewFoundry with your own tools.</PagePurpose>\n </div>\n <div className=\"flex gap-2\">\n <Badge variant=\"secondary\">Base URL: api.crewfoundry.com</Badge>\n <Button size=\"sm\" variant=\"outline\">\n <ExternalLink className=\"h-3 w-3 mr-1\" />\n OpenAPI Spec\n </Button>\n </div>\n </div>\n\n <div className=\"grid gap-4 md:grid-cols-4\">\n {[\n { icon: Server, label: 'REST API', value: 'v2.1.0', color: 'text-status-info-text' },\n {\n icon: Code2,\n label: 'GraphQL',\n value: 'Federation v2',\n color: 'text-action-primary-bg',\n },\n {\n icon: Lock,\n label: 'Auth',\n value: 'OAuth 2.0 + JWT',\n color: 'text-status-success-text',\n },\n {\n icon: Zap,\n label: 'Rate Limit',\n value: '1,000 req/min',\n color: 'text-status-warning-text',\n },\n ].map((item) => (\n <Card key={item.label}>\n <CardContent className=\"flex items-center gap-3 pt-6\">\n <item.icon className={`h-5 w-5 ${item.color}`} />\n <div>\n <p className=\"text-xs text-text-secondary\">{item.label}</p>\n <p className=\"text-sm font-medium\">{item.value}</p>\n </div>\n </CardContent>\n </Card>\n ))}\n </div>\n\n <div className=\"grid gap-6 lg:grid-cols-4\">\n <div className=\"space-y-4\">\n <EmphasisPanel>\n <div className=\"mb-2 text-sm font-semibold\">Quick Start</div>\n <div className=\"space-y-2\">\n {[\n { icon: BookOpen, label: 'Authentication Guide' },\n { icon: Code2, label: 'SDK Reference' },\n { icon: Zap, label: 'Webhooks' },\n { icon: Server, label: 'Rate Limiting' },\n ].map((link) => (\n <button\n key={link.label}\n className=\"flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-sm hover:bg-bg-sunken transition-colors\"\n >\n <link.icon className=\"h-3 w-3 text-text-secondary\" />\n <span>{link.label}</span>\n <ChevronRight className=\"h-3 w-3 ml-auto text-text-secondary\" />\n </button>\n ))}\n </div>\n </EmphasisPanel>\n\n <Card>\n <CardHeader>\n <CardTitle className=\"text-sm\">Authentication</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-2\">\n <div className=\"rounded-md bg-bg-sunken p-3\">\n <code className=\"text-xs font-mono\">Authorization: Bearer {'<token>'}</code>\n </div>\n <p className=\"text-xs text-text-secondary\">\n All API requests require a valid JWT token obtained through the OAuth 2.0 flow.\n </p>\n </CardContent>\n </Card>\n </div>\n\n <div className=\"lg:col-span-3 space-y-4\">\n <div className=\"relative max-w-md\">\n <Search className=\"absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-text-secondary\" />\n <Input\n placeholder=\"Search endpoints...\"\n className=\"pl-9\"\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n />\n </div>\n\n {filteredSections.map((section) => (\n <Card key={section.name}>\n <CardHeader>\n <div className=\"flex items-center gap-2\">\n <CardTitle className=\"text-base\">{section.name}</CardTitle>\n <Badge variant=\"outline\" className=\"text-[10px]\">\n {section.version}\n </Badge>\n </div>\n <CardDescription>{section.endpoints.length} endpoints</CardDescription>\n </CardHeader>\n <CardContent className=\"p-0\">\n {section.endpoints.map((ep, i) => (\n <div\n key={ep.path + ep.method}\n className={`flex items-center gap-3 px-6 py-3 hover:bg-bg-sunken/50 cursor-pointer ${i < section.endpoints.length - 1 ? 'border-b' : ''}`}\n >\n <Badge\n className={`${methodColors[ep.method]} text-[10px] font-mono border-0 min-w-[50px] justify-center`}\n >\n {ep.method}\n </Badge>\n <code className=\"text-sm font-mono flex-1\">{ep.path}</code>\n <span className=\"text-xs text-text-secondary hidden lg:block max-w-[250px] truncate\">\n {ep.description}\n </span>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-6 w-6 p-0\"\n onClick={() => handleCopy(ep.path)}\n >\n <Copy\n className={`h-3 w-3 ${copiedPath === ep.path ? 'text-status-success-text' : 'text-text-secondary'}`}\n />\n </Button>\n </div>\n ))}\n </CardContent>\n </Card>\n ))}\n\n {filteredSections.length === 0 && (\n <div className=\"py-6\">\n <IllustratedEmptyState\n illustration=\"empty-search\"\n title=\"No endpoints match\"\n description=\"Try a different search term to find the API you need.\"\n />\n </div>\n )}\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"HelpApiDocumentationPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/HelpApiDocumentationPagePage.tsx"],"sourcesContent":["import { useMemo, useState } from 'react';\nimport {\n Badge,\n Button,\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n EmphasisPanel,\n GradientText,\n IllustratedEmptyState,\n Input,\n PagePurpose,\n} from '@burdenoff/fe-libs/ui';\nimport { useGlobalUi } from '@burdenoff/fe-libs/shared/providers/shell';\nimport {\n Check,\n ChevronRight,\n Code2,\n Copy,\n Database,\n ListTree,\n Lock,\n Network,\n Search,\n} from 'lucide-react';\nimport { useCrewFoundryStore } from '../store/crewfoundryStore';\n\n// The CrewFoundry API is served by wspace-crewfoundry-svc as an Apollo\n// Federation v2 subgraph, reached through the workspaces public GraphQL\n// gateway. There is no separate REST surface — this reference is derived\n// directly from the published subgraph schema.\nconst ENDPOINT = 'https://graphqlworkspaces.burdenoff.com/workspaces/graphql';\n\n// The 17 domain entities exposed by the subgraph, each with create / update /\n// remove mutations. Names and input types mirror the published schema exactly.\nconst ENTITIES: { name: string; domain: string }[] = [\n { name: 'Announcement', domain: 'Communications' },\n { name: 'Candidate', domain: 'Hiring' },\n { name: 'Client', domain: 'Finance' },\n { name: 'Course', domain: 'Learning' },\n { name: 'Department', domain: 'HR' },\n { name: 'Employee', domain: 'HR' },\n { name: 'Interview', domain: 'Hiring' },\n { name: 'Invoice', domain: 'Finance' },\n { name: 'JobPosting', domain: 'Hiring' },\n { name: 'LearningPath', domain: 'Learning' },\n { name: 'LeaveRequest', domain: 'HR' },\n { name: 'MarketplaceService', domain: 'Marketplace' },\n { name: 'PayrollRecord', domain: 'Finance' },\n { name: 'Project', domain: 'Projects' },\n { name: 'Team', domain: 'Teams' },\n { name: 'TimeEntry', domain: 'HR' },\n { name: 'Vendor', domain: 'Finance' },\n];\n\ntype OperationKind = 'Query' | 'Mutation';\n\ntype ApiOperation = {\n kind: OperationKind;\n name: string;\n signature: string;\n description: string;\n};\n\ntype ApiGroup = {\n id: string;\n name: string;\n description: string;\n operations: ApiOperation[];\n};\n\nconst kindColors: Record<OperationKind, string> = {\n Query: 'bg-status-success-bg text-status-success-text',\n Mutation: 'bg-status-info-bg text-status-info-text',\n};\n\nconst humanize = (value: string): string =>\n value.replace(/([a-z])([A-Z])/g, '$1 $2').toLowerCase();\n\nconst copyToClipboard = async (text: string): Promise<boolean> => {\n try {\n if (typeof navigator !== 'undefined' && navigator.clipboard?.writeText) {\n await navigator.clipboard.writeText(text);\n return true;\n }\n } catch {\n // Fall through to the legacy path for insecure / restricted contexts.\n }\n try {\n if (typeof document === 'undefined') {\n return false;\n }\n const textarea = document.createElement('textarea');\n textarea.value = text;\n textarea.style.position = 'fixed';\n textarea.style.opacity = '0';\n document.body.appendChild(textarea);\n textarea.focus();\n textarea.select();\n const succeeded = document.execCommand('copy');\n document.body.removeChild(textarea);\n return succeeded;\n } catch {\n return false;\n }\n};\n\nexport function HelpApiDocumentationPagePage() {\n const { employees, jobPostings, candidates, payrollRecords, leaveRequests } =\n useCrewFoundryStore();\n const { showToast } = useGlobalUi();\n const [search, setSearch] = useState('');\n const [copied, setCopied] = useState<string | null>(null);\n\n const groups = useMemo<ApiGroup[]>(() => {\n const createOps: ApiOperation[] = ENTITIES.map((entity) => ({\n kind: 'Mutation',\n name: `createCrew${entity.name}`,\n signature: `createCrew${entity.name}(input: CreateCrew${entity.name}Input!): Crew${entity.name}!`,\n description: `Create a ${humanize(entity.name)} record (${entity.domain}).`,\n }));\n const updateOps: ApiOperation[] = ENTITIES.map((entity) => ({\n kind: 'Mutation',\n name: `updateCrew${entity.name}`,\n signature: `updateCrew${entity.name}(id: ID!, input: UpdateCrew${entity.name}Input!): Crew${entity.name}!`,\n description: `Update an existing ${humanize(entity.name)} record (${entity.domain}).`,\n }));\n const removeOps: ApiOperation[] = ENTITIES.map((entity) => ({\n kind: 'Mutation',\n name: `removeCrew${entity.name}`,\n signature: `removeCrew${entity.name}(id: ID!): Boolean!`,\n description: `Delete a ${humanize(entity.name)} record (${entity.domain}).`,\n }));\n\n return [\n {\n id: 'queries',\n name: 'Queries',\n description: 'Read the workspace dataset',\n operations: [\n {\n kind: 'Query',\n name: 'crewfoundryBootstrap',\n signature: 'crewfoundryBootstrap: CrewfoundryBootstrap!',\n description: `Load the full workspace dataset in one call — ${employees.length} employees, ${jobPostings.length} job postings, ${candidates.length} candidates, ${payrollRecords.length} payroll records, ${leaveRequests.length} leave requests, and every other CrewFoundry collection.`,\n },\n ],\n },\n {\n id: 'create',\n name: 'Create mutations',\n description: 'Add new records',\n operations: createOps,\n },\n {\n id: 'update',\n name: 'Update mutations',\n description: 'Modify existing records',\n operations: updateOps,\n },\n {\n id: 'delete',\n name: 'Delete mutations',\n description: 'Remove records',\n operations: removeOps,\n },\n {\n id: 'workflow',\n name: 'Workflow mutations',\n description: 'Enrollment & notifications',\n operations: [\n {\n kind: 'Mutation',\n name: 'enrollCrewCourse',\n signature: 'enrollCrewCourse(id: ID!): CrewCourse!',\n description: 'Enroll the current member into a learning course.',\n },\n {\n kind: 'Mutation',\n name: 'markCrewNotificationRead',\n signature: 'markCrewNotificationRead(id: ID!): Boolean!',\n description: 'Mark a single notification as read.',\n },\n {\n kind: 'Mutation',\n name: 'markAllCrewNotificationsRead',\n signature: 'markAllCrewNotificationsRead: Boolean!',\n description: 'Mark every notification as read.',\n },\n ],\n },\n ];\n }, [\n candidates.length,\n employees.length,\n jobPostings.length,\n leaveRequests.length,\n payrollRecords.length,\n ]);\n\n const totalOperations = useMemo(\n () => groups.reduce((sum, group) => sum + group.operations.length, 0),\n [groups]\n );\n\n const filteredGroups = useMemo(() => {\n const term = search.trim().toLowerCase();\n if (!term) {\n return groups;\n }\n return groups\n .map((group) => ({\n ...group,\n operations: group.operations.filter(\n (op) =>\n op.name.toLowerCase().includes(term) ||\n op.signature.toLowerCase().includes(term) ||\n op.description.toLowerCase().includes(term)\n ),\n }))\n .filter((group) => group.operations.length > 0);\n }, [groups, search]);\n\n const handleCopy = async (value: string) => {\n const ok = await copyToClipboard(value);\n if (ok) {\n setCopied(value);\n showToast('Copied to clipboard', 'success');\n window.setTimeout(() => setCopied((current) => (current === value ? null : current)), 1500);\n } else {\n showToast('Unable to copy to clipboard', 'error');\n }\n };\n\n const scrollToGroup = (id: string) => {\n const target = typeof document !== 'undefined' ? document.getElementById(`group-${id}`) : null;\n target?.scrollIntoView({ behavior: 'smooth', block: 'start' });\n };\n\n const statTiles = [\n { icon: Network, label: 'Protocol', value: 'GraphQL', color: 'text-status-info-text' },\n {\n icon: Code2,\n label: 'Composition',\n value: 'Apollo Federation v2',\n color: 'text-action-primary-bg',\n },\n { icon: Lock, label: 'Auth', value: 'Bearer token', color: 'text-status-success-text' },\n {\n icon: ListTree,\n label: 'Operations',\n value: String(totalOperations),\n color: 'text-status-warning-text',\n },\n ];\n\n return (\n <div className=\"space-y-6 p-6\">\n <div className=\"flex flex-col gap-3 md:flex-row md:items-start md:justify-between\">\n <div>\n <h1 className=\"text-2xl font-semibold\">\n <GradientText>API Documentation</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">\n CrewFoundry GraphQL API reference for integrations\n </p>\n <PagePurpose className=\"mt-1\">Browse the CrewFoundry API reference — use it to find operations, understand request formats, and integrate CrewFoundry with your own tools.</PagePurpose>\n </div>\n <div className=\"flex flex-wrap items-center gap-2\">\n <Badge variant=\"secondary\" className=\"max-w-full truncate font-mono text-[10px]\">\n {ENDPOINT}\n </Badge>\n <Button\n size=\"sm\"\n variant=\"outline\"\n aria-label=\"Copy the GraphQL endpoint URL\"\n onClick={() => void handleCopy(ENDPOINT)}\n >\n {copied === ENDPOINT ? (\n <Check className=\"mr-1 h-3 w-3 text-status-success-text\" />\n ) : (\n <Copy className=\"mr-1 h-3 w-3\" />\n )}\n Copy endpoint\n </Button>\n </div>\n </div>\n\n <div className=\"grid gap-4 md:grid-cols-4\">\n {statTiles.map((item) => (\n <Card key={item.label}>\n <CardContent className=\"flex items-center gap-3 pt-6\">\n <item.icon className={`h-5 w-5 ${item.color}`} />\n <div className=\"min-w-0\">\n <p className=\"text-xs text-text-secondary\">{item.label}</p>\n <p className=\"truncate text-sm font-medium\">{item.value}</p>\n </div>\n </CardContent>\n </Card>\n ))}\n </div>\n\n <div className=\"grid gap-6 lg:grid-cols-4\">\n <div className=\"space-y-4\">\n <EmphasisPanel>\n <div className=\"mb-2 text-sm font-semibold\">Jump to</div>\n <div className=\"space-y-2\">\n {groups.map((group) => (\n <button\n key={group.id}\n type=\"button\"\n aria-label={`Jump to ${group.name}`}\n onClick={() => scrollToGroup(group.id)}\n className=\"flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-sm transition-colors hover:bg-bg-sunken\"\n >\n <ListTree className=\"h-3 w-3 text-text-secondary\" />\n <span>{group.name}</span>\n <Badge variant=\"outline\" className=\"ml-auto text-[10px]\">\n {group.operations.length}\n </Badge>\n <ChevronRight className=\"h-3 w-3 text-text-secondary\" />\n </button>\n ))}\n </div>\n </EmphasisPanel>\n\n <Card>\n <CardHeader>\n <CardTitle className=\"text-sm\">Authentication</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-2\">\n <div className=\"rounded-md bg-bg-sunken p-3\">\n <code className=\"font-mono text-xs\">Authorization: Bearer {'<token>'}</code>\n </div>\n <p className=\"text-xs text-text-secondary\">\n Requests are authenticated at the gateway edge. Send your session bearer token on\n every request; the gateway resolves the actor and enforces workspace-scoped RBAC\n before the subgraph runs.\n </p>\n </CardContent>\n </Card>\n </div>\n\n <div className=\"space-y-4 lg:col-span-3\">\n <div className=\"relative max-w-md\">\n <Search className=\"absolute top-1/2 left-3 h-4 w-4 -translate-y-1/2 text-text-secondary\" />\n <Input\n placeholder=\"Search operations...\"\n className=\"pl-9\"\n value={search}\n onChange={(event) => setSearch(event.target.value)}\n />\n </div>\n\n {filteredGroups.map((group) => (\n <Card key={group.id} id={`group-${group.id}`} className=\"scroll-mt-6\">\n <CardHeader>\n <div className=\"flex items-center gap-2\">\n <Database className=\"h-4 w-4 text-text-secondary\" />\n <CardTitle className=\"text-base\">{group.name}</CardTitle>\n </div>\n <CardDescription>\n {group.description} · {group.operations.length} operations\n </CardDescription>\n </CardHeader>\n <CardContent className=\"p-0\">\n {group.operations.map((op, index) => (\n <div\n key={op.name}\n className={`flex items-center gap-3 px-6 py-3 hover:bg-bg-sunken/50 ${index < group.operations.length - 1 ? 'border-b' : ''}`}\n >\n <Badge\n className={`${kindColors[op.kind]} min-w-[64px] justify-center border-0 font-mono text-[10px]`}\n >\n {op.kind}\n </Badge>\n <div className=\"min-w-0 flex-1\">\n <code className=\"block truncate font-mono text-sm\">{op.signature}</code>\n <span className=\"text-xs text-text-secondary\">{op.description}</span>\n </div>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-6 w-6 shrink-0 p-0\"\n aria-label={`Copy ${op.name} operation name`}\n onClick={() => void handleCopy(op.name)}\n >\n {copied === op.name ? (\n <Check className=\"h-3 w-3 text-status-success-text\" />\n ) : (\n <Copy className=\"h-3 w-3 text-text-secondary\" />\n )}\n </Button>\n </div>\n ))}\n </CardContent>\n </Card>\n ))}\n\n {filteredGroups.length === 0 && (\n <div className=\"py-6\">\n <IllustratedEmptyState\n illustration=\"empty-search\"\n title=\"No operations match\"\n description=\"Try a different search term to find the operation you need.\"\n />\n </div>\n )}\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
@@ -1,10 +1,85 @@
1
1
  import { useCrewFoundryStore as e } from "../store/crewfoundryStore.js";
2
2
  import { Clock as t, FileText as n, Star as r, UserCheck as i, Users as a } from "lucide-react";
3
3
  import { jsx as o, jsxs as s } from "react/jsx-runtime";
4
- import { Badge as c, Card as l, CardContent as u, CardDescription as d, CardHeader as f, CardTitle as p, GlassCard as m, GradientText as h, PagePurpose as g } from "@burdenoff/fe-libs/ui";
4
+ import { Badge as c, Card as l, CardContent as u, CardDescription as d, CardHeader as f, CardTitle as p, GlassCard as m, GradientText as h, IllustratedEmptyState as g, PagePurpose as _, Pagination as v, ResponsiveTable as y } from "@burdenoff/fe-libs/ui";
5
+ import { usePagination as b } from "@burdenoff/fe-libs/shared/hooks";
5
6
  //#region src/crewfoundry/pages/HiringApplicationsPagePage.tsx
6
- function _() {
7
- let { candidates: _, jobPostings: v } = e(), y = _.filter((e) => e.status === "new"), b = _.filter((e) => e.status === "screening"), x = _.filter((e) => e.status === "interview"), S = v.reduce((e, t) => e + t.applicants, 0);
7
+ var x = [
8
+ {
9
+ key: "candidate",
10
+ header: "Candidate",
11
+ priority: "primary",
12
+ cell: (e) => /* @__PURE__ */ s("div", { children: [/* @__PURE__ */ s("p", {
13
+ className: "font-medium",
14
+ children: [
15
+ e.firstName,
16
+ " ",
17
+ e.lastName
18
+ ]
19
+ }), /* @__PURE__ */ o("p", {
20
+ className: "text-xs text-text-secondary",
21
+ children: e.email
22
+ })] })
23
+ },
24
+ {
25
+ key: "position",
26
+ header: "Position",
27
+ priority: "secondary",
28
+ cell: (e) => /* @__PURE__ */ o("span", {
29
+ className: "text-text-secondary",
30
+ children: e.position
31
+ })
32
+ },
33
+ {
34
+ key: "company",
35
+ header: "Company",
36
+ priority: "secondary",
37
+ cell: (e) => /* @__PURE__ */ o("span", {
38
+ className: "text-text-secondary",
39
+ children: e.currentCompany
40
+ })
41
+ },
42
+ {
43
+ key: "experience",
44
+ header: "Experience",
45
+ priority: "hidden-on-mobile",
46
+ cell: (e) => /* @__PURE__ */ s("span", { children: [e.experience, " yrs"] })
47
+ },
48
+ {
49
+ key: "rating",
50
+ header: "Rating",
51
+ priority: "hidden-on-mobile",
52
+ cell: (e) => /* @__PURE__ */ s("span", {
53
+ className: "flex items-center gap-1",
54
+ children: [/* @__PURE__ */ o(r, { className: "h-3 w-3 text-status-warning-text" }), e.rating]
55
+ })
56
+ },
57
+ {
58
+ key: "skills",
59
+ header: "Skills",
60
+ priority: "secondary",
61
+ cell: (e) => /* @__PURE__ */ o("div", {
62
+ className: "flex flex-wrap gap-1",
63
+ children: e.skills.slice(0, 2).map((e) => /* @__PURE__ */ o(c, {
64
+ variant: "outline",
65
+ className: "text-[9px]",
66
+ children: e
67
+ }, e))
68
+ })
69
+ },
70
+ {
71
+ key: "status",
72
+ header: "Status",
73
+ priority: "secondary",
74
+ cell: (e) => /* @__PURE__ */ o(c, {
75
+ variant: e.status === "hired" || e.status === "offer" ? "default" : e.status === "rejected" ? "destructive" : "secondary",
76
+ className: "text-[10px]",
77
+ children: e.status
78
+ })
79
+ }
80
+ ];
81
+ function S() {
82
+ let { candidates: r, jobPostings: S } = e(), { page: C, pageSize: w, offset: T, setPage: E } = b({ initialPageSize: 25 }), D = r.filter((e) => e.status === "new"), O = r.filter((e) => e.status === "screening"), k = r.filter((e) => e.status === "interview"), A = r.filter((e) => e.status === "hired").length, j = S.reduce((e, t) => e + t.applicants, 0), M = j > 0 ? A / j * 100 : 0, N = Math.max(1, ...S.map((e) => e.applicants)), P = [...S].sort((e, t) => t.applicants - e.applicants), F = r.slice(T, T + w);
8
83
  return /* @__PURE__ */ s("div", {
9
84
  className: "space-y-6 p-6",
10
85
  children: [
@@ -17,9 +92,9 @@ function _() {
17
92
  }),
18
93
  /* @__PURE__ */ s("p", {
19
94
  className: "text-sm text-text-secondary",
20
- children: [S, " total applications across all positions"]
95
+ children: [j, " total applications across all positions"]
21
96
  }),
22
- /* @__PURE__ */ o(g, {
97
+ /* @__PURE__ */ o(_, {
23
98
  className: "mt-1",
24
99
  children: "Review and triage incoming job applications — move candidates through your pipeline and decide who to interview next."
25
100
  })
@@ -40,7 +115,7 @@ function _() {
40
115
  }), /* @__PURE__ */ o(n, { className: "h-4 w-4 text-status-info-text" })]
41
116
  }), /* @__PURE__ */ s(u, { children: [/* @__PURE__ */ o("div", {
42
117
  className: "text-2xl font-bold tabular-nums",
43
- children: y.length
118
+ children: D.length
44
119
  }), /* @__PURE__ */ o("p", {
45
120
  className: "text-xs text-text-secondary",
46
121
  children: "Unreviewed applications"
@@ -57,7 +132,7 @@ function _() {
57
132
  }), /* @__PURE__ */ o(t, { className: "h-4 w-4 text-status-warning-text" })]
58
133
  }), /* @__PURE__ */ s(u, { children: [/* @__PURE__ */ o("div", {
59
134
  className: "text-2xl font-bold tabular-nums",
60
- children: b.length
135
+ children: O.length
61
136
  }), /* @__PURE__ */ o("p", {
62
137
  className: "text-xs text-text-secondary",
63
138
  children: "Under review"
@@ -74,7 +149,7 @@ function _() {
74
149
  }), /* @__PURE__ */ o(a, { className: "h-4 w-4 text-action-primary-bg" })]
75
150
  }), /* @__PURE__ */ s(u, { children: [/* @__PURE__ */ o("div", {
76
151
  className: "text-2xl font-bold tabular-nums",
77
- children: x.length
152
+ children: k.length
78
153
  }), /* @__PURE__ */ o("p", {
79
154
  className: "text-xs text-text-secondary",
80
155
  children: "Moving forward"
@@ -89,119 +164,70 @@ function _() {
89
164
  className: "text-sm font-medium",
90
165
  children: "Conversion Rate"
91
166
  }), /* @__PURE__ */ o(i, { className: "h-4 w-4 text-status-success-text" })]
92
- }), /* @__PURE__ */ s(u, { children: [/* @__PURE__ */ o("div", {
167
+ }), /* @__PURE__ */ s(u, { children: [/* @__PURE__ */ s("div", {
93
168
  className: "text-2xl font-bold tabular-nums",
94
- children: "4.8%"
169
+ children: [M.toFixed(1), "%"]
95
170
  }), /* @__PURE__ */ o("p", {
96
171
  className: "text-xs text-text-secondary",
97
- children: "Application to hire"
172
+ children: "Hired vs. total applications"
98
173
  })] })]
99
174
  })
100
175
  ]
101
176
  }),
102
177
  /* @__PURE__ */ s(l, { children: [/* @__PURE__ */ s(f, { children: [/* @__PURE__ */ o(p, { children: "Applications by Position" }), /* @__PURE__ */ o(d, { children: "Applicant count per open role" })] }), /* @__PURE__ */ o(u, {
103
178
  className: "space-y-3",
104
- children: v.sort((e, t) => t.applicants - e.applicants).map((e) => {
105
- let t = Math.max(...v.map((e) => e.applicants));
106
- return /* @__PURE__ */ s("div", {
107
- className: "flex items-center gap-3",
108
- children: [
109
- /* @__PURE__ */ o("span", {
110
- className: "w-56 text-sm font-medium truncate",
111
- children: e.title
112
- }),
113
- /* @__PURE__ */ o("div", {
114
- className: "flex-1 h-4 bg-bg-sunken rounded overflow-hidden",
115
- children: /* @__PURE__ */ o("div", {
116
- className: "h-4 bg-action-primary-bg rounded",
117
- style: { width: `${Math.round(e.applicants / t * 100)}%` }
118
- })
119
- }),
120
- /* @__PURE__ */ o("span", {
121
- className: "text-sm font-medium w-10 text-right",
122
- children: e.applicants
123
- }),
124
- /* @__PURE__ */ o(c, {
125
- variant: e.status === "active" ? "default" : "secondary",
126
- className: "text-[10px]",
127
- children: e.status
179
+ children: P.length === 0 ? /* @__PURE__ */ o(g, {
180
+ illustration: "empty-search",
181
+ title: "No positions yet",
182
+ description: "Create a job posting to start collecting applications."
183
+ }) : P.map((e) => /* @__PURE__ */ s("div", {
184
+ className: "flex items-center gap-3",
185
+ children: [
186
+ /* @__PURE__ */ o("span", {
187
+ className: "w-56 text-sm font-medium truncate",
188
+ children: e.title
189
+ }),
190
+ /* @__PURE__ */ o("div", {
191
+ className: "flex-1 h-4 bg-bg-sunken rounded overflow-hidden",
192
+ children: /* @__PURE__ */ o("div", {
193
+ className: "h-4 bg-action-primary-bg rounded",
194
+ style: { width: `${Math.round(e.applicants / N * 100)}%` }
128
195
  })
129
- ]
130
- }, e.id);
131
- })
132
- })] }),
133
- /* @__PURE__ */ s(l, { children: [/* @__PURE__ */ s(f, { children: [/* @__PURE__ */ o(p, { children: "All Candidates" }), /* @__PURE__ */ o(d, { children: "Complete candidate pipeline" })] }), /* @__PURE__ */ s(u, { children: [/* @__PURE__ */ s("div", {
134
- className: "grid grid-cols-7 gap-2 text-xs font-medium text-text-secondary border-b pb-2 mb-2",
135
- children: [
136
- /* @__PURE__ */ o("span", { children: "Candidate" }),
137
- /* @__PURE__ */ o("span", { children: "Position" }),
138
- /* @__PURE__ */ o("span", { children: "Company" }),
139
- /* @__PURE__ */ o("span", {
140
- className: "text-right",
141
- children: "Experience"
142
- }),
143
- /* @__PURE__ */ o("span", {
144
- className: "text-center",
145
- children: "Rating"
146
- }),
147
- /* @__PURE__ */ o("span", { children: "Skills" }),
148
- /* @__PURE__ */ o("span", {
149
- className: "text-center",
150
- children: "Status"
151
- })
152
- ]
153
- }), _.map((e) => /* @__PURE__ */ s("div", {
154
- className: "grid grid-cols-7 gap-2 py-2 border-b last:border-0 text-sm",
155
- children: [
156
- /* @__PURE__ */ s("div", { children: [/* @__PURE__ */ s("p", {
157
- className: "font-medium",
158
- children: [
159
- e.firstName,
160
- " ",
161
- e.lastName
162
- ]
163
- }), /* @__PURE__ */ o("p", {
164
- className: "text-xs text-text-secondary",
165
- children: e.email
166
- })] }),
167
- /* @__PURE__ */ o("span", {
168
- className: "text-text-secondary truncate",
169
- children: e.position
170
- }),
171
- /* @__PURE__ */ o("span", {
172
- className: "text-text-secondary",
173
- children: e.currentCompany
174
- }),
175
- /* @__PURE__ */ s("span", {
176
- className: "text-right",
177
- children: [e.experience, " yrs"]
178
- }),
179
- /* @__PURE__ */ s("div", {
180
- className: "flex items-center justify-center gap-1",
181
- children: [/* @__PURE__ */ o(r, { className: "h-3 w-3 text-status-warning-text" }), e.rating]
182
- }),
183
- /* @__PURE__ */ o("div", {
184
- className: "flex flex-wrap gap-1",
185
- children: e.skills.slice(0, 2).map((e) => /* @__PURE__ */ o(c, {
186
- variant: "outline",
187
- className: "text-[9px]",
188
- children: e
189
- }, e))
190
- }),
191
- /* @__PURE__ */ o("div", {
192
- className: "text-center",
193
- children: /* @__PURE__ */ o(c, {
194
- variant: e.status === "hired" || e.status === "offer" ? "default" : e.status === "rejected" ? "destructive" : "secondary",
196
+ }),
197
+ /* @__PURE__ */ o("span", {
198
+ className: "text-sm font-medium w-10 text-right",
199
+ children: e.applicants
200
+ }),
201
+ /* @__PURE__ */ o(c, {
202
+ variant: e.status === "active" ? "default" : "secondary",
195
203
  className: "text-[10px]",
196
204
  children: e.status
197
205
  })
198
- })
199
- ]
200
- }, e.id))] })] })
206
+ ]
207
+ }, e.id))
208
+ })] }),
209
+ /* @__PURE__ */ s(l, { children: [/* @__PURE__ */ s(f, { children: [/* @__PURE__ */ o(p, { children: "All Candidates" }), /* @__PURE__ */ o(d, { children: "Complete candidate pipeline" })] }), /* @__PURE__ */ s(u, { children: [/* @__PURE__ */ o(y, {
210
+ data: F,
211
+ rowKey: (e) => e.id,
212
+ columns: x,
213
+ emptyState: /* @__PURE__ */ o(g, {
214
+ illustration: "empty-search",
215
+ title: "No candidates yet",
216
+ description: "Candidates you add to your pipeline will appear here."
217
+ })
218
+ }), r.length > w && /* @__PURE__ */ o("div", {
219
+ className: "mt-4",
220
+ children: /* @__PURE__ */ o(v, {
221
+ page: C,
222
+ pageSize: w,
223
+ totalItems: r.length,
224
+ onPageChange: E
225
+ })
226
+ })] })] })
201
227
  ]
202
228
  });
203
229
  }
204
230
  //#endregion
205
- export { _ as HiringApplicationsPagePage };
231
+ export { S as HiringApplicationsPagePage };
206
232
 
207
233
  //# sourceMappingURL=HiringApplicationsPagePage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"HiringApplicationsPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/HiringApplicationsPagePage.tsx"],"sourcesContent":["import {\n Badge,\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n GlassCard,\n GradientText,\n PagePurpose,\n} from '@burdenoff/fe-libs/ui';\nimport { Clock, FileText, Star, UserCheck, Users } from 'lucide-react';\nimport { useCrewFoundryStore } from '../store/crewfoundryStore';\n\nexport function HiringApplicationsPagePage() {\n const { candidates, jobPostings } = useCrewFoundryStore();\n\n const newApps = candidates.filter((c) => c.status === 'new');\n const screeningApps = candidates.filter((c) => c.status === 'screening');\n const interviewApps = candidates.filter((c) => c.status === 'interview');\n const totalApps = jobPostings.reduce((s, j) => s + j.applicants, 0);\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>Applications</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">\n {totalApps} total applications across all positions\n </p>\n <PagePurpose className=\"mt-1\">Review and triage incoming job applications — move candidates through your pipeline and decide who to interview next.</PagePurpose>\n </div>\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\">New</CardTitle>\n <FileText className=\"h-4 w-4 text-status-info-text\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">{newApps.length}</div>\n <p className=\"text-xs text-text-secondary\">Unreviewed applications</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\">Screening</CardTitle>\n <Clock className=\"h-4 w-4 text-status-warning-text\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">{screeningApps.length}</div>\n <p className=\"text-xs text-text-secondary\">Under review</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\">Interview Stage</CardTitle>\n <Users className=\"h-4 w-4 text-action-primary-bg\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">{interviewApps.length}</div>\n <p className=\"text-xs text-text-secondary\">Moving forward</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\">Conversion Rate</CardTitle>\n <UserCheck className=\"h-4 w-4 text-status-success-text\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">4.8%</div>\n <p className=\"text-xs text-text-secondary\">Application to hire</p>\n </CardContent>\n </GlassCard>\n </div>\n\n <Card>\n <CardHeader>\n <CardTitle>Applications by Position</CardTitle>\n <CardDescription>Applicant count per open role</CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n {jobPostings\n .sort((a, b) => b.applicants - a.applicants)\n .map((job) => {\n const maxApplicants = Math.max(...jobPostings.map((j) => j.applicants));\n return (\n <div key={job.id} className=\"flex items-center gap-3\">\n <span className=\"w-56 text-sm font-medium truncate\">{job.title}</span>\n <div className=\"flex-1 h-4 bg-bg-sunken rounded overflow-hidden\">\n <div\n className=\"h-4 bg-action-primary-bg rounded\"\n style={{ width: `${Math.round((job.applicants / maxApplicants) * 100)}%` }}\n />\n </div>\n <span className=\"text-sm font-medium w-10 text-right\">{job.applicants}</span>\n <Badge\n variant={job.status === 'active' ? 'default' : 'secondary'}\n className=\"text-[10px]\"\n >\n {job.status}\n </Badge>\n </div>\n );\n })}\n </CardContent>\n </Card>\n\n <Card>\n <CardHeader>\n <CardTitle>All Candidates</CardTitle>\n <CardDescription>Complete candidate pipeline</CardDescription>\n </CardHeader>\n <CardContent>\n <div className=\"grid grid-cols-7 gap-2 text-xs font-medium text-text-secondary border-b pb-2 mb-2\">\n <span>Candidate</span>\n <span>Position</span>\n <span>Company</span>\n <span className=\"text-right\">Experience</span>\n <span className=\"text-center\">Rating</span>\n <span>Skills</span>\n <span className=\"text-center\">Status</span>\n </div>\n {candidates.map((c) => (\n <div key={c.id} className=\"grid grid-cols-7 gap-2 py-2 border-b last:border-0 text-sm\">\n <div>\n <p className=\"font-medium\">\n {c.firstName} {c.lastName}\n </p>\n <p className=\"text-xs text-text-secondary\">{c.email}</p>\n </div>\n <span className=\"text-text-secondary truncate\">{c.position}</span>\n <span className=\"text-text-secondary\">{c.currentCompany}</span>\n <span className=\"text-right\">{c.experience} yrs</span>\n <div className=\"flex items-center justify-center gap-1\">\n <Star className=\"h-3 w-3 text-status-warning-text\" />\n {c.rating}\n </div>\n <div className=\"flex flex-wrap gap-1\">\n {c.skills.slice(0, 2).map((s) => (\n <Badge key={s} variant=\"outline\" className=\"text-[9px]\">\n {s}\n </Badge>\n ))}\n </div>\n <div className=\"text-center\">\n <Badge\n variant={\n c.status === 'hired'\n ? 'default'\n : c.status === 'offer'\n ? 'default'\n : c.status === 'rejected'\n ? 'destructive'\n : 'secondary'\n }\n className=\"text-[10px]\"\n >\n {c.status}\n </Badge>\n </div>\n </div>\n ))}\n </CardContent>\n </Card>\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"HiringApplicationsPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/HiringApplicationsPagePage.tsx"],"sourcesContent":["import {\n Badge,\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n GlassCard,\n GradientText,\n IllustratedEmptyState,\n PagePurpose,\n Pagination,\n ResponsiveTable,\n type ResponsiveTableColumn,\n} from '@burdenoff/fe-libs/ui';\nimport { usePagination } from '@burdenoff/fe-libs/shared/hooks';\nimport { Clock, FileText, Star, UserCheck, Users } from 'lucide-react';\nimport { useCrewFoundryStore, type Candidate } from '../store/crewfoundryStore';\n\nconst CANDIDATE_COLUMNS: ResponsiveTableColumn<Candidate>[] = [\n {\n key: 'candidate',\n header: 'Candidate',\n priority: 'primary',\n cell: (c) => (\n <div>\n <p className=\"font-medium\">\n {c.firstName} {c.lastName}\n </p>\n <p className=\"text-xs text-text-secondary\">{c.email}</p>\n </div>\n ),\n },\n {\n key: 'position',\n header: 'Position',\n priority: 'secondary',\n cell: (c) => <span className=\"text-text-secondary\">{c.position}</span>,\n },\n {\n key: 'company',\n header: 'Company',\n priority: 'secondary',\n cell: (c) => <span className=\"text-text-secondary\">{c.currentCompany}</span>,\n },\n {\n key: 'experience',\n header: 'Experience',\n priority: 'hidden-on-mobile',\n cell: (c) => <span>{c.experience} yrs</span>,\n },\n {\n key: 'rating',\n header: 'Rating',\n priority: 'hidden-on-mobile',\n cell: (c) => (\n <span className=\"flex items-center gap-1\">\n <Star className=\"h-3 w-3 text-status-warning-text\" />\n {c.rating}\n </span>\n ),\n },\n {\n key: 'skills',\n header: 'Skills',\n priority: 'secondary',\n cell: (c) => (\n <div className=\"flex flex-wrap gap-1\">\n {c.skills.slice(0, 2).map((s) => (\n <Badge key={s} variant=\"outline\" className=\"text-[9px]\">\n {s}\n </Badge>\n ))}\n </div>\n ),\n },\n {\n key: 'status',\n header: 'Status',\n priority: 'secondary',\n cell: (c) => (\n <Badge\n variant={\n c.status === 'hired'\n ? 'default'\n : c.status === 'offer'\n ? 'default'\n : c.status === 'rejected'\n ? 'destructive'\n : 'secondary'\n }\n className=\"text-[10px]\"\n >\n {c.status}\n </Badge>\n ),\n },\n];\n\nexport function HiringApplicationsPagePage() {\n const { candidates, jobPostings } = useCrewFoundryStore();\n const { page, pageSize, offset, setPage } = usePagination({ initialPageSize: 25 });\n\n const newApps = candidates.filter((c) => c.status === 'new');\n const screeningApps = candidates.filter((c) => c.status === 'screening');\n const interviewApps = candidates.filter((c) => c.status === 'interview');\n const hiredCount = candidates.filter((c) => c.status === 'hired').length;\n const totalApps = jobPostings.reduce((s, j) => s + j.applicants, 0);\n const conversionRate = totalApps > 0 ? (hiredCount / totalApps) * 100 : 0;\n const maxApplicants = Math.max(1, ...jobPostings.map((j) => j.applicants));\n const rankedPositions = [...jobPostings].sort((a, b) => b.applicants - a.applicants);\n const pagedCandidates = candidates.slice(offset, offset + pageSize);\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>Applications</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">\n {totalApps} total applications across all positions\n </p>\n <PagePurpose className=\"mt-1\">Review and triage incoming job applications — move candidates through your pipeline and decide who to interview next.</PagePurpose>\n </div>\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\">New</CardTitle>\n <FileText className=\"h-4 w-4 text-status-info-text\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">{newApps.length}</div>\n <p className=\"text-xs text-text-secondary\">Unreviewed applications</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\">Screening</CardTitle>\n <Clock className=\"h-4 w-4 text-status-warning-text\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">{screeningApps.length}</div>\n <p className=\"text-xs text-text-secondary\">Under review</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\">Interview Stage</CardTitle>\n <Users className=\"h-4 w-4 text-action-primary-bg\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">{interviewApps.length}</div>\n <p className=\"text-xs text-text-secondary\">Moving forward</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\">Conversion Rate</CardTitle>\n <UserCheck className=\"h-4 w-4 text-status-success-text\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">{conversionRate.toFixed(1)}%</div>\n <p className=\"text-xs text-text-secondary\">Hired vs. total applications</p>\n </CardContent>\n </GlassCard>\n </div>\n\n <Card>\n <CardHeader>\n <CardTitle>Applications by Position</CardTitle>\n <CardDescription>Applicant count per open role</CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n {rankedPositions.length === 0 ? (\n <IllustratedEmptyState\n illustration=\"empty-search\"\n title=\"No positions yet\"\n description=\"Create a job posting to start collecting applications.\"\n />\n ) : (\n rankedPositions.map((job) => (\n <div key={job.id} className=\"flex items-center gap-3\">\n <span className=\"w-56 text-sm font-medium truncate\">{job.title}</span>\n <div className=\"flex-1 h-4 bg-bg-sunken rounded overflow-hidden\">\n <div\n className=\"h-4 bg-action-primary-bg rounded\"\n style={{ width: `${Math.round((job.applicants / maxApplicants) * 100)}%` }}\n />\n </div>\n <span className=\"text-sm font-medium w-10 text-right\">{job.applicants}</span>\n <Badge\n variant={job.status === 'active' ? 'default' : 'secondary'}\n className=\"text-[10px]\"\n >\n {job.status}\n </Badge>\n </div>\n ))\n )}\n </CardContent>\n </Card>\n\n <Card>\n <CardHeader>\n <CardTitle>All Candidates</CardTitle>\n <CardDescription>Complete candidate pipeline</CardDescription>\n </CardHeader>\n <CardContent>\n <ResponsiveTable\n data={pagedCandidates}\n rowKey={(c) => c.id}\n columns={CANDIDATE_COLUMNS}\n emptyState={\n <IllustratedEmptyState\n illustration=\"empty-search\"\n title=\"No candidates yet\"\n description=\"Candidates you add to your pipeline will appear here.\"\n />\n }\n />\n {candidates.length > pageSize && (\n <div className=\"mt-4\">\n <Pagination\n page={page}\n pageSize={pageSize}\n totalItems={candidates.length}\n onPageChange={setPage}\n />\n </div>\n )}\n </CardContent>\n </Card>\n </div>\n );\n}\n"],"mappings":"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"}