@hed-hog/operations 0.0.296 → 0.0.298
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.
- package/hedhog/frontend/app/_components/collaborator-details-screen.tsx.ejs +310 -310
- package/hedhog/frontend/app/_components/collaborator-form-screen.tsx.ejs +631 -631
- package/hedhog/frontend/app/_components/contract-details-screen.tsx.ejs +132 -132
- package/hedhog/frontend/app/_components/contract-form-screen.tsx.ejs +558 -558
- package/hedhog/frontend/app/_components/project-details-screen.tsx.ejs +291 -291
- package/hedhog/frontend/app/_components/project-form-screen.tsx.ejs +689 -689
- package/hedhog/frontend/app/_lib/api.ts.ejs +32 -32
- package/hedhog/frontend/app/_lib/hooks/use-operations-access.ts.ejs +44 -44
- package/hedhog/frontend/app/_lib/types.ts.ejs +360 -360
- package/hedhog/frontend/app/_lib/utils/format.ts.ejs +129 -129
- package/hedhog/frontend/app/_lib/utils/forms.ts.ejs +14 -14
- package/hedhog/frontend/app/approvals/page.tsx.ejs +386 -386
- package/hedhog/frontend/app/collaborators/[id]/edit/page.tsx.ejs +11 -11
- package/hedhog/frontend/app/collaborators/[id]/page.tsx.ejs +11 -11
- package/hedhog/frontend/app/collaborators/new/page.tsx.ejs +5 -5
- package/hedhog/frontend/app/collaborators/page.tsx.ejs +261 -261
- package/hedhog/frontend/app/contracts/[id]/edit/page.tsx.ejs +11 -11
- package/hedhog/frontend/app/contracts/[id]/page.tsx.ejs +11 -11
- package/hedhog/frontend/app/contracts/new/page.tsx.ejs +17 -17
- package/hedhog/frontend/app/contracts/page.tsx.ejs +262 -262
- package/hedhog/frontend/app/page.tsx.ejs +319 -319
- package/hedhog/frontend/app/projects/[id]/edit/page.tsx.ejs +11 -11
- package/hedhog/frontend/app/projects/[id]/page.tsx.ejs +11 -11
- package/hedhog/frontend/app/projects/new/page.tsx.ejs +5 -5
- package/hedhog/frontend/app/projects/page.tsx.ejs +236 -236
- package/hedhog/frontend/app/schedule-adjustments/page.tsx.ejs +418 -418
- package/hedhog/frontend/app/team/page.tsx.ejs +339 -339
- package/hedhog/frontend/app/time-off/page.tsx.ejs +328 -328
- package/hedhog/frontend/app/timesheets/page.tsx.ejs +636 -636
- package/hedhog/frontend/messages/en.json +648 -648
- package/hedhog/frontend/messages/pt.json +647 -647
- package/package.json +2 -2
|
@@ -1,129 +1,129 @@
|
|
|
1
|
-
export const operationsCurrency = new Intl.NumberFormat('en-US', {
|
|
2
|
-
style: 'currency',
|
|
3
|
-
currency: 'USD',
|
|
4
|
-
maximumFractionDigits: 0,
|
|
5
|
-
});
|
|
6
|
-
|
|
7
|
-
export function formatCurrency(value: number) {
|
|
8
|
-
return operationsCurrency.format(value);
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export function formatDate(value?: string | null) {
|
|
12
|
-
if (!value) {
|
|
13
|
-
return '-';
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
return new Date(`${value}T00:00:00`).toLocaleDateString('en-US', {
|
|
17
|
-
month: 'short',
|
|
18
|
-
day: 'numeric',
|
|
19
|
-
year: 'numeric',
|
|
20
|
-
});
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export function formatDateTime(value?: string | null) {
|
|
24
|
-
if (!value) {
|
|
25
|
-
return '-';
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
return new Date(value).toLocaleString('en-US', {
|
|
29
|
-
month: 'short',
|
|
30
|
-
day: 'numeric',
|
|
31
|
-
year: 'numeric',
|
|
32
|
-
hour: '2-digit',
|
|
33
|
-
minute: '2-digit',
|
|
34
|
-
});
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export function formatPercent(value?: number | null) {
|
|
38
|
-
if (value === null || value === undefined || Number.isNaN(value)) {
|
|
39
|
-
return '-';
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
return `${value}%`;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
export function formatHours(value?: number | null) {
|
|
46
|
-
if (value === null || value === undefined || Number.isNaN(value)) {
|
|
47
|
-
return '-';
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
return `${Number(value).toFixed(1)}h`;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
export function formatEnumLabel(value?: string | null) {
|
|
54
|
-
if (!value) {
|
|
55
|
-
return '-';
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
return value
|
|
59
|
-
.replace(/[_-]+/g, ' ')
|
|
60
|
-
.replace(/\b\w/g, (match) => match.toUpperCase());
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
export function formatDateRange(
|
|
64
|
-
startDate?: string | null,
|
|
65
|
-
endDate?: string | null
|
|
66
|
-
) {
|
|
67
|
-
if (!startDate && !endDate) {
|
|
68
|
-
return '-';
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
if (!endDate || startDate === endDate) {
|
|
72
|
-
return formatDate(startDate);
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
return `${formatDate(startDate)} to ${formatDate(endDate)}`;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
export function getStatusBadgeClass(value?: string | null) {
|
|
79
|
-
switch (value) {
|
|
80
|
-
case 'active':
|
|
81
|
-
case 'approved':
|
|
82
|
-
case 'completed':
|
|
83
|
-
return 'bg-emerald-100 text-emerald-800';
|
|
84
|
-
case 'submitted':
|
|
85
|
-
case 'pending':
|
|
86
|
-
case 'renewal':
|
|
87
|
-
case 'planning':
|
|
88
|
-
return 'bg-amber-100 text-amber-900';
|
|
89
|
-
case 'rejected':
|
|
90
|
-
case 'cancelled':
|
|
91
|
-
case 'archived':
|
|
92
|
-
case 'closed':
|
|
93
|
-
return 'bg-rose-100 text-rose-800';
|
|
94
|
-
case 'draft':
|
|
95
|
-
case 'paused':
|
|
96
|
-
case 'inactive':
|
|
97
|
-
case 'on_leave':
|
|
98
|
-
return 'bg-slate-100 text-slate-800';
|
|
99
|
-
case 'at_risk':
|
|
100
|
-
return 'bg-orange-100 text-orange-900';
|
|
101
|
-
default:
|
|
102
|
-
return 'bg-sky-100 text-sky-800';
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
export function summarizeScheduleDays(
|
|
107
|
-
days: Array<{
|
|
108
|
-
weekday: string;
|
|
109
|
-
isWorkingDay: boolean;
|
|
110
|
-
startTime?: string | null;
|
|
111
|
-
endTime?: string | null;
|
|
112
|
-
}>
|
|
113
|
-
) {
|
|
114
|
-
if (!days.length) {
|
|
115
|
-
return '-';
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
return days
|
|
119
|
-
.filter((day) => day.isWorkingDay)
|
|
120
|
-
.map((day) => {
|
|
121
|
-
const label = formatEnumLabel(day.weekday);
|
|
122
|
-
if (day.startTime && day.endTime) {
|
|
123
|
-
return `${label}: ${day.startTime}-${day.endTime}`;
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
return label;
|
|
127
|
-
})
|
|
128
|
-
.join(', ');
|
|
129
|
-
}
|
|
1
|
+
export const operationsCurrency = new Intl.NumberFormat('en-US', {
|
|
2
|
+
style: 'currency',
|
|
3
|
+
currency: 'USD',
|
|
4
|
+
maximumFractionDigits: 0,
|
|
5
|
+
});
|
|
6
|
+
|
|
7
|
+
export function formatCurrency(value: number) {
|
|
8
|
+
return operationsCurrency.format(value);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function formatDate(value?: string | null) {
|
|
12
|
+
if (!value) {
|
|
13
|
+
return '-';
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
return new Date(`${value}T00:00:00`).toLocaleDateString('en-US', {
|
|
17
|
+
month: 'short',
|
|
18
|
+
day: 'numeric',
|
|
19
|
+
year: 'numeric',
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function formatDateTime(value?: string | null) {
|
|
24
|
+
if (!value) {
|
|
25
|
+
return '-';
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return new Date(value).toLocaleString('en-US', {
|
|
29
|
+
month: 'short',
|
|
30
|
+
day: 'numeric',
|
|
31
|
+
year: 'numeric',
|
|
32
|
+
hour: '2-digit',
|
|
33
|
+
minute: '2-digit',
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function formatPercent(value?: number | null) {
|
|
38
|
+
if (value === null || value === undefined || Number.isNaN(value)) {
|
|
39
|
+
return '-';
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return `${value}%`;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export function formatHours(value?: number | null) {
|
|
46
|
+
if (value === null || value === undefined || Number.isNaN(value)) {
|
|
47
|
+
return '-';
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return `${Number(value).toFixed(1)}h`;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export function formatEnumLabel(value?: string | null) {
|
|
54
|
+
if (!value) {
|
|
55
|
+
return '-';
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return value
|
|
59
|
+
.replace(/[_-]+/g, ' ')
|
|
60
|
+
.replace(/\b\w/g, (match) => match.toUpperCase());
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export function formatDateRange(
|
|
64
|
+
startDate?: string | null,
|
|
65
|
+
endDate?: string | null
|
|
66
|
+
) {
|
|
67
|
+
if (!startDate && !endDate) {
|
|
68
|
+
return '-';
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (!endDate || startDate === endDate) {
|
|
72
|
+
return formatDate(startDate);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return `${formatDate(startDate)} to ${formatDate(endDate)}`;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export function getStatusBadgeClass(value?: string | null) {
|
|
79
|
+
switch (value) {
|
|
80
|
+
case 'active':
|
|
81
|
+
case 'approved':
|
|
82
|
+
case 'completed':
|
|
83
|
+
return 'bg-emerald-100 text-emerald-800';
|
|
84
|
+
case 'submitted':
|
|
85
|
+
case 'pending':
|
|
86
|
+
case 'renewal':
|
|
87
|
+
case 'planning':
|
|
88
|
+
return 'bg-amber-100 text-amber-900';
|
|
89
|
+
case 'rejected':
|
|
90
|
+
case 'cancelled':
|
|
91
|
+
case 'archived':
|
|
92
|
+
case 'closed':
|
|
93
|
+
return 'bg-rose-100 text-rose-800';
|
|
94
|
+
case 'draft':
|
|
95
|
+
case 'paused':
|
|
96
|
+
case 'inactive':
|
|
97
|
+
case 'on_leave':
|
|
98
|
+
return 'bg-slate-100 text-slate-800';
|
|
99
|
+
case 'at_risk':
|
|
100
|
+
return 'bg-orange-100 text-orange-900';
|
|
101
|
+
default:
|
|
102
|
+
return 'bg-sky-100 text-sky-800';
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export function summarizeScheduleDays(
|
|
107
|
+
days: Array<{
|
|
108
|
+
weekday: string;
|
|
109
|
+
isWorkingDay: boolean;
|
|
110
|
+
startTime?: string | null;
|
|
111
|
+
endTime?: string | null;
|
|
112
|
+
}>
|
|
113
|
+
) {
|
|
114
|
+
if (!days.length) {
|
|
115
|
+
return '-';
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
return days
|
|
119
|
+
.filter((day) => day.isWorkingDay)
|
|
120
|
+
.map((day) => {
|
|
121
|
+
const label = formatEnumLabel(day.weekday);
|
|
122
|
+
if (day.startTime && day.endTime) {
|
|
123
|
+
return `${label}: ${day.startTime}-${day.endTime}`;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
return label;
|
|
127
|
+
})
|
|
128
|
+
.join(', ');
|
|
129
|
+
}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
export function parseNumberInput(value: string) {
|
|
2
|
-
const trimmed = value.trim();
|
|
3
|
-
if (!trimmed) {
|
|
4
|
-
return null;
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
const parsed = Number(trimmed);
|
|
8
|
-
return Number.isFinite(parsed) ? parsed : null;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export function trimToNull(value?: string | null) {
|
|
12
|
-
const trimmed = value?.trim() ?? '';
|
|
13
|
-
return trimmed ? trimmed : null;
|
|
14
|
-
}
|
|
1
|
+
export function parseNumberInput(value: string) {
|
|
2
|
+
const trimmed = value.trim();
|
|
3
|
+
if (!trimmed) {
|
|
4
|
+
return null;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
const parsed = Number(trimmed);
|
|
8
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function trimToNull(value?: string | null) {
|
|
12
|
+
const trimmed = value?.trim() ?? '';
|
|
13
|
+
return trimmed ? trimmed : null;
|
|
14
|
+
}
|