@hed-hog/operations 0.0.332 → 0.0.338

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 (109) hide show
  1. package/dist/controllers/operations-collaborators.controller.d.ts +0 -54
  2. package/dist/controllers/operations-collaborators.controller.d.ts.map +1 -1
  3. package/dist/controllers/operations-collaborators.controller.js +0 -100
  4. package/dist/controllers/operations-collaborators.controller.js.map +1 -1
  5. package/dist/controllers/operations-contracts.controller.d.ts +12 -12
  6. package/dist/operations.service.d.ts +0 -76
  7. package/dist/operations.service.d.ts.map +1 -1
  8. package/dist/operations.service.js +7 -230
  9. package/dist/operations.service.js.map +1 -1
  10. package/dist/operations.service.spec.js +6 -0
  11. package/dist/operations.service.spec.js.map +1 -1
  12. package/hedhog/data/menu.yaml +8 -27
  13. package/hedhog/data/route.yaml +0 -72
  14. package/hedhog/frontend/app/_components/collaborator-details-screen.tsx.ejs +476 -0
  15. package/hedhog/frontend/app/_components/collaborator-form-screen.tsx.ejs +3 -39
  16. package/hedhog/frontend/app/_components/collaborator-select-with-create.tsx.ejs +261 -0
  17. package/hedhog/frontend/app/_components/collaborator-tasks-tab.tsx.ejs +358 -358
  18. package/hedhog/frontend/app/_components/collaborator-timesheets-tab.tsx.ejs +6 -6
  19. package/hedhog/frontend/app/_components/contract-content-editor.tsx.ejs +258 -0
  20. package/hedhog/frontend/app/_components/my-project-summary-screen.tsx.ejs +5 -4
  21. package/hedhog/frontend/app/_components/person-select-with-create.tsx.ejs +1 -0
  22. package/hedhog/frontend/app/_components/project-assignments-tab.tsx.ejs +10 -218
  23. package/hedhog/frontend/app/_components/project-cost-report-screen.tsx.ejs +23 -23
  24. package/hedhog/frontend/app/_components/project-details-screen.tsx.ejs +24 -708
  25. package/hedhog/frontend/app/_components/project-form-screen.tsx.ejs +38 -158
  26. package/hedhog/frontend/app/_components/task-detail-sheet.tsx.ejs +1 -5
  27. package/hedhog/frontend/app/_components/task-form-sheet.tsx.ejs +629 -629
  28. package/hedhog/frontend/app/_lib/api.ts.ejs +0 -151
  29. package/hedhog/frontend/app/_lib/types.ts.ejs +0 -1
  30. package/hedhog/frontend/app/_lib/utils/task-ui.ts.ejs +0 -18
  31. package/hedhog/frontend/app/my-projects/page.tsx.ejs +2 -16
  32. package/hedhog/frontend/app/my-tasks/page.tsx.ejs +86 -24
  33. package/hedhog/frontend/app/projects/page.tsx.ejs +6 -42
  34. package/hedhog/frontend/messages/en.json +2 -96
  35. package/hedhog/frontend/messages/operations/operations/en.json +2100 -0
  36. package/hedhog/frontend/messages/operations/operations/pt.json +2111 -0
  37. package/hedhog/frontend/messages/pt.json +2 -96
  38. package/hedhog/frontend/widgets/capacity-distribution.tsx.ejs +16 -16
  39. package/hedhog/frontend/widgets/effort-by-project.tsx.ejs +16 -16
  40. package/hedhog/frontend/widgets/headcount-by-area.tsx.ejs +16 -16
  41. package/hedhog/frontend/widgets/index.ts.ejs +25 -25
  42. package/hedhog/frontend/widgets/managed-projects-status.tsx.ejs +16 -16
  43. package/hedhog/frontend/widgets/my-hours-period-kpi.tsx.ejs +16 -16
  44. package/hedhog/frontend/widgets/my-open-requests-kpi.tsx.ejs +16 -16
  45. package/hedhog/frontend/widgets/my-pending-requests-list.tsx.ejs +16 -16
  46. package/hedhog/frontend/widgets/my-project-allocations-kpi.tsx.ejs +16 -16
  47. package/hedhog/frontend/widgets/my-quick-actions.tsx.ejs +16 -16
  48. package/hedhog/frontend/widgets/my-relevant-deadlines.tsx.ejs +16 -16
  49. package/hedhog/frontend/widgets/my-timesheet-status-kpi.tsx.ejs +16 -16
  50. package/hedhog/frontend/widgets/my-weekly-journey.tsx.ejs +16 -16
  51. package/hedhog/frontend/widgets/portfolio-costs-kpi.tsx.ejs +16 -16
  52. package/hedhog/frontend/widgets/portfolio-effort-kpi.tsx.ejs +16 -16
  53. package/hedhog/frontend/widgets/portfolio-projects-kpi.tsx.ejs +16 -16
  54. package/hedhog/frontend/widgets/portfolio-risk-kpi.tsx.ejs +16 -16
  55. package/hedhog/frontend/widgets/project-status-overview.tsx.ejs +16 -16
  56. package/hedhog/frontend/widgets/shared-operations-widget.tsx.ejs +169 -169
  57. package/hedhog/frontend/widgets/strategic-deadlines.tsx.ejs +16 -16
  58. package/hedhog/frontend/widgets/team-approval-queue.tsx.ejs +16 -16
  59. package/hedhog/frontend/widgets/team-capacity-kpi.tsx.ejs +16 -16
  60. package/hedhog/frontend/widgets/team-headcount-kpi.tsx.ejs +16 -16
  61. package/hedhog/frontend/widgets/team-hours-kpi.tsx.ejs +16 -16
  62. package/hedhog/frontend/widgets/team-pending-approvals-kpi.tsx.ejs +16 -16
  63. package/hedhog/frontend/widgets/team-utilization-overview.tsx.ejs +16 -16
  64. package/hedhog/frontend/widgets/team-workload-alerts.tsx.ejs +16 -16
  65. package/hedhog/table/operations_collaborator.yaml +8 -8
  66. package/hedhog/table/operations_task.yaml +76 -76
  67. package/hedhog/table/operations_task_activity.yaml +51 -51
  68. package/package.json +6 -6
  69. package/src/controllers/operations-collaborators.controller.ts +8 -117
  70. package/src/controllers/operations-tasks.controller.ts +156 -156
  71. package/src/dashboard/widgets/MyQuickActions.tsx +22 -22
  72. package/src/dto/create-collaborator.dto.ts +4 -4
  73. package/src/operations.service.spec.ts +1006 -988
  74. package/src/operations.service.ts +7 -323
  75. package/dist/dto/create-collaborator-invoice.dto.d.ts +0 -11
  76. package/dist/dto/create-collaborator-invoice.dto.d.ts.map +0 -1
  77. package/dist/dto/create-collaborator-invoice.dto.js +0 -55
  78. package/dist/dto/create-collaborator-invoice.dto.js.map +0 -1
  79. package/dist/dto/create-collaborator-payment.dto.d.ts +0 -10
  80. package/dist/dto/create-collaborator-payment.dto.d.ts.map +0 -1
  81. package/dist/dto/create-collaborator-payment.dto.js +0 -50
  82. package/dist/dto/create-collaborator-payment.dto.js.map +0 -1
  83. package/dist/dto/list-collaborator-invoice.dto.d.ts +0 -4
  84. package/dist/dto/list-collaborator-invoice.dto.d.ts.map +0 -1
  85. package/dist/dto/list-collaborator-invoice.dto.js +0 -8
  86. package/dist/dto/list-collaborator-invoice.dto.js.map +0 -1
  87. package/dist/dto/list-collaborator-payment.dto.d.ts +0 -4
  88. package/dist/dto/list-collaborator-payment.dto.d.ts.map +0 -1
  89. package/dist/dto/list-collaborator-payment.dto.js +0 -8
  90. package/dist/dto/list-collaborator-payment.dto.js.map +0 -1
  91. package/dist/dto/update-collaborator-invoice.dto.d.ts +0 -6
  92. package/dist/dto/update-collaborator-invoice.dto.d.ts.map +0 -1
  93. package/dist/dto/update-collaborator-invoice.dto.js +0 -9
  94. package/dist/dto/update-collaborator-invoice.dto.js.map +0 -1
  95. package/dist/dto/update-collaborator-payment.dto.d.ts +0 -6
  96. package/dist/dto/update-collaborator-payment.dto.d.ts.map +0 -1
  97. package/dist/dto/update-collaborator-payment.dto.js +0 -9
  98. package/dist/dto/update-collaborator-payment.dto.js.map +0 -1
  99. package/hedhog/frontend/app/_components/collaborator-invoices-tab.tsx.ejs +0 -443
  100. package/hedhog/frontend/app/_components/collaborator-payment-history-tab.tsx.ejs +0 -429
  101. package/hedhog/frontend/app/tasks-gantt/page.tsx.ejs +0 -953
  102. package/hedhog/table/operations_collaborator_invoice.yaml +0 -35
  103. package/hedhog/table/operations_collaborator_payment.yaml +0 -32
  104. package/src/dto/create-collaborator-invoice.dto.ts +0 -39
  105. package/src/dto/create-collaborator-payment.dto.ts +0 -35
  106. package/src/dto/list-collaborator-invoice.dto.ts +0 -3
  107. package/src/dto/list-collaborator-payment.dto.ts +0 -3
  108. package/src/dto/update-collaborator-invoice.dto.ts +0 -6
  109. package/src/dto/update-collaborator-payment.dto.ts +0 -6
@@ -0,0 +1,476 @@
1
+ 'use client';
2
+
3
+ import { EmptyState, Page } from '@/components/entity-list';
4
+ import { Button } from '@/components/ui/button';
5
+ import { KpiCardsGrid } from '@/components/ui/kpi-cards-grid';
6
+ import {
7
+ Table,
8
+ TableBody,
9
+ TableCell,
10
+ TableHead,
11
+ TableHeader,
12
+ TableRow,
13
+ } from '@/components/ui/table';
14
+ import { useApp, useQuery } from '@hed-hog/next-app-provider';
15
+ import { Pencil, UserRound } from 'lucide-react';
16
+ import Link from 'next/link';
17
+ import { useTranslations } from 'next-intl';
18
+ import { OperationsHeader } from './operations-header';
19
+ import { SectionCard } from './section-card';
20
+ import { StatusBadge } from './status-badge';
21
+ import { fetchOperations } from '../_lib/api';
22
+ import type { OperationsCollaboratorDetails } from '../_lib/types';
23
+ import {
24
+ formatCurrency,
25
+ formatDate,
26
+ formatDateRange,
27
+ formatEnumLabel,
28
+ formatHours,
29
+ getStatusBadgeClass,
30
+ summarizeScheduleDays,
31
+ } from '../_lib/utils/format';
32
+ import { useOperationsAccess } from '../_lib/hooks/use-operations-access';
33
+
34
+ export function CollaboratorDetailsScreen({
35
+ collaboratorId,
36
+ }: {
37
+ collaboratorId: number;
38
+ }) {
39
+ const t = useTranslations('operations.CollaboratorDetailsPage');
40
+ const commonT = useTranslations('operations.Common');
41
+ const { request, currentLocaleCode, getSettingValue } = useApp();
42
+ const access = useOperationsAccess();
43
+
44
+ const { data: collaborator, refetch } =
45
+ useQuery<OperationsCollaboratorDetails>({
46
+ queryKey: [
47
+ 'operations-collaborator-details',
48
+ currentLocaleCode,
49
+ collaboratorId,
50
+ ],
51
+ queryFn: () =>
52
+ fetchOperations<OperationsCollaboratorDetails>(
53
+ request,
54
+ `/operations/collaborators/${collaboratorId}`
55
+ ),
56
+ });
57
+
58
+ type CompensationHistoryEntry = {
59
+ id: number;
60
+ collaboratorId: number;
61
+ amount: string;
62
+ effectiveDate: string | null;
63
+ actorUserId: number | null;
64
+ actorName: string | null;
65
+ notes: string | null;
66
+ createdAt: string;
67
+ };
68
+
69
+ const { data: compensationHistory = [] } =
70
+ useQuery<CompensationHistoryEntry[]>({
71
+ queryKey: [
72
+ 'operations-collaborator-compensation-history',
73
+ currentLocaleCode,
74
+ collaboratorId,
75
+ ],
76
+ enabled: access.isDirector,
77
+ queryFn: () =>
78
+ fetchOperations<CompensationHistoryEntry[]>(
79
+ request,
80
+ `/operations/collaborators/${collaboratorId}/compensation-history`
81
+ ),
82
+ });
83
+
84
+ if (!collaborator) {
85
+ return (
86
+ <Page>
87
+ <OperationsHeader
88
+ title={t('title')}
89
+ description={t('description')}
90
+ current={t('breadcrumb')}
91
+ />
92
+ <EmptyState
93
+ icon={<UserRound className="size-12" />}
94
+ title={commonT('states.emptyTitle')}
95
+ description={t('notFound')}
96
+ actionLabel={commonT('actions.refresh')}
97
+ onAction={() => void refetch()}
98
+ />
99
+ </Page>
100
+ );
101
+ }
102
+
103
+ const summaryCards = [
104
+ {
105
+ key: 'timesheets',
106
+ title: t('cards.timesheets'),
107
+ value: collaborator.timesheetSummary.totalTimesheets,
108
+ description: t('cards.timesheetsDescription', {
109
+ pending: collaborator.timesheetSummary.pendingTimesheets,
110
+ }),
111
+ },
112
+ {
113
+ key: 'hours',
114
+ title: t('cards.loggedHours'),
115
+ value: formatHours(collaborator.timesheetSummary.totalHours),
116
+ description: t('cards.loggedHoursDescription'),
117
+ },
118
+ {
119
+ key: 'timeOff',
120
+ title: t('cards.timeOff'),
121
+ value: collaborator.timeOffSummary.totalRequests,
122
+ description: t('cards.timeOffDescription', {
123
+ pending: collaborator.timeOffSummary.pendingRequests,
124
+ }),
125
+ },
126
+ {
127
+ key: 'assignments',
128
+ title: t('cards.assignments'),
129
+ value: collaborator.assignedProjects.length,
130
+ description: t('cards.assignmentsDescription'),
131
+ },
132
+ ];
133
+
134
+ return (
135
+ <Page>
136
+ <OperationsHeader
137
+ title={collaborator.displayName}
138
+ description={t('description')}
139
+ current={t('breadcrumb')}
140
+ actions={
141
+ access.isDirector ? (
142
+ <Button size="sm" asChild>
143
+ <Link href={`/operations/collaborators/${collaborator.id}/edit`}>
144
+ <Pencil className="size-4" />
145
+ {commonT('actions.edit')}
146
+ </Link>
147
+ </Button>
148
+ ) : undefined
149
+ }
150
+ />
151
+
152
+ <div className="grid gap-4 xl:grid-cols-4">
153
+ <SectionCard title={t('sections.profile')} className="xl:col-span-2">
154
+ <dl className="grid gap-3 md:grid-cols-2 text-sm">
155
+ <div>
156
+ <dt className="text-muted-foreground">
157
+ {commonT('labels.collaborator')}
158
+ </dt>
159
+ <dd className="font-medium">{collaborator.displayName}</dd>
160
+ </div>
161
+ <div>
162
+ <dt className="text-muted-foreground">
163
+ {commonT('labels.collaboratorType')}
164
+ </dt>
165
+ <dd className="font-medium">
166
+ {collaborator.collaboratorTypeName ||
167
+ formatEnumLabel(
168
+ collaborator.collaboratorTypeSlug ??
169
+ collaborator.collaboratorType
170
+ )}
171
+ </dd>
172
+ </div>
173
+ <div>
174
+ <dt className="text-muted-foreground">
175
+ {commonT('labels.department')}
176
+ </dt>
177
+ <dd className="font-medium">
178
+ {collaborator.department || commonT('labels.notAvailable')}
179
+ </dd>
180
+ </div>
181
+ <div>
182
+ <dt className="text-muted-foreground">
183
+ {commonT('labels.title')}
184
+ </dt>
185
+ <dd className="font-medium">
186
+ {collaborator.title || commonT('labels.notAvailable')}
187
+ </dd>
188
+ </div>
189
+ <div>
190
+ <dt className="text-muted-foreground">
191
+ {commonT('labels.supervisor')}
192
+ </dt>
193
+ <dd className="font-medium">
194
+ {collaborator.supervisorName || commonT('labels.notAssigned')}
195
+ </dd>
196
+ </div>
197
+ <div>
198
+ <dt className="text-muted-foreground">
199
+ {commonT('labels.weeklyCapacity')}
200
+ </dt>
201
+ <dd className="font-medium">
202
+ {formatHours(collaborator.weeklyCapacityHours)}
203
+ </dd>
204
+ </div>
205
+ <div>
206
+ <dt className="text-muted-foreground">
207
+ {commonT('labels.startDate')}
208
+ </dt>
209
+ <dd className="font-medium">
210
+ {formatDate(collaborator.joinedAt)}
211
+ </dd>
212
+ </div>
213
+ <div>
214
+ <dt className="text-muted-foreground">
215
+ {commonT('labels.status')}
216
+ </dt>
217
+ <dd className="font-medium">
218
+ <StatusBadge
219
+ label={formatEnumLabel(collaborator.status)}
220
+ className={getStatusBadgeClass(collaborator.status)}
221
+ />
222
+ </dd>
223
+ </div>
224
+ {collaborator.equityParticipation ? (
225
+ <>
226
+ <div>
227
+ <dt className="text-muted-foreground">
228
+ {commonT('labels.equityParticipation')}
229
+ </dt>
230
+ <dd className="font-medium">
231
+ {formatEnumLabel(
232
+ collaborator.equityParticipation.participationType
233
+ )}
234
+ </dd>
235
+ </div>
236
+ <div>
237
+ <dt className="text-muted-foreground">
238
+ {commonT('labels.votingPower')}
239
+ </dt>
240
+ <dd className="font-medium">
241
+ {collaborator.equityParticipation.votingPower != null
242
+ ? `${collaborator.equityParticipation.votingPower}%`
243
+ : commonT('labels.notAvailable')}
244
+ </dd>
245
+ </div>
246
+ </>
247
+ ) : null}
248
+ </dl>
249
+ </SectionCard>
250
+
251
+ <SectionCard
252
+ title={t('sections.primaryContract')}
253
+ className="xl:col-span-2"
254
+ >
255
+ {collaborator.relatedContracts.length > 0 ? (
256
+ <div className="space-y-3">
257
+ {collaborator.relatedContracts.slice(0, 2).map((contract) => (
258
+ <div
259
+ key={contract.id}
260
+ className="flex items-center justify-between rounded-lg border px-4 py-3"
261
+ >
262
+ <div>
263
+ <div className="font-medium">
264
+ {contract.name || contract.code}
265
+ </div>
266
+ <div className="text-sm text-muted-foreground">
267
+ {contract.code} •{' '}
268
+ {formatEnumLabel(contract.contractCategory)}
269
+ </div>
270
+ </div>
271
+ <div className="flex items-center gap-2">
272
+ <StatusBadge
273
+ label={formatEnumLabel(contract.status)}
274
+ className={getStatusBadgeClass(contract.status)}
275
+ />
276
+ <Button variant="outline" size="sm" asChild>
277
+ <Link href={`/operations/contracts?edit=${contract.id}`}>
278
+ {commonT('actions.openContract')}
279
+ </Link>
280
+ </Button>
281
+ </div>
282
+ </div>
283
+ ))}
284
+ </div>
285
+ ) : (
286
+ <p className="text-sm text-muted-foreground">{t('noContracts')}</p>
287
+ )}
288
+ </SectionCard>
289
+ </div>
290
+
291
+ <KpiCardsGrid items={summaryCards} />
292
+
293
+ <div className="grid gap-4 xl:grid-cols-2">
294
+ <SectionCard
295
+ title={t('sections.projects')}
296
+ description={t('sections.projectsDescription')}
297
+ >
298
+ {collaborator.assignedProjects.length > 0 ? (
299
+ <div className="overflow-x-auto rounded-md border">
300
+ <Table>
301
+ <TableHeader>
302
+ <TableRow>
303
+ <TableHead>{commonT('labels.project')}</TableHead>
304
+ <TableHead>{commonT('labels.role')}</TableHead>
305
+ <TableHead>{commonT('labels.timeline')}</TableHead>
306
+ <TableHead>{commonT('labels.status')}</TableHead>
307
+ </TableRow>
308
+ </TableHeader>
309
+ <TableBody>
310
+ {collaborator.assignedProjects.map((project) => (
311
+ <TableRow key={project.id}>
312
+ <TableCell>
313
+ <div className="font-medium">{project.name}</div>
314
+ <div className="text-xs text-muted-foreground">
315
+ {project.code}
316
+ </div>
317
+ </TableCell>
318
+ <TableCell>
319
+ {project.roleLabel || commonT('labels.notAssigned')}
320
+ </TableCell>
321
+ <TableCell>
322
+ {formatDateRange(project.startDate, project.endDate)}
323
+ </TableCell>
324
+ <TableCell>
325
+ <StatusBadge
326
+ label={formatEnumLabel(project.status)}
327
+ className={getStatusBadgeClass(project.status)}
328
+ />
329
+ </TableCell>
330
+ </TableRow>
331
+ ))}
332
+ </TableBody>
333
+ </Table>
334
+ </div>
335
+ ) : (
336
+ <p className="text-sm text-muted-foreground">{t('noProjects')}</p>
337
+ )}
338
+ </SectionCard>
339
+
340
+ <SectionCard
341
+ title={t('sections.schedule')}
342
+ description={t('sections.scheduleDescription')}
343
+ >
344
+ <p className="text-sm">
345
+ {summarizeScheduleDays(
346
+ collaborator.weeklySchedule,
347
+ currentLocaleCode
348
+ )}
349
+ </p>
350
+ </SectionCard>
351
+ </div>
352
+
353
+ <div className="grid gap-4 xl:grid-cols-2">
354
+ <SectionCard
355
+ title={t('sections.timeOff')}
356
+ description={t('sections.timeOffDescription')}
357
+ >
358
+ <dl className="grid gap-3 md:grid-cols-3 text-sm">
359
+ <div>
360
+ <dt className="text-muted-foreground">
361
+ {commonT('labels.total')}
362
+ </dt>
363
+ <dd className="font-medium">
364
+ {collaborator.timeOffSummary.totalRequests}
365
+ </dd>
366
+ </div>
367
+ <div>
368
+ <dt className="text-muted-foreground">
369
+ {commonT('labels.pending')}
370
+ </dt>
371
+ <dd className="font-medium">
372
+ {collaborator.timeOffSummary.pendingRequests}
373
+ </dd>
374
+ </div>
375
+ <div>
376
+ <dt className="text-muted-foreground">
377
+ {commonT('labels.approved')}
378
+ </dt>
379
+ <dd className="font-medium">
380
+ {collaborator.timeOffSummary.approvedRequests}
381
+ </dd>
382
+ </div>
383
+ </dl>
384
+ </SectionCard>
385
+
386
+ <SectionCard
387
+ title={t('sections.scheduleAdjustments')}
388
+ description={t('sections.scheduleAdjustmentsDescription')}
389
+ >
390
+ {collaborator.scheduleAdjustmentRequests.length > 0 ? (
391
+ <div className="space-y-2">
392
+ {collaborator.scheduleAdjustmentRequests.map((request) => (
393
+ <div
394
+ key={request.id}
395
+ className="flex items-center justify-between rounded-lg border px-4 py-3 text-sm"
396
+ >
397
+ <div>
398
+ <div className="font-medium">
399
+ {formatEnumLabel(request.requestScope)}
400
+ </div>
401
+ <div className="text-muted-foreground">
402
+ {formatDateRange(
403
+ request.effectiveStartDate,
404
+ request.effectiveEndDate
405
+ )}
406
+ </div>
407
+ </div>
408
+ <StatusBadge
409
+ label={formatEnumLabel(request.status)}
410
+ className={getStatusBadgeClass(request.status)}
411
+ />
412
+ </div>
413
+ ))}
414
+ </div>
415
+ ) : (
416
+ <p className="text-sm text-muted-foreground">
417
+ {t('noScheduleAdjustments')}
418
+ </p>
419
+ )}
420
+ </SectionCard>
421
+ </div>
422
+
423
+ {access.isDirector && (
424
+ <SectionCard
425
+ title={t('sections.compensationHistory')}
426
+ description={t('sections.compensationHistoryDescription')}
427
+ >
428
+ {compensationHistory.length > 0 ? (
429
+ <div className="overflow-x-auto rounded-md border">
430
+ <Table>
431
+ <TableHeader>
432
+ <TableRow>
433
+ <TableHead>{t('compensationHistory.amount')}</TableHead>
434
+ <TableHead>{t('compensationHistory.effectiveDate')}</TableHead>
435
+ <TableHead>{t('compensationHistory.recordedAt')}</TableHead>
436
+ <TableHead>{t('compensationHistory.changedBy')}</TableHead>
437
+ <TableHead>{t('compensationHistory.notes')}</TableHead>
438
+ </TableRow>
439
+ </TableHeader>
440
+ <TableBody>
441
+ {compensationHistory.map((entry) => (
442
+ <TableRow key={entry.id}>
443
+ <TableCell className="font-medium">
444
+ {formatCurrency(
445
+ Number(entry.amount),
446
+ getSettingValue,
447
+ currentLocaleCode
448
+ )}
449
+ </TableCell>
450
+ <TableCell>
451
+ {entry.effectiveDate
452
+ ? formatDate(entry.effectiveDate)
453
+ : '—'}
454
+ </TableCell>
455
+ <TableCell>{formatDate(entry.createdAt)}</TableCell>
456
+ <TableCell>
457
+ {entry.actorName ?? '—'}
458
+ </TableCell>
459
+ <TableCell className="text-muted-foreground">
460
+ {entry.notes ?? '—'}
461
+ </TableCell>
462
+ </TableRow>
463
+ ))}
464
+ </TableBody>
465
+ </Table>
466
+ </div>
467
+ ) : (
468
+ <p className="text-sm text-muted-foreground">
469
+ {t('noCompensationHistory')}
470
+ </p>
471
+ )}
472
+ </SectionCard>
473
+ )}
474
+ </Page>
475
+ );
476
+ }
@@ -111,8 +111,6 @@ import {
111
111
  trimToNull,
112
112
  } from '../_lib/utils/forms';
113
113
  import { CollaboratorCostsSection } from './collaborator-costs-section';
114
- import { CollaboratorInvoicesTab } from './collaborator-invoices-tab';
115
- import { CollaboratorPaymentHistoryTab } from './collaborator-payment-history-tab';
116
114
  import { CollaboratorTasksTab } from './collaborator-tasks-tab';
117
115
  import { CollaboratorTimesheetsTab } from './collaborator-timesheets-tab';
118
116
  import { DepartmentPicker } from './department-picker';
@@ -2145,7 +2143,9 @@ export function CollaboratorFormScreen({
2145
2143
 
2146
2144
  const formContent = isSheetMode ? (
2147
2145
  <Tabs defaultValue="details" className="w-full">
2148
- <TabsList className="mx-4 mb-2 flex w-[calc(100%-2rem)] flex-wrap gap-0.5 h-auto">
2146
+ <TabsList
2147
+ className={`mx-4 mb-2 grid w-[calc(100%-2rem)] ${!isCreateMode && !isHourlyType ? 'grid-cols-7' : isCreateMode && isHourlyType ? 'grid-cols-5' : 'grid-cols-6'}`}
2148
+ >
2149
2149
  <TabsTrigger value="details">{t('tabs.details')}</TabsTrigger>
2150
2150
  <TabsTrigger value="costs">{t('tabs.costs')}</TabsTrigger>
2151
2151
  {!isHourlyType ? (
@@ -2159,14 +2159,6 @@ export function CollaboratorFormScreen({
2159
2159
  {!isCreateMode ? (
2160
2160
  <TabsTrigger value="salary">{t('tabs.salary')}</TabsTrigger>
2161
2161
  ) : null}
2162
- {!isCreateMode ? (
2163
- <TabsTrigger value="paymentHistory">
2164
- {t('tabs.paymentHistory')}
2165
- </TabsTrigger>
2166
- ) : null}
2167
- {!isCreateMode ? (
2168
- <TabsTrigger value="invoices">{t('tabs.invoices')}</TabsTrigger>
2169
- ) : null}
2170
2162
  </TabsList>
2171
2163
  <TabsContent value="details" className="mt-0 space-y-4 px-4 pt-2">
2172
2164
  {profileContent}
@@ -2384,34 +2376,6 @@ export function CollaboratorFormScreen({
2384
2376
  )}
2385
2377
  </TabsContent>
2386
2378
  ) : null}
2387
- {!isCreateMode ? (
2388
- <TabsContent value="paymentHistory" className="mt-0 px-4 pt-2">
2389
- {collaborator ? (
2390
- <CollaboratorPaymentHistoryTab
2391
- collaboratorId={collaborator.id}
2392
- disabled={!access.isDirector}
2393
- />
2394
- ) : (
2395
- <p className="text-sm text-muted-foreground">
2396
- {t('sections.costsSaveBefore')}
2397
- </p>
2398
- )}
2399
- </TabsContent>
2400
- ) : null}
2401
- {!isCreateMode ? (
2402
- <TabsContent value="invoices" className="mt-0 px-4 pt-2">
2403
- {collaborator ? (
2404
- <CollaboratorInvoicesTab
2405
- collaboratorId={collaborator.id}
2406
- disabled={!access.isDirector}
2407
- />
2408
- ) : (
2409
- <p className="text-sm text-muted-foreground">
2410
- {t('sections.costsSaveBefore')}
2411
- </p>
2412
- )}
2413
- </TabsContent>
2414
- ) : null}
2415
2379
  </Tabs>
2416
2380
  ) : (
2417
2381
  <div className="space-y-4 px-4">