@hed-hog/operations 0.0.3 → 0.0.286

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 +626 -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 +455 -60
  41. package/hedhog/frontend/app/_lib/mocks/tasks.mock.ts.ejs +117 -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 +156 -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 +155 -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 +202 -0
  59. package/hedhog/frontend/app/contracts/[id]/page.tsx.ejs +108 -108
  60. package/hedhog/frontend/app/contracts/page.tsx.ejs +181 -124
  61. package/hedhog/frontend/app/evaluations/page.tsx.ejs +278 -0
  62. package/hedhog/frontend/app/goals/page.tsx.ejs +171 -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 +936 -186
  68. package/hedhog/frontend/app/projects/page.tsx.ejs +1074 -111
  69. package/hedhog/frontend/app/rewards/page.tsx.ejs +196 -0
  70. package/hedhog/frontend/app/tasks/page.tsx.ejs +999 -47
  71. package/hedhog/frontend/app/timesheets/page.tsx.ejs +126 -126
  72. package/hedhog/frontend/messages/en.json +454 -142
  73. package/hedhog/frontend/messages/pt.json +454 -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 +4 -4
  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
@@ -0,0 +1,196 @@
1
+ 'use client';
2
+
3
+ import { Page, PaginationFooter, SearchBar } from '@/components/entity-list';
4
+ import { Badge } from '@/components/ui/badge';
5
+ import {
6
+ Table,
7
+ TableBody,
8
+ TableCell,
9
+ TableHead,
10
+ TableHeader,
11
+ TableRow,
12
+ } from '@/components/ui/table';
13
+ import { Gift } from 'lucide-react';
14
+ import { useTranslations } from 'next-intl';
15
+ import { useMemo, useState } from 'react';
16
+ import { OperationsHeader } from '../_components/operations-header';
17
+ import { SectionCard } from '../_components/section-card';
18
+ import { StatusBadge } from '../_components/status-badge';
19
+ import { useOperationsGrowthData } from '../_lib/hooks/use-operations-growth-data';
20
+ import { formatCurrency, formatDate } from '../_lib/utils/format';
21
+ import { getGrowthRewardBadgeClasses, humanizeGrowthStatus } from '../_lib/utils/growth';
22
+
23
+ const PAGE_SIZE_OPTIONS = [4, 8, 12];
24
+ const DEFAULT_PAGE_SIZE = PAGE_SIZE_OPTIONS[0] ?? 4;
25
+
26
+ export default function OperationsRewardsPage() {
27
+ const t = useTranslations('operations.RewardsPage');
28
+ const { rewards, recognitions, users, projects } = useOperationsGrowthData();
29
+ const [searchInput, setSearchInput] = useState('');
30
+ const [search, setSearch] = useState('');
31
+ const [employeeFilter, setEmployeeFilter] = useState('all');
32
+ const [currentPage, setCurrentPage] = useState(1);
33
+ const [pageSize, setPageSize] = useState(DEFAULT_PAGE_SIZE);
34
+
35
+ const filteredRewards = useMemo(
36
+ () =>
37
+ rewards.filter((reward) => {
38
+ const employee = users.find((item) => item.id === reward.employeeId);
39
+ const haystack = `${employee?.name ?? ''} ${reward.description} ${reward.type} ${reward.origin}`;
40
+ const matchesSearch = haystack.toLowerCase().includes(search.toLowerCase());
41
+ const matchesEmployee =
42
+ employeeFilter === 'all' || reward.employeeId === employeeFilter;
43
+
44
+ return matchesSearch && matchesEmployee;
45
+ }),
46
+ [employeeFilter, rewards, search, users]
47
+ );
48
+
49
+ const totalPages = Math.max(1, Math.ceil(filteredRewards.length / pageSize));
50
+ const safePage = Math.min(Math.max(currentPage, 1), totalPages);
51
+ const paginatedRewards = filteredRewards.slice(
52
+ (safePage - 1) * pageSize,
53
+ safePage * pageSize
54
+ );
55
+
56
+ return (
57
+ <Page>
58
+ <OperationsHeader
59
+ title={t('title')}
60
+ description={t('description')}
61
+ current={t('breadcrumb')}
62
+ />
63
+
64
+ <SearchBar
65
+ className="mb-6"
66
+ searchQuery={searchInput}
67
+ onSearchChange={setSearchInput}
68
+ onSearch={() => {
69
+ setSearch(searchInput);
70
+ setCurrentPage(1);
71
+ }}
72
+ placeholder={t('searchPlaceholder')}
73
+ controls={[
74
+ {
75
+ id: 'employee-filter',
76
+ type: 'select',
77
+ value: employeeFilter,
78
+ onChange: (value) => {
79
+ setEmployeeFilter(value);
80
+ setCurrentPage(1);
81
+ },
82
+ placeholder: t('filters.allEmployees'),
83
+ options: [
84
+ { value: 'all', label: t('filters.allEmployees') },
85
+ ...users.map((item) => ({ value: item.id, label: item.name })),
86
+ ],
87
+ },
88
+ ]}
89
+ />
90
+
91
+ <SectionCard title={t('rewardsTitle')} description={t('rewardsDescription')}>
92
+ <div className="space-y-4">
93
+ <Table>
94
+ <TableHeader>
95
+ <TableRow>
96
+ <TableHead>{t('columns.employee')}</TableHead>
97
+ <TableHead>{t('columns.type')}</TableHead>
98
+ <TableHead>{t('columns.origin')}</TableHead>
99
+ <TableHead>{t('columns.amount')}</TableHead>
100
+ <TableHead>{t('columns.score')}</TableHead>
101
+ <TableHead>{t('columns.status')}</TableHead>
102
+ </TableRow>
103
+ </TableHeader>
104
+ <TableBody>
105
+ {paginatedRewards.map((reward) => {
106
+ const employee = users.find((item) => item.id === reward.employeeId);
107
+
108
+ return (
109
+ <TableRow key={reward.id}>
110
+ <TableCell className="font-medium">{employee?.name}</TableCell>
111
+ <TableCell>{humanizeGrowthStatus(reward.type)}</TableCell>
112
+ <TableCell>{humanizeGrowthStatus(reward.origin)}</TableCell>
113
+ <TableCell>
114
+ {reward.amount && reward.currency
115
+ ? formatCurrency(reward.amount)
116
+ : t('notApplicable')}
117
+ </TableCell>
118
+ <TableCell>{reward.relatedScore ?? '-'}</TableCell>
119
+ <TableCell>
120
+ <StatusBadge
121
+ label={humanizeGrowthStatus(reward.status)}
122
+ className={getGrowthRewardBadgeClasses(reward.status)}
123
+ />
124
+ </TableCell>
125
+ </TableRow>
126
+ );
127
+ })}
128
+ </TableBody>
129
+ </Table>
130
+ <PaginationFooter
131
+ currentPage={safePage}
132
+ pageSize={pageSize}
133
+ totalItems={filteredRewards.length}
134
+ onPageChange={setCurrentPage}
135
+ onPageSizeChange={(value) => {
136
+ setPageSize(value);
137
+ setCurrentPage(1);
138
+ }}
139
+ pageSizeOptions={PAGE_SIZE_OPTIONS}
140
+ />
141
+ </div>
142
+ </SectionCard>
143
+
144
+ <SectionCard title={t('recognitionTitle')} description={t('recognitionDescription')}>
145
+ <div className="grid gap-4 lg:grid-cols-2">
146
+ {recognitions.map((recognition) => {
147
+ const employee = users.find((item) => item.id === recognition.employeeId);
148
+ const author = users.find((item) => item.id === recognition.authorId);
149
+ const project = projects.find((item) => item.id === recognition.projectId);
150
+
151
+ return (
152
+ <div key={recognition.id} className="rounded-lg border p-4">
153
+ <div className="mb-3 flex items-center justify-between gap-3">
154
+ <div>
155
+ <p className="font-medium">{employee?.name}</p>
156
+ <p className="text-muted-foreground text-sm">{author?.name}</p>
157
+ </div>
158
+ <Badge variant="secondary">+{recognition.relatedScore ?? 0}</Badge>
159
+ </div>
160
+ <p className="text-sm">{recognition.message}</p>
161
+ <div className="text-muted-foreground mt-3 flex items-center justify-between text-xs">
162
+ <span>{project?.name ?? t('withoutProject')}</span>
163
+ <span>{formatDate(recognition.date)}</span>
164
+ </div>
165
+ </div>
166
+ );
167
+ })}
168
+ </div>
169
+ </SectionCard>
170
+
171
+ <SectionCard title={t('highlightsTitle')} description={t('highlightsDescription')}>
172
+ <div className="grid gap-4 md:grid-cols-3">
173
+ <div className="rounded-lg border border-dashed border-slate-300 p-4">
174
+ <Gift className="mb-3 h-5 w-5 text-emerald-700" />
175
+ <p className="font-medium">{t('highlights.granted')}</p>
176
+ <p className="mt-2 text-2xl font-bold">
177
+ {rewards.filter((item) => item.status === 'granted').length}
178
+ </p>
179
+ </div>
180
+ <div className="rounded-lg border border-dashed border-slate-300 p-4">
181
+ <Gift className="mb-3 h-5 w-5 text-blue-700" />
182
+ <p className="font-medium">{t('highlights.publicRecognition')}</p>
183
+ <p className="mt-2 text-2xl font-bold">{recognitions.length}</p>
184
+ </div>
185
+ <div className="rounded-lg border border-dashed border-slate-300 p-4">
186
+ <Gift className="mb-3 h-5 w-5 text-orange-700" />
187
+ <p className="font-medium">{t('highlights.financial')}</p>
188
+ <p className="mt-2 text-2xl font-bold">
189
+ {rewards.filter((item) => item.type === 'financial' || item.type === 'bonus').length}
190
+ </p>
191
+ </div>
192
+ </div>
193
+ </SectionCard>
194
+ </Page>
195
+ );
196
+ }