@hed-hog/operations 0.0.295 → 0.0.296

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 (126) hide show
  1. package/dist/operations.controller.d.ts +415 -0
  2. package/dist/operations.controller.d.ts.map +1 -0
  3. package/dist/operations.controller.js +333 -0
  4. package/dist/operations.controller.js.map +1 -0
  5. package/dist/operations.module.d.ts.map +1 -1
  6. package/dist/operations.module.js +4 -3
  7. package/dist/operations.module.js.map +1 -1
  8. package/dist/operations.service.d.ts +589 -153
  9. package/dist/operations.service.d.ts.map +1 -1
  10. package/dist/operations.service.js +2229 -100
  11. package/dist/operations.service.js.map +1 -1
  12. package/hedhog/data/menu.yaml +198 -251
  13. package/hedhog/data/role.yaml +23 -14
  14. package/hedhog/data/route.yaml +317 -143
  15. package/hedhog/frontend/app/_components/collaborator-details-screen.tsx.ejs +310 -0
  16. package/hedhog/frontend/app/_components/collaborator-form-screen.tsx.ejs +631 -0
  17. package/hedhog/frontend/app/_components/contract-details-screen.tsx.ejs +132 -0
  18. package/hedhog/frontend/app/_components/contract-form-screen.tsx.ejs +558 -0
  19. package/hedhog/frontend/app/_components/project-details-screen.tsx.ejs +291 -0
  20. package/hedhog/frontend/app/_components/project-form-screen.tsx.ejs +689 -0
  21. package/hedhog/frontend/app/_lib/api.ts.ejs +32 -0
  22. package/hedhog/frontend/app/_lib/hooks/use-operations-access.ts.ejs +44 -0
  23. package/hedhog/frontend/app/_lib/types.ts.ejs +360 -0
  24. package/hedhog/frontend/app/_lib/utils/format.ts.ejs +129 -25
  25. package/hedhog/frontend/app/_lib/utils/forms.ts.ejs +14 -0
  26. package/hedhog/frontend/app/approvals/page.tsx.ejs +386 -147
  27. package/hedhog/frontend/app/collaborators/[id]/edit/page.tsx.ejs +11 -0
  28. package/hedhog/frontend/app/collaborators/[id]/page.tsx.ejs +11 -0
  29. package/hedhog/frontend/app/collaborators/new/page.tsx.ejs +5 -0
  30. package/hedhog/frontend/app/collaborators/page.tsx.ejs +261 -0
  31. package/hedhog/frontend/app/contracts/[id]/edit/page.tsx.ejs +11 -0
  32. package/hedhog/frontend/app/contracts/[id]/page.tsx.ejs +11 -108
  33. package/hedhog/frontend/app/contracts/new/page.tsx.ejs +17 -0
  34. package/hedhog/frontend/app/contracts/page.tsx.ejs +262 -181
  35. package/hedhog/frontend/app/page.tsx.ejs +319 -177
  36. package/hedhog/frontend/app/projects/[id]/edit/page.tsx.ejs +11 -0
  37. package/hedhog/frontend/app/projects/[id]/page.tsx.ejs +11 -936
  38. package/hedhog/frontend/app/projects/new/page.tsx.ejs +5 -0
  39. package/hedhog/frontend/app/projects/page.tsx.ejs +236 -1074
  40. package/hedhog/frontend/app/schedule-adjustments/page.tsx.ejs +418 -0
  41. package/hedhog/frontend/app/team/page.tsx.ejs +339 -0
  42. package/hedhog/frontend/app/time-off/page.tsx.ejs +328 -0
  43. package/hedhog/frontend/app/timesheets/page.tsx.ejs +636 -126
  44. package/hedhog/frontend/messages/en.json +648 -454
  45. package/hedhog/frontend/messages/pt.json +647 -454
  46. package/hedhog/table/operations_approval.yaml +49 -0
  47. package/hedhog/table/operations_approval_history.yaml +29 -0
  48. package/hedhog/table/{operations_employee.yaml → operations_collaborator.yaml} +67 -64
  49. package/hedhog/table/operations_collaborator_schedule_day.yaml +34 -0
  50. package/hedhog/table/operations_contract.yaml +100 -48
  51. package/hedhog/table/operations_contract_document.yaml +39 -0
  52. package/hedhog/table/operations_contract_financial_term.yaml +40 -0
  53. package/hedhog/table/operations_contract_history.yaml +27 -0
  54. package/hedhog/table/operations_contract_party.yaml +46 -0
  55. package/hedhog/table/operations_contract_revision.yaml +38 -0
  56. package/hedhog/table/operations_contract_signature.yaml +38 -0
  57. package/hedhog/table/operations_project.yaml +54 -50
  58. package/hedhog/table/{operations_allocation.yaml → operations_project_assignment.yaml} +55 -52
  59. package/hedhog/table/operations_schedule_adjustment_day.yaml +34 -0
  60. package/hedhog/table/operations_schedule_adjustment_request.yaml +53 -0
  61. package/hedhog/table/operations_time_off_request.yaml +57 -0
  62. package/hedhog/table/operations_timesheet.yaml +41 -36
  63. package/hedhog/table/operations_timesheet_entry.yaml +40 -50
  64. package/package.json +8 -7
  65. package/src/operations.controller.ts +182 -0
  66. package/src/operations.module.ts +22 -21
  67. package/src/operations.service.ts +3595 -137
  68. package/hedhog/data/operations_career_level.yaml +0 -102
  69. package/hedhog/data/operations_career_track.yaml +0 -8
  70. package/hedhog/data/operations_certification.yaml +0 -38
  71. package/hedhog/data/operations_evaluation_cycle.yaml +0 -18
  72. package/hedhog/data/operations_performance_criterion.yaml +0 -48
  73. package/hedhog/frontend/app/_components/allocation-calendar.tsx.ejs +0 -56
  74. package/hedhog/frontend/app/_components/kanban-board.tsx.ejs +0 -626
  75. package/hedhog/frontend/app/_components/timesheet-entry-dialog.tsx.ejs +0 -142
  76. package/hedhog/frontend/app/_lib/hooks/use-operations-data.ts.ejs +0 -41
  77. package/hedhog/frontend/app/_lib/hooks/use-operations-growth-data.ts.ejs +0 -63
  78. package/hedhog/frontend/app/_lib/mocks/allocations.mock.ts.ejs +0 -74
  79. package/hedhog/frontend/app/_lib/mocks/contracts.mock.ts.ejs +0 -74
  80. package/hedhog/frontend/app/_lib/mocks/operations-growth.mock.ts.ejs +0 -824
  81. package/hedhog/frontend/app/_lib/mocks/projects.mock.ts.ejs +0 -455
  82. package/hedhog/frontend/app/_lib/mocks/tasks.mock.ts.ejs +0 -117
  83. package/hedhog/frontend/app/_lib/mocks/timesheets.mock.ts.ejs +0 -84
  84. package/hedhog/frontend/app/_lib/mocks/users.mock.ts.ejs +0 -67
  85. package/hedhog/frontend/app/_lib/services/contracts.service.ts.ejs +0 -10
  86. package/hedhog/frontend/app/_lib/services/operations-growth.service.ts.ejs +0 -31
  87. package/hedhog/frontend/app/_lib/services/projects.service.ts.ejs +0 -10
  88. package/hedhog/frontend/app/_lib/services/tasks.service.ts.ejs +0 -10
  89. package/hedhog/frontend/app/_lib/services/timesheets.service.ts.ejs +0 -10
  90. package/hedhog/frontend/app/_lib/types/operations-growth.ts.ejs +0 -209
  91. package/hedhog/frontend/app/_lib/types/operations.ts.ejs +0 -156
  92. package/hedhog/frontend/app/_lib/utils/growth.ts.ejs +0 -62
  93. package/hedhog/frontend/app/_lib/utils/metrics.ts.ejs +0 -103
  94. package/hedhog/frontend/app/_lib/utils/status.ts.ejs +0 -80
  95. package/hedhog/frontend/app/allocations/page.tsx.ejs +0 -155
  96. package/hedhog/frontend/app/career/page.tsx.ejs +0 -143
  97. package/hedhog/frontend/app/certifications/page.tsx.ejs +0 -202
  98. package/hedhog/frontend/app/evaluations/page.tsx.ejs +0 -278
  99. package/hedhog/frontend/app/goals/page.tsx.ejs +0 -171
  100. package/hedhog/frontend/app/growth/page.tsx.ejs +0 -288
  101. package/hedhog/frontend/app/manager/page.tsx.ejs +0 -175
  102. package/hedhog/frontend/app/rewards/page.tsx.ejs +0 -196
  103. package/hedhog/frontend/app/tasks/page.tsx.ejs +0 -999
  104. package/hedhog/table/operations_calibration_item.yaml +0 -61
  105. package/hedhog/table/operations_calibration_session.yaml +0 -25
  106. package/hedhog/table/operations_career_level.yaml +0 -75
  107. package/hedhog/table/operations_career_track.yaml +0 -21
  108. package/hedhog/table/operations_certification.yaml +0 -48
  109. package/hedhog/table/operations_employee_certification.yaml +0 -43
  110. package/hedhog/table/operations_employee_connect.yaml +0 -61
  111. package/hedhog/table/operations_employee_evaluation.yaml +0 -113
  112. package/hedhog/table/operations_employee_evaluation_item.yaml +0 -39
  113. package/hedhog/table/operations_employee_profile.yaml +0 -80
  114. package/hedhog/table/operations_employee_skill_matrix.yaml +0 -30
  115. package/hedhog/table/operations_evaluation_cycle.yaml +0 -31
  116. package/hedhog/table/operations_goal.yaml +0 -67
  117. package/hedhog/table/operations_goal_progress.yaml +0 -31
  118. package/hedhog/table/operations_performance_criterion.yaml +0 -29
  119. package/hedhog/table/operations_promotion_readiness.yaml +0 -49
  120. package/hedhog/table/operations_promotion_recommendation.yaml +0 -63
  121. package/hedhog/table/operations_public_recognition.yaml +0 -46
  122. package/hedhog/table/operations_reward.yaml +0 -100
  123. package/hedhog/table/operations_score_event.yaml +0 -81
  124. package/hedhog/table/operations_task.yaml +0 -60
  125. package/src/operations-data.controller.ts +0 -54
  126. package/src/operations-growth.controller.ts +0 -44
@@ -0,0 +1,261 @@
1
+ 'use client';
2
+
3
+ import { EmptyState, Page, SearchBar } from '@/components/entity-list';
4
+ import { Button } from '@/components/ui/button';
5
+ import {
6
+ Table,
7
+ TableBody,
8
+ TableCell,
9
+ TableHead,
10
+ TableHeader,
11
+ TableRow,
12
+ } from '@/components/ui/table';
13
+ import { useApp, useQuery } from '@hed-hog/next-app-provider';
14
+ import { Eye, FileText, Pencil, UserRound } from 'lucide-react';
15
+ import Link from 'next/link';
16
+ import { useMemo, useState } from 'react';
17
+ import { useTranslations } from 'next-intl';
18
+ import { OperationsHeader } from '../_components/operations-header';
19
+ import { StatusBadge } from '../_components/status-badge';
20
+ import { fetchOperations, mutateOperations } from '../_lib/api';
21
+ import { useOperationsAccess } from '../_lib/hooks/use-operations-access';
22
+ import type { OperationsCollaborator } from '../_lib/types';
23
+ import {
24
+ formatDate,
25
+ formatEnumLabel,
26
+ formatHours,
27
+ getStatusBadgeClass,
28
+ } from '../_lib/utils/format';
29
+
30
+ export default function OperationsCollaboratorsPage() {
31
+ const t = useTranslations('operations.CollaboratorsPage');
32
+ const commonT = useTranslations('operations.Common');
33
+ const { request, showToastHandler, currentLocaleCode } = useApp();
34
+ const access = useOperationsAccess();
35
+ const [search, setSearch] = useState('');
36
+ const [statusFilter, setStatusFilter] = useState('all');
37
+ const [typeFilter, setTypeFilter] = useState('all');
38
+
39
+ const { data: collaborators = [], refetch } = useQuery<OperationsCollaborator[]>({
40
+ queryKey: ['operations-collaborators-list', currentLocaleCode],
41
+ enabled: access.isCollaborator,
42
+ queryFn: () =>
43
+ fetchOperations<OperationsCollaborator[]>(request, '/operations/collaborators'),
44
+ });
45
+
46
+ const filteredRows = useMemo(
47
+ () =>
48
+ collaborators.filter((item) => {
49
+ const matchesSearch = !search.trim()
50
+ ? true
51
+ : [
52
+ item.displayName,
53
+ item.code,
54
+ item.department,
55
+ item.title,
56
+ item.supervisorName,
57
+ ]
58
+ .filter(Boolean)
59
+ .some((value) =>
60
+ String(value).toLowerCase().includes(search.trim().toLowerCase())
61
+ );
62
+ const matchesStatus =
63
+ statusFilter === 'all' ? true : item.status === statusFilter;
64
+ const matchesType =
65
+ typeFilter === 'all' ? true : item.collaboratorType === typeFilter;
66
+ return matchesSearch && matchesStatus && matchesType;
67
+ }),
68
+ [collaborators, search, statusFilter, typeFilter]
69
+ );
70
+
71
+ const toggleStatus = async (collaborator: OperationsCollaborator) => {
72
+ const nextStatus = collaborator.status === 'inactive' ? 'active' : 'inactive';
73
+
74
+ try {
75
+ await mutateOperations(
76
+ request,
77
+ `/operations/collaborators/${collaborator.id}`,
78
+ 'PATCH',
79
+ { status: nextStatus }
80
+ );
81
+ showToastHandler?.('success', t('messages.statusSuccess'));
82
+ await refetch();
83
+ } catch {
84
+ showToastHandler?.('error', t('messages.statusError'));
85
+ }
86
+ };
87
+
88
+ return (
89
+ <Page>
90
+ <OperationsHeader
91
+ title={t('title')}
92
+ description={t('description')}
93
+ current={t('breadcrumb')}
94
+ actions={
95
+ access.isDirector ? (
96
+ <Button size="sm" asChild>
97
+ <Link href="/operations/collaborators/new">
98
+ {commonT('actions.create')}
99
+ </Link>
100
+ </Button>
101
+ ) : undefined
102
+ }
103
+ />
104
+
105
+ <SearchBar
106
+ searchQuery={search}
107
+ onSearchChange={setSearch}
108
+ onSearch={() => undefined}
109
+ placeholder={t('searchPlaceholder')}
110
+ controls={[
111
+ {
112
+ id: 'type',
113
+ type: 'select',
114
+ value: typeFilter,
115
+ onChange: setTypeFilter,
116
+ placeholder: commonT('labels.collaboratorType'),
117
+ options: [
118
+ { value: 'all', label: commonT('filters.allTypes') },
119
+ { value: 'clt', label: 'CLT' },
120
+ { value: 'pj', label: 'PJ' },
121
+ { value: 'freelancer', label: 'Freelancer' },
122
+ { value: 'intern', label: 'Intern' },
123
+ { value: 'other', label: 'Other' }
124
+ ]
125
+ },
126
+ {
127
+ id: 'status',
128
+ type: 'select',
129
+ value: statusFilter,
130
+ onChange: setStatusFilter,
131
+ placeholder: commonT('labels.status'),
132
+ options: [
133
+ { value: 'all', label: commonT('filters.allStatuses') },
134
+ { value: 'active', label: formatEnumLabel('active') },
135
+ { value: 'on_leave', label: formatEnumLabel('on_leave') },
136
+ { value: 'inactive', label: formatEnumLabel('inactive') }
137
+ ]
138
+ }
139
+ ]}
140
+ />
141
+
142
+ {filteredRows.length > 0 ? (
143
+ <div className="overflow-x-auto rounded-md border">
144
+ <Table>
145
+ <TableHeader>
146
+ <TableRow>
147
+ <TableHead>{commonT('labels.collaborator')}</TableHead>
148
+ <TableHead>{commonT('labels.collaboratorType')}</TableHead>
149
+ <TableHead>{commonT('labels.title')}</TableHead>
150
+ <TableHead>{commonT('labels.status')}</TableHead>
151
+ <TableHead>{commonT('labels.supervisor')}</TableHead>
152
+ <TableHead>{commonT('labels.weeklyCapacity')}</TableHead>
153
+ <TableHead>{commonT('labels.contractStatus')}</TableHead>
154
+ <TableHead>{commonT('labels.startDate')}</TableHead>
155
+ <TableHead className="w-[260px] text-right">
156
+ {commonT('labels.actions')}
157
+ </TableHead>
158
+ </TableRow>
159
+ </TableHeader>
160
+ <TableBody>
161
+ {filteredRows.map((collaborator) => (
162
+ <TableRow key={collaborator.id}>
163
+ <TableCell>
164
+ <div className="font-medium">{collaborator.displayName}</div>
165
+ <div className="text-xs text-muted-foreground">
166
+ {collaborator.code}
167
+ </div>
168
+ </TableCell>
169
+ <TableCell>{formatEnumLabel(collaborator.collaboratorType)}</TableCell>
170
+ <TableCell>
171
+ {[collaborator.department, collaborator.title]
172
+ .filter(Boolean)
173
+ .join(' • ') || commonT('labels.notAvailable')}
174
+ </TableCell>
175
+ <TableCell>
176
+ <StatusBadge
177
+ label={formatEnumLabel(collaborator.status)}
178
+ className={getStatusBadgeClass(collaborator.status)}
179
+ />
180
+ </TableCell>
181
+ <TableCell>
182
+ {collaborator.supervisorName || commonT('labels.notAssigned')}
183
+ </TableCell>
184
+ <TableCell>{formatHours(collaborator.weeklyCapacityHours)}</TableCell>
185
+ <TableCell>
186
+ {collaborator.contractStatus ? (
187
+ <StatusBadge
188
+ label={formatEnumLabel(collaborator.contractStatus)}
189
+ className={getStatusBadgeClass(collaborator.contractStatus)}
190
+ />
191
+ ) : (
192
+ commonT('labels.notAssigned')
193
+ )}
194
+ </TableCell>
195
+ <TableCell>{formatDate(collaborator.joinedAt)}</TableCell>
196
+ <TableCell>
197
+ <div className="flex justify-end gap-2">
198
+ <Button variant="outline" size="icon" asChild>
199
+ <Link href={`/operations/collaborators/${collaborator.id}`}>
200
+ <Eye className="size-4" />
201
+ </Link>
202
+ </Button>
203
+ {access.isDirector ? (
204
+ <Button variant="outline" size="icon" asChild>
205
+ <Link href={`/operations/collaborators/${collaborator.id}/edit`}>
206
+ <Pencil className="size-4" />
207
+ </Link>
208
+ </Button>
209
+ ) : null}
210
+ <Button
211
+ variant="outline"
212
+ size="icon"
213
+ asChild={Boolean(collaborator.contractId)}
214
+ disabled={!collaborator.contractId}
215
+ >
216
+ {collaborator.contractId ? (
217
+ <Link href={`/operations/contracts?edit=${collaborator.contractId}`}>
218
+ <FileText className="size-4" />
219
+ </Link>
220
+ ) : (
221
+ <span>
222
+ <FileText className="size-4" />
223
+ </span>
224
+ )}
225
+ </Button>
226
+ {access.isDirector ? (
227
+ <Button
228
+ variant="outline"
229
+ size="sm"
230
+ onClick={() => void toggleStatus(collaborator)}
231
+ >
232
+ {collaborator.status === 'inactive'
233
+ ? commonT('actions.activate')
234
+ : commonT('actions.deactivate')}
235
+ </Button>
236
+ ) : null}
237
+ </div>
238
+ </TableCell>
239
+ </TableRow>
240
+ ))}
241
+ </TableBody>
242
+ </Table>
243
+ </div>
244
+ ) : (
245
+ <EmptyState
246
+ icon={<UserRound className="size-12" />}
247
+ title={commonT('states.emptyTitle')}
248
+ description={t('emptyDescription')}
249
+ actionLabel={access.isDirector ? commonT('actions.create') : commonT('actions.refresh')}
250
+ onAction={
251
+ access.isDirector
252
+ ? () => {
253
+ window.location.href = '/operations/collaborators/new';
254
+ }
255
+ : () => void refetch()
256
+ }
257
+ />
258
+ )}
259
+ </Page>
260
+ );
261
+ }
@@ -0,0 +1,11 @@
1
+ import { ContractFormScreen } from '../../../_components/contract-form-screen';
2
+
3
+ export default async function OperationsContractEditPage({
4
+ params,
5
+ }: {
6
+ params: Promise<{ id: string }>;
7
+ }) {
8
+ const { id } = await params;
9
+
10
+ return <ContractFormScreen contractId={Number(id)} />;
11
+ }
@@ -1,108 +1,11 @@
1
- 'use client';
2
-
3
- import { Page } from '@/components/entity-list';
4
- import { useParams } from 'next/navigation';
5
- import { OperationsHeader } from '../../_components/operations-header';
6
- import { SectionCard } from '../../_components/section-card';
7
- import { StatusBadge } from '../../_components/status-badge';
8
- import { useOperationsData } from '../../_lib/hooks/use-operations-data';
9
- import { formatCurrency, formatDate } from '../../_lib/utils/format';
10
- import {
11
- getContractBadgeClasses,
12
- getContractTypeLabel,
13
- } from '../../_lib/utils/status';
14
-
15
- export default function ContractDetailsPage() {
16
- const params = useParams<{ id: string }>();
17
- const { contracts, projects } = useOperationsData();
18
- const contract = contracts.find((item) => item.id === params.id);
19
-
20
- if (!contract) {
21
- return <Page>Contract not found.</Page>;
22
- }
23
-
24
- const linkedProjects = projects.filter((project) =>
25
- contract.linkedProjectIds.includes(project.id)
26
- );
27
-
28
- return (
29
- <Page>
30
- <OperationsHeader
31
- title={contract.name}
32
- description="Static mock detail page with production-ready structure."
33
- current="Contract Details"
34
- />
35
-
36
- <div className="grid gap-4 xl:grid-cols-2">
37
- <SectionCard title="Contract Info">
38
- <div className="grid gap-3 text-sm sm:grid-cols-2">
39
- <p>
40
- <span className="font-medium">Client:</span> {contract.client}
41
- </p>
42
- <p>
43
- <span className="font-medium">Type:</span>{' '}
44
- {getContractTypeLabel(contract.type)}
45
- </p>
46
- <p>
47
- <span className="font-medium">Start:</span>{' '}
48
- {formatDate(contract.startDate)}
49
- </p>
50
- <p>
51
- <span className="font-medium">End:</span>{' '}
52
- {formatDate(contract.endDate)}
53
- </p>
54
- <p>
55
- <span className="font-medium">Hour Rate:</span>{' '}
56
- {formatCurrency(contract.hourlyRate)}
57
- </p>
58
- <p>
59
- <span className="font-medium">Hour Limit:</span>{' '}
60
- {contract.hourLimit}h
61
- </p>
62
- <div className="sm:col-span-2">
63
- <StatusBadge
64
- label={contract.status}
65
- className={getContractBadgeClasses(contract.status)}
66
- />
67
- </div>
68
- </div>
69
- </SectionCard>
70
-
71
- <SectionCard title="Linked Projects">
72
- <div className="space-y-3">
73
- {linkedProjects.map((project) => (
74
- <div key={project.id} className="rounded-lg border p-3">
75
- <p className="font-medium">{project.name}</p>
76
- <p className="text-sm text-muted-foreground">{project.client}</p>
77
- </div>
78
- ))}
79
- </div>
80
- </SectionCard>
81
-
82
- <SectionCard title="Billing Rules">
83
- <ul className="space-y-2 text-sm">
84
- {contract.billingRules.map((rule) => (
85
- <li key={rule} className="rounded-md bg-muted/40 p-3">
86
- {rule}
87
- </li>
88
- ))}
89
- </ul>
90
- </SectionCard>
91
-
92
- <SectionCard title="SLA">
93
- <p className="text-sm text-muted-foreground">{contract.sla}</p>
94
- </SectionCard>
95
-
96
- <SectionCard title="Adjustments / Revisions" className="xl:col-span-2">
97
- <ul className="space-y-2 text-sm">
98
- {contract.revisions.map((revision) => (
99
- <li key={revision} className="rounded-md border p-3">
100
- {revision}
101
- </li>
102
- ))}
103
- </ul>
104
- </SectionCard>
105
- </div>
106
- </Page>
107
- );
108
- }
1
+ import { ContractDetailsScreen } from '../../_components/contract-details-screen';
2
+
3
+ export default async function OperationsContractDetailsPage({
4
+ params,
5
+ }: {
6
+ params: Promise<{ id: string }>;
7
+ }) {
8
+ const { id } = await params;
9
+
10
+ return <ContractDetailsScreen contractId={Number(id)} />;
11
+ }
@@ -0,0 +1,17 @@
1
+ import { ContractFormScreen } from '../../_components/contract-form-screen';
2
+
3
+ export default async function OperationsContractCreatePage({
4
+ searchParams,
5
+ }: {
6
+ searchParams?: Promise<{ duplicate?: string }>;
7
+ }) {
8
+ const resolved = searchParams ? await searchParams : undefined;
9
+
10
+ return (
11
+ <ContractFormScreen
12
+ duplicateFromId={
13
+ resolved?.duplicate ? Number(resolved.duplicate) : undefined
14
+ }
15
+ />
16
+ );
17
+ }