@hed-hog/operations 0.0.2 → 0.0.285

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 (108) hide show
  1. package/README.md +122 -0
  2. package/dist/index.d.ts +1 -0
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +1 -0
  5. package/dist/index.js.map +1 -1
  6. package/dist/operations-data.controller.d.ts +139 -0
  7. package/dist/operations-data.controller.d.ts.map +1 -0
  8. package/dist/operations-data.controller.js +113 -0
  9. package/dist/operations-data.controller.js.map +1 -0
  10. package/dist/operations-growth.controller.d.ts +48 -0
  11. package/dist/operations-growth.controller.d.ts.map +1 -0
  12. package/dist/operations-growth.controller.js +90 -0
  13. package/dist/operations-growth.controller.js.map +1 -0
  14. package/dist/operations.module.d.ts.map +1 -1
  15. package/dist/operations.module.js +10 -4
  16. package/dist/operations.module.js.map +1 -1
  17. package/dist/operations.service.d.ts +178 -0
  18. package/dist/operations.service.d.ts.map +1 -0
  19. package/dist/operations.service.js +134 -0
  20. package/dist/operations.service.js.map +1 -0
  21. package/hedhog/data/menu.yaml +251 -132
  22. package/hedhog/data/operations_career_level.yaml +102 -0
  23. package/hedhog/data/operations_career_track.yaml +8 -0
  24. package/hedhog/data/operations_certification.yaml +38 -0
  25. package/hedhog/data/operations_evaluation_cycle.yaml +18 -0
  26. package/hedhog/data/operations_performance_criterion.yaml +48 -0
  27. package/hedhog/data/role.yaml +14 -7
  28. package/hedhog/data/route.yaml +143 -80
  29. package/hedhog/frontend/app/_components/allocation-calendar.tsx.ejs +56 -56
  30. package/hedhog/frontend/app/_components/kanban-board.tsx.ejs +83 -83
  31. package/hedhog/frontend/app/_components/operations-header.tsx.ejs +29 -29
  32. package/hedhog/frontend/app/_components/section-card.tsx.ejs +32 -32
  33. package/hedhog/frontend/app/_components/status-badge.tsx.ejs +15 -15
  34. package/hedhog/frontend/app/_components/timesheet-entry-dialog.tsx.ejs +142 -142
  35. package/hedhog/frontend/app/_lib/hooks/use-operations-data.ts.ejs +41 -41
  36. package/hedhog/frontend/app/_lib/hooks/use-operations-growth-data.ts.ejs +63 -0
  37. package/hedhog/frontend/app/_lib/mocks/allocations.mock.ts.ejs +74 -74
  38. package/hedhog/frontend/app/_lib/mocks/contracts.mock.ts.ejs +74 -74
  39. package/hedhog/frontend/app/_lib/mocks/operations-growth.mock.ts.ejs +824 -0
  40. package/hedhog/frontend/app/_lib/mocks/projects.mock.ts.ejs +60 -60
  41. package/hedhog/frontend/app/_lib/mocks/tasks.mock.ts.ejs +88 -88
  42. package/hedhog/frontend/app/_lib/mocks/timesheets.mock.ts.ejs +84 -84
  43. package/hedhog/frontend/app/_lib/mocks/users.mock.ts.ejs +67 -67
  44. package/hedhog/frontend/app/_lib/services/contracts.service.ts.ejs +10 -10
  45. package/hedhog/frontend/app/_lib/services/operations-growth.service.ts.ejs +31 -0
  46. package/hedhog/frontend/app/_lib/services/projects.service.ts.ejs +10 -10
  47. package/hedhog/frontend/app/_lib/services/tasks.service.ts.ejs +10 -10
  48. package/hedhog/frontend/app/_lib/services/timesheets.service.ts.ejs +10 -10
  49. package/hedhog/frontend/app/_lib/types/operations-growth.ts.ejs +209 -0
  50. package/hedhog/frontend/app/_lib/types/operations.ts.ejs +95 -95
  51. package/hedhog/frontend/app/_lib/utils/format.ts.ejs +25 -25
  52. package/hedhog/frontend/app/_lib/utils/growth.ts.ejs +62 -0
  53. package/hedhog/frontend/app/_lib/utils/metrics.ts.ejs +103 -103
  54. package/hedhog/frontend/app/_lib/utils/status.ts.ejs +80 -80
  55. package/hedhog/frontend/app/allocations/page.tsx.ejs +154 -99
  56. package/hedhog/frontend/app/approvals/page.tsx.ejs +147 -147
  57. package/hedhog/frontend/app/career/page.tsx.ejs +143 -0
  58. package/hedhog/frontend/app/certifications/page.tsx.ejs +201 -0
  59. package/hedhog/frontend/app/contracts/[id]/page.tsx.ejs +108 -108
  60. package/hedhog/frontend/app/contracts/page.tsx.ejs +180 -124
  61. package/hedhog/frontend/app/evaluations/page.tsx.ejs +277 -0
  62. package/hedhog/frontend/app/goals/page.tsx.ejs +170 -0
  63. package/hedhog/frontend/app/growth/page.tsx.ejs +288 -0
  64. package/hedhog/frontend/app/layout.tsx.ejs +9 -9
  65. package/hedhog/frontend/app/manager/page.tsx.ejs +175 -0
  66. package/hedhog/frontend/app/page.tsx.ejs +177 -177
  67. package/hedhog/frontend/app/projects/[id]/page.tsx.ejs +186 -186
  68. package/hedhog/frontend/app/projects/page.tsx.ejs +111 -111
  69. package/hedhog/frontend/app/rewards/page.tsx.ejs +195 -0
  70. package/hedhog/frontend/app/tasks/page.tsx.ejs +47 -47
  71. package/hedhog/frontend/app/timesheets/page.tsx.ejs +126 -126
  72. package/hedhog/frontend/messages/en.json +152 -142
  73. package/hedhog/frontend/messages/pt.json +152 -142
  74. package/hedhog/table/operations_allocation.yaml +52 -0
  75. package/hedhog/table/operations_calibration_item.yaml +61 -0
  76. package/hedhog/table/operations_calibration_session.yaml +25 -0
  77. package/hedhog/table/operations_career_level.yaml +75 -0
  78. package/hedhog/table/operations_career_track.yaml +21 -0
  79. package/hedhog/table/operations_certification.yaml +48 -0
  80. package/hedhog/table/operations_contract.yaml +57 -0
  81. package/hedhog/table/operations_employee.yaml +64 -0
  82. package/hedhog/table/operations_employee_certification.yaml +43 -0
  83. package/hedhog/table/operations_employee_connect.yaml +61 -0
  84. package/hedhog/table/operations_employee_evaluation.yaml +113 -0
  85. package/hedhog/table/operations_employee_evaluation_item.yaml +39 -0
  86. package/hedhog/table/operations_employee_profile.yaml +80 -0
  87. package/hedhog/table/operations_employee_skill_matrix.yaml +30 -0
  88. package/hedhog/table/operations_evaluation_cycle.yaml +31 -0
  89. package/hedhog/table/operations_goal.yaml +67 -0
  90. package/hedhog/table/operations_goal_progress.yaml +31 -0
  91. package/hedhog/table/operations_performance_criterion.yaml +29 -0
  92. package/hedhog/table/operations_project.yaml +66 -0
  93. package/hedhog/table/operations_promotion_readiness.yaml +49 -0
  94. package/hedhog/table/operations_promotion_recommendation.yaml +63 -0
  95. package/hedhog/table/operations_public_recognition.yaml +46 -0
  96. package/hedhog/table/operations_reward.yaml +100 -0
  97. package/hedhog/table/operations_score_event.yaml +81 -0
  98. package/hedhog/table/operations_task.yaml +60 -0
  99. package/hedhog/table/operations_timesheet.yaml +49 -0
  100. package/hedhog/table/operations_timesheet_entry.yaml +51 -0
  101. package/package.json +3 -3
  102. package/src/index.ts +2 -1
  103. package/src/language/en.json +8 -8
  104. package/src/language/pt.json +8 -8
  105. package/src/operations-data.controller.ts +54 -0
  106. package/src/operations-growth.controller.ts +44 -0
  107. package/src/operations.module.ts +21 -15
  108. package/src/operations.service.ts +137 -0
@@ -1,177 +1,177 @@
1
- 'use client';
2
-
3
- import { Page } from '@/components/entity-list';
4
- import { KpiCard } from '@/components/ui/kpi-card';
5
- import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table';
6
- import { Activity, BadgeDollarSign, Clock3, FolderKanban, Users } from 'lucide-react';
7
- import { useTranslations } from 'next-intl';
8
- import {
9
- Bar,
10
- BarChart,
11
- CartesianGrid,
12
- Cell,
13
- Line,
14
- LineChart,
15
- Pie,
16
- PieChart,
17
- ResponsiveContainer,
18
- Tooltip,
19
- XAxis,
20
- YAxis,
21
- } from 'recharts';
22
- import { OperationsHeader } from './_components/operations-header';
23
- import { SectionCard } from './_components/section-card';
24
- import { StatusBadge } from './_components/status-badge';
25
- import { useOperationsData } from './_lib/hooks/use-operations-data';
26
- import { formatCurrency, formatHours } from './_lib/utils/format';
27
- import { getApprovalBadgeClasses, getApprovalLabel } from './_lib/utils/status';
28
-
29
- const chartColors = ['#0f766e', '#1d4ed8', '#f97316', '#be123c', '#7c3aed'];
30
-
31
- export default function OperationsDashboardPage() {
32
- const t = useTranslations('operations.DashboardPage');
33
- const {
34
- dashboardMetrics,
35
- hoursByProject,
36
- hoursByUser,
37
- approvalStatusData,
38
- weeklyTrendData,
39
- recentTimesheets,
40
- users,
41
- projects,
42
- tasks,
43
- } = useOperationsData();
44
-
45
- return (
46
- <Page>
47
- <OperationsHeader
48
- title={t('title')}
49
- description={t('description')}
50
- current={t('breadcrumb')}
51
- />
52
-
53
- <div className="grid gap-4 md:grid-cols-2 xl:grid-cols-5">
54
- <KpiCard
55
- title={t('cards.activeProjects')}
56
- value={dashboardMetrics.totalActiveProjects}
57
- icon={FolderKanban}
58
- />
59
- <KpiCard
60
- title={t('cards.loggedHours')}
61
- value={formatHours(dashboardMetrics.hoursLoggedThisMonth)}
62
- icon={Clock3}
63
- />
64
- <KpiCard
65
- title={t('cards.pendingHours')}
66
- value={formatHours(dashboardMetrics.hoursPendingApproval)}
67
- icon={Activity}
68
- />
69
- <KpiCard
70
- title={t('cards.revenue')}
71
- value={formatCurrency(dashboardMetrics.revenue)}
72
- icon={BadgeDollarSign}
73
- />
74
- <KpiCard
75
- title={t('cards.utilization')}
76
- value={`${dashboardMetrics.utilization.toFixed(0)}%`}
77
- icon={Users}
78
- />
79
- </div>
80
-
81
- <div className="grid gap-4 xl:grid-cols-2">
82
- <SectionCard title={t('charts.hoursByProject')} description={t('charts.hoursByProjectDescription')}>
83
- <ResponsiveContainer width="100%" height={280}>
84
- <BarChart data={hoursByProject}>
85
- <CartesianGrid strokeDasharray="3 3" className="stroke-muted" />
86
- <XAxis dataKey="name" tick={{ fontSize: 11 }} interval={0} angle={-15} textAnchor="end" height={55} />
87
- <YAxis />
88
- <Tooltip />
89
- <Bar dataKey="hours" radius={[6, 6, 0, 0]}>
90
- {hoursByProject.map((item, index) => (
91
- <Cell key={item.name} fill={chartColors[index % chartColors.length]} />
92
- ))}
93
- </Bar>
94
- </BarChart>
95
- </ResponsiveContainer>
96
- </SectionCard>
97
-
98
- <SectionCard title={t('charts.hoursByUser')} description={t('charts.hoursByUserDescription')}>
99
- <ResponsiveContainer width="100%" height={280}>
100
- <BarChart data={hoursByUser}>
101
- <CartesianGrid strokeDasharray="3 3" className="stroke-muted" />
102
- <XAxis dataKey="name" />
103
- <YAxis />
104
- <Tooltip />
105
- <Bar dataKey="hours" radius={[6, 6, 0, 0]}>
106
- {hoursByUser.map((item, index) => (
107
- <Cell key={item.name} fill={chartColors[index % chartColors.length]} />
108
- ))}
109
- </Bar>
110
- </BarChart>
111
- </ResponsiveContainer>
112
- </SectionCard>
113
-
114
- <SectionCard title={t('charts.approvalStatus')} description={t('charts.approvalStatusDescription')}>
115
- <ResponsiveContainer width="100%" height={280}>
116
- <PieChart>
117
- <Pie data={approvalStatusData} dataKey="value" nameKey="name" outerRadius={110}>
118
- {approvalStatusData.map((item, index) => (
119
- <Cell key={item.name} fill={chartColors[index % chartColors.length]} />
120
- ))}
121
- </Pie>
122
- <Tooltip />
123
- </PieChart>
124
- </ResponsiveContainer>
125
- </SectionCard>
126
-
127
- <SectionCard title={t('charts.weeklyTrend')} description={t('charts.weeklyTrendDescription')}>
128
- <ResponsiveContainer width="100%" height={280}>
129
- <LineChart data={weeklyTrendData}>
130
- <CartesianGrid strokeDasharray="3 3" className="stroke-muted" />
131
- <XAxis dataKey="week" />
132
- <YAxis />
133
- <Tooltip />
134
- <Line dataKey="hours" type="monotone" stroke="#1d4ed8" strokeWidth={3} />
135
- </LineChart>
136
- </ResponsiveContainer>
137
- </SectionCard>
138
- </div>
139
-
140
- <SectionCard title={t('recentTable.title')} description={t('recentTable.description')}>
141
- <Table>
142
- <TableHeader>
143
- <TableRow>
144
- <TableHead>{t('recentTable.user')}</TableHead>
145
- <TableHead>{t('recentTable.project')}</TableHead>
146
- <TableHead>{t('recentTable.task')}</TableHead>
147
- <TableHead>{t('recentTable.hours')}</TableHead>
148
- <TableHead>{t('recentTable.status')}</TableHead>
149
- </TableRow>
150
- </TableHeader>
151
- <TableBody>
152
- {recentTimesheets.map((entry) => {
153
- const user = users.find((item) => item.id === entry.userId);
154
- const project = projects.find((item) => item.id === entry.projectId);
155
- const task = tasks.find((item) => item.id === entry.taskId);
156
-
157
- return (
158
- <TableRow key={entry.id}>
159
- <TableCell>{user?.name}</TableCell>
160
- <TableCell>{project?.name}</TableCell>
161
- <TableCell>{task?.title}</TableCell>
162
- <TableCell>{formatHours(entry.hours)}</TableCell>
163
- <TableCell>
164
- <StatusBadge
165
- label={getApprovalLabel(entry.status)}
166
- className={getApprovalBadgeClasses(entry.status)}
167
- />
168
- </TableCell>
169
- </TableRow>
170
- );
171
- })}
172
- </TableBody>
173
- </Table>
174
- </SectionCard>
175
- </Page>
176
- );
177
- }
1
+ 'use client';
2
+
3
+ import { Page } from '@/components/entity-list';
4
+ import { KpiCard } from '@/components/ui/kpi-card';
5
+ import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table';
6
+ import { Activity, BadgeDollarSign, Clock3, FolderKanban, Users } from 'lucide-react';
7
+ import { useTranslations } from 'next-intl';
8
+ import {
9
+ Bar,
10
+ BarChart,
11
+ CartesianGrid,
12
+ Cell,
13
+ Line,
14
+ LineChart,
15
+ Pie,
16
+ PieChart,
17
+ ResponsiveContainer,
18
+ Tooltip,
19
+ XAxis,
20
+ YAxis,
21
+ } from 'recharts';
22
+ import { OperationsHeader } from './_components/operations-header';
23
+ import { SectionCard } from './_components/section-card';
24
+ import { StatusBadge } from './_components/status-badge';
25
+ import { useOperationsData } from './_lib/hooks/use-operations-data';
26
+ import { formatCurrency, formatHours } from './_lib/utils/format';
27
+ import { getApprovalBadgeClasses, getApprovalLabel } from './_lib/utils/status';
28
+
29
+ const chartColors = ['#0f766e', '#1d4ed8', '#f97316', '#be123c', '#7c3aed'];
30
+
31
+ export default function OperationsDashboardPage() {
32
+ const t = useTranslations('operations.DashboardPage');
33
+ const {
34
+ dashboardMetrics,
35
+ hoursByProject,
36
+ hoursByUser,
37
+ approvalStatusData,
38
+ weeklyTrendData,
39
+ recentTimesheets,
40
+ users,
41
+ projects,
42
+ tasks,
43
+ } = useOperationsData();
44
+
45
+ return (
46
+ <Page>
47
+ <OperationsHeader
48
+ title={t('title')}
49
+ description={t('description')}
50
+ current={t('breadcrumb')}
51
+ />
52
+
53
+ <div className="grid gap-4 md:grid-cols-2 xl:grid-cols-5">
54
+ <KpiCard
55
+ title={t('cards.activeProjects')}
56
+ value={dashboardMetrics.totalActiveProjects}
57
+ icon={FolderKanban}
58
+ />
59
+ <KpiCard
60
+ title={t('cards.loggedHours')}
61
+ value={formatHours(dashboardMetrics.hoursLoggedThisMonth)}
62
+ icon={Clock3}
63
+ />
64
+ <KpiCard
65
+ title={t('cards.pendingHours')}
66
+ value={formatHours(dashboardMetrics.hoursPendingApproval)}
67
+ icon={Activity}
68
+ />
69
+ <KpiCard
70
+ title={t('cards.revenue')}
71
+ value={formatCurrency(dashboardMetrics.revenue)}
72
+ icon={BadgeDollarSign}
73
+ />
74
+ <KpiCard
75
+ title={t('cards.utilization')}
76
+ value={`${dashboardMetrics.utilization.toFixed(0)}%`}
77
+ icon={Users}
78
+ />
79
+ </div>
80
+
81
+ <div className="grid gap-4 xl:grid-cols-2">
82
+ <SectionCard title={t('charts.hoursByProject')} description={t('charts.hoursByProjectDescription')}>
83
+ <ResponsiveContainer width="100%" height={280}>
84
+ <BarChart data={hoursByProject}>
85
+ <CartesianGrid strokeDasharray="3 3" className="stroke-muted" />
86
+ <XAxis dataKey="name" tick={{ fontSize: 11 }} interval={0} angle={-15} textAnchor="end" height={55} />
87
+ <YAxis />
88
+ <Tooltip />
89
+ <Bar dataKey="hours" radius={[6, 6, 0, 0]}>
90
+ {hoursByProject.map((item, index) => (
91
+ <Cell key={item.name} fill={chartColors[index % chartColors.length]} />
92
+ ))}
93
+ </Bar>
94
+ </BarChart>
95
+ </ResponsiveContainer>
96
+ </SectionCard>
97
+
98
+ <SectionCard title={t('charts.hoursByUser')} description={t('charts.hoursByUserDescription')}>
99
+ <ResponsiveContainer width="100%" height={280}>
100
+ <BarChart data={hoursByUser}>
101
+ <CartesianGrid strokeDasharray="3 3" className="stroke-muted" />
102
+ <XAxis dataKey="name" />
103
+ <YAxis />
104
+ <Tooltip />
105
+ <Bar dataKey="hours" radius={[6, 6, 0, 0]}>
106
+ {hoursByUser.map((item, index) => (
107
+ <Cell key={item.name} fill={chartColors[index % chartColors.length]} />
108
+ ))}
109
+ </Bar>
110
+ </BarChart>
111
+ </ResponsiveContainer>
112
+ </SectionCard>
113
+
114
+ <SectionCard title={t('charts.approvalStatus')} description={t('charts.approvalStatusDescription')}>
115
+ <ResponsiveContainer width="100%" height={280}>
116
+ <PieChart>
117
+ <Pie data={approvalStatusData} dataKey="value" nameKey="name" outerRadius={110}>
118
+ {approvalStatusData.map((item, index) => (
119
+ <Cell key={item.name} fill={chartColors[index % chartColors.length]} />
120
+ ))}
121
+ </Pie>
122
+ <Tooltip />
123
+ </PieChart>
124
+ </ResponsiveContainer>
125
+ </SectionCard>
126
+
127
+ <SectionCard title={t('charts.weeklyTrend')} description={t('charts.weeklyTrendDescription')}>
128
+ <ResponsiveContainer width="100%" height={280}>
129
+ <LineChart data={weeklyTrendData}>
130
+ <CartesianGrid strokeDasharray="3 3" className="stroke-muted" />
131
+ <XAxis dataKey="week" />
132
+ <YAxis />
133
+ <Tooltip />
134
+ <Line dataKey="hours" type="monotone" stroke="#1d4ed8" strokeWidth={3} />
135
+ </LineChart>
136
+ </ResponsiveContainer>
137
+ </SectionCard>
138
+ </div>
139
+
140
+ <SectionCard title={t('recentTable.title')} description={t('recentTable.description')}>
141
+ <Table>
142
+ <TableHeader>
143
+ <TableRow>
144
+ <TableHead>{t('recentTable.user')}</TableHead>
145
+ <TableHead>{t('recentTable.project')}</TableHead>
146
+ <TableHead>{t('recentTable.task')}</TableHead>
147
+ <TableHead>{t('recentTable.hours')}</TableHead>
148
+ <TableHead>{t('recentTable.status')}</TableHead>
149
+ </TableRow>
150
+ </TableHeader>
151
+ <TableBody>
152
+ {recentTimesheets.map((entry) => {
153
+ const user = users.find((item) => item.id === entry.userId);
154
+ const project = projects.find((item) => item.id === entry.projectId);
155
+ const task = tasks.find((item) => item.id === entry.taskId);
156
+
157
+ return (
158
+ <TableRow key={entry.id}>
159
+ <TableCell>{user?.name}</TableCell>
160
+ <TableCell>{project?.name}</TableCell>
161
+ <TableCell>{task?.title}</TableCell>
162
+ <TableCell>{formatHours(entry.hours)}</TableCell>
163
+ <TableCell>
164
+ <StatusBadge
165
+ label={getApprovalLabel(entry.status)}
166
+ className={getApprovalBadgeClasses(entry.status)}
167
+ />
168
+ </TableCell>
169
+ </TableRow>
170
+ );
171
+ })}
172
+ </TableBody>
173
+ </Table>
174
+ </SectionCard>
175
+ </Page>
176
+ );
177
+ }