@burdenoff/microfe-crewfoundry 2026.704.3 → 2026.704.4

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 (89) hide show
  1. package/dist/crewfoundry/pages/AdminAdminPagePage.js +76 -75
  2. package/dist/crewfoundry/pages/AdminAdminPagePage.js.map +1 -1
  3. package/dist/crewfoundry/pages/AnalyticsFinancialAnalyticsPagePage.js +118 -117
  4. package/dist/crewfoundry/pages/AnalyticsFinancialAnalyticsPagePage.js.map +1 -1
  5. package/dist/crewfoundry/pages/AnalyticsHiringAnalyticsPagePage.js +115 -114
  6. package/dist/crewfoundry/pages/AnalyticsHiringAnalyticsPagePage.js.map +1 -1
  7. package/dist/crewfoundry/pages/CommunicationsAnnouncementsPagePage.js +105 -104
  8. package/dist/crewfoundry/pages/CommunicationsAnnouncementsPagePage.js.map +1 -1
  9. package/dist/crewfoundry/pages/CommunicationsTeamsPagePage.js +52 -51
  10. package/dist/crewfoundry/pages/CommunicationsTeamsPagePage.js.map +1 -1
  11. package/dist/crewfoundry/pages/CompanyClientManagementPagePage.js +94 -93
  12. package/dist/crewfoundry/pages/CompanyClientManagementPagePage.js.map +1 -1
  13. package/dist/crewfoundry/pages/CompanyCompanyProfilePagePage.js +97 -96
  14. package/dist/crewfoundry/pages/CompanyCompanyProfilePagePage.js.map +1 -1
  15. package/dist/crewfoundry/pages/CompanyVendorManagementPagePage.js +68 -67
  16. package/dist/crewfoundry/pages/CompanyVendorManagementPagePage.js.map +1 -1
  17. package/dist/crewfoundry/pages/DashboardAnalyticsPagePage.js +96 -95
  18. package/dist/crewfoundry/pages/DashboardAnalyticsPagePage.js.map +1 -1
  19. package/dist/crewfoundry/pages/DashboardDashboardPagePage.js +153 -152
  20. package/dist/crewfoundry/pages/DashboardDashboardPagePage.js.map +1 -1
  21. package/dist/crewfoundry/pages/DashboardEnhancedDashboardPagePage.js +107 -106
  22. package/dist/crewfoundry/pages/DashboardEnhancedDashboardPagePage.js.map +1 -1
  23. package/dist/crewfoundry/pages/HiringApplicationsPagePage.js +77 -76
  24. package/dist/crewfoundry/pages/HiringApplicationsPagePage.js.map +1 -1
  25. package/dist/crewfoundry/pages/HiringCandidatesPagePage.js +80 -79
  26. package/dist/crewfoundry/pages/HiringCandidatesPagePage.js.map +1 -1
  27. package/dist/crewfoundry/pages/HiringInterviewsPagePage.js +102 -101
  28. package/dist/crewfoundry/pages/HiringInterviewsPagePage.js.map +1 -1
  29. package/dist/crewfoundry/pages/HiringJobDetailsPagePage.js +126 -125
  30. package/dist/crewfoundry/pages/HiringJobDetailsPagePage.js.map +1 -1
  31. package/dist/crewfoundry/pages/HiringJobsPagePage.js +64 -63
  32. package/dist/crewfoundry/pages/HiringJobsPagePage.js.map +1 -1
  33. package/dist/crewfoundry/pages/HrDepartmentsPagePage.js +96 -95
  34. package/dist/crewfoundry/pages/HrDepartmentsPagePage.js.map +1 -1
  35. package/dist/crewfoundry/pages/HrLeaveManagementPagePage.js +127 -126
  36. package/dist/crewfoundry/pages/HrLeaveManagementPagePage.js.map +1 -1
  37. package/dist/crewfoundry/pages/HrPayrollPagePage.js +118 -117
  38. package/dist/crewfoundry/pages/HrPayrollPagePage.js.map +1 -1
  39. package/dist/crewfoundry/pages/HrTimeTrackingPagePage.js +123 -122
  40. package/dist/crewfoundry/pages/HrTimeTrackingPagePage.js.map +1 -1
  41. package/dist/crewfoundry/pages/LearningCourseDetailsPagePage.js +77 -76
  42. package/dist/crewfoundry/pages/LearningCourseDetailsPagePage.js.map +1 -1
  43. package/dist/crewfoundry/pages/LearningCourseLearningPagePage.js +49 -48
  44. package/dist/crewfoundry/pages/LearningCourseLearningPagePage.js.map +1 -1
  45. package/dist/crewfoundry/pages/LearningCoursesPagePage.js +62 -61
  46. package/dist/crewfoundry/pages/LearningCoursesPagePage.js.map +1 -1
  47. package/dist/crewfoundry/pages/LearningLearningPagePage.js +72 -71
  48. package/dist/crewfoundry/pages/LearningLearningPagePage.js.map +1 -1
  49. package/dist/crewfoundry/pages/LearningLearningPathDetailPagePage.js +70 -69
  50. package/dist/crewfoundry/pages/LearningLearningPathDetailPagePage.js.map +1 -1
  51. package/dist/crewfoundry/pages/LearningLearningPathsPagePage.js +57 -56
  52. package/dist/crewfoundry/pages/LearningLearningPathsPagePage.js.map +1 -1
  53. package/dist/crewfoundry/pages/MarketplaceEarningsPagePage.js +58 -57
  54. package/dist/crewfoundry/pages/MarketplaceEarningsPagePage.js.map +1 -1
  55. package/dist/crewfoundry/pages/MarketplaceFreelancerProfilePageEnhancedPage.js +122 -121
  56. package/dist/crewfoundry/pages/MarketplaceFreelancerProfilePageEnhancedPage.js.map +1 -1
  57. package/dist/crewfoundry/pages/MarketplaceMarketplacePagePage.js +70 -69
  58. package/dist/crewfoundry/pages/MarketplaceMarketplacePagePage.js.map +1 -1
  59. package/dist/crewfoundry/pages/MarketplaceMarketplaceServicesPagePage.js +41 -40
  60. package/dist/crewfoundry/pages/MarketplaceMarketplaceServicesPagePage.js.map +1 -1
  61. package/dist/crewfoundry/pages/MarketplaceMyServicesPagePage.js +65 -64
  62. package/dist/crewfoundry/pages/MarketplaceMyServicesPagePage.js.map +1 -1
  63. package/dist/crewfoundry/pages/MarketplaceProjectDetailsPagePage.js +75 -74
  64. package/dist/crewfoundry/pages/MarketplaceProjectDetailsPagePage.js.map +1 -1
  65. package/dist/crewfoundry/pages/PaymentsInvoicesPagePage.js +60 -59
  66. package/dist/crewfoundry/pages/PaymentsInvoicesPagePage.js.map +1 -1
  67. package/dist/crewfoundry/pages/PaymentsPaymentDashboardPagePage.js +53 -52
  68. package/dist/crewfoundry/pages/PaymentsPaymentDashboardPagePage.js.map +1 -1
  69. package/dist/crewfoundry/pages/PaymentsPaymentMethodsPagePage.js +37 -36
  70. package/dist/crewfoundry/pages/PaymentsPaymentMethodsPagePage.js.map +1 -1
  71. package/dist/crewfoundry/pages/ProjectsProjectDetailsPagePage.js +126 -125
  72. package/dist/crewfoundry/pages/ProjectsProjectDetailsPagePage.js.map +1 -1
  73. package/dist/crewfoundry/pages/ProjectsProjectsPagePage.js +62 -61
  74. package/dist/crewfoundry/pages/ProjectsProjectsPagePage.js.map +1 -1
  75. package/dist/crewfoundry/pages/TeamsTeamAnalyticsPagePage.js +50 -49
  76. package/dist/crewfoundry/pages/TeamsTeamAnalyticsPagePage.js.map +1 -1
  77. package/dist/crewfoundry/pages/TeamsTeamDetailPagePage.js +72 -71
  78. package/dist/crewfoundry/pages/TeamsTeamDetailPagePage.js.map +1 -1
  79. package/dist/crewfoundry/pages/TeamsTeamDirectoryPagePage.js +40 -39
  80. package/dist/crewfoundry/pages/TeamsTeamDirectoryPagePage.js.map +1 -1
  81. package/dist/crewfoundry/pages/TeamsTeamSettingsPagePage.js +130 -129
  82. package/dist/crewfoundry/pages/TeamsTeamSettingsPagePage.js.map +1 -1
  83. package/dist/crewfoundry/pages/TeamsTeamsPagePage.js +60 -59
  84. package/dist/crewfoundry/pages/TeamsTeamsPagePage.js.map +1 -1
  85. package/dist/crewfoundry/store/crewfoundryStore.js +177 -146
  86. package/dist/crewfoundry/store/crewfoundryStore.js.map +1 -1
  87. package/dist/crewfoundry/utils/formatEnumLabel.js +8 -0
  88. package/dist/crewfoundry/utils/formatEnumLabel.js.map +1 -0
  89. package/package.json +1 -1
@@ -1,13 +1,14 @@
1
1
  import { useCrewFoundryStore as e } from "../store/crewfoundryStore.js";
2
- import { FormModal as t } from "../components/forms/FormModal.js";
3
- import { getText as n, newClientId as r } from "../components/forms/formValues.js";
4
- import { useMemo as i, useState as a } from "react";
5
- import { Calendar as o, Clock as s, Plus as c, Star as l, Video as u } from "lucide-react";
6
- import { jsx as d, jsxs as f } from "react/jsx-runtime";
7
- import { Badge as p, Button as m, Card as h, CardContent as g, CardDescription as _, CardHeader as v, CardTitle as y, GlassCard as b, GradientText as x, PagePurpose as S } from "@burdenoff/fe-libs/ui";
8
- import { useGlobalUi as C } from "@burdenoff/fe-libs/shared/providers/shell";
2
+ import { formatEnumLabel as t } from "../utils/formatEnumLabel.js";
3
+ import { FormModal as n } from "../components/forms/FormModal.js";
4
+ import { getText as r, newClientId as i } from "../components/forms/formValues.js";
5
+ import { useMemo as a, useState as o } from "react";
6
+ import { Calendar as s, Clock as c, Plus as l, Star as u, Video as d } from "lucide-react";
7
+ import { jsx as f, jsxs as p } from "react/jsx-runtime";
8
+ import { Badge as m, Button as h, Card as g, CardContent as _, CardDescription as v, CardHeader as y, CardTitle as b, GlassCard as x, GradientText as S, PagePurpose as C } from "@burdenoff/fe-libs/ui";
9
+ import { useGlobalUi as w } from "@burdenoff/fe-libs/shared/providers/shell";
9
10
  //#region src/crewfoundry/pages/HiringInterviewsPagePage.tsx
10
- var w = [
11
+ var T = [
11
12
  {
12
13
  label: "Phone",
13
14
  value: "phone"
@@ -28,7 +29,7 @@ var w = [
28
29
  label: "Technical",
29
30
  value: "technical"
30
31
  }
31
- ], T = [
32
+ ], E = [
32
33
  {
33
34
  name: "status",
34
35
  label: "Status",
@@ -65,23 +66,23 @@ var w = [
65
66
  colSpan: 2
66
67
  }
67
68
  ];
68
- function E() {
69
- let { showToast: E } = C(), { interviews: D, candidates: O, addInterview: k, updateInterview: A } = e(), [j, M] = a(!1), [N, P] = a(null), F = D.filter((e) => e.status === "scheduled"), I = D.filter((e) => e.status === "completed"), L = i(() => {
69
+ function D() {
70
+ let { showToast: D } = w(), { interviews: O, candidates: k, addInterview: A, updateInterview: j } = e(), [M, N] = o(!1), [P, F] = o(null), I = O.filter((e) => e.status === "scheduled"), L = O.filter((e) => e.status === "completed"), R = a(() => {
70
71
  let e = /* @__PURE__ */ new Date(), t = new Date(e);
71
72
  t.setDate(e.getDate() - (e.getDay() + 6) % 7), t.setHours(0, 0, 0, 0);
72
73
  let n = new Date(t);
73
- return n.setDate(t.getDate() + 7), D.filter((e) => {
74
+ return n.setDate(t.getDate() + 7), O.filter((e) => {
74
75
  let r = new Date(e.date);
75
76
  return !Number.isNaN(r.getTime()) && r >= t && r < n;
76
77
  }).length;
77
- }, [D]), R = i(() => [
78
+ }, [O]), z = a(() => [
78
79
  {
79
80
  name: "candidateId",
80
81
  label: "Candidate",
81
82
  type: "select",
82
83
  required: !0,
83
- placeholder: O.length ? "Select a candidate…" : "No candidates available",
84
- options: O.map((e) => ({
84
+ placeholder: k.length ? "Select a candidate…" : "No candidates available",
85
+ options: k.map((e) => ({
85
86
  label: `${e.firstName} ${e.lastName} — ${e.position}`,
86
87
  value: e.id
87
88
  }))
@@ -110,148 +111,148 @@ function E() {
110
111
  label: "Type",
111
112
  type: "select",
112
113
  required: !0,
113
- options: w
114
+ options: T
114
115
  }
115
- ], [O]);
116
- return /* @__PURE__ */ f("div", {
116
+ ], [k]);
117
+ return /* @__PURE__ */ p("div", {
117
118
  className: "space-y-6 p-6",
118
119
  children: [
119
- /* @__PURE__ */ f("div", {
120
+ /* @__PURE__ */ p("div", {
120
121
  className: "flex items-center justify-between",
121
- children: [/* @__PURE__ */ f("div", { children: [
122
- /* @__PURE__ */ d("h1", {
122
+ children: [/* @__PURE__ */ p("div", { children: [
123
+ /* @__PURE__ */ f("h1", {
123
124
  className: "text-2xl font-semibold",
124
- children: /* @__PURE__ */ d(x, { children: "Interviews" })
125
+ children: /* @__PURE__ */ f(S, { children: "Interviews" })
125
126
  }),
126
- /* @__PURE__ */ f("p", {
127
+ /* @__PURE__ */ p("p", {
127
128
  className: "text-sm text-text-secondary",
128
129
  children: [
129
- F.length,
130
- " upcoming · ",
131
130
  I.length,
131
+ " upcoming · ",
132
+ L.length,
132
133
  " completed"
133
134
  ]
134
135
  }),
135
- /* @__PURE__ */ d(S, {
136
+ /* @__PURE__ */ f(C, {
136
137
  className: "mt-1",
137
138
  children: "Schedule and track interviews across your hiring pipeline — keep everyone aligned on who's meeting which candidate and when."
138
139
  })
139
- ] }), /* @__PURE__ */ f(m, {
140
+ ] }), /* @__PURE__ */ p(h, {
140
141
  size: "sm",
141
- onClick: () => M(!0),
142
- children: [/* @__PURE__ */ d(c, { className: "h-4 w-4 mr-1" }), "Schedule Interview"]
142
+ onClick: () => N(!0),
143
+ children: [/* @__PURE__ */ f(l, { className: "h-4 w-4 mr-1" }), "Schedule Interview"]
143
144
  })]
144
145
  }),
145
- /* @__PURE__ */ f("div", {
146
+ /* @__PURE__ */ p("div", {
146
147
  className: "grid gap-4 md:grid-cols-3",
147
148
  children: [
148
- /* @__PURE__ */ f(b, {
149
+ /* @__PURE__ */ p(x, {
149
150
  treatment: "glass",
150
151
  glow: !0,
151
152
  className: "border-border-seam",
152
- children: [/* @__PURE__ */ f(v, {
153
+ children: [/* @__PURE__ */ p(y, {
153
154
  className: "flex flex-row items-center justify-between space-y-0 pb-2",
154
- children: [/* @__PURE__ */ d(y, {
155
+ children: [/* @__PURE__ */ f(b, {
155
156
  className: "text-sm font-medium",
156
157
  children: "Scheduled"
157
- }), /* @__PURE__ */ d(o, { className: "h-4 w-4 text-status-info-text" })]
158
- }), /* @__PURE__ */ d(g, { children: /* @__PURE__ */ d("div", {
158
+ }), /* @__PURE__ */ f(s, { className: "h-4 w-4 text-status-info-text" })]
159
+ }), /* @__PURE__ */ f(_, { children: /* @__PURE__ */ f("div", {
159
160
  className: "text-2xl font-bold tabular-nums",
160
- children: F.length
161
+ children: I.length
161
162
  }) })]
162
163
  }),
163
- /* @__PURE__ */ f(b, {
164
+ /* @__PURE__ */ p(x, {
164
165
  treatment: "metric",
165
166
  className: "border-border-seam",
166
- children: [/* @__PURE__ */ f(v, {
167
+ children: [/* @__PURE__ */ p(y, {
167
168
  className: "flex flex-row items-center justify-between space-y-0 pb-2",
168
- children: [/* @__PURE__ */ d(y, {
169
+ children: [/* @__PURE__ */ f(b, {
169
170
  className: "text-sm font-medium",
170
171
  children: "Completed"
171
- }), /* @__PURE__ */ d(s, { className: "h-4 w-4 text-status-success-text" })]
172
- }), /* @__PURE__ */ d(g, { children: /* @__PURE__ */ d("div", {
172
+ }), /* @__PURE__ */ f(c, { className: "h-4 w-4 text-status-success-text" })]
173
+ }), /* @__PURE__ */ f(_, { children: /* @__PURE__ */ f("div", {
173
174
  className: "text-2xl font-bold tabular-nums",
174
- children: I.length
175
+ children: L.length
175
176
  }) })]
176
177
  }),
177
- /* @__PURE__ */ f(b, {
178
+ /* @__PURE__ */ p(x, {
178
179
  treatment: "metric",
179
180
  className: "border-border-seam",
180
- children: [/* @__PURE__ */ f(v, {
181
+ children: [/* @__PURE__ */ p(y, {
181
182
  className: "flex flex-row items-center justify-between space-y-0 pb-2",
182
- children: [/* @__PURE__ */ d(y, {
183
+ children: [/* @__PURE__ */ f(b, {
183
184
  className: "text-sm font-medium",
184
185
  children: "This Week"
185
- }), /* @__PURE__ */ d(u, { className: "h-4 w-4 text-text-secondary" })]
186
- }), /* @__PURE__ */ d(g, { children: /* @__PURE__ */ d("div", {
186
+ }), /* @__PURE__ */ f(d, { className: "h-4 w-4 text-text-secondary" })]
187
+ }), /* @__PURE__ */ f(_, { children: /* @__PURE__ */ f("div", {
187
188
  className: "text-2xl font-bold tabular-nums",
188
- children: L
189
+ children: R
189
190
  }) })]
190
191
  })
191
192
  ]
192
193
  }),
193
- /* @__PURE__ */ f(h, { children: [/* @__PURE__ */ f(v, { children: [/* @__PURE__ */ d(y, { children: "Upcoming Interviews" }), /* @__PURE__ */ d(_, { children: "Scheduled interviews for the coming days" })] }), /* @__PURE__ */ d(g, {
194
+ /* @__PURE__ */ p(g, { children: [/* @__PURE__ */ p(y, { children: [/* @__PURE__ */ f(b, { children: "Upcoming Interviews" }), /* @__PURE__ */ f(v, { children: "Scheduled interviews for the coming days" })] }), /* @__PURE__ */ f(_, {
194
195
  className: "space-y-3",
195
- children: F.map((e) => /* @__PURE__ */ f("div", {
196
+ children: I.map((e) => /* @__PURE__ */ p("div", {
196
197
  className: "flex flex-wrap items-center justify-between gap-3 rounded border p-4",
197
- children: [/* @__PURE__ */ f("div", { children: [
198
- /* @__PURE__ */ d("p", {
198
+ children: [/* @__PURE__ */ p("div", { children: [
199
+ /* @__PURE__ */ f("p", {
199
200
  className: "text-sm font-medium",
200
201
  children: e.candidateName
201
202
  }),
202
- /* @__PURE__ */ d("p", {
203
+ /* @__PURE__ */ f("p", {
203
204
  className: "text-xs text-text-secondary",
204
205
  children: e.position
205
206
  }),
206
- /* @__PURE__ */ f("p", {
207
+ /* @__PURE__ */ p("p", {
207
208
  className: "text-xs text-text-secondary mt-1",
208
209
  children: ["Interviewer: ", e.interviewerName]
209
210
  })
210
- ] }), /* @__PURE__ */ f("div", {
211
+ ] }), /* @__PURE__ */ p("div", {
211
212
  className: "flex items-center gap-3",
212
213
  children: [
213
- /* @__PURE__ */ f("div", {
214
+ /* @__PURE__ */ p("div", {
214
215
  className: "text-right",
215
- children: [/* @__PURE__ */ d("p", {
216
+ children: [/* @__PURE__ */ f("p", {
216
217
  className: "text-sm font-medium",
217
218
  children: e.date
218
- }), /* @__PURE__ */ d("p", {
219
+ }), /* @__PURE__ */ f("p", {
219
220
  className: "text-xs text-text-secondary",
220
221
  children: e.time
221
222
  })]
222
223
  }),
223
- /* @__PURE__ */ d(p, {
224
+ /* @__PURE__ */ f(m, {
224
225
  variant: "outline",
225
- children: e.type
226
+ children: t(e.type)
226
227
  }),
227
- /* @__PURE__ */ d(p, {
228
+ /* @__PURE__ */ f(m, {
228
229
  variant: "secondary",
229
- children: e.status
230
+ children: t(e.status)
230
231
  }),
231
- /* @__PURE__ */ d(m, {
232
+ /* @__PURE__ */ f(h, {
232
233
  variant: "outline",
233
234
  size: "sm",
234
- onClick: () => P(e),
235
+ onClick: () => F(e),
235
236
  children: "Record outcome"
236
237
  })
237
238
  ]
238
239
  })]
239
240
  }, e.id))
240
241
  })] }),
241
- I.length > 0 && /* @__PURE__ */ f(h, { children: [/* @__PURE__ */ f(v, { children: [/* @__PURE__ */ d(y, { children: "Completed Interviews" }), /* @__PURE__ */ d(_, { children: "Recent interview feedback" })] }), /* @__PURE__ */ d(g, {
242
+ L.length > 0 && /* @__PURE__ */ p(g, { children: [/* @__PURE__ */ p(y, { children: [/* @__PURE__ */ f(b, { children: "Completed Interviews" }), /* @__PURE__ */ f(v, { children: "Recent interview feedback" })] }), /* @__PURE__ */ f(_, {
242
243
  className: "space-y-3",
243
- children: I.map((e) => /* @__PURE__ */ f("div", {
244
+ children: L.map((e) => /* @__PURE__ */ p("div", {
244
245
  className: "flex flex-wrap items-center justify-between gap-3 rounded border p-4",
245
- children: [/* @__PURE__ */ f("div", { children: [
246
- /* @__PURE__ */ d("p", {
246
+ children: [/* @__PURE__ */ p("div", { children: [
247
+ /* @__PURE__ */ f("p", {
247
248
  className: "text-sm font-medium",
248
249
  children: e.candidateName
249
250
  }),
250
- /* @__PURE__ */ d("p", {
251
+ /* @__PURE__ */ f("p", {
251
252
  className: "text-xs text-text-secondary",
252
253
  children: e.position
253
254
  }),
254
- e.feedback && /* @__PURE__ */ f("p", {
255
+ e.feedback && /* @__PURE__ */ p("p", {
255
256
  className: "text-xs text-text-secondary mt-1 italic",
256
257
  children: [
257
258
  "\"",
@@ -259,72 +260,72 @@ function E() {
259
260
  "\""
260
261
  ]
261
262
  })
262
- ] }), /* @__PURE__ */ f("div", {
263
+ ] }), /* @__PURE__ */ p("div", {
263
264
  className: "flex items-center gap-3",
264
- children: [e.rating && /* @__PURE__ */ f("div", {
265
+ children: [e.rating && /* @__PURE__ */ p("div", {
265
266
  className: "flex items-center gap-1",
266
- children: [/* @__PURE__ */ d(l, { className: "h-4 w-4 text-status-warning-text" }), /* @__PURE__ */ f("span", {
267
+ children: [/* @__PURE__ */ f(u, { className: "h-4 w-4 text-status-warning-text" }), /* @__PURE__ */ p("span", {
267
268
  className: "text-sm font-medium",
268
269
  children: [e.rating, "/5"]
269
270
  })]
270
- }), /* @__PURE__ */ d(p, {
271
+ }), /* @__PURE__ */ f(m, {
271
272
  variant: "default",
272
273
  children: "completed"
273
274
  })]
274
275
  })]
275
276
  }, e.id))
276
277
  })] }),
277
- /* @__PURE__ */ d(t, {
278
- open: j,
279
- onOpenChange: M,
278
+ /* @__PURE__ */ f(n, {
279
+ open: M,
280
+ onOpenChange: N,
280
281
  title: "Schedule Interview",
281
282
  description: "Set up a conversation with a candidate in your pipeline.",
282
- fields: R,
283
+ fields: z,
283
284
  submitLabel: "Schedule",
284
285
  onSubmit: async (e) => {
285
- let t = O.find((t) => t.id === n(e, "candidateId"));
286
+ let t = k.find((t) => t.id === r(e, "candidateId"));
286
287
  if (!t) throw Error("Please select a candidate");
287
- await k({
288
- id: r(),
288
+ await A({
289
+ id: i(),
289
290
  candidateId: t.id,
290
291
  candidateName: `${t.firstName} ${t.lastName}`,
291
292
  position: t.position,
292
- interviewerName: n(e, "interviewerName"),
293
- date: n(e, "date"),
294
- time: n(e, "time"),
293
+ interviewerName: r(e, "interviewerName"),
294
+ date: r(e, "date"),
295
+ time: r(e, "time"),
295
296
  type: e.type,
296
297
  status: "scheduled"
297
- }), E("Interview scheduled", "success");
298
+ }), D("Interview scheduled", "success");
298
299
  }
299
300
  }),
300
- /* @__PURE__ */ d(t, {
301
- open: N !== null,
301
+ /* @__PURE__ */ f(n, {
302
+ open: P !== null,
302
303
  onOpenChange: (e) => {
303
- e || P(null);
304
+ e || F(null);
304
305
  },
305
306
  title: "Record Interview Outcome",
306
- description: N ? `${N.candidateName} — ${N.position}` : void 0,
307
- fields: T,
308
- initialValues: N ? {
309
- status: N.status,
310
- rating: N.rating ?? "",
311
- feedback: N.feedback ?? ""
307
+ description: P ? `${P.candidateName} — ${P.position}` : void 0,
308
+ fields: E,
309
+ initialValues: P ? {
310
+ status: P.status,
311
+ rating: P.rating ?? "",
312
+ feedback: P.feedback ?? ""
312
313
  } : void 0,
313
314
  submitLabel: "Save outcome",
314
315
  onSubmit: async (e) => {
315
- if (!N) return;
316
- let t = e.rating, r = typeof t == "number" || typeof t == "string" && t.trim() !== "";
317
- await A(N.id, {
316
+ if (!P) return;
317
+ let t = e.rating, n = typeof t == "number" || typeof t == "string" && t.trim() !== "";
318
+ await j(P.id, {
318
319
  status: e.status,
319
- feedback: n(e, "feedback"),
320
- ...r ? { rating: Number(t) } : {}
321
- }), E("Interview updated", "success");
320
+ feedback: r(e, "feedback"),
321
+ ...n ? { rating: Number(t) } : {}
322
+ }), D("Interview updated", "success");
322
323
  }
323
324
  })
324
325
  ]
325
326
  });
326
327
  }
327
328
  //#endregion
328
- export { E as HiringInterviewsPagePage };
329
+ export { D as HiringInterviewsPagePage };
329
330
 
330
331
  //# sourceMappingURL=HiringInterviewsPagePage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"HiringInterviewsPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/HiringInterviewsPagePage.tsx"],"sourcesContent":["import { useMemo, useState } from 'react';\nimport {\n Badge,\n Button,\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n GlassCard,\n GradientText,\n PagePurpose,\n} from '@burdenoff/fe-libs/ui';\nimport { useGlobalUi } from '@burdenoff/fe-libs/shared/providers/shell';\nimport { Calendar, Clock, Plus, Star, Video } from 'lucide-react';\nimport { useCrewFoundryStore, type Interview } from '../store/crewfoundryStore';\nimport { FormModal, type FieldConfig, type FormValues } from '../components/forms/FormModal';\nimport { getText, newClientId } from '../components/forms/formValues';\n\nconst INTERVIEW_TYPE_OPTIONS: FieldConfig['options'] = [\n { label: 'Phone', value: 'phone' },\n { label: 'Video', value: 'video' },\n { label: 'Onsite', value: 'onsite' },\n { label: 'Panel', value: 'panel' },\n { label: 'Technical', value: 'technical' },\n];\n\nconst INTERVIEW_STATUS_OPTIONS: FieldConfig['options'] = [\n { label: 'Scheduled', value: 'scheduled' },\n { label: 'Completed', value: 'completed' },\n { label: 'Cancelled', value: 'cancelled' },\n { label: 'No show', value: 'no_show' },\n];\n\nconst UPDATE_FIELDS: FieldConfig[] = [\n {\n name: 'status',\n label: 'Status',\n type: 'select',\n options: INTERVIEW_STATUS_OPTIONS,\n required: true,\n },\n { name: 'rating', label: 'Rating (out of 5)', type: 'number' },\n { name: 'feedback', label: 'Feedback', type: 'textarea', colSpan: 2 },\n];\n\nexport function HiringInterviewsPagePage() {\n const { showToast } = useGlobalUi();\n const { interviews, candidates, addInterview, updateInterview } = useCrewFoundryStore();\n const [scheduleOpen, setScheduleOpen] = useState(false);\n const [updateTarget, setUpdateTarget] = useState<Interview | null>(null);\n\n const scheduled = interviews.filter((i) => i.status === 'scheduled');\n const completed = interviews.filter((i) => i.status === 'completed');\n\n // Interviews dated within the current calendar week (Mon–Sun).\n const thisWeekCount = useMemo(() => {\n const now = new Date();\n const startOfWeek = new Date(now);\n startOfWeek.setDate(now.getDate() - ((now.getDay() + 6) % 7));\n startOfWeek.setHours(0, 0, 0, 0);\n const endOfWeek = new Date(startOfWeek);\n endOfWeek.setDate(startOfWeek.getDate() + 7);\n return interviews.filter((i) => {\n const date = new Date(i.date);\n return !Number.isNaN(date.getTime()) && date >= startOfWeek && date < endOfWeek;\n }).length;\n }, [interviews]);\n\n const scheduleFields = useMemo<FieldConfig[]>(\n () => [\n {\n name: 'candidateId',\n label: 'Candidate',\n type: 'select',\n required: true,\n placeholder: candidates.length ? 'Select a candidate…' : 'No candidates available',\n options: candidates.map((c) => ({\n label: `${c.firstName} ${c.lastName} — ${c.position}`,\n value: c.id,\n })),\n },\n { name: 'interviewerName', label: 'Interviewer', type: 'text', required: true },\n { name: 'date', label: 'Date', type: 'date', required: true },\n { name: 'time', label: 'Time', type: 'text', required: true, placeholder: 'e.g. 10:30 AM' },\n {\n name: 'type',\n label: 'Type',\n type: 'select',\n required: true,\n options: INTERVIEW_TYPE_OPTIONS,\n },\n ],\n [candidates]\n );\n\n const handleSchedule = async (values: FormValues) => {\n const candidate = candidates.find((c) => c.id === getText(values, 'candidateId'));\n if (!candidate) {\n throw new Error('Please select a candidate');\n }\n await addInterview({\n id: newClientId(),\n candidateId: candidate.id,\n candidateName: `${candidate.firstName} ${candidate.lastName}`,\n position: candidate.position,\n interviewerName: getText(values, 'interviewerName'),\n date: getText(values, 'date'),\n time: getText(values, 'time'),\n type: values.type as Interview['type'],\n status: 'scheduled',\n });\n showToast('Interview scheduled', 'success');\n };\n\n const handleUpdate = async (values: FormValues) => {\n if (!updateTarget) {\n return;\n }\n const ratingRaw = values.rating;\n const hasRating =\n typeof ratingRaw === 'number' || (typeof ratingRaw === 'string' && ratingRaw.trim() !== '');\n await updateInterview(updateTarget.id, {\n status: values.status as Interview['status'],\n feedback: getText(values, 'feedback'),\n ...(hasRating ? { rating: Number(ratingRaw) } : {}),\n });\n showToast('Interview updated', 'success');\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>Interviews</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">\n {scheduled.length} upcoming · {completed.length} completed\n </p>\n <PagePurpose className=\"mt-1\">\n Schedule and track interviews across your hiring pipeline — keep everyone aligned on\n who&apos;s meeting which candidate and when.\n </PagePurpose>\n </div>\n <Button size=\"sm\" onClick={() => setScheduleOpen(true)}>\n <Plus className=\"h-4 w-4 mr-1\" />\n Schedule Interview\n </Button>\n </div>\n\n <div className=\"grid gap-4 md:grid-cols-3\">\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\">Scheduled</CardTitle>\n <Calendar className=\"h-4 w-4 text-status-info-text\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">{scheduled.length}</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\">Completed</CardTitle>\n <Clock className=\"h-4 w-4 text-status-success-text\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">{completed.length}</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\">This Week</CardTitle>\n <Video className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">{thisWeekCount}</div>\n </CardContent>\n </GlassCard>\n </div>\n\n <Card>\n <CardHeader>\n <CardTitle>Upcoming Interviews</CardTitle>\n <CardDescription>Scheduled interviews for the coming days</CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n {scheduled.map((interview) => (\n <div\n key={interview.id}\n className=\"flex flex-wrap items-center justify-between gap-3 rounded border p-4\"\n >\n <div>\n <p className=\"text-sm font-medium\">{interview.candidateName}</p>\n <p className=\"text-xs text-text-secondary\">{interview.position}</p>\n <p className=\"text-xs text-text-secondary mt-1\">\n Interviewer: {interview.interviewerName}\n </p>\n </div>\n <div className=\"flex items-center gap-3\">\n <div className=\"text-right\">\n <p className=\"text-sm font-medium\">{interview.date}</p>\n <p className=\"text-xs text-text-secondary\">{interview.time}</p>\n </div>\n <Badge variant=\"outline\">{interview.type}</Badge>\n <Badge variant=\"secondary\">{interview.status}</Badge>\n <Button variant=\"outline\" size=\"sm\" onClick={() => setUpdateTarget(interview)}>\n Record outcome\n </Button>\n </div>\n </div>\n ))}\n </CardContent>\n </Card>\n\n {completed.length > 0 && (\n <Card>\n <CardHeader>\n <CardTitle>Completed Interviews</CardTitle>\n <CardDescription>Recent interview feedback</CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n {completed.map((interview) => (\n <div\n key={interview.id}\n className=\"flex flex-wrap items-center justify-between gap-3 rounded border p-4\"\n >\n <div>\n <p className=\"text-sm font-medium\">{interview.candidateName}</p>\n <p className=\"text-xs text-text-secondary\">{interview.position}</p>\n {interview.feedback && (\n <p className=\"text-xs text-text-secondary mt-1 italic\">\n &quot;{interview.feedback}&quot;\n </p>\n )}\n </div>\n <div className=\"flex items-center gap-3\">\n {interview.rating && (\n <div className=\"flex items-center gap-1\">\n <Star className=\"h-4 w-4 text-status-warning-text\" />\n <span className=\"text-sm font-medium\">{interview.rating}/5</span>\n </div>\n )}\n <Badge variant=\"default\">completed</Badge>\n </div>\n </div>\n ))}\n </CardContent>\n </Card>\n )}\n\n <FormModal\n open={scheduleOpen}\n onOpenChange={setScheduleOpen}\n title=\"Schedule Interview\"\n description=\"Set up a conversation with a candidate in your pipeline.\"\n fields={scheduleFields}\n submitLabel=\"Schedule\"\n onSubmit={handleSchedule}\n />\n <FormModal\n open={updateTarget !== null}\n onOpenChange={(open) => {\n if (!open) {\n setUpdateTarget(null);\n }\n }}\n title=\"Record Interview Outcome\"\n description={\n updateTarget ? `${updateTarget.candidateName} — ${updateTarget.position}` : undefined\n }\n fields={UPDATE_FIELDS}\n initialValues={\n updateTarget\n ? {\n status: updateTarget.status,\n rating: updateTarget.rating ?? '',\n feedback: updateTarget.feedback ?? '',\n }\n : undefined\n }\n submitLabel=\"Save outcome\"\n onSubmit={handleUpdate}\n />\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"HiringInterviewsPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/HiringInterviewsPagePage.tsx"],"sourcesContent":["import { useMemo, useState } from 'react';\nimport {\n Badge,\n Button,\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n GlassCard,\n GradientText,\n PagePurpose,\n} from '@burdenoff/fe-libs/ui';\nimport { useGlobalUi } from '@burdenoff/fe-libs/shared/providers/shell';\nimport { Calendar, Clock, Plus, Star, Video } from 'lucide-react';\nimport { useCrewFoundryStore, type Interview } from '../store/crewfoundryStore';\nimport { FormModal, type FieldConfig, type FormValues } from '../components/forms/FormModal';\nimport { getText, newClientId } from '../components/forms/formValues';\nimport { formatEnumLabel } from '../utils/formatEnumLabel';\n\nconst INTERVIEW_TYPE_OPTIONS: FieldConfig['options'] = [\n { label: 'Phone', value: 'phone' },\n { label: 'Video', value: 'video' },\n { label: 'Onsite', value: 'onsite' },\n { label: 'Panel', value: 'panel' },\n { label: 'Technical', value: 'technical' },\n];\n\nconst INTERVIEW_STATUS_OPTIONS: FieldConfig['options'] = [\n { label: 'Scheduled', value: 'scheduled' },\n { label: 'Completed', value: 'completed' },\n { label: 'Cancelled', value: 'cancelled' },\n { label: 'No show', value: 'no_show' },\n];\n\nconst UPDATE_FIELDS: FieldConfig[] = [\n {\n name: 'status',\n label: 'Status',\n type: 'select',\n options: INTERVIEW_STATUS_OPTIONS,\n required: true,\n },\n { name: 'rating', label: 'Rating (out of 5)', type: 'number' },\n { name: 'feedback', label: 'Feedback', type: 'textarea', colSpan: 2 },\n];\n\nexport function HiringInterviewsPagePage() {\n const { showToast } = useGlobalUi();\n const { interviews, candidates, addInterview, updateInterview } = useCrewFoundryStore();\n const [scheduleOpen, setScheduleOpen] = useState(false);\n const [updateTarget, setUpdateTarget] = useState<Interview | null>(null);\n\n const scheduled = interviews.filter((i) => i.status === 'scheduled');\n const completed = interviews.filter((i) => i.status === 'completed');\n\n // Interviews dated within the current calendar week (Mon–Sun).\n const thisWeekCount = useMemo(() => {\n const now = new Date();\n const startOfWeek = new Date(now);\n startOfWeek.setDate(now.getDate() - ((now.getDay() + 6) % 7));\n startOfWeek.setHours(0, 0, 0, 0);\n const endOfWeek = new Date(startOfWeek);\n endOfWeek.setDate(startOfWeek.getDate() + 7);\n return interviews.filter((i) => {\n const date = new Date(i.date);\n return !Number.isNaN(date.getTime()) && date >= startOfWeek && date < endOfWeek;\n }).length;\n }, [interviews]);\n\n const scheduleFields = useMemo<FieldConfig[]>(\n () => [\n {\n name: 'candidateId',\n label: 'Candidate',\n type: 'select',\n required: true,\n placeholder: candidates.length ? 'Select a candidate…' : 'No candidates available',\n options: candidates.map((c) => ({\n label: `${c.firstName} ${c.lastName} — ${c.position}`,\n value: c.id,\n })),\n },\n { name: 'interviewerName', label: 'Interviewer', type: 'text', required: true },\n { name: 'date', label: 'Date', type: 'date', required: true },\n { name: 'time', label: 'Time', type: 'text', required: true, placeholder: 'e.g. 10:30 AM' },\n {\n name: 'type',\n label: 'Type',\n type: 'select',\n required: true,\n options: INTERVIEW_TYPE_OPTIONS,\n },\n ],\n [candidates]\n );\n\n const handleSchedule = async (values: FormValues) => {\n const candidate = candidates.find((c) => c.id === getText(values, 'candidateId'));\n if (!candidate) {\n throw new Error('Please select a candidate');\n }\n await addInterview({\n id: newClientId(),\n candidateId: candidate.id,\n candidateName: `${candidate.firstName} ${candidate.lastName}`,\n position: candidate.position,\n interviewerName: getText(values, 'interviewerName'),\n date: getText(values, 'date'),\n time: getText(values, 'time'),\n type: values.type as Interview['type'],\n status: 'scheduled',\n });\n showToast('Interview scheduled', 'success');\n };\n\n const handleUpdate = async (values: FormValues) => {\n if (!updateTarget) {\n return;\n }\n const ratingRaw = values.rating;\n const hasRating =\n typeof ratingRaw === 'number' || (typeof ratingRaw === 'string' && ratingRaw.trim() !== '');\n await updateInterview(updateTarget.id, {\n status: values.status as Interview['status'],\n feedback: getText(values, 'feedback'),\n ...(hasRating ? { rating: Number(ratingRaw) } : {}),\n });\n showToast('Interview updated', 'success');\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>Interviews</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">\n {scheduled.length} upcoming · {completed.length} completed\n </p>\n <PagePurpose className=\"mt-1\">\n Schedule and track interviews across your hiring pipeline — keep everyone aligned on\n who&apos;s meeting which candidate and when.\n </PagePurpose>\n </div>\n <Button size=\"sm\" onClick={() => setScheduleOpen(true)}>\n <Plus className=\"h-4 w-4 mr-1\" />\n Schedule Interview\n </Button>\n </div>\n\n <div className=\"grid gap-4 md:grid-cols-3\">\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\">Scheduled</CardTitle>\n <Calendar className=\"h-4 w-4 text-status-info-text\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">{scheduled.length}</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\">Completed</CardTitle>\n <Clock className=\"h-4 w-4 text-status-success-text\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">{completed.length}</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\">This Week</CardTitle>\n <Video className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">{thisWeekCount}</div>\n </CardContent>\n </GlassCard>\n </div>\n\n <Card>\n <CardHeader>\n <CardTitle>Upcoming Interviews</CardTitle>\n <CardDescription>Scheduled interviews for the coming days</CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n {scheduled.map((interview) => (\n <div\n key={interview.id}\n className=\"flex flex-wrap items-center justify-between gap-3 rounded border p-4\"\n >\n <div>\n <p className=\"text-sm font-medium\">{interview.candidateName}</p>\n <p className=\"text-xs text-text-secondary\">{interview.position}</p>\n <p className=\"text-xs text-text-secondary mt-1\">\n Interviewer: {interview.interviewerName}\n </p>\n </div>\n <div className=\"flex items-center gap-3\">\n <div className=\"text-right\">\n <p className=\"text-sm font-medium\">{interview.date}</p>\n <p className=\"text-xs text-text-secondary\">{interview.time}</p>\n </div>\n <Badge variant=\"outline\">{formatEnumLabel(interview.type)}</Badge>\n <Badge variant=\"secondary\">{formatEnumLabel(interview.status)}</Badge>\n <Button variant=\"outline\" size=\"sm\" onClick={() => setUpdateTarget(interview)}>\n Record outcome\n </Button>\n </div>\n </div>\n ))}\n </CardContent>\n </Card>\n\n {completed.length > 0 && (\n <Card>\n <CardHeader>\n <CardTitle>Completed Interviews</CardTitle>\n <CardDescription>Recent interview feedback</CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n {completed.map((interview) => (\n <div\n key={interview.id}\n className=\"flex flex-wrap items-center justify-between gap-3 rounded border p-4\"\n >\n <div>\n <p className=\"text-sm font-medium\">{interview.candidateName}</p>\n <p className=\"text-xs text-text-secondary\">{interview.position}</p>\n {interview.feedback && (\n <p className=\"text-xs text-text-secondary mt-1 italic\">\n &quot;{interview.feedback}&quot;\n </p>\n )}\n </div>\n <div className=\"flex items-center gap-3\">\n {interview.rating && (\n <div className=\"flex items-center gap-1\">\n <Star className=\"h-4 w-4 text-status-warning-text\" />\n <span className=\"text-sm font-medium\">{interview.rating}/5</span>\n </div>\n )}\n <Badge variant=\"default\">completed</Badge>\n </div>\n </div>\n ))}\n </CardContent>\n </Card>\n )}\n\n <FormModal\n open={scheduleOpen}\n onOpenChange={setScheduleOpen}\n title=\"Schedule Interview\"\n description=\"Set up a conversation with a candidate in your pipeline.\"\n fields={scheduleFields}\n submitLabel=\"Schedule\"\n onSubmit={handleSchedule}\n />\n <FormModal\n open={updateTarget !== null}\n onOpenChange={(open) => {\n if (!open) {\n setUpdateTarget(null);\n }\n }}\n title=\"Record Interview Outcome\"\n description={\n updateTarget ? `${updateTarget.candidateName} — ${updateTarget.position}` : undefined\n }\n fields={UPDATE_FIELDS}\n initialValues={\n updateTarget\n ? {\n status: updateTarget.status,\n rating: updateTarget.rating ?? '',\n feedback: updateTarget.feedback ?? '',\n }\n : undefined\n }\n submitLabel=\"Save outcome\"\n onSubmit={handleUpdate}\n />\n </div>\n );\n}\n"],"mappings":"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"}