@burdenoff/microfe-crewfoundry 2026.704.3 → 2026.704.5
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 +76 -75
- package/dist/crewfoundry/pages/AdminAdminPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/AnalyticsFinancialAnalyticsPagePage.js +118 -117
- package/dist/crewfoundry/pages/AnalyticsFinancialAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/AnalyticsHiringAnalyticsPagePage.js +115 -114
- package/dist/crewfoundry/pages/AnalyticsHiringAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CommunicationsAnnouncementsPagePage.js +105 -104
- package/dist/crewfoundry/pages/CommunicationsAnnouncementsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CommunicationsTeamsPagePage.js +52 -51
- package/dist/crewfoundry/pages/CommunicationsTeamsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CompanyClientManagementPagePage.js +94 -93
- package/dist/crewfoundry/pages/CompanyClientManagementPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CompanyCompanyProfilePagePage.js +97 -96
- package/dist/crewfoundry/pages/CompanyCompanyProfilePagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CompanyVendorManagementPagePage.js +68 -67
- package/dist/crewfoundry/pages/CompanyVendorManagementPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/DashboardAnalyticsPagePage.js +96 -95
- package/dist/crewfoundry/pages/DashboardAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/DashboardDashboardPagePage.js +153 -152
- package/dist/crewfoundry/pages/DashboardDashboardPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/DashboardEnhancedDashboardPagePage.js +111 -110
- package/dist/crewfoundry/pages/DashboardEnhancedDashboardPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringApplicationsPagePage.js +77 -76
- package/dist/crewfoundry/pages/HiringApplicationsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringCandidatesPagePage.js +80 -79
- package/dist/crewfoundry/pages/HiringCandidatesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringCreateJobPagePage.js +1 -1
- package/dist/crewfoundry/pages/HiringCreateJobPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringInterviewsPagePage.js +102 -101
- package/dist/crewfoundry/pages/HiringInterviewsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringJobDetailsPagePage.js +126 -125
- package/dist/crewfoundry/pages/HiringJobDetailsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringJobsPagePage.js +64 -63
- package/dist/crewfoundry/pages/HiringJobsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrDepartmentsPagePage.js +96 -95
- package/dist/crewfoundry/pages/HrDepartmentsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrLeaveManagementPagePage.js +129 -127
- package/dist/crewfoundry/pages/HrLeaveManagementPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrPayrollPagePage.js +118 -117
- package/dist/crewfoundry/pages/HrPayrollPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrTimeTrackingPagePage.js +123 -122
- package/dist/crewfoundry/pages/HrTimeTrackingPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningAssessmentsPagePage.js +1 -1
- package/dist/crewfoundry/pages/LearningAssessmentsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningCertificatesPagePage.js +1 -1
- package/dist/crewfoundry/pages/LearningCertificatesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningCourseDetailsPagePage.js +77 -76
- package/dist/crewfoundry/pages/LearningCourseDetailsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningCourseLearningPagePage.js +49 -48
- package/dist/crewfoundry/pages/LearningCourseLearningPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningCoursesPagePage.js +62 -61
- package/dist/crewfoundry/pages/LearningCoursesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningLearningPagePage.js +72 -71
- package/dist/crewfoundry/pages/LearningLearningPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningLearningPathDetailPagePage.js +70 -69
- package/dist/crewfoundry/pages/LearningLearningPathDetailPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningLearningPathsPagePage.js +57 -56
- package/dist/crewfoundry/pages/LearningLearningPathsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceEarningsPagePage.js +58 -57
- package/dist/crewfoundry/pages/MarketplaceEarningsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceFreelancerProfilePageEnhancedPage.js +122 -121
- package/dist/crewfoundry/pages/MarketplaceFreelancerProfilePageEnhancedPage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceFreelancerProfilePagePage.js +2 -2
- package/dist/crewfoundry/pages/MarketplaceFreelancerProfilePagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceMarketplacePagePage.js +70 -69
- package/dist/crewfoundry/pages/MarketplaceMarketplacePagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceMarketplaceServicesPagePage.js +41 -40
- package/dist/crewfoundry/pages/MarketplaceMarketplaceServicesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceMyServicesPagePage.js +65 -64
- package/dist/crewfoundry/pages/MarketplaceMyServicesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceProjectDetailsPagePage.js +75 -74
- package/dist/crewfoundry/pages/MarketplaceProjectDetailsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceServiceDetailsPagePage.js +4 -4
- package/dist/crewfoundry/pages/MarketplaceServiceDetailsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/PaymentsInvoicesPagePage.js +60 -59
- package/dist/crewfoundry/pages/PaymentsInvoicesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/PaymentsPaymentDashboardPagePage.js +53 -52
- package/dist/crewfoundry/pages/PaymentsPaymentDashboardPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/PaymentsPaymentMethodsPagePage.js +37 -36
- package/dist/crewfoundry/pages/PaymentsPaymentMethodsPagePage.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 +126 -125
- package/dist/crewfoundry/pages/ProjectsProjectDetailsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/ProjectsProjectsPagePage.js +62 -61
- package/dist/crewfoundry/pages/ProjectsProjectsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/TeamsTeamAnalyticsPagePage.js +50 -49
- package/dist/crewfoundry/pages/TeamsTeamAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/TeamsTeamDetailPagePage.js +72 -71
- package/dist/crewfoundry/pages/TeamsTeamDetailPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/TeamsTeamDirectoryPagePage.js +40 -39
- package/dist/crewfoundry/pages/TeamsTeamDirectoryPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/TeamsTeamSettingsPagePage.js +134 -133
- package/dist/crewfoundry/pages/TeamsTeamSettingsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/TeamsTeamsPagePage.js +60 -59
- package/dist/crewfoundry/pages/TeamsTeamsPagePage.js.map +1 -1
- package/dist/crewfoundry/store/crewfoundryStore.js +177 -146
- package/dist/crewfoundry/store/crewfoundryStore.js.map +1 -1
- package/dist/crewfoundry/utils/formatEnumLabel.js +8 -0
- package/dist/crewfoundry/utils/formatEnumLabel.js.map +1 -0
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HrDepartmentsPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/HrDepartmentsPagePage.tsx"],"sourcesContent":["import { 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 Separator,\n} from '@burdenoff/fe-libs/ui';\nimport { Building2, DollarSign, MapPin, Pencil, Plus, Trash2, Users } from 'lucide-react';\nimport { useCrewFoundryStore, type Department } from '../store/crewfoundryStore';\nimport {\n FormModal,\n useFormModal,\n type FieldConfig,\n type FormValues,\n} from '../components/forms/FormModal';\nimport { ConfirmDialog } from '../components/forms/ConfirmDialog';\nimport { getNumber, getText, newClientId } from '../components/forms/formValues';\n\nconst DEPARTMENT_FIELDS: FieldConfig[] = [\n { name: 'name', label: 'Department name', type: 'text', required: true, colSpan: 2 },\n { name: 'headName', label: 'Department head', type: 'text', required: true },\n { name: 'location', label: 'Location', type: 'text', required: true },\n { name: 'budget', label: 'Annual budget', type: 'number', required: true },\n {\n name: 'status',\n label: 'Status',\n type: 'select',\n required: true,\n options: [\n { label: 'Active', value: 'active' },\n { label: 'Restructuring', value: 'restructuring' },\n ],\n },\n];\n\nconst toFormValues = (department: Department): FormValues => ({\n name: department.name,\n headName: department.headName,\n location: department.location,\n budget: department.budget,\n status: department.status,\n});\n\nexport function HrDepartmentsPagePage() {\n const { departments, employees, addDepartment, updateDepartment, removeDepartment } =\n useCrewFoundryStore();\n const form = useFormModal<Department>();\n const [deleting, setDeleting] = useState<Department | null>(null);\n\n const totalBudget = departments.reduce((s, d) => s + d.budget, 0);\n const totalHeadcount = departments.reduce((s, d) => s + d.employeeCount, 0);\n\n const editing = form.context;\n\n const handleSubmit = async (values: FormValues) => {\n const payload: Department = {\n id: editing?.id ?? newClientId(),\n name: getText(values, 'name'),\n headId: editing?.headId ?? '',\n headName: getText(values, 'headName'),\n employeeCount: editing?.employeeCount ?? 0,\n budget: getNumber(values, 'budget'),\n location: getText(values, 'location'),\n status: getText(values, 'status') as Department['status'],\n };\n if (editing) {\n await updateDepartment(editing.id, payload);\n } else {\n await addDepartment(payload);\n }\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>Departments</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">\n Organizational structure and department management\n </p>\n <PagePurpose className=\"mt-1\">\n Organize your company into departments — set up structure, assign heads, and see how\n headcount is distributed across the org.\n </PagePurpose>\n </div>\n <Button size=\"sm\" onClick={() => form.openModal()}>\n <Plus className=\"h-4 w-4 mr-1\" />\n Add Department\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\">Total Departments</CardTitle>\n <Building2 className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">{departments.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\">Total Headcount</CardTitle>\n <Users className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">{totalHeadcount}</div>\n </CardContent>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"border-border-seam\">\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Total Budget</CardTitle>\n <DollarSign className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">\n ${(totalBudget / 1000000).toFixed(1)}M\n </div>\n </CardContent>\n </GlassCard>\n </div>\n\n <div className=\"grid gap-4 md:grid-cols-2\">\n {departments.map((dept) => {\n const deptEmps = employees.filter((e) => e.department === dept.name);\n const avgSalary =\n deptEmps.length > 0\n ? Math.round(deptEmps.reduce((s, e) => s + e.salary, 0) / deptEmps.length)\n : 0;\n const avgPerf =\n deptEmps.length > 0\n ? (deptEmps.reduce((s, e) => s + e.performanceScore, 0) / deptEmps.length).toFixed(1)\n : '0';\n\n return (\n <Card key={dept.id}>\n <CardHeader>\n <div className=\"flex items-center justify-between\">\n <CardTitle className=\"text-lg\">{dept.name}</CardTitle>\n <div className=\"flex items-center gap-1\">\n <Badge variant={dept.status === 'active' ? 'default' : 'secondary'}>\n {dept.status}\n </Badge>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-8 w-8 p-0\"\n aria-label={`Edit ${dept.name}`}\n onClick={() => form.openModal(dept)}\n >\n <Pencil className=\"h-4 w-4\" />\n </Button>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-8 w-8 p-0\"\n aria-label={`Delete ${dept.name}`}\n onClick={() => setDeleting(dept)}\n >\n <Trash2 className=\"h-4 w-4 text-status-error-text\" />\n </Button>\n </div>\n </div>\n <CardDescription className=\"flex items-center gap-1\">\n <MapPin className=\"h-3 w-3\" />\n {dept.location}\n </CardDescription>\n </CardHeader>\n <CardContent>\n <div className=\"grid grid-cols-2 gap-4 mb-4\">\n <div>\n <p className=\"text-xs text-text-secondary\">Department Head</p>\n <p className=\"text-sm font-medium\">{dept.headName}</p>\n </div>\n <div>\n <p className=\"text-xs text-text-secondary\">Headcount</p>\n <p className=\"text-sm font-medium\">{dept.employeeCount} employees</p>\n </div>\n <div>\n <p className=\"text-xs text-text-secondary\">Annual Budget</p>\n <p className=\"text-sm font-medium\">${(dept.budget / 1000000).toFixed(1)}M</p>\n </div>\n <div>\n <p className=\"text-xs text-text-secondary\">Avg Salary</p>\n <p className=\"text-sm font-medium\">${avgSalary.toLocaleString()}</p>\n </div>\n </div>\n <Separator className=\"mb-3\" />\n <div className=\"flex items-center justify-between text-xs\">\n <span className=\"text-text-secondary\">Avg Performance: {avgPerf}/5</span>\n <span className=\"text-text-secondary\">\n Cost/Head:{' '}\n {dept.employeeCount > 0\n ? `$${Math.round(dept.budget / dept.employeeCount / 1000)}K`\n : '—'}\n </span>\n </div>\n </CardContent>\n </Card>\n );\n })}\n </div>\n\n <FormModal\n open={form.open}\n onOpenChange={form.onOpenChange}\n title={editing ? 'Edit department' : 'Add department'}\n description={\n editing\n ? 'Update this department’s details.'\n : 'Create a new department in your organization.'\n }\n fields={DEPARTMENT_FIELDS}\n initialValues={editing ? toFormValues(editing) : undefined}\n submitLabel={editing ? 'Save changes' : 'Add department'}\n onSubmit={handleSubmit}\n />\n\n <ConfirmDialog\n open={deleting !== null}\n onOpenChange={(open) => {\n if (!open) {\n setDeleting(null);\n }\n }}\n title=\"Delete department?\"\n description={\n deleting ? `${deleting.name} will be removed. This cannot be undone.` : undefined\n }\n confirmLabel=\"Delete\"\n destructive\n onConfirm={async () => {\n if (deleting) {\n await removeDepartment(deleting.id);\n setDeleting(null);\n }\n }}\n />\n </div>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"HrDepartmentsPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/HrDepartmentsPagePage.tsx"],"sourcesContent":["import { 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 Separator,\n} from '@burdenoff/fe-libs/ui';\nimport { Building2, DollarSign, MapPin, Pencil, Plus, Trash2, Users } from 'lucide-react';\nimport { useCrewFoundryStore, type Department } from '../store/crewfoundryStore';\nimport {\n FormModal,\n useFormModal,\n type FieldConfig,\n type FormValues,\n} from '../components/forms/FormModal';\nimport { ConfirmDialog } from '../components/forms/ConfirmDialog';\nimport { getNumber, getText, newClientId } from '../components/forms/formValues';\nimport { formatEnumLabel } from '../utils/formatEnumLabel';\n\nconst DEPARTMENT_FIELDS: FieldConfig[] = [\n { name: 'name', label: 'Department name', type: 'text', required: true, colSpan: 2 },\n { name: 'headName', label: 'Department head', type: 'text', required: true },\n { name: 'location', label: 'Location', type: 'text', required: true },\n { name: 'budget', label: 'Annual budget', type: 'number', required: true },\n {\n name: 'status',\n label: 'Status',\n type: 'select',\n required: true,\n options: [\n { label: 'Active', value: 'active' },\n { label: 'Restructuring', value: 'restructuring' },\n ],\n },\n];\n\nconst toFormValues = (department: Department): FormValues => ({\n name: department.name,\n headName: department.headName,\n location: department.location,\n budget: department.budget,\n status: department.status,\n});\n\nexport function HrDepartmentsPagePage() {\n const { departments, employees, addDepartment, updateDepartment, removeDepartment } =\n useCrewFoundryStore();\n const form = useFormModal<Department>();\n const [deleting, setDeleting] = useState<Department | null>(null);\n\n const totalBudget = departments.reduce((s, d) => s + d.budget, 0);\n const totalHeadcount = departments.reduce((s, d) => s + d.employeeCount, 0);\n\n const editing = form.context;\n\n const handleSubmit = async (values: FormValues) => {\n const payload: Department = {\n id: editing?.id ?? newClientId(),\n name: getText(values, 'name'),\n headId: editing?.headId ?? '',\n headName: getText(values, 'headName'),\n employeeCount: editing?.employeeCount ?? 0,\n budget: getNumber(values, 'budget'),\n location: getText(values, 'location'),\n status: getText(values, 'status') as Department['status'],\n };\n if (editing) {\n await updateDepartment(editing.id, payload);\n } else {\n await addDepartment(payload);\n }\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>Departments</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">\n Organizational structure and department management\n </p>\n <PagePurpose className=\"mt-1\">\n Organize your company into departments — set up structure, assign heads, and see how\n headcount is distributed across the org.\n </PagePurpose>\n </div>\n <Button size=\"sm\" onClick={() => form.openModal()}>\n <Plus className=\"h-4 w-4 mr-1\" />\n Add Department\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\">Total Departments</CardTitle>\n <Building2 className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">{departments.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\">Total Headcount</CardTitle>\n <Users className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">{totalHeadcount}</div>\n </CardContent>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"border-border-seam\">\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Total Budget</CardTitle>\n <DollarSign className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">\n ${(totalBudget / 1000000).toFixed(1)}M\n </div>\n </CardContent>\n </GlassCard>\n </div>\n\n <div className=\"grid gap-4 md:grid-cols-2\">\n {departments.map((dept) => {\n const deptEmps = employees.filter((e) => e.department === dept.name);\n const avgSalary =\n deptEmps.length > 0\n ? Math.round(deptEmps.reduce((s, e) => s + e.salary, 0) / deptEmps.length)\n : 0;\n const avgPerf =\n deptEmps.length > 0\n ? (deptEmps.reduce((s, e) => s + e.performanceScore, 0) / deptEmps.length).toFixed(1)\n : '0';\n\n return (\n <Card key={dept.id}>\n <CardHeader>\n <div className=\"flex items-center justify-between\">\n <CardTitle className=\"text-lg\">{dept.name}</CardTitle>\n <div className=\"flex items-center gap-1\">\n <Badge variant={dept.status === 'active' ? 'default' : 'secondary'}>\n {formatEnumLabel(dept.status)}\n </Badge>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-8 w-8 p-0\"\n aria-label={`Edit ${dept.name}`}\n onClick={() => form.openModal(dept)}\n >\n <Pencil className=\"h-4 w-4\" />\n </Button>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-8 w-8 p-0\"\n aria-label={`Delete ${dept.name}`}\n onClick={() => setDeleting(dept)}\n >\n <Trash2 className=\"h-4 w-4 text-status-error-text\" />\n </Button>\n </div>\n </div>\n <CardDescription className=\"flex items-center gap-1\">\n <MapPin className=\"h-3 w-3\" />\n {dept.location}\n </CardDescription>\n </CardHeader>\n <CardContent>\n <div className=\"grid grid-cols-2 gap-4 mb-4\">\n <div>\n <p className=\"text-xs text-text-secondary\">Department Head</p>\n <p className=\"text-sm font-medium\">{dept.headName}</p>\n </div>\n <div>\n <p className=\"text-xs text-text-secondary\">Headcount</p>\n <p className=\"text-sm font-medium\">{dept.employeeCount} employees</p>\n </div>\n <div>\n <p className=\"text-xs text-text-secondary\">Annual Budget</p>\n <p className=\"text-sm font-medium\">${(dept.budget / 1000000).toFixed(1)}M</p>\n </div>\n <div>\n <p className=\"text-xs text-text-secondary\">Avg Salary</p>\n <p className=\"text-sm font-medium\">${avgSalary.toLocaleString()}</p>\n </div>\n </div>\n <Separator className=\"mb-3\" />\n <div className=\"flex items-center justify-between text-xs\">\n <span className=\"text-text-secondary\">Avg Performance: {avgPerf}/5</span>\n <span className=\"text-text-secondary\">\n Cost/Head:{' '}\n {dept.employeeCount > 0\n ? `$${Math.round(dept.budget / dept.employeeCount / 1000)}K`\n : '—'}\n </span>\n </div>\n </CardContent>\n </Card>\n );\n })}\n </div>\n\n <FormModal\n open={form.open}\n onOpenChange={form.onOpenChange}\n title={editing ? 'Edit department' : 'Add department'}\n description={\n editing\n ? 'Update this department’s details.'\n : 'Create a new department in your organization.'\n }\n fields={DEPARTMENT_FIELDS}\n initialValues={editing ? toFormValues(editing) : undefined}\n submitLabel={editing ? 'Save changes' : 'Add department'}\n onSubmit={handleSubmit}\n />\n\n <ConfirmDialog\n open={deleting !== null}\n onOpenChange={(open) => {\n if (!open) {\n setDeleting(null);\n }\n }}\n title=\"Delete department?\"\n description={\n deleting ? `${deleting.name} will be removed. This cannot be undone.` : undefined\n }\n confirmLabel=\"Delete\"\n destructive\n onConfirm={async () => {\n if (deleting) {\n await removeDepartment(deleting.id);\n setDeleting(null);\n }\n }}\n />\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import { useCrewFoundryStore as e } from "../store/crewfoundryStore.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
2
|
+
import { formatEnumLabel as t } from "../utils/formatEnumLabel.js";
|
|
3
|
+
import { FormModal as n, useFormModal as r } from "../components/forms/FormModal.js";
|
|
4
|
+
import { getNumber as i, getText as a, newClientId as o } from "../components/forms/formValues.js";
|
|
5
|
+
import { useMemo as s } from "react";
|
|
6
|
+
import { Calendar as c, CheckCircle as l, Clock as u, XCircle 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, Pagination as w, ResponsiveTable as T } from "@burdenoff/fe-libs/ui";
|
|
9
|
+
import { usePagination as E } from "@burdenoff/fe-libs/shared/hooks";
|
|
10
|
+
import { useAuth as D, useGlobalUi as O } from "@burdenoff/fe-libs/shared/providers/shell";
|
|
10
11
|
//#region src/crewfoundry/pages/HrLeaveManagementPagePage.tsx
|
|
11
|
-
var
|
|
12
|
+
var k = [
|
|
12
13
|
{
|
|
13
14
|
label: "Annual",
|
|
14
15
|
value: "annual"
|
|
@@ -33,18 +34,18 @@ var O = [
|
|
|
33
34
|
label: "Unpaid",
|
|
34
35
|
value: "unpaid"
|
|
35
36
|
}
|
|
36
|
-
],
|
|
37
|
-
function
|
|
38
|
-
let { leaveRequests:
|
|
37
|
+
], A = (e) => e.split("_").map((e) => e[0]?.toUpperCase() + e.slice(1)).join(" ");
|
|
38
|
+
function j() {
|
|
39
|
+
let { leaveRequests: j, employees: M, addLeaveRequest: N, updateLeaveRequest: P } = e(), { showToast: F } = O(), { currentUser: I } = D(), L = r(), R = I?.name || [I?.firstName, I?.lastName].filter(Boolean).join(" ") || I?.email || "Manager", z = s(() => M.map((e) => ({
|
|
39
40
|
label: `${e.firstName} ${e.lastName}`,
|
|
40
41
|
value: e.id
|
|
41
|
-
})), [
|
|
42
|
+
})), [M]), B = s(() => [
|
|
42
43
|
{
|
|
43
44
|
name: "employeeId",
|
|
44
45
|
label: "Employee",
|
|
45
46
|
type: "select",
|
|
46
47
|
required: !0,
|
|
47
|
-
options:
|
|
48
|
+
options: z,
|
|
48
49
|
colSpan: 2
|
|
49
50
|
},
|
|
50
51
|
{
|
|
@@ -52,7 +53,7 @@ function A() {
|
|
|
52
53
|
label: "Leave type",
|
|
53
54
|
type: "select",
|
|
54
55
|
required: !0,
|
|
55
|
-
options:
|
|
56
|
+
options: k
|
|
56
57
|
},
|
|
57
58
|
{
|
|
58
59
|
name: "days",
|
|
@@ -79,7 +80,7 @@ function A() {
|
|
|
79
80
|
required: !0,
|
|
80
81
|
colSpan: 2
|
|
81
82
|
}
|
|
82
|
-
], [
|
|
83
|
+
], [z]), V = j.filter((e) => e.status === "pending").length, H = j.filter((e) => e.status === "approved").length, U = j.filter((e) => e.status === "approved").reduce((e, t) => e + t.days, 0), W = s(() => {
|
|
83
84
|
let e = {
|
|
84
85
|
annual: 20,
|
|
85
86
|
sick: 12,
|
|
@@ -87,25 +88,25 @@ function A() {
|
|
|
87
88
|
maternity: 90,
|
|
88
89
|
paternity: 30,
|
|
89
90
|
unpaid: 15
|
|
90
|
-
}, t =
|
|
91
|
+
}, t = j.filter((e) => e.status === "approved").reduce((e, t) => (e[t.type] = (e[t.type] || 0) + t.days, e), {});
|
|
91
92
|
return Object.entries(e).map(([e, n]) => {
|
|
92
93
|
let r = t[e] || 0;
|
|
93
94
|
return {
|
|
94
|
-
type:
|
|
95
|
+
type: A(e),
|
|
95
96
|
total: n,
|
|
96
97
|
used: r,
|
|
97
98
|
remaining: Math.max(n - r, 0)
|
|
98
99
|
};
|
|
99
100
|
});
|
|
100
|
-
}, [
|
|
101
|
+
}, [j]), G = s(() => {
|
|
101
102
|
let e = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
102
|
-
return
|
|
103
|
-
}, [
|
|
103
|
+
return j.filter((t) => t.status === "approved" && t.startDate <= e && t.endDate >= e).length;
|
|
104
|
+
}, [j]), K = s(() => j.filter((e) => e.status === "pending"), [j]), q = s(() => [...j].sort((e, t) => t.startDate.localeCompare(e.startDate)), [j]), J = E({ initialPageSize: 5 }), Y = E({ initialPageSize: 10 }), X = K.slice(J.offset, J.offset + J.pageSize), Z = q.slice(Y.offset, Y.offset + Y.pageSize), Q = [
|
|
104
105
|
{
|
|
105
106
|
key: "employee",
|
|
106
107
|
header: "Employee",
|
|
107
108
|
priority: "primary",
|
|
108
|
-
cell: (e) => /* @__PURE__ */
|
|
109
|
+
cell: (e) => /* @__PURE__ */ f("span", {
|
|
109
110
|
className: "font-medium",
|
|
110
111
|
children: e.employeeName
|
|
111
112
|
})
|
|
@@ -113,7 +114,7 @@ function A() {
|
|
|
113
114
|
{
|
|
114
115
|
key: "department",
|
|
115
116
|
header: "Department",
|
|
116
|
-
cell: (e) => /* @__PURE__ */
|
|
117
|
+
cell: (e) => /* @__PURE__ */ f("span", {
|
|
117
118
|
className: "text-text-secondary",
|
|
118
119
|
children: e.department
|
|
119
120
|
})
|
|
@@ -121,16 +122,16 @@ function A() {
|
|
|
121
122
|
{
|
|
122
123
|
key: "type",
|
|
123
124
|
header: "Type",
|
|
124
|
-
cell: (e) => /* @__PURE__ */
|
|
125
|
+
cell: (e) => /* @__PURE__ */ f(m, {
|
|
125
126
|
variant: "outline",
|
|
126
127
|
className: "w-fit text-[10px]",
|
|
127
|
-
children: e.type
|
|
128
|
+
children: t(e.type)
|
|
128
129
|
})
|
|
129
130
|
},
|
|
130
131
|
{
|
|
131
132
|
key: "period",
|
|
132
133
|
header: "Period",
|
|
133
|
-
cell: (e) => /* @__PURE__ */
|
|
134
|
+
cell: (e) => /* @__PURE__ */ p("span", {
|
|
134
135
|
className: "text-xs",
|
|
135
136
|
children: [
|
|
136
137
|
e.startDate,
|
|
@@ -144,12 +145,12 @@ function A() {
|
|
|
144
145
|
header: "Days",
|
|
145
146
|
headerClassName: "text-right",
|
|
146
147
|
cellClassName: "md:text-right",
|
|
147
|
-
cell: (e) => /* @__PURE__ */
|
|
148
|
+
cell: (e) => /* @__PURE__ */ f("span", { children: e.days })
|
|
148
149
|
},
|
|
149
150
|
{
|
|
150
151
|
key: "reason",
|
|
151
152
|
header: "Reason",
|
|
152
|
-
cell: (e) => /* @__PURE__ */
|
|
153
|
+
cell: (e) => /* @__PURE__ */ f("span", {
|
|
153
154
|
className: "block max-w-[16rem] truncate text-xs text-text-secondary",
|
|
154
155
|
children: e.reason
|
|
155
156
|
})
|
|
@@ -157,197 +158,198 @@ function A() {
|
|
|
157
158
|
{
|
|
158
159
|
key: "status",
|
|
159
160
|
header: "Status",
|
|
160
|
-
cell: (e) => /* @__PURE__ */
|
|
161
|
+
cell: (e) => /* @__PURE__ */ f(m, {
|
|
161
162
|
variant: e.status === "approved" ? "default" : e.status === "pending" ? "secondary" : "destructive",
|
|
162
163
|
className: "text-[10px]",
|
|
163
|
-
children: e.status
|
|
164
|
+
children: t(e.status)
|
|
164
165
|
})
|
|
165
166
|
}
|
|
166
|
-
],
|
|
167
|
-
let t =
|
|
168
|
-
await
|
|
169
|
-
id:
|
|
167
|
+
], ee = async (e) => {
|
|
168
|
+
let t = a(e, "employeeId"), n = M.find((e) => e.id === t);
|
|
169
|
+
await N({
|
|
170
|
+
id: o(),
|
|
170
171
|
employeeId: t,
|
|
171
172
|
employeeName: n ? `${n.firstName} ${n.lastName}` : "",
|
|
172
173
|
department: n?.department ?? "",
|
|
173
|
-
type:
|
|
174
|
-
startDate:
|
|
175
|
-
endDate:
|
|
176
|
-
days:
|
|
174
|
+
type: a(e, "type"),
|
|
175
|
+
startDate: a(e, "startDate"),
|
|
176
|
+
endDate: a(e, "endDate"),
|
|
177
|
+
days: i(e, "days"),
|
|
177
178
|
status: "pending",
|
|
178
|
-
reason:
|
|
179
|
+
reason: a(e, "reason")
|
|
179
180
|
});
|
|
180
181
|
}, $ = async (e, t) => {
|
|
181
182
|
try {
|
|
182
|
-
await
|
|
183
|
+
await P(e.id, {
|
|
183
184
|
status: t,
|
|
184
|
-
approverName:
|
|
185
|
+
approverName: R
|
|
185
186
|
});
|
|
186
187
|
} catch (e) {
|
|
187
|
-
|
|
188
|
+
F(e instanceof Error ? e.message : "Unable to update leave request", "error");
|
|
188
189
|
}
|
|
189
190
|
};
|
|
190
|
-
return /* @__PURE__ */
|
|
191
|
+
return /* @__PURE__ */ p("div", {
|
|
191
192
|
className: "space-y-6 p-6",
|
|
192
193
|
children: [
|
|
193
|
-
/* @__PURE__ */
|
|
194
|
+
/* @__PURE__ */ p("div", {
|
|
194
195
|
className: "flex items-center justify-between",
|
|
195
|
-
children: [/* @__PURE__ */
|
|
196
|
-
/* @__PURE__ */
|
|
196
|
+
children: [/* @__PURE__ */ p("div", { children: [
|
|
197
|
+
/* @__PURE__ */ f("h1", {
|
|
197
198
|
className: "text-2xl font-semibold",
|
|
198
|
-
children: /* @__PURE__ */
|
|
199
|
+
children: /* @__PURE__ */ f(S, { children: "Leave Management" })
|
|
199
200
|
}),
|
|
200
|
-
/* @__PURE__ */
|
|
201
|
+
/* @__PURE__ */ f("p", {
|
|
201
202
|
className: "text-sm text-text-secondary",
|
|
202
203
|
children: "Track and manage employee leave requests"
|
|
203
204
|
}),
|
|
204
|
-
/* @__PURE__ */
|
|
205
|
+
/* @__PURE__ */ f(C, {
|
|
205
206
|
className: "mt-1",
|
|
206
207
|
children: "Handle time-off in one place — review and approve leave requests and keep an eye on team availability and balances."
|
|
207
208
|
})
|
|
208
|
-
] }), /* @__PURE__ */
|
|
209
|
+
] }), /* @__PURE__ */ p(h, {
|
|
209
210
|
size: "sm",
|
|
210
|
-
onClick: () =>
|
|
211
|
-
children: [/* @__PURE__ */
|
|
211
|
+
onClick: () => L.openModal(),
|
|
212
|
+
children: [/* @__PURE__ */ f(c, { className: "mr-1 h-4 w-4" }), "Request Leave"]
|
|
212
213
|
})]
|
|
213
214
|
}),
|
|
214
|
-
/* @__PURE__ */
|
|
215
|
+
/* @__PURE__ */ p("div", {
|
|
215
216
|
className: "grid gap-4 md:grid-cols-2 lg:grid-cols-4",
|
|
216
217
|
children: [
|
|
217
|
-
/* @__PURE__ */
|
|
218
|
+
/* @__PURE__ */ p(x, {
|
|
218
219
|
treatment: "glass",
|
|
219
220
|
glow: !0,
|
|
220
221
|
className: "border-border-seam",
|
|
221
|
-
children: [/* @__PURE__ */
|
|
222
|
+
children: [/* @__PURE__ */ p(y, {
|
|
222
223
|
className: "flex flex-row items-center justify-between space-y-0 pb-2",
|
|
223
|
-
children: [/* @__PURE__ */
|
|
224
|
+
children: [/* @__PURE__ */ f(b, {
|
|
224
225
|
className: "text-sm font-medium",
|
|
225
226
|
children: "Pending"
|
|
226
|
-
}), /* @__PURE__ */
|
|
227
|
-
}), /* @__PURE__ */
|
|
227
|
+
}), /* @__PURE__ */ f(u, { className: "h-4 w-4 text-status-warning-text" })]
|
|
228
|
+
}), /* @__PURE__ */ p(_, { children: [/* @__PURE__ */ f("div", {
|
|
228
229
|
className: "text-2xl font-bold tabular-nums",
|
|
229
|
-
children:
|
|
230
|
-
}), /* @__PURE__ */
|
|
230
|
+
children: V
|
|
231
|
+
}), /* @__PURE__ */ f("p", {
|
|
231
232
|
className: "text-xs text-text-secondary",
|
|
232
233
|
children: "Awaiting approval"
|
|
233
234
|
})] })]
|
|
234
235
|
}),
|
|
235
|
-
/* @__PURE__ */
|
|
236
|
+
/* @__PURE__ */ p(x, {
|
|
236
237
|
treatment: "metric",
|
|
237
238
|
className: "border-border-seam",
|
|
238
|
-
children: [/* @__PURE__ */
|
|
239
|
+
children: [/* @__PURE__ */ p(y, {
|
|
239
240
|
className: "flex flex-row items-center justify-between space-y-0 pb-2",
|
|
240
|
-
children: [/* @__PURE__ */
|
|
241
|
+
children: [/* @__PURE__ */ f(b, {
|
|
241
242
|
className: "text-sm font-medium",
|
|
242
243
|
children: "Approved"
|
|
243
|
-
}), /* @__PURE__ */
|
|
244
|
-
}), /* @__PURE__ */
|
|
244
|
+
}), /* @__PURE__ */ f(l, { className: "h-4 w-4 text-status-success-text" })]
|
|
245
|
+
}), /* @__PURE__ */ p(_, { children: [/* @__PURE__ */ f("div", {
|
|
245
246
|
className: "text-2xl font-bold tabular-nums",
|
|
246
|
-
children:
|
|
247
|
-
}), /* @__PURE__ */
|
|
247
|
+
children: H
|
|
248
|
+
}), /* @__PURE__ */ f("p", {
|
|
248
249
|
className: "text-xs text-text-secondary",
|
|
249
250
|
children: "Current period"
|
|
250
251
|
})] })]
|
|
251
252
|
}),
|
|
252
|
-
/* @__PURE__ */
|
|
253
|
+
/* @__PURE__ */ p(x, {
|
|
253
254
|
treatment: "metric",
|
|
254
255
|
className: "border-border-seam",
|
|
255
|
-
children: [/* @__PURE__ */
|
|
256
|
+
children: [/* @__PURE__ */ p(y, {
|
|
256
257
|
className: "flex flex-row items-center justify-between space-y-0 pb-2",
|
|
257
|
-
children: [/* @__PURE__ */
|
|
258
|
+
children: [/* @__PURE__ */ f(b, {
|
|
258
259
|
className: "text-sm font-medium",
|
|
259
260
|
children: "Days Used"
|
|
260
|
-
}), /* @__PURE__ */
|
|
261
|
-
}), /* @__PURE__ */
|
|
261
|
+
}), /* @__PURE__ */ f(c, { className: "h-4 w-4 text-text-secondary" })]
|
|
262
|
+
}), /* @__PURE__ */ p(_, { children: [/* @__PURE__ */ f("div", {
|
|
262
263
|
className: "text-2xl font-bold tabular-nums",
|
|
263
|
-
children:
|
|
264
|
-
}), /* @__PURE__ */
|
|
264
|
+
children: U
|
|
265
|
+
}), /* @__PURE__ */ f("p", {
|
|
265
266
|
className: "text-xs text-text-secondary",
|
|
266
267
|
children: "Total approved days"
|
|
267
268
|
})] })]
|
|
268
269
|
}),
|
|
269
|
-
/* @__PURE__ */
|
|
270
|
+
/* @__PURE__ */ p(x, {
|
|
270
271
|
treatment: "metric",
|
|
271
272
|
className: "border-border-seam",
|
|
272
|
-
children: [/* @__PURE__ */
|
|
273
|
+
children: [/* @__PURE__ */ p(y, {
|
|
273
274
|
className: "flex flex-row items-center justify-between space-y-0 pb-2",
|
|
274
|
-
children: [/* @__PURE__ */
|
|
275
|
+
children: [/* @__PURE__ */ f(b, {
|
|
275
276
|
className: "text-sm font-medium",
|
|
276
277
|
children: "On Leave Today"
|
|
277
|
-
}), /* @__PURE__ */ d
|
|
278
|
-
}), /* @__PURE__ */
|
|
278
|
+
}), /* @__PURE__ */ f(d, { className: "h-4 w-4 text-text-secondary" })]
|
|
279
|
+
}), /* @__PURE__ */ p(_, { children: [/* @__PURE__ */ f("div", {
|
|
279
280
|
className: "text-2xl font-bold tabular-nums",
|
|
280
|
-
children:
|
|
281
|
-
}), /* @__PURE__ */
|
|
281
|
+
children: G
|
|
282
|
+
}), /* @__PURE__ */ f("p", {
|
|
282
283
|
className: "text-xs text-text-secondary",
|
|
283
284
|
children: "Out of office"
|
|
284
285
|
})] })]
|
|
285
286
|
})
|
|
286
287
|
]
|
|
287
288
|
}),
|
|
288
|
-
/* @__PURE__ */
|
|
289
|
+
/* @__PURE__ */ p("div", {
|
|
289
290
|
className: "grid gap-4 md:grid-cols-2",
|
|
290
|
-
children: [/* @__PURE__ */
|
|
291
|
+
children: [/* @__PURE__ */ p(g, { children: [/* @__PURE__ */ p(y, { children: [/* @__PURE__ */ f(b, { children: "Leave Balances" }), /* @__PURE__ */ f(v, { children: "Company-wide leave allocation (default policy) vs. approved days used" })] }), /* @__PURE__ */ f(_, {
|
|
291
292
|
className: "space-y-4",
|
|
292
|
-
children:
|
|
293
|
-
let
|
|
294
|
-
return /* @__PURE__ */
|
|
293
|
+
children: W.map((e) => {
|
|
294
|
+
let n = Math.round(e.used / Math.max(e.total, 1) * 100);
|
|
295
|
+
return /* @__PURE__ */ p("div", {
|
|
295
296
|
className: "space-y-1",
|
|
296
|
-
children: [/* @__PURE__ */
|
|
297
|
+
children: [/* @__PURE__ */ p("div", {
|
|
297
298
|
className: "flex justify-between text-sm",
|
|
298
|
-
children: [/* @__PURE__ */
|
|
299
|
+
children: [/* @__PURE__ */ f("span", {
|
|
299
300
|
className: "font-medium",
|
|
300
|
-
children: e.type
|
|
301
|
-
}), /* @__PURE__ */
|
|
301
|
+
children: t(e.type)
|
|
302
|
+
}), /* @__PURE__ */ p("span", { children: [
|
|
302
303
|
e.used,
|
|
303
304
|
"/",
|
|
304
305
|
e.total,
|
|
305
306
|
" days used"
|
|
306
307
|
] })]
|
|
307
|
-
}), /* @__PURE__ */
|
|
308
|
+
}), /* @__PURE__ */ f("div", {
|
|
308
309
|
className: "h-2 overflow-hidden rounded bg-bg-sunken",
|
|
309
|
-
children: /* @__PURE__ */
|
|
310
|
-
className: `h-2 rounded ${
|
|
311
|
-
style: { width: `${
|
|
310
|
+
children: /* @__PURE__ */ f("div", {
|
|
311
|
+
className: `h-2 rounded ${n > 80 ? "bg-status-error-text" : n > 50 ? "bg-status-warning-text" : "bg-status-success-text"}`,
|
|
312
|
+
style: { width: `${n}%` }
|
|
312
313
|
})
|
|
313
314
|
})]
|
|
314
315
|
}, e.type);
|
|
315
316
|
})
|
|
316
|
-
})] }), /* @__PURE__ */
|
|
317
|
+
})] }), /* @__PURE__ */ p(g, { children: [/* @__PURE__ */ p(y, { children: [/* @__PURE__ */ f(b, { children: "Pending Approvals" }), /* @__PURE__ */ f(v, { children: "Leave requests waiting for your review" })] }), /* @__PURE__ */ p(_, {
|
|
317
318
|
className: "space-y-3",
|
|
318
319
|
children: [
|
|
319
|
-
|
|
320
|
+
X.map((e) => /* @__PURE__ */ p("div", {
|
|
320
321
|
className: "flex items-center justify-between rounded border p-3",
|
|
321
|
-
children: [/* @__PURE__ */
|
|
322
|
-
/* @__PURE__ */
|
|
322
|
+
children: [/* @__PURE__ */ p("div", { children: [
|
|
323
|
+
/* @__PURE__ */ f("p", {
|
|
323
324
|
className: "text-sm font-medium",
|
|
324
325
|
children: e.employeeName
|
|
325
326
|
}),
|
|
326
|
-
/* @__PURE__ */
|
|
327
|
+
/* @__PURE__ */ p("p", {
|
|
327
328
|
className: "text-xs text-text-secondary",
|
|
328
329
|
children: [
|
|
329
|
-
e.type,
|
|
330
|
+
t(e.type),
|
|
330
331
|
" · ",
|
|
331
332
|
e.days,
|
|
332
333
|
" days · ",
|
|
333
334
|
e.startDate,
|
|
334
|
-
" to
|
|
335
|
+
" to",
|
|
336
|
+
" ",
|
|
335
337
|
e.endDate
|
|
336
338
|
]
|
|
337
339
|
}),
|
|
338
|
-
/* @__PURE__ */
|
|
340
|
+
/* @__PURE__ */ f("p", {
|
|
339
341
|
className: "mt-1 text-xs text-text-secondary",
|
|
340
342
|
children: e.reason
|
|
341
343
|
})
|
|
342
|
-
] }), /* @__PURE__ */
|
|
344
|
+
] }), /* @__PURE__ */ p("div", {
|
|
343
345
|
className: "flex gap-1",
|
|
344
|
-
children: [/* @__PURE__ */
|
|
346
|
+
children: [/* @__PURE__ */ f(h, {
|
|
345
347
|
size: "sm",
|
|
346
348
|
variant: "outline",
|
|
347
349
|
className: "h-7 text-xs",
|
|
348
350
|
onClick: () => $(e, "rejected"),
|
|
349
351
|
children: "Reject"
|
|
350
|
-
}), /* @__PURE__ */
|
|
352
|
+
}), /* @__PURE__ */ f(h, {
|
|
351
353
|
size: "sm",
|
|
352
354
|
className: "h-7 text-xs",
|
|
353
355
|
onClick: () => $(e, "approved"),
|
|
@@ -355,49 +357,49 @@ function A() {
|
|
|
355
357
|
})]
|
|
356
358
|
})]
|
|
357
359
|
}, e.id)),
|
|
358
|
-
|
|
360
|
+
V === 0 && /* @__PURE__ */ f("p", {
|
|
359
361
|
className: "py-6 text-center text-sm text-text-secondary",
|
|
360
362
|
children: "No leave requests are awaiting approval."
|
|
361
363
|
}),
|
|
362
|
-
|
|
363
|
-
page:
|
|
364
|
-
pageSize:
|
|
365
|
-
totalItems:
|
|
366
|
-
onPageChange:
|
|
364
|
+
K.length > J.pageSize && /* @__PURE__ */ f(w, {
|
|
365
|
+
page: J.page,
|
|
366
|
+
pageSize: J.pageSize,
|
|
367
|
+
totalItems: K.length,
|
|
368
|
+
onPageChange: J.setPage
|
|
367
369
|
})
|
|
368
370
|
]
|
|
369
371
|
})] })]
|
|
370
372
|
}),
|
|
371
|
-
/* @__PURE__ */
|
|
373
|
+
/* @__PURE__ */ p(g, { children: [/* @__PURE__ */ p(y, { children: [/* @__PURE__ */ f(b, { children: "All Leave Requests" }), /* @__PURE__ */ f(v, { children: "Complete leave request history" })] }), /* @__PURE__ */ p(_, {
|
|
372
374
|
className: "space-y-4",
|
|
373
|
-
children: [/* @__PURE__ */
|
|
374
|
-
data:
|
|
375
|
+
children: [/* @__PURE__ */ f(T, {
|
|
376
|
+
data: Z,
|
|
375
377
|
rowKey: (e) => e.id,
|
|
376
|
-
columns:
|
|
377
|
-
emptyState: /* @__PURE__ */
|
|
378
|
+
columns: Q,
|
|
379
|
+
emptyState: /* @__PURE__ */ f("p", {
|
|
378
380
|
className: "py-6 text-center text-sm text-text-secondary",
|
|
379
381
|
children: "No leave requests yet."
|
|
380
382
|
})
|
|
381
|
-
}),
|
|
382
|
-
page:
|
|
383
|
-
pageSize:
|
|
384
|
-
totalItems:
|
|
385
|
-
onPageChange:
|
|
383
|
+
}), q.length > Y.pageSize && /* @__PURE__ */ f(w, {
|
|
384
|
+
page: Y.page,
|
|
385
|
+
pageSize: Y.pageSize,
|
|
386
|
+
totalItems: q.length,
|
|
387
|
+
onPageChange: Y.setPage
|
|
386
388
|
})]
|
|
387
389
|
})] }),
|
|
388
|
-
/* @__PURE__ */
|
|
389
|
-
open:
|
|
390
|
-
onOpenChange:
|
|
390
|
+
/* @__PURE__ */ f(n, {
|
|
391
|
+
open: L.open,
|
|
392
|
+
onOpenChange: L.onOpenChange,
|
|
391
393
|
title: "Request leave",
|
|
392
394
|
description: "Submit a new time-off request for review.",
|
|
393
|
-
fields:
|
|
395
|
+
fields: B,
|
|
394
396
|
submitLabel: "Submit request",
|
|
395
|
-
onSubmit:
|
|
397
|
+
onSubmit: ee
|
|
396
398
|
})
|
|
397
399
|
]
|
|
398
400
|
});
|
|
399
401
|
}
|
|
400
402
|
//#endregion
|
|
401
|
-
export {
|
|
403
|
+
export { j as HrLeaveManagementPagePage };
|
|
402
404
|
|
|
403
405
|
//# sourceMappingURL=HrLeaveManagementPagePage.js.map
|