@hed-hog/operations 0.0.303 → 0.0.304

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 (166) hide show
  1. package/README.md +200 -43
  2. package/dist/controllers/operations-approvals.controller.d.ts +9 -0
  3. package/dist/controllers/operations-approvals.controller.d.ts.map +1 -0
  4. package/dist/controllers/operations-approvals.controller.js +64 -0
  5. package/dist/controllers/operations-approvals.controller.js.map +1 -0
  6. package/dist/controllers/operations-collaborators.controller.d.ts +223 -0
  7. package/dist/controllers/operations-collaborators.controller.d.ts.map +1 -0
  8. package/dist/controllers/operations-collaborators.controller.js +96 -0
  9. package/dist/controllers/operations-collaborators.controller.js.map +1 -0
  10. package/dist/controllers/operations-contracts.controller.d.ts +683 -0
  11. package/dist/controllers/operations-contracts.controller.d.ts.map +1 -0
  12. package/dist/controllers/operations-contracts.controller.js +198 -0
  13. package/dist/controllers/operations-contracts.controller.js.map +1 -0
  14. package/dist/controllers/operations-org-structure.controller.d.ts +108 -0
  15. package/dist/controllers/operations-org-structure.controller.d.ts.map +1 -0
  16. package/dist/controllers/operations-org-structure.controller.js +143 -0
  17. package/dist/controllers/operations-org-structure.controller.js.map +1 -0
  18. package/dist/controllers/operations-projects.controller.d.ts +169 -0
  19. package/dist/controllers/operations-projects.controller.d.ts.map +1 -0
  20. package/dist/controllers/operations-projects.controller.js +87 -0
  21. package/dist/controllers/operations-projects.controller.js.map +1 -0
  22. package/dist/controllers/operations-tasks.controller.d.ts +54 -0
  23. package/dist/controllers/operations-tasks.controller.d.ts.map +1 -0
  24. package/dist/controllers/operations-tasks.controller.js +79 -0
  25. package/dist/controllers/operations-tasks.controller.js.map +1 -0
  26. package/dist/controllers/operations-timesheets.controller.d.ts +99 -0
  27. package/dist/controllers/operations-timesheets.controller.d.ts.map +1 -0
  28. package/dist/controllers/operations-timesheets.controller.js +154 -0
  29. package/dist/controllers/operations-timesheets.controller.js.map +1 -0
  30. package/dist/dto/create-collaborator-type.dto.d.ts +10 -0
  31. package/dist/dto/create-collaborator-type.dto.d.ts.map +1 -0
  32. package/dist/dto/create-collaborator-type.dto.js +56 -0
  33. package/dist/dto/create-collaborator-type.dto.js.map +1 -0
  34. package/dist/dto/create-collaborator.dto.d.ts +42 -0
  35. package/dist/dto/create-collaborator.dto.d.ts.map +1 -0
  36. package/dist/dto/create-collaborator.dto.js +228 -0
  37. package/dist/dto/create-collaborator.dto.js.map +1 -0
  38. package/dist/dto/create-schedule-adjustment-request.dto.d.ts +17 -0
  39. package/dist/dto/create-schedule-adjustment-request.dto.d.ts.map +1 -0
  40. package/dist/dto/create-schedule-adjustment-request.dto.js +89 -0
  41. package/dist/dto/create-schedule-adjustment-request.dto.js.map +1 -0
  42. package/dist/dto/create-task.dto.d.ts +8 -0
  43. package/dist/dto/create-task.dto.d.ts.map +1 -0
  44. package/dist/dto/create-task.dto.js +50 -0
  45. package/dist/dto/create-task.dto.js.map +1 -0
  46. package/dist/dto/create-time-off-request.dto.d.ts +9 -0
  47. package/dist/dto/create-time-off-request.dto.d.ts.map +1 -0
  48. package/dist/dto/create-time-off-request.dto.js +54 -0
  49. package/dist/dto/create-time-off-request.dto.js.map +1 -0
  50. package/dist/dto/create-timesheet-entry.dto.d.ts +12 -0
  51. package/dist/dto/create-timesheet-entry.dto.d.ts.map +1 -0
  52. package/dist/dto/create-timesheet-entry.dto.js +75 -0
  53. package/dist/dto/create-timesheet-entry.dto.js.map +1 -0
  54. package/dist/dto/list-collaborator-types.dto.d.ts +4 -0
  55. package/dist/dto/list-collaborator-types.dto.d.ts.map +1 -0
  56. package/dist/dto/list-collaborator-types.dto.js +29 -0
  57. package/dist/dto/list-collaborator-types.dto.js.map +1 -0
  58. package/dist/dto/list-collaborators.dto.d.ts +8 -0
  59. package/dist/dto/list-collaborators.dto.d.ts.map +1 -0
  60. package/dist/dto/list-collaborators.dto.js +42 -0
  61. package/dist/dto/list-collaborators.dto.js.map +1 -0
  62. package/dist/dto/list-project-options.dto.d.ts +4 -0
  63. package/dist/dto/list-project-options.dto.d.ts.map +1 -0
  64. package/dist/dto/list-project-options.dto.js +8 -0
  65. package/dist/dto/list-project-options.dto.js.map +1 -0
  66. package/dist/dto/list-tasks.dto.d.ts +7 -0
  67. package/dist/dto/list-tasks.dto.d.ts.map +1 -0
  68. package/dist/dto/list-tasks.dto.js +38 -0
  69. package/dist/dto/list-tasks.dto.js.map +1 -0
  70. package/dist/dto/list-timesheet-entries.dto.d.ts +10 -0
  71. package/dist/dto/list-timesheet-entries.dto.d.ts.map +1 -0
  72. package/dist/dto/list-timesheet-entries.dto.js +54 -0
  73. package/dist/dto/list-timesheet-entries.dto.js.map +1 -0
  74. package/dist/dto/update-collaborator-type.dto.d.ts +4 -0
  75. package/dist/dto/update-collaborator-type.dto.d.ts.map +1 -0
  76. package/dist/dto/update-collaborator-type.dto.js +8 -0
  77. package/dist/dto/update-collaborator-type.dto.js.map +1 -0
  78. package/dist/dto/update-collaborator.dto.d.ts +4 -0
  79. package/dist/dto/update-collaborator.dto.d.ts.map +1 -0
  80. package/dist/dto/update-collaborator.dto.js +8 -0
  81. package/dist/dto/update-collaborator.dto.js.map +1 -0
  82. package/dist/dto/update-task.dto.d.ts +8 -0
  83. package/dist/dto/update-task.dto.d.ts.map +1 -0
  84. package/dist/dto/update-task.dto.js +51 -0
  85. package/dist/dto/update-task.dto.js.map +1 -0
  86. package/dist/operations.controller.d.ts +0 -1045
  87. package/dist/operations.controller.d.ts.map +1 -1
  88. package/dist/operations.controller.js +0 -429
  89. package/dist/operations.controller.js.map +1 -1
  90. package/dist/operations.module.d.ts.map +1 -1
  91. package/dist/operations.module.js +23 -2
  92. package/dist/operations.module.js.map +1 -1
  93. package/dist/operations.service.d.ts +373 -8
  94. package/dist/operations.service.d.ts.map +1 -1
  95. package/dist/operations.service.js +1598 -111
  96. package/dist/operations.service.js.map +1 -1
  97. package/dist/operations.service.spec.js +315 -1
  98. package/dist/operations.service.spec.js.map +1 -1
  99. package/dist/services/shared/operations-access.service.d.ts +16 -0
  100. package/dist/services/shared/operations-access.service.d.ts.map +1 -0
  101. package/dist/services/shared/operations-access.service.js +48 -0
  102. package/dist/services/shared/operations-access.service.js.map +1 -0
  103. package/hedhog/data/dashboard.yaml +20 -0
  104. package/hedhog/data/dashboard_component.yaml +274 -0
  105. package/hedhog/data/dashboard_component_role.yaml +174 -0
  106. package/hedhog/data/dashboard_item.yaml +299 -0
  107. package/hedhog/data/dashboard_role.yaml +20 -0
  108. package/hedhog/data/menu.yaml +30 -13
  109. package/hedhog/data/operations_collaborator_type.yaml +76 -0
  110. package/hedhog/data/route.yaml +183 -0
  111. package/hedhog/frontend/app/_components/async-options-combobox.tsx.ejs +231 -0
  112. package/hedhog/frontend/app/_components/collaborator-details-screen.tsx.ejs +134 -49
  113. package/hedhog/frontend/app/_components/collaborator-form-screen.tsx.ejs +772 -93
  114. package/hedhog/frontend/app/_components/department-select-with-create.tsx.ejs +38 -16
  115. package/hedhog/frontend/app/_components/project-form-screen.tsx.ejs +875 -632
  116. package/hedhog/frontend/app/_components/timesheet-task-create-sheet.tsx.ejs +213 -0
  117. package/hedhog/frontend/app/_lib/api.ts.ejs +30 -1
  118. package/hedhog/frontend/app/_lib/types.ts.ejs +142 -39
  119. package/hedhog/frontend/app/_lib/utils/format.ts.ejs +33 -2
  120. package/hedhog/frontend/app/approvals/page.tsx.ejs +116 -98
  121. package/hedhog/frontend/app/collaborator-types/page.tsx.ejs +502 -0
  122. package/hedhog/frontend/app/collaborators/page.tsx.ejs +109 -68
  123. package/hedhog/frontend/app/contracts/templates/page.tsx.ejs +11 -9
  124. package/hedhog/frontend/app/departments/page.tsx.ejs +1 -1
  125. package/hedhog/frontend/app/projects/page.tsx.ejs +5 -1
  126. package/hedhog/frontend/app/schedule-adjustments/page.tsx.ejs +244 -120
  127. package/hedhog/frontend/app/team/page.tsx.ejs +15 -2
  128. package/hedhog/frontend/app/time-off/page.tsx.ejs +158 -82
  129. package/hedhog/frontend/app/timesheets/page.tsx.ejs +814 -357
  130. package/hedhog/frontend/messages/en.json +243 -51
  131. package/hedhog/frontend/messages/pt.json +458 -268
  132. package/hedhog/table/operations_collaborator.yaml +26 -13
  133. package/hedhog/table/operations_collaborator_equity_participation.yaml +43 -0
  134. package/hedhog/table/operations_collaborator_type.yaml +33 -0
  135. package/hedhog/table/operations_job_title.yaml +24 -0
  136. package/hedhog/table/operations_project_assignment.yaml +9 -0
  137. package/hedhog/table/operations_project_role.yaml +39 -0
  138. package/hedhog/table/operations_task.yaml +30 -0
  139. package/hedhog/table/operations_timesheet_entry.yaml +12 -0
  140. package/package.json +6 -6
  141. package/src/controllers/operations-approvals.controller.ts +24 -0
  142. package/src/controllers/operations-collaborators.controller.ts +60 -0
  143. package/src/controllers/operations-contracts.controller.ts +138 -0
  144. package/src/controllers/operations-org-structure.controller.ts +92 -0
  145. package/src/controllers/operations-projects.controller.ts +50 -0
  146. package/src/controllers/operations-tasks.controller.ts +52 -0
  147. package/src/controllers/operations-timesheets.controller.ts +100 -0
  148. package/src/dto/create-collaborator-type.dto.ts +43 -0
  149. package/src/dto/create-collaborator.dto.ts +223 -0
  150. package/src/dto/create-schedule-adjustment-request.dto.ts +91 -0
  151. package/src/dto/create-task.dto.ts +35 -0
  152. package/src/dto/create-time-off-request.dto.ts +53 -0
  153. package/src/dto/create-timesheet-entry.dto.ts +67 -0
  154. package/src/dto/list-collaborator-types.dto.ts +15 -0
  155. package/src/dto/list-collaborators.dto.ts +30 -0
  156. package/src/dto/list-project-options.dto.ts +3 -0
  157. package/src/dto/list-tasks.dto.ts +25 -0
  158. package/src/dto/list-timesheet-entries.dto.ts +40 -0
  159. package/src/dto/update-collaborator-type.dto.ts +3 -0
  160. package/src/dto/update-collaborator.dto.ts +3 -0
  161. package/src/dto/update-task.dto.ts +36 -0
  162. package/src/operations.controller.ts +1 -278
  163. package/src/operations.module.ts +23 -2
  164. package/src/operations.service.spec.ts +450 -0
  165. package/src/operations.service.ts +4641 -2163
  166. package/src/services/shared/operations-access.service.ts +52 -0
@@ -23,7 +23,6 @@ import {
23
23
  import { ToggleGroup, ToggleGroupItem } from '@/components/ui/toggle-group';
24
24
  import { useApp, useQuery } from '@hed-hog/next-app-provider';
25
25
  import {
26
- Building2,
27
26
  CalendarDays,
28
27
  FileText,
29
28
  LayoutGrid,
@@ -43,8 +42,12 @@ import { OperationsHeader } from '../_components/operations-header';
43
42
  import { StatusBadge } from '../_components/status-badge';
44
43
  import { fetchOperations, mutateOperations } from '../_lib/api';
45
44
  import { useOperationsAccess } from '../_lib/hooks/use-operations-access';
46
- import type { OperationsCollaborator } from '../_lib/types';
45
+ import type {
46
+ OperationsCollaborator,
47
+ OperationsCollaboratorType,
48
+ } from '../_lib/types';
47
49
  import {
50
+ formatCurrency,
48
51
  formatDate,
49
52
  formatEnumLabel,
50
53
  formatHours,
@@ -136,23 +139,6 @@ export default function OperationsCollaboratorsPage() {
136
139
  }
137
140
  };
138
141
 
139
- const getCollaboratorTypeLabel = (value?: string | null) => {
140
- switch (value) {
141
- case 'clt':
142
- return formT('options.collaboratorTypes.clt');
143
- case 'pj':
144
- return formT('options.collaboratorTypes.pj');
145
- case 'freelancer':
146
- return formT('options.collaboratorTypes.freelancer');
147
- case 'intern':
148
- return formT('options.collaboratorTypes.intern');
149
- case 'other':
150
- return formT('options.collaboratorTypes.other');
151
- default:
152
- return formatEnumLabel(value);
153
- }
154
- };
155
-
156
142
  const getStatusLabel = (value?: string | null) => {
157
143
  switch (value) {
158
144
  case 'active':
@@ -180,6 +166,28 @@ export default function OperationsCollaboratorsPage() {
180
166
  ),
181
167
  });
182
168
 
169
+ const { data: collaboratorTypes = [] } = useQuery<OperationsCollaboratorType[]>({
170
+ queryKey: ['operations-collaborator-types-list', currentLocaleCode],
171
+ enabled: access.isCollaborator,
172
+ queryFn: () =>
173
+ fetchOperations<OperationsCollaboratorType[]>(
174
+ request,
175
+ '/operations/collaborator-types?active=true'
176
+ ),
177
+ });
178
+
179
+ const getCollaboratorTypeLabel = (
180
+ slug?: string | null,
181
+ fallbackName?: string | null
182
+ ) => {
183
+ if (fallbackName) {
184
+ return fallbackName;
185
+ }
186
+
187
+ const matchedType = collaboratorTypes.find((item) => item.slug === slug);
188
+ return matchedType?.name ?? formatEnumLabel(slug);
189
+ };
190
+
183
191
  const filteredRows = useMemo(
184
192
  () =>
185
193
  collaborators.filter((item) => {
@@ -201,7 +209,10 @@ export default function OperationsCollaboratorsPage() {
201
209
  const matchesStatus =
202
210
  statusFilter === 'all' ? true : item.status === statusFilter;
203
211
  const matchesType =
204
- typeFilter === 'all' ? true : item.collaboratorType === typeFilter;
212
+ typeFilter === 'all'
213
+ ? true
214
+ : item.collaboratorTypeSlug === typeFilter ||
215
+ item.collaboratorType === typeFilter;
205
216
  return matchesSearch && matchesStatus && matchesType;
206
217
  }),
207
218
  [collaborators, search, statusFilter, typeFilter]
@@ -212,18 +223,21 @@ export default function OperationsCollaboratorsPage() {
212
223
  {
213
224
  key: 'total',
214
225
  title: t('cards.total'),
226
+ description: t('cards.totalDescription'),
215
227
  value: collaborators.length,
216
228
  icon: Users,
217
229
  },
218
230
  {
219
231
  key: 'active',
220
232
  title: t('cards.active'),
233
+ description: t('cards.activeDescription'),
221
234
  value: collaborators.filter((item) => item.status === 'active').length,
222
235
  icon: UserCheck,
223
236
  },
224
237
  {
225
238
  key: 'onLeave',
226
239
  title: t('cards.onLeave'),
240
+ description: t('cards.onLeaveDescription'),
227
241
  value: collaborators.filter((item) => item.status === 'on_leave')
228
242
  .length,
229
243
  icon: CalendarDays,
@@ -231,6 +245,7 @@ export default function OperationsCollaboratorsPage() {
231
245
  {
232
246
  key: 'withContracts',
233
247
  title: t('cards.withContracts'),
248
+ description: t('cards.withContractsDescription'),
234
249
  value: collaborators.filter((item) => Boolean(item.contractId)).length,
235
250
  icon: FileText,
236
251
  },
@@ -277,12 +292,6 @@ export default function OperationsCollaboratorsPage() {
277
292
  actions={
278
293
  access.isDirector ? (
279
294
  <div className="flex flex-wrap gap-2">
280
- <Button variant="outline" size="sm" asChild>
281
- <Link href="/operations/departments">
282
- <Building2 className="size-4" />
283
- {commonT('actions.manageDepartments')}
284
- </Link>
285
- </Button>
286
295
  <Button size="sm" onClick={openCreateSheet}>
287
296
  {commonT('actions.create')}
288
297
  </Button>
@@ -309,17 +318,10 @@ export default function OperationsCollaboratorsPage() {
309
318
  placeholder: commonT('labels.collaboratorType'),
310
319
  options: [
311
320
  { value: 'all', label: commonT('filters.allTypes') },
312
- { value: 'clt', label: getCollaboratorTypeLabel('clt') },
313
- { value: 'pj', label: getCollaboratorTypeLabel('pj') },
314
- {
315
- value: 'freelancer',
316
- label: getCollaboratorTypeLabel('freelancer'),
317
- },
318
- {
319
- value: 'intern',
320
- label: getCollaboratorTypeLabel('intern'),
321
- },
322
- { value: 'other', label: getCollaboratorTypeLabel('other') },
321
+ ...collaboratorTypes.map((item) => ({
322
+ value: item.slug,
323
+ label: item.name,
324
+ })),
323
325
  ],
324
326
  },
325
327
  {
@@ -377,7 +379,8 @@ export default function OperationsCollaboratorsPage() {
377
379
  {filteredRows.map((collaborator) => (
378
380
  <Card
379
381
  key={collaborator.id}
380
- className="overflow-hidden border-border/60 py-0 shadow-sm transition-all hover:-translate-y-0.5 hover:shadow-md"
382
+ className="cursor-pointer overflow-hidden border-border/60 py-0 shadow-sm transition-all hover:-translate-y-0.5 hover:shadow-md"
383
+ onClick={() => openEditSheet(collaborator.id)}
381
384
  >
382
385
  <CardContent className="space-y-4 p-4">
383
386
  <div className="flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between">
@@ -410,7 +413,11 @@ export default function OperationsCollaboratorsPage() {
410
413
 
411
414
  <div className="flex flex-wrap gap-2">
412
415
  <span className="inline-flex items-center rounded-full bg-primary/10 px-2.5 py-1 text-xs font-medium text-primary">
413
- {getCollaboratorTypeLabel(collaborator.collaboratorType)}
416
+ {getCollaboratorTypeLabel(
417
+ collaborator.collaboratorTypeSlug ??
418
+ collaborator.collaboratorType,
419
+ collaborator.collaboratorTypeName
420
+ )}
414
421
  </span>
415
422
  {collaborator.department ? (
416
423
  <span className="inline-flex items-center rounded-full bg-muted px-2.5 py-1 text-xs font-medium text-muted-foreground">
@@ -433,6 +440,14 @@ export default function OperationsCollaboratorsPage() {
433
440
  </span>{' '}
434
441
  {formatHours(collaborator.weeklyCapacityHours)}
435
442
  </div>
443
+ <div>
444
+ <span className="font-medium text-foreground">
445
+ {formT('fields.compensationAmount')}:
446
+ </span>{' '}
447
+ {collaborator.compensationAmount != null
448
+ ? formatCurrency(collaborator.compensationAmount)
449
+ : commonT('labels.notAvailable')}
450
+ </div>
436
451
  <div>
437
452
  <span className="font-medium text-foreground">
438
453
  {commonT('labels.startDate')}:
@@ -443,22 +458,21 @@ export default function OperationsCollaboratorsPage() {
443
458
  currentLocaleCode
444
459
  )}
445
460
  </div>
446
- <div className="flex items-center gap-2">
461
+ </div>
462
+
463
+ {collaborator.contractStatus ? (
464
+ <div className="flex items-center gap-2 text-xs text-muted-foreground">
447
465
  <span className="font-medium text-foreground">
448
466
  {commonT('labels.contractStatus')}:
449
467
  </span>
450
- {collaborator.contractStatus ? (
451
- <StatusBadge
452
- label={getStatusLabel(collaborator.contractStatus)}
453
- className={getStatusBadgeClass(
454
- collaborator.contractStatus
455
- )}
456
- />
457
- ) : (
458
- <span>{commonT('labels.notAssigned')}</span>
459
- )}
468
+ <StatusBadge
469
+ label={getStatusLabel(collaborator.contractStatus)}
470
+ className={getStatusBadgeClass(
471
+ collaborator.contractStatus
472
+ )}
473
+ />
460
474
  </div>
461
- </div>
475
+ ) : null}
462
476
 
463
477
  <div className="flex flex-wrap justify-end gap-2 border-t border-border/60 pt-3">
464
478
  {access.isDirector ? (
@@ -530,9 +544,9 @@ export default function OperationsCollaboratorsPage() {
530
544
  {commonT('labels.weeklyCapacity')}
531
545
  </TableHead>
532
546
  <TableHead className="hidden 2xl:table-cell">
533
- {commonT('labels.contractStatus')}
547
+ {formT('fields.compensationAmount')}
534
548
  </TableHead>
535
- <TableHead className="hidden 2xl:table-cell">
549
+ <TableHead className="hidden xl:table-cell">
536
550
  {commonT('labels.startDate')}
537
551
  </TableHead>
538
552
  <TableHead className="w-30 text-right sm:w-42.5">
@@ -542,7 +556,11 @@ export default function OperationsCollaboratorsPage() {
542
556
  </TableHeader>
543
557
  <TableBody>
544
558
  {filteredRows.map((collaborator) => (
545
- <TableRow key={collaborator.id} className="hover:bg-muted/30">
559
+ <TableRow
560
+ key={collaborator.id}
561
+ className="cursor-pointer hover:bg-muted/30"
562
+ onClick={() => openEditSheet(collaborator.id)}
563
+ >
546
564
  <TableCell>
547
565
  <div className="flex items-center gap-3">
548
566
  <Avatar className="h-9 w-9 border border-border/60 bg-muted">
@@ -564,16 +582,46 @@ export default function OperationsCollaboratorsPage() {
564
582
  {[
565
583
  collaborator.code,
566
584
  collaborator.department,
567
- collaborator.title,
568
585
  ]
569
586
  .filter(Boolean)
570
- .join(' • ')}
587
+ .join(' • ') ||
588
+ collaborator.title ||
589
+ commonT('labels.notAvailable')}
590
+ </div>
591
+ <div className="mt-1 flex flex-wrap gap-x-3 gap-y-1 text-[11px] text-muted-foreground lg:hidden">
592
+ <span>
593
+ <span className="font-medium text-foreground/80">
594
+ {commonT('labels.supervisor')}:
595
+ </span>{' '}
596
+ {collaborator.supervisorName ||
597
+ commonT('labels.notAssigned')}
598
+ </span>
599
+ <span>
600
+ <span className="font-medium text-foreground/80">
601
+ {commonT('labels.weeklyCapacity')}:
602
+ </span>{' '}
603
+ {formatHours(collaborator.weeklyCapacityHours)}
604
+ </span>
605
+ <span>
606
+ <span className="font-medium text-foreground/80">
607
+ {commonT('labels.startDate')}:
608
+ </span>{' '}
609
+ {formatDate(
610
+ collaborator.joinedAt,
611
+ getSettingValue,
612
+ currentLocaleCode
613
+ )}
614
+ </span>
571
615
  </div>
572
616
  </div>
573
617
  </div>
574
618
  </TableCell>
575
619
  <TableCell className="hidden md:table-cell">
576
- {getCollaboratorTypeLabel(collaborator.collaboratorType)}
620
+ {getCollaboratorTypeLabel(
621
+ collaborator.collaboratorTypeSlug ??
622
+ collaborator.collaboratorType,
623
+ collaborator.collaboratorTypeName
624
+ )}
577
625
  </TableCell>
578
626
  <TableCell className="hidden max-w-55 sm:table-cell">
579
627
  <div className="truncate">
@@ -598,18 +646,11 @@ export default function OperationsCollaboratorsPage() {
598
646
  {formatHours(collaborator.weeklyCapacityHours)}
599
647
  </TableCell>
600
648
  <TableCell className="hidden 2xl:table-cell">
601
- {collaborator.contractStatus ? (
602
- <StatusBadge
603
- label={getStatusLabel(collaborator.contractStatus)}
604
- className={getStatusBadgeClass(
605
- collaborator.contractStatus
606
- )}
607
- />
608
- ) : (
609
- commonT('labels.notAssigned')
610
- )}
649
+ {collaborator.compensationAmount != null
650
+ ? formatCurrency(collaborator.compensationAmount)
651
+ : commonT('labels.notAvailable')}
611
652
  </TableCell>
612
- <TableCell className="hidden 2xl:table-cell">
653
+ <TableCell className="hidden xl:table-cell">
613
654
  {formatDate(
614
655
  collaborator.joinedAt,
615
656
  getSettingValue,
@@ -362,15 +362,17 @@ export default function OperationsContractTemplatesPage() {
362
362
  <SheetDescription>{t('sheet.description')}</SheetDescription>
363
363
  </SheetHeader>
364
364
 
365
- <ContractTemplateFormScreen
366
- templateId={editingTemplate?.id}
367
- onCancel={() => setIsSheetOpen(false)}
368
- onSaved={async () => {
369
- setIsSheetOpen(false);
370
- setEditingTemplate(null);
371
- await refetch();
372
- }}
373
- />
365
+ <div className="px-4">
366
+ <ContractTemplateFormScreen
367
+ templateId={editingTemplate?.id}
368
+ onCancel={() => setIsSheetOpen(false)}
369
+ onSaved={async () => {
370
+ setIsSheetOpen(false);
371
+ setEditingTemplate(null);
372
+ await refetch();
373
+ }}
374
+ />
375
+ </div>
374
376
  </SheetContent>
375
377
  </Sheet>
376
378
  </Page>
@@ -370,7 +370,7 @@ export default function OperationsDepartmentsPage() {
370
370
  </SheetHeader>
371
371
 
372
372
  <form
373
- className="mt-6 space-y-4"
373
+ className="mt-6 space-y-4 px-4"
374
374
  onSubmit={(event) => {
375
375
  event.preventDefault();
376
376
  void saveDepartment();
@@ -137,24 +137,28 @@ export default function OperationsProjectsPage() {
137
137
  {
138
138
  key: 'total',
139
139
  title: t('cards.total'),
140
+ description: t('cards.totalDescription'),
140
141
  value: projects.length,
141
142
  icon: FolderKanban,
142
143
  },
143
144
  {
144
145
  key: 'active',
145
146
  title: t('cards.active'),
147
+ description: t('cards.activeDescription'),
146
148
  value: projects.filter((item) => item.status === 'active').length,
147
149
  icon: PlayCircle,
148
150
  },
149
151
  {
150
152
  key: 'atRisk',
151
153
  title: t('cards.atRisk'),
154
+ description: t('cards.atRiskDescription'),
152
155
  value: projects.filter((item) => item.status === 'at_risk').length,
153
156
  icon: ShieldAlert,
154
157
  },
155
158
  {
156
159
  key: 'upcomingDeliveries',
157
160
  title: t('cards.upcomingDeliveries'),
161
+ description: t('cards.upcomingDeliveriesDescription'),
158
162
  value: projects.filter((item) => Boolean(item.endDate)).length,
159
163
  icon: CalendarDays,
160
164
  },
@@ -255,7 +259,7 @@ export default function OperationsProjectsPage() {
255
259
  </TableHeader>
256
260
  <TableBody>
257
261
  {filteredRows.map((project) => (
258
- <TableRow key={project.id} className="hover:bg-muted/30">
262
+ <TableRow key={project.id} className="cursor-pointer hover:bg-muted/30">
259
263
  <TableCell>
260
264
  <div className="min-w-0">
261
265
  <div className="truncate font-medium">{project.name}</div>