@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
@@ -1,429 +0,0 @@
1
- 'use client';
2
-
3
- import { Button } from '@/components/ui/button';
4
- import { Input } from '@/components/ui/input';
5
- import { Label } from '@/components/ui/label';
6
- import {
7
- Select,
8
- SelectContent,
9
- SelectItem,
10
- SelectTrigger,
11
- SelectValue,
12
- } from '@/components/ui/select';
13
- import {
14
- Table,
15
- TableBody,
16
- TableCell,
17
- TableHead,
18
- TableHeader,
19
- TableRow,
20
- } from '@/components/ui/table';
21
- import { Textarea } from '@/components/ui/textarea';
22
- import { useApp, useQuery } from '@hed-hog/next-app-provider';
23
- import { BanknoteIcon, Pencil, Plus, Trash2, X } from 'lucide-react';
24
- import { useTranslations } from 'next-intl';
25
- import { useState } from 'react';
26
- import {
27
- type CollaboratorPayment,
28
- createCollaboratorPayment,
29
- deleteCollaboratorPayment,
30
- fetchCollaboratorPayments,
31
- updateCollaboratorPayment,
32
- } from '../_lib/api';
33
- import { formatCurrency, formatDate } from '../_lib/utils/format';
34
-
35
- const PAYMENT_METHODS = ['bank_transfer', 'pix', 'check', 'other'] as const;
36
- type PaymentMethod = (typeof PAYMENT_METHODS)[number];
37
-
38
- type FormState = {
39
- amount: string;
40
- paymentDate: string;
41
- referenceMonth: string;
42
- paymentMethod: PaymentMethod;
43
- notes: string;
44
- };
45
-
46
- function emptyForm(): FormState {
47
- return {
48
- amount: '',
49
- paymentDate: '',
50
- referenceMonth: '',
51
- paymentMethod: 'pix',
52
- notes: '',
53
- };
54
- }
55
-
56
- function paymentToForm(p: CollaboratorPayment): FormState {
57
- return {
58
- amount: p.amount ? Number(p.amount).toFixed(2).replace('.', ',') : '',
59
- paymentDate: p.paymentDate ? p.paymentDate.slice(0, 10) : '',
60
- referenceMonth: p.referenceMonth
61
- ? p.referenceMonth.split('-').reverse().join('/')
62
- : '',
63
- paymentMethod: (p.paymentMethod as PaymentMethod) ?? 'pix',
64
- notes: p.notes ?? '',
65
- };
66
- }
67
-
68
- type Props = {
69
- collaboratorId: number;
70
- disabled?: boolean;
71
- };
72
-
73
- export function CollaboratorPaymentHistoryTab({
74
- collaboratorId,
75
- disabled = false,
76
- }: Props) {
77
- const t = useTranslations('operations.CollaboratorFormPage');
78
- const commonT = useTranslations('operations.Common');
79
- const { request, showToastHandler, getSettingValue, currentLocaleCode } =
80
- useApp();
81
-
82
- const [isAdding, setIsAdding] = useState(false);
83
- const [editingId, setEditingId] = useState<number | null>(null);
84
- const [confirmDeleteId, setConfirmDeleteId] = useState<number | null>(null);
85
- const [form, setForm] = useState<FormState>(emptyForm());
86
- const [saving, setSaving] = useState(false);
87
-
88
- const {
89
- data: payments = [],
90
- isLoading,
91
- refetch,
92
- } = useQuery<CollaboratorPayment[]>({
93
- queryKey: [
94
- 'operations-collaborator-payment-history',
95
- currentLocaleCode,
96
- collaboratorId,
97
- ],
98
- staleTime: 0,
99
- refetchOnMount: 'always',
100
- queryFn: () => fetchCollaboratorPayments(request, collaboratorId),
101
- });
102
-
103
- function openAdd() {
104
- setEditingId(null);
105
- setForm(emptyForm());
106
- setIsAdding(true);
107
- }
108
-
109
- function openEdit(p: CollaboratorPayment) {
110
- setIsAdding(false);
111
- setForm(paymentToForm(p));
112
- setEditingId(p.id);
113
- }
114
-
115
- function cancelForm() {
116
- setIsAdding(false);
117
- setEditingId(null);
118
- setForm(emptyForm());
119
- }
120
-
121
- async function handleSave() {
122
- const amount = parseFloat(form.amount.replace(',', '.'));
123
- if (!form.paymentDate || isNaN(amount) || amount <= 0) return;
124
-
125
- setSaving(true);
126
- try {
127
- const rawMonth = form.referenceMonth;
128
- const referenceMonth =
129
- rawMonth && rawMonth.length === 7
130
- ? rawMonth.split('/').reverse().join('-')
131
- : rawMonth || null;
132
-
133
- const data = {
134
- amount,
135
- paymentDate: form.paymentDate,
136
- referenceMonth,
137
- paymentMethod: form.paymentMethod,
138
- notes: form.notes || null,
139
- };
140
-
141
- if (editingId !== null) {
142
- await updateCollaboratorPayment(
143
- request,
144
- collaboratorId,
145
- editingId,
146
- data
147
- );
148
- } else {
149
- await createCollaboratorPayment(request, collaboratorId, data);
150
- }
151
-
152
- showToastHandler?.('success', t('messages.saveSuccess'));
153
- cancelForm();
154
- await refetch();
155
- } catch {
156
- showToastHandler?.('error', t('messages.saveError'));
157
- } finally {
158
- setSaving(false);
159
- }
160
- }
161
-
162
- async function handleDelete(paymentId: number) {
163
- setSaving(true);
164
- try {
165
- await deleteCollaboratorPayment(request, collaboratorId, paymentId);
166
- showToastHandler?.('success', t('messages.deleteSuccess'));
167
- setConfirmDeleteId(null);
168
- await refetch();
169
- } catch {
170
- showToastHandler?.('error', t('messages.deleteError'));
171
- } finally {
172
- setSaving(false);
173
- }
174
- }
175
-
176
- const methodLabel = (m: string) => {
177
- const key =
178
- `paymentHistory.method${m.charAt(0).toUpperCase() + m.slice(1).replace(/_([a-z])/g, (_, c: string) => c.toUpperCase())}` as Parameters<
179
- typeof t
180
- >[0];
181
- try {
182
- return t(key);
183
- } catch {
184
- return m;
185
- }
186
- };
187
-
188
- const showForm = isAdding || editingId !== null;
189
-
190
- return (
191
- <div className="space-y-4">
192
- {!disabled && (
193
- <div className="flex justify-end">
194
- <Button
195
- size="sm"
196
- variant="outline"
197
- onClick={openAdd}
198
- disabled={showForm}
199
- >
200
- <Plus className="mr-1 size-4" />
201
- {t('paymentHistory.add')}
202
- </Button>
203
- </div>
204
- )}
205
-
206
- {showForm && (
207
- <div className="rounded-md border bg-muted/30 p-4">
208
- <p className="mb-3 text-sm font-medium">
209
- {editingId !== null
210
- ? t('paymentHistory.editTitle')
211
- : t('paymentHistory.add')}
212
- </p>
213
- <div className="grid grid-cols-1 gap-3 sm:grid-cols-2">
214
- <div className="space-y-1">
215
- <Label className="text-xs">{t('paymentHistory.amount')} *</Label>
216
- <Input
217
- type="text"
218
- inputMode="numeric"
219
- placeholder="0,00"
220
- value={form.amount}
221
- onChange={(e) => {
222
- const digits = e.target.value.replace(/\D/g, '');
223
- if (!digits) {
224
- setForm((f) => ({ ...f, amount: '' }));
225
- return;
226
- }
227
- const cents = parseInt(digits, 10);
228
- const formatted = (cents / 100).toFixed(2).replace('.', ',');
229
- setForm((f) => ({ ...f, amount: formatted }));
230
- }}
231
- />
232
- </div>
233
- <div className="space-y-1">
234
- <Label className="text-xs">
235
- {t('paymentHistory.paymentDate')} *
236
- </Label>
237
- <Input
238
- type="date"
239
- value={form.paymentDate}
240
- onChange={(e) =>
241
- setForm((f) => ({ ...f, paymentDate: e.target.value }))
242
- }
243
- />
244
- </div>
245
- <div className="space-y-1">
246
- <Label className="text-xs">
247
- {t('paymentHistory.referenceMonth')}
248
- </Label>
249
- <Input
250
- type="text"
251
- inputMode="numeric"
252
- placeholder="MM/AAAA"
253
- maxLength={7}
254
- value={form.referenceMonth}
255
- onChange={(e) => {
256
- const digits = e.target.value.replace(/\D/g, '');
257
- const masked =
258
- digits.length > 2
259
- ? digits.slice(0, 2) + '/' + digits.slice(2, 6)
260
- : digits;
261
- setForm((f) => ({ ...f, referenceMonth: masked }));
262
- }}
263
- />
264
- </div>
265
- <div className="space-y-1">
266
- <Label className="text-xs">
267
- {t('paymentHistory.paymentMethod')}
268
- </Label>
269
- <Select
270
- value={form.paymentMethod}
271
- onValueChange={(v) =>
272
- setForm((f) => ({
273
- ...f,
274
- paymentMethod: v as PaymentMethod,
275
- }))
276
- }
277
- >
278
- <SelectTrigger className="w-full cursor-pointer">
279
- <SelectValue />
280
- </SelectTrigger>
281
- <SelectContent>
282
- {PAYMENT_METHODS.map((m) => (
283
- <SelectItem key={m} value={m} className="cursor-pointer">
284
- {methodLabel(m)}
285
- </SelectItem>
286
- ))}
287
- </SelectContent>
288
- </Select>
289
- </div>
290
- <div className="space-y-1 sm:col-span-2">
291
- <Label className="text-xs">{t('paymentHistory.notes')}</Label>
292
- <Textarea
293
- rows={2}
294
- value={form.notes}
295
- onChange={(e) =>
296
- setForm((f) => ({ ...f, notes: e.target.value }))
297
- }
298
- />
299
- </div>
300
- </div>
301
- <div className="mt-3 flex justify-end gap-2">
302
- <Button
303
- size="sm"
304
- variant="ghost"
305
- onClick={cancelForm}
306
- disabled={saving}
307
- >
308
- <X className="mr-1 size-4" />
309
- {commonT('actions.cancel')}
310
- </Button>
311
- <Button size="sm" onClick={handleSave} disabled={saving}>
312
- {commonT('actions.save')}
313
- </Button>
314
- </div>
315
- </div>
316
- )}
317
-
318
- {isLoading ? (
319
- <p className="text-sm text-muted-foreground">{t('loading')}</p>
320
- ) : payments.length === 0 && !showForm ? (
321
- <div className="flex flex-col items-center gap-3 py-10 text-center">
322
- <BanknoteIcon className="size-10 text-muted-foreground/40" />
323
- <p className="text-sm text-muted-foreground">
324
- {t('tabs.paymentHistoryEmpty')}
325
- </p>
326
- </div>
327
- ) : payments.length > 0 ? (
328
- <div className="overflow-x-auto rounded-md border">
329
- <Table>
330
- <TableHeader>
331
- <TableRow>
332
- <TableHead>{t('paymentHistory.amount')}</TableHead>
333
- <TableHead>{t('paymentHistory.paymentDate')}</TableHead>
334
- <TableHead>{t('paymentHistory.referenceMonth')}</TableHead>
335
- <TableHead>{t('paymentHistory.paymentMethod')}</TableHead>
336
- <TableHead>{t('paymentHistory.notes')}</TableHead>
337
- {!disabled && (
338
- <TableHead className="w-20 text-right"></TableHead>
339
- )}
340
- </TableRow>
341
- </TableHeader>
342
- <TableBody>
343
- {payments.map((entry) => (
344
- <TableRow key={entry.id}>
345
- <TableCell className="font-medium">
346
- {formatCurrency(
347
- Number(entry.amount),
348
- getSettingValue,
349
- currentLocaleCode
350
- )}
351
- </TableCell>
352
- <TableCell>
353
- {entry.paymentDate
354
- ? formatDate(
355
- entry.paymentDate,
356
- getSettingValue,
357
- currentLocaleCode
358
- )
359
- : '—'}
360
- </TableCell>
361
- <TableCell>
362
- {entry.referenceMonth
363
- ? entry.referenceMonth.split('-').reverse().join('/')
364
- : '—'}
365
- </TableCell>
366
- <TableCell>
367
- {entry.paymentMethod
368
- ? methodLabel(entry.paymentMethod)
369
- : '—'}
370
- </TableCell>
371
- <TableCell className="text-muted-foreground">
372
- {entry.notes ?? '—'}
373
- </TableCell>
374
- {!disabled && (
375
- <TableCell className="text-right">
376
- {confirmDeleteId === entry.id ? (
377
- <div className="flex items-center justify-end gap-1">
378
- <span className="text-xs text-muted-foreground">
379
- {t('paymentHistory.deleteConfirm')}
380
- </span>
381
- <Button
382
- size="sm"
383
- variant="destructive"
384
- className="h-7 px-2 text-xs cursor-pointer"
385
- disabled={saving}
386
- onClick={() => handleDelete(entry.id)}
387
- >
388
- {commonT('actions.delete')}
389
- </Button>
390
- <Button
391
- size="sm"
392
- variant="ghost"
393
- className="h-7 px-2 text-xs cursor-pointer"
394
- onClick={() => setConfirmDeleteId(null)}
395
- >
396
- <X className="size-3" />
397
- </Button>
398
- </div>
399
- ) : (
400
- <div className="flex items-center justify-end gap-1">
401
- <Button
402
- size="icon"
403
- variant="ghost"
404
- className="size-7 cursor-pointer"
405
- onClick={() => openEdit(entry)}
406
- >
407
- <Pencil className="size-3.5" />
408
- </Button>
409
- <Button
410
- size="icon"
411
- variant="ghost"
412
- className="size-7 cursor-pointer text-destructive hover:text-destructive"
413
- onClick={() => setConfirmDeleteId(entry.id)}
414
- >
415
- <Trash2 className="size-3.5" />
416
- </Button>
417
- </div>
418
- )}
419
- </TableCell>
420
- )}
421
- </TableRow>
422
- ))}
423
- </TableBody>
424
- </Table>
425
- </div>
426
- ) : null}
427
- </div>
428
- );
429
- }