@burdenoff/microfe-crewfoundry 2026.703.1 → 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.
- package/dist/crewfoundry/pages/AdminAdminPagePage.js +117 -164
- package/dist/crewfoundry/pages/AdminAdminPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/AnalyticsAnalyticsPagePage.js +99 -82
- package/dist/crewfoundry/pages/AnalyticsAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/AnalyticsEmployeeAnalyticsPagePage.js +160 -192
- package/dist/crewfoundry/pages/AnalyticsEmployeeAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/AnalyticsFinancialAnalyticsPagePage.js +238 -231
- package/dist/crewfoundry/pages/AnalyticsFinancialAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/AnalyticsHiringAnalyticsPagePage.js +196 -166
- package/dist/crewfoundry/pages/AnalyticsHiringAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CommunicationsCallsPagePage.js +45 -147
- package/dist/crewfoundry/pages/CommunicationsCallsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CommunicationsDirectoryPagePage.js +20 -11
- package/dist/crewfoundry/pages/CommunicationsDirectoryPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CommunicationsFilesPagePage.js +45 -152
- package/dist/crewfoundry/pages/CommunicationsFilesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CommunicationsMessagesPagePage.js +50 -138
- package/dist/crewfoundry/pages/CommunicationsMessagesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CommunicationsTeamsPagePage.js +149 -67
- package/dist/crewfoundry/pages/CommunicationsTeamsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CommunicationsVideoCallsPagePage.js +50 -201
- package/dist/crewfoundry/pages/CommunicationsVideoCallsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CompanyClientManagementPagePage.js +205 -136
- package/dist/crewfoundry/pages/CompanyClientManagementPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CompanyCompanyDashboardPagePage.js +25 -31
- package/dist/crewfoundry/pages/CompanyCompanyDashboardPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CompanyCompanyProfilePagePage.js +118 -104
- package/dist/crewfoundry/pages/CompanyCompanyProfilePagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CompanyVendorManagementPagePage.js +117 -58
- package/dist/crewfoundry/pages/CompanyVendorManagementPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/DashboardAnalyticsPagePage.js +90 -94
- package/dist/crewfoundry/pages/DashboardAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/DashboardDashboardPagePage.js +210 -191
- package/dist/crewfoundry/pages/DashboardDashboardPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/DashboardEnhancedDashboardPagePage.js +213 -180
- package/dist/crewfoundry/pages/DashboardEnhancedDashboardPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/DashboardExecutiveDashboardPage.js +133 -264
- package/dist/crewfoundry/pages/DashboardExecutiveDashboardPage.js.map +1 -1
- package/dist/crewfoundry/pages/HelpApiDocumentationPagePage.js +279 -212
- package/dist/crewfoundry/pages/HelpApiDocumentationPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringApplicationsPagePage.js +131 -105
- package/dist/crewfoundry/pages/HiringApplicationsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringCandidatesPagePage.js +167 -148
- package/dist/crewfoundry/pages/HiringCandidatesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringCreateJobPagePage.js +3 -3
- package/dist/crewfoundry/pages/HiringCreateJobPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringInterviewsPagePage.js +13 -5
- package/dist/crewfoundry/pages/HiringInterviewsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringJobDetailsPagePage.js +151 -152
- package/dist/crewfoundry/pages/HiringJobDetailsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringJobsPagePage.js +38 -21
- package/dist/crewfoundry/pages/HiringJobsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrDepartmentsPagePage.js +3 -3
- package/dist/crewfoundry/pages/HrDepartmentsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrEmployeesPagePage.js +134 -127
- package/dist/crewfoundry/pages/HrEmployeesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrLeaveManagementPagePage.js +163 -132
- package/dist/crewfoundry/pages/HrLeaveManagementPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrPayrollPagePage.js +202 -160
- package/dist/crewfoundry/pages/HrPayrollPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrTimeTrackingPagePage.js +104 -91
- package/dist/crewfoundry/pages/HrTimeTrackingPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningAssessmentsPagePage.js +29 -147
- package/dist/crewfoundry/pages/LearningAssessmentsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningCertificatesPagePage.js +22 -106
- package/dist/crewfoundry/pages/LearningCertificatesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningCourseDetailsPagePage.js +74 -74
- package/dist/crewfoundry/pages/LearningCourseDetailsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningCourseLearningPagePage.js +101 -97
- package/dist/crewfoundry/pages/LearningCourseLearningPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningCoursesPagePage.js +64 -47
- package/dist/crewfoundry/pages/LearningCoursesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningLearningAnalyticsPagePage.js +111 -121
- package/dist/crewfoundry/pages/LearningLearningAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningLearningPagePage.js +131 -110
- package/dist/crewfoundry/pages/LearningLearningPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningLearningPathDetailPagePage.js +65 -64
- package/dist/crewfoundry/pages/LearningLearningPathDetailPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningLearningPathsPagePage.js +58 -43
- package/dist/crewfoundry/pages/LearningLearningPathsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningMyLearningPagePage.js +66 -82
- package/dist/crewfoundry/pages/LearningMyLearningPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceBookingManagementPagePage.js +38 -88
- package/dist/crewfoundry/pages/MarketplaceBookingManagementPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceEarningsPagePage.js +59 -65
- package/dist/crewfoundry/pages/MarketplaceEarningsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceFreelancerProfilePageEnhancedPage.js +209 -323
- package/dist/crewfoundry/pages/MarketplaceFreelancerProfilePageEnhancedPage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceFreelancerProfilePagePage.js +175 -220
- package/dist/crewfoundry/pages/MarketplaceFreelancerProfilePagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceMarketplacePagePage.js +74 -59
- package/dist/crewfoundry/pages/MarketplaceMarketplacePagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceMarketplaceServicesPagePage.js +96 -80
- package/dist/crewfoundry/pages/MarketplaceMarketplaceServicesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceMessagingPagePage.js +28 -100
- package/dist/crewfoundry/pages/MarketplaceMessagingPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceMyServicesPagePage.js +27 -20
- package/dist/crewfoundry/pages/MarketplaceMyServicesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceProjectDetailsPagePage.js +73 -73
- package/dist/crewfoundry/pages/MarketplaceProjectDetailsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceServiceDetailsPagePage.js +62 -56
- package/dist/crewfoundry/pages/MarketplaceServiceDetailsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/PaymentsEscrowPagePage.js +40 -138
- package/dist/crewfoundry/pages/PaymentsEscrowPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/PaymentsInvoicesPagePage.js +126 -93
- package/dist/crewfoundry/pages/PaymentsInvoicesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/PaymentsPaymentDashboardPagePage.js +99 -77
- package/dist/crewfoundry/pages/PaymentsPaymentDashboardPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/PaymentsSecurityPagePage.js +73 -74
- package/dist/crewfoundry/pages/PaymentsSecurityPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/ProjectsCreateProjectPagePage.js +1 -1
- package/dist/crewfoundry/pages/ProjectsCreateProjectPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/ProjectsProjectDetailsPagePage.js +122 -122
- package/dist/crewfoundry/pages/ProjectsProjectDetailsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/ProjectsProjectsPagePage.js +130 -113
- package/dist/crewfoundry/pages/ProjectsProjectsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/TeamsTeamAnalyticsPagePage.js +68 -59
- package/dist/crewfoundry/pages/TeamsTeamAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/TeamsTeamDetailPagePage.js +73 -62
- package/dist/crewfoundry/pages/TeamsTeamDetailPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/TeamsTeamDirectoryPagePage.js +82 -58
- package/dist/crewfoundry/pages/TeamsTeamDirectoryPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/TeamsTeamSettingsPagePage.js +153 -153
- package/dist/crewfoundry/pages/TeamsTeamSettingsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/TeamsTeamsPagePage.js +63 -48
- package/dist/crewfoundry/pages/TeamsTeamsPagePage.js.map +1 -1
- package/dist/crewfoundry/store/crewfoundryStore.js +35 -3
- package/dist/crewfoundry/store/crewfoundryStore.js.map +1 -1
- package/package.json +1 -1
|
@@ -66,7 +66,15 @@ var w = [
|
|
|
66
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
|
+
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(() => {
|
|
70
|
+
let e = /* @__PURE__ */ new Date(), t = new Date(e);
|
|
71
|
+
t.setDate(e.getDate() - (e.getDay() + 6) % 7), t.setHours(0, 0, 0, 0);
|
|
72
|
+
let n = new Date(t);
|
|
73
|
+
return n.setDate(t.getDate() + 7), D.filter((e) => {
|
|
74
|
+
let r = new Date(e.date);
|
|
75
|
+
return !Number.isNaN(r.getTime()) && r >= t && r < n;
|
|
76
|
+
}).length;
|
|
77
|
+
}, [D]), R = i(() => [
|
|
70
78
|
{
|
|
71
79
|
name: "candidateId",
|
|
72
80
|
label: "Candidate",
|
|
@@ -177,7 +185,7 @@ function E() {
|
|
|
177
185
|
}), /* @__PURE__ */ d(u, { className: "h-4 w-4 text-text-secondary" })]
|
|
178
186
|
}), /* @__PURE__ */ d(g, { children: /* @__PURE__ */ d("div", {
|
|
179
187
|
className: "text-2xl font-bold tabular-nums",
|
|
180
|
-
children:
|
|
188
|
+
children: L
|
|
181
189
|
}) })]
|
|
182
190
|
})
|
|
183
191
|
]
|
|
@@ -185,7 +193,7 @@ function E() {
|
|
|
185
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, {
|
|
186
194
|
className: "space-y-3",
|
|
187
195
|
children: F.map((e) => /* @__PURE__ */ f("div", {
|
|
188
|
-
className: "flex items-center justify-between rounded border p-4",
|
|
196
|
+
className: "flex flex-wrap items-center justify-between gap-3 rounded border p-4",
|
|
189
197
|
children: [/* @__PURE__ */ f("div", { children: [
|
|
190
198
|
/* @__PURE__ */ d("p", {
|
|
191
199
|
className: "text-sm font-medium",
|
|
@@ -233,7 +241,7 @@ function E() {
|
|
|
233
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, {
|
|
234
242
|
className: "space-y-3",
|
|
235
243
|
children: I.map((e) => /* @__PURE__ */ f("div", {
|
|
236
|
-
className: "flex items-center justify-between rounded border p-4",
|
|
244
|
+
className: "flex flex-wrap items-center justify-between gap-3 rounded border p-4",
|
|
237
245
|
children: [/* @__PURE__ */ f("div", { children: [
|
|
238
246
|
/* @__PURE__ */ d("p", {
|
|
239
247
|
className: "text-sm font-medium",
|
|
@@ -271,7 +279,7 @@ function E() {
|
|
|
271
279
|
onOpenChange: M,
|
|
272
280
|
title: "Schedule Interview",
|
|
273
281
|
description: "Set up a conversation with a candidate in your pipeline.",
|
|
274
|
-
fields:
|
|
282
|
+
fields: R,
|
|
275
283
|
submitLabel: "Schedule",
|
|
276
284
|
onSubmit: async (e) => {
|
|
277
285
|
let t = O.find((t) => t.id === n(e, "candidateId"));
|
|
@@ -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 { name: 'status', label: 'Status', type: 'select', options: INTERVIEW_STATUS_OPTIONS, required: true },\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 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 { name: 'type', label: 'Type', type: 'select', required: true, options: INTERVIEW_TYPE_OPTIONS },\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' ||\n (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\">Schedule and track interviews across your hiring pipeline — keep everyone aligned on who's meeting which candidate and when.</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\">{scheduled.length}</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 items-center justify-between 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\n variant=\"outline\"\n size=\"sm\"\n onClick={() => setUpdateTarget(interview)}\n >\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 items-center justify-between 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 "{interview.feedback}"\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={updateTarget ? `${updateTarget.candidateName} — ${updateTarget.position}` : undefined}\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';\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 { name: 'status', label: 'Status', type: 'select', options: INTERVIEW_STATUS_OPTIONS, required: true },\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 { name: 'type', label: 'Type', type: 'select', required: true, options: INTERVIEW_TYPE_OPTIONS },\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' ||\n (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\">Schedule and track interviews across your hiring pipeline — keep everyone aligned on who's meeting which candidate and when.</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\n variant=\"outline\"\n size=\"sm\"\n onClick={() => setUpdateTarget(interview)}\n >\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 "{interview.feedback}"\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={updateTarget ? `${updateTarget.candidateName} — ${updateTarget.position}` : undefined}\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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"}
|
|
@@ -4,12 +4,12 @@ import { ConfirmDialog as n } from "../components/forms/ConfirmDialog.js";
|
|
|
4
4
|
import { getNumber as r, getTags as i, getText as a } from "../components/forms/formValues.js";
|
|
5
5
|
import { useState as o } from "react";
|
|
6
6
|
import { Briefcase as s, Calendar as c, CheckCircle as l, DollarSign as u, MapPin as d, Pencil as f, Share2 as p, Trash2 as m, Users as h } from "lucide-react";
|
|
7
|
-
import { useNavigate as g } from "react-router-dom";
|
|
8
|
-
import { jsx as
|
|
9
|
-
import { Badge as
|
|
10
|
-
import { useGlobalUi as
|
|
7
|
+
import { useNavigate as g, useSearchParams as _ } from "react-router-dom";
|
|
8
|
+
import { jsx as v, jsxs as y } from "react/jsx-runtime";
|
|
9
|
+
import { Badge as b, Button as x, Card as S, CardContent as C, CardDescription as w, CardHeader as T, CardTitle as E, GlassCard as D, GradientText as O, IllustratedEmptyState as k, NextSteps as A, PagePurpose as j, ResponsiveTable as M } from "@burdenoff/fe-libs/ui";
|
|
10
|
+
import { useGlobalUi as N } from "@burdenoff/fe-libs/shared/providers/shell";
|
|
11
11
|
//#region src/crewfoundry/pages/HiringJobDetailsPagePage.tsx
|
|
12
|
-
var
|
|
12
|
+
var P = [
|
|
13
13
|
{
|
|
14
14
|
name: "title",
|
|
15
15
|
label: "Job Title",
|
|
@@ -137,188 +137,233 @@ var M = [
|
|
|
137
137
|
label: "Benefits",
|
|
138
138
|
type: "tags"
|
|
139
139
|
}
|
|
140
|
+
], F = [
|
|
141
|
+
{
|
|
142
|
+
key: "name",
|
|
143
|
+
header: "Name",
|
|
144
|
+
priority: "primary",
|
|
145
|
+
cell: (e) => /* @__PURE__ */ y("span", {
|
|
146
|
+
className: "font-medium",
|
|
147
|
+
children: [
|
|
148
|
+
e.firstName,
|
|
149
|
+
" ",
|
|
150
|
+
e.lastName
|
|
151
|
+
]
|
|
152
|
+
})
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
key: "source",
|
|
156
|
+
header: "Source",
|
|
157
|
+
priority: "secondary",
|
|
158
|
+
cell: (e) => /* @__PURE__ */ v("span", {
|
|
159
|
+
className: "text-text-secondary",
|
|
160
|
+
children: e.source
|
|
161
|
+
})
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
key: "experience",
|
|
165
|
+
header: "Experience",
|
|
166
|
+
priority: "secondary",
|
|
167
|
+
cell: (e) => /* @__PURE__ */ y("span", { children: [e.experience, " yrs"] })
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
key: "rating",
|
|
171
|
+
header: "Rating",
|
|
172
|
+
priority: "secondary",
|
|
173
|
+
cell: (e) => /* @__PURE__ */ y("span", { children: [e.rating, "/5"] })
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
key: "status",
|
|
177
|
+
header: "Status",
|
|
178
|
+
priority: "secondary",
|
|
179
|
+
cell: (e) => /* @__PURE__ */ v(b, {
|
|
180
|
+
variant: e.status === "hired" ? "default" : "secondary",
|
|
181
|
+
className: "text-[10px]",
|
|
182
|
+
children: e.status
|
|
183
|
+
})
|
|
184
|
+
}
|
|
140
185
|
];
|
|
141
|
-
function
|
|
142
|
-
let
|
|
143
|
-
if (!
|
|
186
|
+
function I() {
|
|
187
|
+
let I = g(), [L] = _(), { showToast: R } = N(), { jobPostings: z, candidates: B, updateJobPosting: V, removeJobPosting: H } = e(), U = L.get("id"), W = U ? z.find((e) => e.id === U) : z[0], [G, K] = o(!1), [q, J] = o(!1);
|
|
188
|
+
if (!W) return /* @__PURE__ */ v("div", {
|
|
144
189
|
className: "p-6",
|
|
145
|
-
children: /* @__PURE__ */
|
|
190
|
+
children: /* @__PURE__ */ v(k, {
|
|
146
191
|
illustration: "empty-search",
|
|
147
192
|
title: "No job posting found",
|
|
148
193
|
description: "This job posting is no longer available."
|
|
149
194
|
})
|
|
150
195
|
});
|
|
151
|
-
let
|
|
152
|
-
title:
|
|
153
|
-
department:
|
|
154
|
-
location:
|
|
155
|
-
type:
|
|
156
|
-
experienceLevel:
|
|
157
|
-
status:
|
|
158
|
-
salaryMin:
|
|
159
|
-
salaryMax:
|
|
160
|
-
deadline:
|
|
161
|
-
description:
|
|
162
|
-
requirements:
|
|
163
|
-
benefits:
|
|
196
|
+
let Y = B.filter((e) => e.position === W.title), X = {
|
|
197
|
+
title: W.title,
|
|
198
|
+
department: W.department,
|
|
199
|
+
location: W.location,
|
|
200
|
+
type: W.type,
|
|
201
|
+
experienceLevel: W.experienceLevel,
|
|
202
|
+
status: W.status,
|
|
203
|
+
salaryMin: W.salaryMin,
|
|
204
|
+
salaryMax: W.salaryMax,
|
|
205
|
+
deadline: W.deadline,
|
|
206
|
+
description: W.description,
|
|
207
|
+
requirements: W.requirements,
|
|
208
|
+
benefits: W.benefits
|
|
164
209
|
};
|
|
165
|
-
return /* @__PURE__ */
|
|
210
|
+
return /* @__PURE__ */ y("div", {
|
|
166
211
|
className: "space-y-6 p-6 max-w-4xl",
|
|
167
212
|
children: [
|
|
168
|
-
/* @__PURE__ */
|
|
213
|
+
/* @__PURE__ */ y("div", {
|
|
169
214
|
className: "flex items-center justify-between",
|
|
170
|
-
children: [/* @__PURE__ */
|
|
171
|
-
/* @__PURE__ */
|
|
215
|
+
children: [/* @__PURE__ */ y("div", { children: [
|
|
216
|
+
/* @__PURE__ */ y("div", {
|
|
172
217
|
className: "flex items-center gap-2 mb-1",
|
|
173
|
-
children: [/* @__PURE__ */
|
|
218
|
+
children: [/* @__PURE__ */ v("h1", {
|
|
174
219
|
className: "text-2xl font-semibold",
|
|
175
|
-
children: /* @__PURE__ */
|
|
176
|
-
}), /* @__PURE__ */
|
|
177
|
-
variant:
|
|
178
|
-
children:
|
|
220
|
+
children: /* @__PURE__ */ v(O, { children: W.title })
|
|
221
|
+
}), /* @__PURE__ */ v(b, {
|
|
222
|
+
variant: W.status === "active" ? "default" : "secondary",
|
|
223
|
+
children: W.status
|
|
179
224
|
})]
|
|
180
225
|
}),
|
|
181
|
-
/* @__PURE__ */
|
|
226
|
+
/* @__PURE__ */ y("div", {
|
|
182
227
|
className: "flex items-center gap-4 text-sm text-text-secondary",
|
|
183
228
|
children: [
|
|
184
|
-
/* @__PURE__ */
|
|
229
|
+
/* @__PURE__ */ y("span", {
|
|
185
230
|
className: "flex items-center gap-1",
|
|
186
|
-
children: [/* @__PURE__ */
|
|
231
|
+
children: [/* @__PURE__ */ v(s, { className: "h-3 w-3" }), W.department]
|
|
187
232
|
}),
|
|
188
|
-
/* @__PURE__ */
|
|
233
|
+
/* @__PURE__ */ y("span", {
|
|
189
234
|
className: "flex items-center gap-1",
|
|
190
|
-
children: [/* @__PURE__ */
|
|
235
|
+
children: [/* @__PURE__ */ v(d, { className: "h-3 w-3" }), W.location]
|
|
191
236
|
}),
|
|
192
|
-
/* @__PURE__ */
|
|
237
|
+
/* @__PURE__ */ y("span", {
|
|
193
238
|
className: "flex items-center gap-1",
|
|
194
239
|
children: [
|
|
195
|
-
/* @__PURE__ */
|
|
240
|
+
/* @__PURE__ */ v(c, { className: "h-3 w-3" }),
|
|
196
241
|
"Posted ",
|
|
197
|
-
|
|
242
|
+
W.postedDate
|
|
198
243
|
]
|
|
199
244
|
})
|
|
200
245
|
]
|
|
201
246
|
}),
|
|
202
|
-
/* @__PURE__ */
|
|
247
|
+
/* @__PURE__ */ v(j, {
|
|
203
248
|
className: "mt-2",
|
|
204
249
|
children: "Everything about this role in one place — review applicants, requirements, and compensation here to decide who to interview and keep the posting current."
|
|
205
250
|
})
|
|
206
|
-
] }), /* @__PURE__ */
|
|
251
|
+
] }), /* @__PURE__ */ y("div", {
|
|
207
252
|
className: "flex gap-2",
|
|
208
253
|
children: [
|
|
209
|
-
/* @__PURE__ */
|
|
254
|
+
/* @__PURE__ */ y(x, {
|
|
210
255
|
variant: "outline",
|
|
211
256
|
size: "sm",
|
|
212
|
-
onClick: () =>
|
|
213
|
-
children: [/* @__PURE__ */
|
|
257
|
+
onClick: () => R("Sharing job postings is coming soon", "info"),
|
|
258
|
+
children: [/* @__PURE__ */ v(p, { className: "h-4 w-4 mr-1" }), "Share"]
|
|
214
259
|
}),
|
|
215
|
-
/* @__PURE__ */
|
|
260
|
+
/* @__PURE__ */ y(x, {
|
|
216
261
|
variant: "outline",
|
|
217
262
|
size: "sm",
|
|
218
|
-
onClick: () =>
|
|
219
|
-
children: [/* @__PURE__ */
|
|
263
|
+
onClick: () => K(!0),
|
|
264
|
+
children: [/* @__PURE__ */ v(f, { className: "h-4 w-4 mr-1" }), "Edit Posting"]
|
|
220
265
|
}),
|
|
221
|
-
/* @__PURE__ */
|
|
266
|
+
/* @__PURE__ */ v(x, {
|
|
222
267
|
variant: "destructive",
|
|
223
268
|
size: "sm",
|
|
224
269
|
"aria-label": "Delete job posting",
|
|
225
|
-
onClick: () =>
|
|
226
|
-
children: /* @__PURE__ */
|
|
270
|
+
onClick: () => J(!0),
|
|
271
|
+
children: /* @__PURE__ */ v(m, { className: "h-4 w-4" })
|
|
227
272
|
})
|
|
228
273
|
]
|
|
229
274
|
})]
|
|
230
275
|
}),
|
|
231
|
-
/* @__PURE__ */
|
|
276
|
+
/* @__PURE__ */ v(A, {
|
|
232
277
|
storageKey: "crewfoundry-job-details",
|
|
233
278
|
steps: [
|
|
234
279
|
{
|
|
235
280
|
id: "applicants",
|
|
236
281
|
label: "Review applicants",
|
|
237
282
|
description: "Screen the candidates who applied for this role.",
|
|
238
|
-
icon: /* @__PURE__ */
|
|
239
|
-
onClick: () =>
|
|
283
|
+
icon: /* @__PURE__ */ v(h, { className: "h-4 w-4" }),
|
|
284
|
+
onClick: () => I("../../hiring/applications-page")
|
|
240
285
|
},
|
|
241
286
|
{
|
|
242
287
|
id: "interviews",
|
|
243
288
|
label: "Schedule interviews",
|
|
244
289
|
description: "Set up conversations with promising candidates.",
|
|
245
|
-
icon: /* @__PURE__ */
|
|
246
|
-
onClick: () =>
|
|
290
|
+
icon: /* @__PURE__ */ v(c, { className: "h-4 w-4" }),
|
|
291
|
+
onClick: () => I("../../hiring/interviews-page")
|
|
247
292
|
},
|
|
248
293
|
{
|
|
249
294
|
id: "candidates",
|
|
250
295
|
label: "Browse your talent pool",
|
|
251
296
|
description: "Source more candidates that fit this position.",
|
|
252
|
-
icon: /* @__PURE__ */
|
|
253
|
-
onClick: () =>
|
|
297
|
+
icon: /* @__PURE__ */ v(s, { className: "h-4 w-4" }),
|
|
298
|
+
onClick: () => I("../../hiring/candidates-page")
|
|
254
299
|
}
|
|
255
300
|
]
|
|
256
301
|
}),
|
|
257
|
-
/* @__PURE__ */
|
|
302
|
+
/* @__PURE__ */ y("div", {
|
|
258
303
|
className: "grid gap-4 md:grid-cols-4",
|
|
259
304
|
children: [
|
|
260
|
-
/* @__PURE__ */
|
|
305
|
+
/* @__PURE__ */ v(D, {
|
|
261
306
|
treatment: "glass",
|
|
262
307
|
glow: !0,
|
|
263
308
|
className: "border-border-seam",
|
|
264
|
-
children: /* @__PURE__ */
|
|
309
|
+
children: /* @__PURE__ */ y(C, {
|
|
265
310
|
className: "p-4 text-center",
|
|
266
311
|
children: [
|
|
267
|
-
/* @__PURE__ */
|
|
268
|
-
/* @__PURE__ */
|
|
312
|
+
/* @__PURE__ */ v(h, { className: "h-5 w-5 mx-auto text-text-secondary mb-1" }),
|
|
313
|
+
/* @__PURE__ */ v("p", {
|
|
269
314
|
className: "text-2xl font-bold tabular-nums",
|
|
270
|
-
children:
|
|
315
|
+
children: W.applicants
|
|
271
316
|
}),
|
|
272
|
-
/* @__PURE__ */
|
|
317
|
+
/* @__PURE__ */ v("p", {
|
|
273
318
|
className: "text-xs text-text-secondary",
|
|
274
319
|
children: "Applicants"
|
|
275
320
|
})
|
|
276
321
|
]
|
|
277
322
|
})
|
|
278
323
|
}),
|
|
279
|
-
/* @__PURE__ */
|
|
324
|
+
/* @__PURE__ */ v(S, { children: /* @__PURE__ */ y(C, {
|
|
280
325
|
className: "p-4 text-center",
|
|
281
326
|
children: [
|
|
282
|
-
/* @__PURE__ */
|
|
283
|
-
/* @__PURE__ */
|
|
327
|
+
/* @__PURE__ */ v(u, { className: "h-5 w-5 mx-auto text-text-secondary mb-1" }),
|
|
328
|
+
/* @__PURE__ */ y("p", {
|
|
284
329
|
className: "text-lg font-bold",
|
|
285
330
|
children: [
|
|
286
331
|
"$",
|
|
287
|
-
(
|
|
332
|
+
(W.salaryMin / 1e3).toFixed(0),
|
|
288
333
|
"K-$",
|
|
289
|
-
(
|
|
334
|
+
(W.salaryMax / 1e3).toFixed(0),
|
|
290
335
|
"K"
|
|
291
336
|
]
|
|
292
337
|
}),
|
|
293
|
-
/* @__PURE__ */
|
|
338
|
+
/* @__PURE__ */ v("p", {
|
|
294
339
|
className: "text-xs text-text-secondary",
|
|
295
340
|
children: "Salary Range"
|
|
296
341
|
})
|
|
297
342
|
]
|
|
298
343
|
}) }),
|
|
299
|
-
/* @__PURE__ */
|
|
344
|
+
/* @__PURE__ */ v(S, { children: /* @__PURE__ */ y(C, {
|
|
300
345
|
className: "p-4 text-center",
|
|
301
346
|
children: [
|
|
302
|
-
/* @__PURE__ */
|
|
303
|
-
/* @__PURE__ */
|
|
347
|
+
/* @__PURE__ */ v(c, { className: "h-5 w-5 mx-auto text-text-secondary mb-1" }),
|
|
348
|
+
/* @__PURE__ */ v("p", {
|
|
304
349
|
className: "text-lg font-bold",
|
|
305
|
-
children:
|
|
350
|
+
children: W.deadline
|
|
306
351
|
}),
|
|
307
|
-
/* @__PURE__ */
|
|
352
|
+
/* @__PURE__ */ v("p", {
|
|
308
353
|
className: "text-xs text-text-secondary",
|
|
309
354
|
children: "Deadline"
|
|
310
355
|
})
|
|
311
356
|
]
|
|
312
357
|
}) }),
|
|
313
|
-
/* @__PURE__ */
|
|
358
|
+
/* @__PURE__ */ v(S, { children: /* @__PURE__ */ y(C, {
|
|
314
359
|
className: "p-4 text-center",
|
|
315
360
|
children: [
|
|
316
|
-
/* @__PURE__ */
|
|
317
|
-
/* @__PURE__ */
|
|
361
|
+
/* @__PURE__ */ v(l, { className: "h-5 w-5 mx-auto text-text-secondary mb-1" }),
|
|
362
|
+
/* @__PURE__ */ v("p", {
|
|
318
363
|
className: "text-lg font-bold",
|
|
319
|
-
children:
|
|
364
|
+
children: W.experienceLevel
|
|
320
365
|
}),
|
|
321
|
-
/* @__PURE__ */
|
|
366
|
+
/* @__PURE__ */ v("p", {
|
|
322
367
|
className: "text-xs text-text-secondary",
|
|
323
368
|
children: "Level"
|
|
324
369
|
})
|
|
@@ -326,84 +371,38 @@ function N() {
|
|
|
326
371
|
}) })
|
|
327
372
|
]
|
|
328
373
|
}),
|
|
329
|
-
/* @__PURE__ */
|
|
374
|
+
/* @__PURE__ */ y(S, { children: [/* @__PURE__ */ v(T, { children: /* @__PURE__ */ v(E, { children: "Description" }) }), /* @__PURE__ */ v(C, { children: /* @__PURE__ */ v("p", {
|
|
330
375
|
className: "text-sm text-text-secondary",
|
|
331
|
-
children:
|
|
376
|
+
children: W.description
|
|
332
377
|
}) })] }),
|
|
333
|
-
/* @__PURE__ */
|
|
378
|
+
/* @__PURE__ */ y("div", {
|
|
334
379
|
className: "grid gap-4 md:grid-cols-2",
|
|
335
|
-
children: [/* @__PURE__ */
|
|
380
|
+
children: [/* @__PURE__ */ y(S, { children: [/* @__PURE__ */ v(T, { children: /* @__PURE__ */ v(E, { children: "Requirements" }) }), /* @__PURE__ */ v(C, { children: /* @__PURE__ */ v("ul", {
|
|
336
381
|
className: "space-y-2",
|
|
337
|
-
children:
|
|
382
|
+
children: W.requirements.map((e, t) => /* @__PURE__ */ y("li", {
|
|
338
383
|
className: "flex items-start gap-2 text-sm",
|
|
339
|
-
children: [/* @__PURE__ */
|
|
384
|
+
children: [/* @__PURE__ */ v(l, { className: "h-4 w-4 text-status-success-text mt-0.5 flex-shrink-0" }), e]
|
|
340
385
|
}, t))
|
|
341
|
-
}) })] }), /* @__PURE__ */
|
|
386
|
+
}) })] }), /* @__PURE__ */ y(S, { children: [/* @__PURE__ */ v(T, { children: /* @__PURE__ */ v(E, { children: "Benefits" }) }), /* @__PURE__ */ v(C, { children: /* @__PURE__ */ v("ul", {
|
|
342
387
|
className: "space-y-2",
|
|
343
|
-
children:
|
|
388
|
+
children: W.benefits.map((e, t) => /* @__PURE__ */ y("li", {
|
|
344
389
|
className: "flex items-start gap-2 text-sm",
|
|
345
|
-
children: [/* @__PURE__ */
|
|
390
|
+
children: [/* @__PURE__ */ v(l, { className: "h-4 w-4 text-status-info-text mt-0.5 flex-shrink-0" }), e]
|
|
346
391
|
}, t))
|
|
347
392
|
}) })] })]
|
|
348
393
|
}),
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
}),
|
|
358
|
-
/* @__PURE__ */ _("span", {
|
|
359
|
-
className: "text-center",
|
|
360
|
-
children: "Rating"
|
|
361
|
-
}),
|
|
362
|
-
/* @__PURE__ */ _("span", {
|
|
363
|
-
className: "text-center",
|
|
364
|
-
children: "Status"
|
|
365
|
-
})
|
|
366
|
-
]
|
|
367
|
-
}), W.map((e) => /* @__PURE__ */ v("div", {
|
|
368
|
-
className: "grid grid-cols-5 gap-2 py-2 border-b last:border-0 text-sm",
|
|
369
|
-
children: [
|
|
370
|
-
/* @__PURE__ */ v("span", {
|
|
371
|
-
className: "font-medium",
|
|
372
|
-
children: [
|
|
373
|
-
e.firstName,
|
|
374
|
-
" ",
|
|
375
|
-
e.lastName
|
|
376
|
-
]
|
|
377
|
-
}),
|
|
378
|
-
/* @__PURE__ */ _("span", {
|
|
379
|
-
className: "text-text-secondary",
|
|
380
|
-
children: e.source
|
|
381
|
-
}),
|
|
382
|
-
/* @__PURE__ */ v("span", {
|
|
383
|
-
className: "text-right",
|
|
384
|
-
children: [e.experience, " yrs"]
|
|
385
|
-
}),
|
|
386
|
-
/* @__PURE__ */ v("div", {
|
|
387
|
-
className: "text-center",
|
|
388
|
-
children: [e.rating, "/5"]
|
|
389
|
-
}),
|
|
390
|
-
/* @__PURE__ */ _("div", {
|
|
391
|
-
className: "text-center",
|
|
392
|
-
children: /* @__PURE__ */ _(y, {
|
|
393
|
-
variant: e.status === "hired" ? "default" : "secondary",
|
|
394
|
-
className: "text-[10px]",
|
|
395
|
-
children: e.status
|
|
396
|
-
})
|
|
397
|
-
})
|
|
398
|
-
]
|
|
399
|
-
}, e.id))] })] }),
|
|
400
|
-
/* @__PURE__ */ _(t, {
|
|
401
|
-
open: B,
|
|
402
|
-
onOpenChange: V,
|
|
394
|
+
Y.length > 0 && /* @__PURE__ */ y(S, { children: [/* @__PURE__ */ y(T, { children: [/* @__PURE__ */ v(E, { children: "Applicants for this Role" }), /* @__PURE__ */ y(w, { children: [Y.length, " candidates"] })] }), /* @__PURE__ */ v(C, { children: /* @__PURE__ */ v(M, {
|
|
395
|
+
data: Y,
|
|
396
|
+
rowKey: (e) => e.id,
|
|
397
|
+
columns: F
|
|
398
|
+
}) })] }),
|
|
399
|
+
/* @__PURE__ */ v(t, {
|
|
400
|
+
open: G,
|
|
401
|
+
onOpenChange: K,
|
|
403
402
|
title: "Edit Job Posting",
|
|
404
403
|
description: "Update the role details, compensation, and status.",
|
|
405
|
-
fields:
|
|
406
|
-
initialValues:
|
|
404
|
+
fields: P,
|
|
405
|
+
initialValues: X,
|
|
407
406
|
submitLabel: "Save changes",
|
|
408
407
|
onSubmit: async (e) => {
|
|
409
408
|
let t = {
|
|
@@ -420,24 +419,24 @@ function N() {
|
|
|
420
419
|
requirements: i(e, "requirements"),
|
|
421
420
|
benefits: i(e, "benefits")
|
|
422
421
|
};
|
|
423
|
-
await
|
|
422
|
+
await V(W.id, t), R("Job posting updated", "success");
|
|
424
423
|
}
|
|
425
424
|
}),
|
|
426
|
-
/* @__PURE__ */
|
|
427
|
-
open:
|
|
428
|
-
onOpenChange:
|
|
425
|
+
/* @__PURE__ */ v(n, {
|
|
426
|
+
open: q,
|
|
427
|
+
onOpenChange: J,
|
|
429
428
|
title: "Delete job posting",
|
|
430
|
-
description: `Permanently remove “${
|
|
429
|
+
description: `Permanently remove “${W.title}”? This cannot be undone.`,
|
|
431
430
|
confirmLabel: "Delete",
|
|
432
431
|
destructive: !0,
|
|
433
432
|
onConfirm: async () => {
|
|
434
|
-
await
|
|
433
|
+
await H(W.id), R("Job posting deleted", "success"), I("../jobs-page");
|
|
435
434
|
}
|
|
436
435
|
})
|
|
437
436
|
]
|
|
438
437
|
});
|
|
439
438
|
}
|
|
440
439
|
//#endregion
|
|
441
|
-
export {
|
|
440
|
+
export { I as HiringJobDetailsPagePage };
|
|
442
441
|
|
|
443
442
|
//# sourceMappingURL=HiringJobDetailsPagePage.js.map
|