@hed-hog/operations 0.0.328 → 0.0.330

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 (596) hide show
  1. package/dist/controllers/operations-tasks.controller.d.ts +5 -5
  2. package/dist/operations.service.d.ts +5 -5
  3. package/dist/operations.service.d.ts.map +1 -1
  4. package/dist/operations.service.js +24 -4
  5. package/dist/operations.service.js.map +1 -1
  6. package/dist/operations.service.spec.js +1 -1
  7. package/dist/operations.service.spec.js.map +1 -1
  8. package/hedhog/data/dashboard_component_role.yaml +8 -8
  9. package/hedhog/data/dashboard_role.yaml +1 -1
  10. package/hedhog/data/menu.yaml +6 -16
  11. package/hedhog/data/role.yaml +1 -1
  12. package/hedhog/data/route.yaml +55 -55
  13. package/hedhog/frontend/app/_components/async-options-combobox.tsx.ejs +15 -9
  14. package/hedhog/frontend/app/_components/collaborator-form-screen.tsx.ejs +7 -7
  15. package/hedhog/frontend/app/_components/department-picker.tsx.ejs +125 -0
  16. package/hedhog/frontend/app/_components/department-select-with-create.tsx.ejs +64 -325
  17. package/hedhog/frontend/app/_components/project-costs-section.tsx.ejs +51 -81
  18. package/hedhog/frontend/app/_components/project-details-screen.tsx.ejs +39 -11
  19. package/hedhog/frontend/app/_components/project-form-screen.tsx.ejs +37 -20
  20. package/hedhog/frontend/app/_components/system-user-picker.tsx.ejs +198 -0
  21. package/hedhog/frontend/app/_components/system-user-select-with-create.tsx.ejs +107 -569
  22. package/hedhog/frontend/app/_components/task-file-attachments.tsx.ejs +10 -8
  23. package/hedhog/frontend/app/_lib/hooks/use-values-visibility.ts.ejs +61 -0
  24. package/hedhog/frontend/app/approvals/page.tsx.ejs +5 -1
  25. package/hedhog/frontend/app/collaborators/page.tsx.ejs +68 -34
  26. package/hedhog/frontend/app/my-projects/page.tsx.ejs +45 -6
  27. package/hedhog/frontend/app/my-tasks/page.tsx.ejs +1 -1
  28. package/hedhog/frontend/app/projects/page.tsx.ejs +60 -5
  29. package/hedhog/frontend/app/reports/collaborators/page.tsx.ejs +65 -52
  30. package/hedhog/frontend/app/reports/projects/page.tsx.ejs +80 -82
  31. package/hedhog/frontend/app/schedule-adjustments/page.tsx.ejs +7 -1
  32. package/hedhog/frontend/messages/en.json +284 -8
  33. package/hedhog/frontend/messages/operations/en.json +67 -3
  34. package/hedhog/frontend/messages/operations/pt.json +67 -3
  35. package/hedhog/frontend/messages/pt.json +282 -6
  36. package/package.json +5 -5
  37. package/src/operations.service.spec.ts +1 -1
  38. package/src/operations.service.ts +25 -5
  39. package/hedhog/frontend/app/_components/collaborator-details-screen.tsx.ejs +0 -476
  40. package/hedhog/frontend/app/_components/collaborator-select-with-create.tsx.ejs +0 -261
  41. package/hedhog/frontend/app/_components/contract-content-editor.tsx.ejs +0 -258
  42. package/hedhog/frontend/app/_components/person-select-with-create.tsx.ejs +0 -1
  43. package/hedhog/frontend/messages/en.json.ejs +0 -2060
  44. package/hedhog/frontend/messages/operations/operations/en.json +0 -2102
  45. package/hedhog/frontend/messages/operations/operations/pt.json +0 -2111
  46. package/hedhog/frontend/messages/pt.json.ejs +0 -2067
  47. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/async-options-combobox.d.ts +0 -29
  48. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/async-options-combobox.d.ts.map +0 -1
  49. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/async-options-combobox.js +0 -95
  50. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/async-options-combobox.js.map +0 -1
  51. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/async-options-combobox.tsx +0 -233
  52. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/collaborator-costs-section.d.ts +0 -10
  53. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/collaborator-costs-section.d.ts.map +0 -1
  54. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/collaborator-costs-section.js +0 -577
  55. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/collaborator-costs-section.js.map +0 -1
  56. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/collaborator-costs-section.tsx +0 -868
  57. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/collaborator-details-screen.d.ts +0 -4
  58. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/collaborator-details-screen.d.ts.map +0 -1
  59. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/collaborator-details-screen.js +0 -337
  60. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/collaborator-details-screen.js.map +0 -1
  61. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/collaborator-details-screen.tsx +0 -476
  62. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/collaborator-form-screen.d.ts +0 -9
  63. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/collaborator-form-screen.d.ts.map +0 -1
  64. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/collaborator-form-screen.js +0 -1348
  65. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/collaborator-form-screen.js.map +0 -1
  66. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/collaborator-form-screen.tsx +0 -2233
  67. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/collaborator-select-with-create.d.ts +0 -12
  68. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/collaborator-select-with-create.d.ts.map +0 -1
  69. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/collaborator-select-with-create.js +0 -162
  70. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/collaborator-select-with-create.js.map +0 -1
  71. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/collaborator-select-with-create.tsx +0 -261
  72. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/contract-content-editor.d.ts +0 -18
  73. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/contract-content-editor.d.ts.map +0 -1
  74. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/contract-content-editor.js +0 -145
  75. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/contract-content-editor.js.map +0 -1
  76. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/contract-content-editor.tsx +0 -258
  77. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/contract-details-screen.d.ts +0 -4
  78. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/contract-details-screen.d.ts.map +0 -1
  79. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/contract-details-screen.js +0 -223
  80. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/contract-details-screen.js.map +0 -1
  81. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/contract-details-screen.tsx +0 -342
  82. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/contract-form-screen.d.ts +0 -58
  83. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/contract-form-screen.d.ts.map +0 -1
  84. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/contract-form-screen.js +0 -438
  85. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/contract-form-screen.js.map +0 -1
  86. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/contract-form-screen.tsx +0 -698
  87. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/department-select-with-create.d.ts +0 -20
  88. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/department-select-with-create.d.ts.map +0 -1
  89. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/department-select-with-create.js +0 -233
  90. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/department-select-with-create.js.map +0 -1
  91. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/department-select-with-create.tsx +0 -392
  92. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/my-project-summary-screen.d.ts +0 -4
  93. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/my-project-summary-screen.d.ts.map +0 -1
  94. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/my-project-summary-screen.js +0 -814
  95. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/my-project-summary-screen.js.map +0 -1
  96. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/my-project-summary-screen.tsx +0 -1288
  97. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/operations-calendar-view.d.ts +0 -21
  98. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/operations-calendar-view.d.ts.map +0 -1
  99. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/operations-calendar-view.js +0 -174
  100. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/operations-calendar-view.js.map +0 -1
  101. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/operations-calendar-view.tsx +0 -306
  102. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/operations-header.d.ts +0 -10
  103. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/operations-header.d.ts.map +0 -1
  104. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/operations-header.js +0 -12
  105. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/operations-header.js.map +0 -1
  106. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/operations-header.tsx +0 -29
  107. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/person-select-with-create.d.ts +0 -15
  108. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/person-select-with-create.d.ts.map +0 -1
  109. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/person-select-with-create.js +0 -501
  110. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/person-select-with-create.js.map +0 -1
  111. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/person-select-with-create.tsx +0 -853
  112. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/project-costs-section.d.ts +0 -6
  113. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/project-costs-section.d.ts.map +0 -1
  114. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/project-costs-section.js +0 -847
  115. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/project-costs-section.js.map +0 -1
  116. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/project-costs-section.tsx +0 -1340
  117. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/project-details-screen.d.ts +0 -4
  118. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/project-details-screen.d.ts.map +0 -1
  119. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/project-details-screen.js +0 -2930
  120. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/project-details-screen.js.map +0 -1
  121. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/project-details-screen.tsx +0 -4378
  122. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/project-form-screen.d.ts +0 -9
  123. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/project-form-screen.d.ts.map +0 -1
  124. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/project-form-screen.js +0 -1013
  125. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/project-form-screen.js.map +0 -1
  126. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/project-form-screen.tsx +0 -1745
  127. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/section-card.d.ts +0 -13
  128. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/section-card.d.ts.map +0 -1
  129. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/section-card.js +0 -38
  130. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/section-card.js.map +0 -1
  131. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/section-card.tsx +0 -74
  132. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/status-badge.d.ts +0 -7
  133. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/status-badge.d.ts.map +0 -1
  134. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/status-badge.js +0 -11
  135. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/status-badge.js.map +0 -1
  136. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/status-badge.tsx +0 -15
  137. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/system-user-select-with-create.d.ts +0 -18
  138. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/system-user-select-with-create.d.ts.map +0 -1
  139. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/system-user-select-with-create.js +0 -406
  140. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/system-user-select-with-create.js.map +0 -1
  141. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/system-user-select-with-create.tsx +0 -660
  142. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/task-detail-sheet.d.ts +0 -26
  143. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/task-detail-sheet.d.ts.map +0 -1
  144. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/task-detail-sheet.js +0 -332
  145. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/task-detail-sheet.js.map +0 -1
  146. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/task-detail-sheet.tsx +0 -518
  147. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/task-file-attachments.d.ts +0 -6
  148. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/task-file-attachments.d.ts.map +0 -1
  149. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/task-file-attachments.js +0 -255
  150. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/task-file-attachments.js.map +0 -1
  151. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/task-file-attachments.tsx +0 -388
  152. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/timesheet-task-create-sheet.d.ts +0 -10
  153. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/timesheet-task-create-sheet.d.ts.map +0 -1
  154. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/timesheet-task-create-sheet.js +0 -131
  155. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/timesheet-task-create-sheet.js.map +0 -1
  156. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/timesheet-task-create-sheet.tsx +0 -214
  157. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_lib/api.d.ts +0 -108
  158. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_lib/api.d.ts.map +0 -1
  159. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_lib/api.js +0 -162
  160. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_lib/api.js.map +0 -1
  161. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_lib/api.ts +0 -428
  162. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_lib/hooks/use-operations-access.d.ts +0 -8
  163. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_lib/hooks/use-operations-access.d.ts.map +0 -1
  164. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_lib/hooks/use-operations-access.js +0 -36
  165. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_lib/hooks/use-operations-access.js.map +0 -1
  166. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_lib/hooks/use-operations-access.ts +0 -44
  167. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_lib/types.d.ts +0 -837
  168. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_lib/types.d.ts.map +0 -1
  169. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_lib/types.js +0 -3
  170. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_lib/types.js.map +0 -1
  171. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_lib/types.ts +0 -861
  172. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_lib/utils/format.d.ts +0 -16
  173. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_lib/utils/format.d.ts.map +0 -1
  174. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_lib/utils/format.js +0 -182
  175. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_lib/utils/format.js.map +0 -1
  176. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_lib/utils/format.ts +0 -250
  177. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_lib/utils/forms.d.ts +0 -4
  178. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_lib/utils/forms.d.ts.map +0 -1
  179. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_lib/utils/forms.js +0 -51
  180. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_lib/utils/forms.js.map +0 -1
  181. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_lib/utils/forms.ts +0 -61
  182. package/hedhog/frontend/src/app/(app)/(libraries)/operations/approvals/page.d.ts +0 -2
  183. package/hedhog/frontend/src/app/(app)/(libraries)/operations/approvals/page.d.ts.map +0 -1
  184. package/hedhog/frontend/src/app/(app)/(libraries)/operations/approvals/page.js +0 -954
  185. package/hedhog/frontend/src/app/(app)/(libraries)/operations/approvals/page.js.map +0 -1
  186. package/hedhog/frontend/src/app/(app)/(libraries)/operations/approvals/page.tsx +0 -1277
  187. package/hedhog/frontend/src/app/(app)/(libraries)/operations/collaborator-types/page.d.ts +0 -2
  188. package/hedhog/frontend/src/app/(app)/(libraries)/operations/collaborator-types/page.d.ts.map +0 -1
  189. package/hedhog/frontend/src/app/(app)/(libraries)/operations/collaborator-types/page.js +0 -488
  190. package/hedhog/frontend/src/app/(app)/(libraries)/operations/collaborator-types/page.js.map +0 -1
  191. package/hedhog/frontend/src/app/(app)/(libraries)/operations/collaborator-types/page.tsx +0 -805
  192. package/hedhog/frontend/src/app/(app)/(libraries)/operations/collaborators/[id]/edit/page.d.ts +0 -6
  193. package/hedhog/frontend/src/app/(app)/(libraries)/operations/collaborators/[id]/edit/page.d.ts.map +0 -1
  194. package/hedhog/frontend/src/app/(app)/(libraries)/operations/collaborators/[id]/edit/page.js +0 -9
  195. package/hedhog/frontend/src/app/(app)/(libraries)/operations/collaborators/[id]/edit/page.js.map +0 -1
  196. package/hedhog/frontend/src/app/(app)/(libraries)/operations/collaborators/[id]/edit/page.tsx +0 -11
  197. package/hedhog/frontend/src/app/(app)/(libraries)/operations/collaborators/[id]/page.d.ts +0 -6
  198. package/hedhog/frontend/src/app/(app)/(libraries)/operations/collaborators/[id]/page.d.ts.map +0 -1
  199. package/hedhog/frontend/src/app/(app)/(libraries)/operations/collaborators/[id]/page.js +0 -9
  200. package/hedhog/frontend/src/app/(app)/(libraries)/operations/collaborators/[id]/page.js.map +0 -1
  201. package/hedhog/frontend/src/app/(app)/(libraries)/operations/collaborators/[id]/page.tsx +0 -11
  202. package/hedhog/frontend/src/app/(app)/(libraries)/operations/collaborators/new/page.d.ts +0 -2
  203. package/hedhog/frontend/src/app/(app)/(libraries)/operations/collaborators/new/page.d.ts.map +0 -1
  204. package/hedhog/frontend/src/app/(app)/(libraries)/operations/collaborators/new/page.js +0 -8
  205. package/hedhog/frontend/src/app/(app)/(libraries)/operations/collaborators/new/page.js.map +0 -1
  206. package/hedhog/frontend/src/app/(app)/(libraries)/operations/collaborators/new/page.tsx +0 -5
  207. package/hedhog/frontend/src/app/(app)/(libraries)/operations/collaborators/page.d.ts +0 -2
  208. package/hedhog/frontend/src/app/(app)/(libraries)/operations/collaborators/page.d.ts.map +0 -1
  209. package/hedhog/frontend/src/app/(app)/(libraries)/operations/collaborators/page.js +0 -612
  210. package/hedhog/frontend/src/app/(app)/(libraries)/operations/collaborators/page.js.map +0 -1
  211. package/hedhog/frontend/src/app/(app)/(libraries)/operations/collaborators/page.tsx +0 -939
  212. package/hedhog/frontend/src/app/(app)/(libraries)/operations/contracts/[id]/edit/page.d.ts +0 -6
  213. package/hedhog/frontend/src/app/(app)/(libraries)/operations/contracts/[id]/edit/page.d.ts.map +0 -1
  214. package/hedhog/frontend/src/app/(app)/(libraries)/operations/contracts/[id]/edit/page.js +0 -9
  215. package/hedhog/frontend/src/app/(app)/(libraries)/operations/contracts/[id]/edit/page.js.map +0 -1
  216. package/hedhog/frontend/src/app/(app)/(libraries)/operations/contracts/[id]/edit/page.tsx +0 -11
  217. package/hedhog/frontend/src/app/(app)/(libraries)/operations/contracts/[id]/page.d.ts +0 -6
  218. package/hedhog/frontend/src/app/(app)/(libraries)/operations/contracts/[id]/page.d.ts.map +0 -1
  219. package/hedhog/frontend/src/app/(app)/(libraries)/operations/contracts/[id]/page.js +0 -9
  220. package/hedhog/frontend/src/app/(app)/(libraries)/operations/contracts/[id]/page.js.map +0 -1
  221. package/hedhog/frontend/src/app/(app)/(libraries)/operations/contracts/[id]/page.tsx +0 -11
  222. package/hedhog/frontend/src/app/(app)/(libraries)/operations/contracts/new/page.d.ts +0 -6
  223. package/hedhog/frontend/src/app/(app)/(libraries)/operations/contracts/new/page.d.ts.map +0 -1
  224. package/hedhog/frontend/src/app/(app)/(libraries)/operations/contracts/new/page.js +0 -9
  225. package/hedhog/frontend/src/app/(app)/(libraries)/operations/contracts/new/page.js.map +0 -1
  226. package/hedhog/frontend/src/app/(app)/(libraries)/operations/contracts/new/page.tsx +0 -17
  227. package/hedhog/frontend/src/app/(app)/(libraries)/operations/contracts/page.d.ts +0 -2
  228. package/hedhog/frontend/src/app/(app)/(libraries)/operations/contracts/page.d.ts.map +0 -1
  229. package/hedhog/frontend/src/app/(app)/(libraries)/operations/contracts/page.js +0 -348
  230. package/hedhog/frontend/src/app/(app)/(libraries)/operations/contracts/page.js.map +0 -1
  231. package/hedhog/frontend/src/app/(app)/(libraries)/operations/contracts/page.tsx +0 -536
  232. package/hedhog/frontend/src/app/(app)/(libraries)/operations/departments/page.d.ts +0 -2
  233. package/hedhog/frontend/src/app/(app)/(libraries)/operations/departments/page.d.ts.map +0 -1
  234. package/hedhog/frontend/src/app/(app)/(libraries)/operations/departments/page.js +0 -401
  235. package/hedhog/frontend/src/app/(app)/(libraries)/operations/departments/page.js.map +0 -1
  236. package/hedhog/frontend/src/app/(app)/(libraries)/operations/departments/page.tsx +0 -607
  237. package/hedhog/frontend/src/app/(app)/(libraries)/operations/layout.d.ts +0 -5
  238. package/hedhog/frontend/src/app/(app)/(libraries)/operations/layout.d.ts.map +0 -1
  239. package/hedhog/frontend/src/app/(app)/(libraries)/operations/layout.js +0 -7
  240. package/hedhog/frontend/src/app/(app)/(libraries)/operations/layout.js.map +0 -1
  241. package/hedhog/frontend/src/app/(app)/(libraries)/operations/layout.tsx +0 -9
  242. package/hedhog/frontend/src/app/(app)/(libraries)/operations/my-projects/[id]/page.d.ts +0 -6
  243. package/hedhog/frontend/src/app/(app)/(libraries)/operations/my-projects/[id]/page.d.ts.map +0 -1
  244. package/hedhog/frontend/src/app/(app)/(libraries)/operations/my-projects/[id]/page.js +0 -9
  245. package/hedhog/frontend/src/app/(app)/(libraries)/operations/my-projects/[id]/page.js.map +0 -1
  246. package/hedhog/frontend/src/app/(app)/(libraries)/operations/my-projects/[id]/page.tsx +0 -11
  247. package/hedhog/frontend/src/app/(app)/(libraries)/operations/my-projects/page.d.ts +0 -2
  248. package/hedhog/frontend/src/app/(app)/(libraries)/operations/my-projects/page.d.ts.map +0 -1
  249. package/hedhog/frontend/src/app/(app)/(libraries)/operations/my-projects/page.js +0 -321
  250. package/hedhog/frontend/src/app/(app)/(libraries)/operations/my-projects/page.js.map +0 -1
  251. package/hedhog/frontend/src/app/(app)/(libraries)/operations/my-projects/page.tsx +0 -440
  252. package/hedhog/frontend/src/app/(app)/(libraries)/operations/my-tasks/page.d.ts +0 -2
  253. package/hedhog/frontend/src/app/(app)/(libraries)/operations/my-tasks/page.d.ts.map +0 -1
  254. package/hedhog/frontend/src/app/(app)/(libraries)/operations/my-tasks/page.js +0 -939
  255. package/hedhog/frontend/src/app/(app)/(libraries)/operations/my-tasks/page.js.map +0 -1
  256. package/hedhog/frontend/src/app/(app)/(libraries)/operations/my-tasks/page.tsx +0 -1499
  257. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/async-options-combobox.d.ts +0 -29
  258. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/async-options-combobox.d.ts.map +0 -1
  259. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/async-options-combobox.js +0 -95
  260. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/async-options-combobox.js.map +0 -1
  261. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/async-options-combobox.tsx +0 -233
  262. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/collaborator-costs-section.d.ts +0 -10
  263. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/collaborator-costs-section.d.ts.map +0 -1
  264. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/collaborator-costs-section.js +0 -577
  265. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/collaborator-costs-section.js.map +0 -1
  266. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/collaborator-costs-section.tsx +0 -868
  267. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/collaborator-details-screen.d.ts +0 -4
  268. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/collaborator-details-screen.d.ts.map +0 -1
  269. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/collaborator-details-screen.js +0 -337
  270. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/collaborator-details-screen.js.map +0 -1
  271. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/collaborator-details-screen.tsx +0 -476
  272. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/collaborator-form-screen.d.ts +0 -9
  273. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/collaborator-form-screen.d.ts.map +0 -1
  274. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/collaborator-form-screen.js +0 -1348
  275. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/collaborator-form-screen.js.map +0 -1
  276. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/collaborator-form-screen.tsx +0 -2233
  277. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/collaborator-select-with-create.d.ts +0 -12
  278. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/collaborator-select-with-create.d.ts.map +0 -1
  279. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/collaborator-select-with-create.js +0 -162
  280. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/collaborator-select-with-create.js.map +0 -1
  281. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/collaborator-select-with-create.tsx +0 -261
  282. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/contract-content-editor.d.ts +0 -18
  283. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/contract-content-editor.d.ts.map +0 -1
  284. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/contract-content-editor.js +0 -145
  285. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/contract-content-editor.js.map +0 -1
  286. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/contract-content-editor.tsx +0 -258
  287. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/contract-details-screen.d.ts +0 -4
  288. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/contract-details-screen.d.ts.map +0 -1
  289. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/contract-details-screen.js +0 -223
  290. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/contract-details-screen.js.map +0 -1
  291. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/contract-details-screen.tsx +0 -342
  292. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/contract-form-screen.d.ts +0 -58
  293. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/contract-form-screen.d.ts.map +0 -1
  294. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/contract-form-screen.js +0 -438
  295. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/contract-form-screen.js.map +0 -1
  296. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/contract-form-screen.tsx +0 -698
  297. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/department-select-with-create.d.ts +0 -20
  298. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/department-select-with-create.d.ts.map +0 -1
  299. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/department-select-with-create.js +0 -233
  300. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/department-select-with-create.js.map +0 -1
  301. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/department-select-with-create.tsx +0 -392
  302. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/my-project-summary-screen.d.ts +0 -4
  303. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/my-project-summary-screen.d.ts.map +0 -1
  304. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/my-project-summary-screen.js +0 -814
  305. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/my-project-summary-screen.js.map +0 -1
  306. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/my-project-summary-screen.tsx +0 -1288
  307. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/operations-calendar-view.d.ts +0 -21
  308. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/operations-calendar-view.d.ts.map +0 -1
  309. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/operations-calendar-view.js +0 -174
  310. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/operations-calendar-view.js.map +0 -1
  311. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/operations-calendar-view.tsx +0 -306
  312. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/operations-header.d.ts +0 -10
  313. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/operations-header.d.ts.map +0 -1
  314. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/operations-header.js +0 -12
  315. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/operations-header.js.map +0 -1
  316. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/operations-header.tsx +0 -29
  317. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/person-select-with-create.d.ts +0 -15
  318. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/person-select-with-create.d.ts.map +0 -1
  319. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/person-select-with-create.js +0 -501
  320. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/person-select-with-create.js.map +0 -1
  321. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/person-select-with-create.tsx +0 -853
  322. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/project-cost-report-screen.d.ts +0 -6
  323. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/project-cost-report-screen.d.ts.map +0 -1
  324. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/project-cost-report-screen.js +0 -459
  325. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/project-cost-report-screen.js.map +0 -1
  326. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/project-cost-report-screen.tsx +0 -598
  327. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/project-costs-section.d.ts +0 -6
  328. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/project-costs-section.d.ts.map +0 -1
  329. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/project-costs-section.js +0 -876
  330. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/project-costs-section.js.map +0 -1
  331. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/project-costs-section.tsx +0 -1368
  332. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/project-details-screen.d.ts +0 -4
  333. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/project-details-screen.d.ts.map +0 -1
  334. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/project-details-screen.js +0 -2930
  335. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/project-details-screen.js.map +0 -1
  336. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/project-details-screen.tsx +0 -4378
  337. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/project-form-screen.d.ts +0 -9
  338. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/project-form-screen.d.ts.map +0 -1
  339. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/project-form-screen.js +0 -1013
  340. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/project-form-screen.js.map +0 -1
  341. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/project-form-screen.tsx +0 -1745
  342. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/section-card.d.ts +0 -13
  343. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/section-card.d.ts.map +0 -1
  344. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/section-card.js +0 -38
  345. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/section-card.js.map +0 -1
  346. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/section-card.tsx +0 -74
  347. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/status-badge.d.ts +0 -7
  348. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/status-badge.d.ts.map +0 -1
  349. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/status-badge.js +0 -11
  350. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/status-badge.js.map +0 -1
  351. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/status-badge.tsx +0 -15
  352. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/system-user-select-with-create.d.ts +0 -18
  353. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/system-user-select-with-create.d.ts.map +0 -1
  354. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/system-user-select-with-create.js +0 -406
  355. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/system-user-select-with-create.js.map +0 -1
  356. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/system-user-select-with-create.tsx +0 -660
  357. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/task-detail-sheet.d.ts +0 -26
  358. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/task-detail-sheet.d.ts.map +0 -1
  359. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/task-detail-sheet.js +0 -332
  360. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/task-detail-sheet.js.map +0 -1
  361. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/task-detail-sheet.tsx +0 -518
  362. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/task-file-attachments.d.ts +0 -6
  363. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/task-file-attachments.d.ts.map +0 -1
  364. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/task-file-attachments.js +0 -255
  365. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/task-file-attachments.js.map +0 -1
  366. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/task-file-attachments.tsx +0 -388
  367. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/timesheet-task-create-sheet.d.ts +0 -10
  368. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/timesheet-task-create-sheet.d.ts.map +0 -1
  369. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/timesheet-task-create-sheet.js +0 -131
  370. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/timesheet-task-create-sheet.js.map +0 -1
  371. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/timesheet-task-create-sheet.tsx +0 -214
  372. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_lib/api.d.ts +0 -108
  373. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_lib/api.d.ts.map +0 -1
  374. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_lib/api.js +0 -162
  375. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_lib/api.js.map +0 -1
  376. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_lib/api.ts +0 -428
  377. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_lib/hooks/use-operations-access.d.ts +0 -8
  378. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_lib/hooks/use-operations-access.d.ts.map +0 -1
  379. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_lib/hooks/use-operations-access.js +0 -36
  380. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_lib/hooks/use-operations-access.js.map +0 -1
  381. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_lib/hooks/use-operations-access.ts +0 -44
  382. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_lib/types.d.ts +0 -837
  383. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_lib/types.d.ts.map +0 -1
  384. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_lib/types.js +0 -3
  385. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_lib/types.js.map +0 -1
  386. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_lib/types.ts +0 -861
  387. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_lib/utils/format.d.ts +0 -16
  388. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_lib/utils/format.d.ts.map +0 -1
  389. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_lib/utils/format.js +0 -182
  390. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_lib/utils/format.js.map +0 -1
  391. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_lib/utils/format.ts +0 -250
  392. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_lib/utils/forms.d.ts +0 -4
  393. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_lib/utils/forms.d.ts.map +0 -1
  394. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_lib/utils/forms.js +0 -51
  395. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_lib/utils/forms.js.map +0 -1
  396. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_lib/utils/forms.ts +0 -61
  397. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/approvals/page.d.ts +0 -2
  398. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/approvals/page.d.ts.map +0 -1
  399. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/approvals/page.js +0 -954
  400. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/approvals/page.js.map +0 -1
  401. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/approvals/page.tsx +0 -1277
  402. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/collaborator-types/page.d.ts +0 -2
  403. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/collaborator-types/page.d.ts.map +0 -1
  404. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/collaborator-types/page.js +0 -488
  405. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/collaborator-types/page.js.map +0 -1
  406. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/collaborator-types/page.tsx +0 -805
  407. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/collaborators/[id]/edit/page.d.ts +0 -6
  408. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/collaborators/[id]/edit/page.d.ts.map +0 -1
  409. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/collaborators/[id]/edit/page.js +0 -9
  410. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/collaborators/[id]/edit/page.js.map +0 -1
  411. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/collaborators/[id]/edit/page.tsx +0 -11
  412. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/collaborators/[id]/page.d.ts +0 -6
  413. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/collaborators/[id]/page.d.ts.map +0 -1
  414. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/collaborators/[id]/page.js +0 -9
  415. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/collaborators/[id]/page.js.map +0 -1
  416. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/collaborators/[id]/page.tsx +0 -11
  417. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/collaborators/new/page.d.ts +0 -2
  418. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/collaborators/new/page.d.ts.map +0 -1
  419. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/collaborators/new/page.js +0 -8
  420. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/collaborators/new/page.js.map +0 -1
  421. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/collaborators/new/page.tsx +0 -5
  422. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/collaborators/page.d.ts +0 -2
  423. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/collaborators/page.d.ts.map +0 -1
  424. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/collaborators/page.js +0 -612
  425. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/collaborators/page.js.map +0 -1
  426. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/collaborators/page.tsx +0 -939
  427. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/contracts/[id]/edit/page.d.ts +0 -6
  428. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/contracts/[id]/edit/page.d.ts.map +0 -1
  429. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/contracts/[id]/edit/page.js +0 -9
  430. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/contracts/[id]/edit/page.js.map +0 -1
  431. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/contracts/[id]/edit/page.tsx +0 -11
  432. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/contracts/[id]/page.d.ts +0 -6
  433. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/contracts/[id]/page.d.ts.map +0 -1
  434. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/contracts/[id]/page.js +0 -9
  435. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/contracts/[id]/page.js.map +0 -1
  436. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/contracts/[id]/page.tsx +0 -11
  437. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/contracts/new/page.d.ts +0 -6
  438. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/contracts/new/page.d.ts.map +0 -1
  439. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/contracts/new/page.js +0 -9
  440. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/contracts/new/page.js.map +0 -1
  441. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/contracts/new/page.tsx +0 -17
  442. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/contracts/page.d.ts +0 -2
  443. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/contracts/page.d.ts.map +0 -1
  444. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/contracts/page.js +0 -348
  445. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/contracts/page.js.map +0 -1
  446. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/contracts/page.tsx +0 -536
  447. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/departments/page.d.ts +0 -2
  448. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/departments/page.d.ts.map +0 -1
  449. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/departments/page.js +0 -401
  450. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/departments/page.js.map +0 -1
  451. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/departments/page.tsx +0 -607
  452. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/layout.d.ts +0 -5
  453. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/layout.d.ts.map +0 -1
  454. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/layout.js +0 -7
  455. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/layout.js.map +0 -1
  456. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/layout.tsx +0 -9
  457. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/my-projects/[id]/page.d.ts +0 -6
  458. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/my-projects/[id]/page.d.ts.map +0 -1
  459. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/my-projects/[id]/page.js +0 -9
  460. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/my-projects/[id]/page.js.map +0 -1
  461. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/my-projects/[id]/page.tsx +0 -11
  462. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/my-projects/page.d.ts +0 -2
  463. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/my-projects/page.d.ts.map +0 -1
  464. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/my-projects/page.js +0 -321
  465. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/my-projects/page.js.map +0 -1
  466. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/my-projects/page.tsx +0 -440
  467. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/my-tasks/page.d.ts +0 -2
  468. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/my-tasks/page.d.ts.map +0 -1
  469. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/my-tasks/page.js +0 -939
  470. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/my-tasks/page.js.map +0 -1
  471. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/my-tasks/page.tsx +0 -1499
  472. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/page.d.ts +0 -2
  473. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/page.d.ts.map +0 -1
  474. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/page.js +0 -8
  475. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/page.js.map +0 -1
  476. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/page.tsx +0 -5
  477. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/project-cost-categories/page.d.ts +0 -2
  478. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/project-cost-categories/page.d.ts.map +0 -1
  479. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/project-cost-categories/page.js +0 -436
  480. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/project-cost-categories/page.js.map +0 -1
  481. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/project-cost-categories/page.tsx +0 -675
  482. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/project-cost-types/page.d.ts +0 -2
  483. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/project-cost-types/page.d.ts.map +0 -1
  484. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/project-cost-types/page.js +0 -563
  485. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/project-cost-types/page.js.map +0 -1
  486. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/project-cost-types/page.tsx +0 -846
  487. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/projects/[id]/costs-report/page.d.ts +0 -6
  488. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/projects/[id]/costs-report/page.d.ts.map +0 -1
  489. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/projects/[id]/costs-report/page.js +0 -9
  490. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/projects/[id]/costs-report/page.js.map +0 -1
  491. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/projects/[id]/costs-report/page.tsx +0 -10
  492. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/projects/[id]/edit/page.d.ts +0 -6
  493. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/projects/[id]/edit/page.d.ts.map +0 -1
  494. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/projects/[id]/edit/page.js +0 -9
  495. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/projects/[id]/edit/page.js.map +0 -1
  496. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/projects/[id]/edit/page.tsx +0 -11
  497. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/projects/[id]/page.d.ts +0 -6
  498. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/projects/[id]/page.d.ts.map +0 -1
  499. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/projects/[id]/page.js +0 -9
  500. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/projects/[id]/page.js.map +0 -1
  501. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/projects/[id]/page.tsx +0 -11
  502. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/projects/new/page.d.ts +0 -2
  503. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/projects/new/page.d.ts.map +0 -1
  504. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/projects/new/page.js +0 -8
  505. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/projects/new/page.js.map +0 -1
  506. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/projects/new/page.tsx +0 -5
  507. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/projects/page.d.ts +0 -2
  508. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/projects/page.d.ts.map +0 -1
  509. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/projects/page.js +0 -492
  510. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/projects/page.js.map +0 -1
  511. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/projects/page.tsx +0 -757
  512. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/reports/collaborators/page.d.ts +0 -2
  513. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/reports/collaborators/page.d.ts.map +0 -1
  514. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/reports/collaborators/page.js +0 -342
  515. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/reports/collaborators/page.js.map +0 -1
  516. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/reports/collaborators/page.tsx +0 -430
  517. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/reports/projects/page.d.ts +0 -2
  518. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/reports/projects/page.d.ts.map +0 -1
  519. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/reports/projects/page.js +0 -338
  520. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/reports/projects/page.js.map +0 -1
  521. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/reports/projects/page.tsx +0 -428
  522. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/schedule-adjustments/page.d.ts +0 -2
  523. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/schedule-adjustments/page.d.ts.map +0 -1
  524. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/schedule-adjustments/page.js +0 -660
  525. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/schedule-adjustments/page.js.map +0 -1
  526. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/schedule-adjustments/page.tsx +0 -992
  527. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/time-off/page.d.ts +0 -2
  528. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/time-off/page.d.ts.map +0 -1
  529. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/time-off/page.js +0 -515
  530. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/time-off/page.js.map +0 -1
  531. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/time-off/page.tsx +0 -707
  532. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/timesheets/page.d.ts +0 -2
  533. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/timesheets/page.d.ts.map +0 -1
  534. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/timesheets/page.js +0 -1141
  535. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/timesheets/page.js.map +0 -1
  536. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/timesheets/page.tsx +0 -1705
  537. package/hedhog/frontend/src/app/(app)/(libraries)/operations/page.d.ts +0 -2
  538. package/hedhog/frontend/src/app/(app)/(libraries)/operations/page.d.ts.map +0 -1
  539. package/hedhog/frontend/src/app/(app)/(libraries)/operations/page.js +0 -8
  540. package/hedhog/frontend/src/app/(app)/(libraries)/operations/page.js.map +0 -1
  541. package/hedhog/frontend/src/app/(app)/(libraries)/operations/page.tsx +0 -5
  542. package/hedhog/frontend/src/app/(app)/(libraries)/operations/project-cost-categories/page.d.ts +0 -2
  543. package/hedhog/frontend/src/app/(app)/(libraries)/operations/project-cost-categories/page.d.ts.map +0 -1
  544. package/hedhog/frontend/src/app/(app)/(libraries)/operations/project-cost-categories/page.js +0 -436
  545. package/hedhog/frontend/src/app/(app)/(libraries)/operations/project-cost-categories/page.js.map +0 -1
  546. package/hedhog/frontend/src/app/(app)/(libraries)/operations/project-cost-categories/page.tsx +0 -675
  547. package/hedhog/frontend/src/app/(app)/(libraries)/operations/project-cost-types/page.d.ts +0 -2
  548. package/hedhog/frontend/src/app/(app)/(libraries)/operations/project-cost-types/page.d.ts.map +0 -1
  549. package/hedhog/frontend/src/app/(app)/(libraries)/operations/project-cost-types/page.js +0 -563
  550. package/hedhog/frontend/src/app/(app)/(libraries)/operations/project-cost-types/page.js.map +0 -1
  551. package/hedhog/frontend/src/app/(app)/(libraries)/operations/project-cost-types/page.tsx +0 -846
  552. package/hedhog/frontend/src/app/(app)/(libraries)/operations/projects/[id]/edit/page.d.ts +0 -6
  553. package/hedhog/frontend/src/app/(app)/(libraries)/operations/projects/[id]/edit/page.d.ts.map +0 -1
  554. package/hedhog/frontend/src/app/(app)/(libraries)/operations/projects/[id]/edit/page.js +0 -9
  555. package/hedhog/frontend/src/app/(app)/(libraries)/operations/projects/[id]/edit/page.js.map +0 -1
  556. package/hedhog/frontend/src/app/(app)/(libraries)/operations/projects/[id]/edit/page.tsx +0 -11
  557. package/hedhog/frontend/src/app/(app)/(libraries)/operations/projects/[id]/page.d.ts +0 -6
  558. package/hedhog/frontend/src/app/(app)/(libraries)/operations/projects/[id]/page.d.ts.map +0 -1
  559. package/hedhog/frontend/src/app/(app)/(libraries)/operations/projects/[id]/page.js +0 -9
  560. package/hedhog/frontend/src/app/(app)/(libraries)/operations/projects/[id]/page.js.map +0 -1
  561. package/hedhog/frontend/src/app/(app)/(libraries)/operations/projects/[id]/page.tsx +0 -11
  562. package/hedhog/frontend/src/app/(app)/(libraries)/operations/projects/new/page.d.ts +0 -2
  563. package/hedhog/frontend/src/app/(app)/(libraries)/operations/projects/new/page.d.ts.map +0 -1
  564. package/hedhog/frontend/src/app/(app)/(libraries)/operations/projects/new/page.js +0 -8
  565. package/hedhog/frontend/src/app/(app)/(libraries)/operations/projects/new/page.js.map +0 -1
  566. package/hedhog/frontend/src/app/(app)/(libraries)/operations/projects/new/page.tsx +0 -5
  567. package/hedhog/frontend/src/app/(app)/(libraries)/operations/projects/page.d.ts +0 -2
  568. package/hedhog/frontend/src/app/(app)/(libraries)/operations/projects/page.d.ts.map +0 -1
  569. package/hedhog/frontend/src/app/(app)/(libraries)/operations/projects/page.js +0 -492
  570. package/hedhog/frontend/src/app/(app)/(libraries)/operations/projects/page.js.map +0 -1
  571. package/hedhog/frontend/src/app/(app)/(libraries)/operations/projects/page.tsx +0 -757
  572. package/hedhog/frontend/src/app/(app)/(libraries)/operations/reports/collaborators/page.d.ts +0 -2
  573. package/hedhog/frontend/src/app/(app)/(libraries)/operations/reports/collaborators/page.d.ts.map +0 -1
  574. package/hedhog/frontend/src/app/(app)/(libraries)/operations/reports/collaborators/page.js +0 -342
  575. package/hedhog/frontend/src/app/(app)/(libraries)/operations/reports/collaborators/page.js.map +0 -1
  576. package/hedhog/frontend/src/app/(app)/(libraries)/operations/reports/collaborators/page.tsx +0 -430
  577. package/hedhog/frontend/src/app/(app)/(libraries)/operations/reports/projects/page.d.ts +0 -2
  578. package/hedhog/frontend/src/app/(app)/(libraries)/operations/reports/projects/page.d.ts.map +0 -1
  579. package/hedhog/frontend/src/app/(app)/(libraries)/operations/reports/projects/page.js +0 -338
  580. package/hedhog/frontend/src/app/(app)/(libraries)/operations/reports/projects/page.js.map +0 -1
  581. package/hedhog/frontend/src/app/(app)/(libraries)/operations/reports/projects/page.tsx +0 -428
  582. package/hedhog/frontend/src/app/(app)/(libraries)/operations/schedule-adjustments/page.d.ts +0 -2
  583. package/hedhog/frontend/src/app/(app)/(libraries)/operations/schedule-adjustments/page.d.ts.map +0 -1
  584. package/hedhog/frontend/src/app/(app)/(libraries)/operations/schedule-adjustments/page.js +0 -660
  585. package/hedhog/frontend/src/app/(app)/(libraries)/operations/schedule-adjustments/page.js.map +0 -1
  586. package/hedhog/frontend/src/app/(app)/(libraries)/operations/schedule-adjustments/page.tsx +0 -992
  587. package/hedhog/frontend/src/app/(app)/(libraries)/operations/time-off/page.d.ts +0 -2
  588. package/hedhog/frontend/src/app/(app)/(libraries)/operations/time-off/page.d.ts.map +0 -1
  589. package/hedhog/frontend/src/app/(app)/(libraries)/operations/time-off/page.js +0 -515
  590. package/hedhog/frontend/src/app/(app)/(libraries)/operations/time-off/page.js.map +0 -1
  591. package/hedhog/frontend/src/app/(app)/(libraries)/operations/time-off/page.tsx +0 -707
  592. package/hedhog/frontend/src/app/(app)/(libraries)/operations/timesheets/page.d.ts +0 -2
  593. package/hedhog/frontend/src/app/(app)/(libraries)/operations/timesheets/page.d.ts.map +0 -1
  594. package/hedhog/frontend/src/app/(app)/(libraries)/operations/timesheets/page.js +0 -1141
  595. package/hedhog/frontend/src/app/(app)/(libraries)/operations/timesheets/page.js.map +0 -1
  596. package/hedhog/frontend/src/app/(app)/(libraries)/operations/timesheets/page.tsx +0 -1705
@@ -1,1745 +0,0 @@
1
- 'use client';
2
-
3
- import { EmptyState, Page } from '@/components/entity-list';
4
- import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar';
5
- import { Button } from '@/components/ui/button';
6
- import { Checkbox } from '@/components/ui/checkbox';
7
- import {
8
- Command,
9
- CommandEmpty,
10
- CommandGroup,
11
- CommandInput,
12
- CommandItem,
13
- CommandList,
14
- } from '@/components/ui/command';
15
- import {
16
- Form,
17
- FormControl,
18
- FormField,
19
- FormItem,
20
- FormLabel,
21
- FormMessage,
22
- } from '@/components/ui/form';
23
- import { FormActions } from '@/components/ui/form-actions';
24
- import { Input } from '@/components/ui/input';
25
- import { InputMoney } from '@/components/ui/input-money';
26
- import { Label } from '@/components/ui/label';
27
- import {
28
- Popover,
29
- PopoverContent,
30
- PopoverTrigger,
31
- } from '@/components/ui/popover';
32
- import {
33
- Select,
34
- SelectContent,
35
- SelectItem,
36
- SelectTrigger,
37
- SelectValue,
38
- } from '@/components/ui/select';
39
- import {
40
- Sheet,
41
- SheetContent,
42
- SheetDescription,
43
- SheetHeader,
44
- SheetTitle,
45
- } from '@/components/ui/sheet';
46
- import { Textarea } from '@/components/ui/textarea';
47
- import {
48
- Tooltip,
49
- TooltipContent,
50
- TooltipTrigger,
51
- } from '@/components/ui/tooltip';
52
- import { useApp, useQuery } from '@hed-hog/next-app-provider';
53
- import { zodResolver } from '@hookform/resolvers/zod';
54
- import {
55
- ArrowLeft,
56
- Check,
57
- ChevronsUpDown,
58
- FileText,
59
- FolderKanban,
60
- Info,
61
- Plus,
62
- Save,
63
- Search,
64
- X,
65
- } from 'lucide-react';
66
- import { useTranslations } from 'next-intl';
67
- import Link from 'next/link';
68
- import { useRouter } from 'next/navigation';
69
- import { useEffect, useMemo, useState } from 'react';
70
- import { useForm } from 'react-hook-form';
71
- import { z } from 'zod';
72
- import {
73
- fetchOperations,
74
- getOperationsErrorMessage,
75
- mutateOperations,
76
- } from '../_lib/api';
77
- import { useOperationsAccess } from '../_lib/hooks/use-operations-access';
78
- import type {
79
- OperationsCollaborator,
80
- OperationsContract,
81
- OperationsProjectDetails,
82
- OperationsProjectRole,
83
- } from '../_lib/types';
84
- import { formatEnumLabel } from '../_lib/utils/format';
85
- import {
86
- normalizePercentInput,
87
- parseNumberInput,
88
- trimToNull,
89
- } from '../_lib/utils/forms';
90
- import { ContractFormScreen } from './contract-form-screen';
91
- import { DepartmentSelectWithCreate } from './department-select-with-create';
92
- import { OperationsHeader } from './operations-header';
93
- import { PersonSelectWithCreate } from './person-select-with-create';
94
-
95
- const OPTION_PAGE_SIZE = 12;
96
-
97
- type TeamAssignmentState = {
98
- collaboratorId: number;
99
- selected: boolean;
100
- projectRoleId: string;
101
- roleLabel: string;
102
- weeklyHours: string;
103
- allocationPercent: string;
104
- status: string;
105
- startDate: string;
106
- endDate: string;
107
- };
108
-
109
- type ProjectFormState = {
110
- contractId: string;
111
- managerCollaboratorId: string;
112
- code: string;
113
- name: string;
114
- clientName: string;
115
- summary: string;
116
- status: string;
117
- progressPercent: string;
118
- deliveryModel: string;
119
- budgetAmount: string;
120
- startDate: string;
121
- endDate: string;
122
- billingModel: string;
123
- monthlyHourCap: string;
124
- contractCode: string;
125
- contractName: string;
126
- contractDescription: string;
127
- teamAssignments: TeamAssignmentState[];
128
- };
129
-
130
- type ProjectFormValues = ProjectFormState;
131
-
132
- function generateProjectCode(name: string): string {
133
- const words = name.trim().split(/\s+/).filter(Boolean);
134
- if (words.length === 0) return '';
135
- if (words.length === 1) return words[0]!.slice(0, 5).toUpperCase();
136
- return words
137
- .map((w) => w[0]!.toUpperCase())
138
- .join('')
139
- .slice(0, 6);
140
- }
141
-
142
- function normalizeDateInputValue(value?: string | null) {
143
- if (!value) {
144
- return '';
145
- }
146
-
147
- const normalizedValue = String(value).trim();
148
-
149
- if (!normalizedValue) {
150
- return '';
151
- }
152
-
153
- const directMatch = normalizedValue.match(/^\d{4}-\d{2}-\d{2}/);
154
-
155
- if (directMatch?.[0]) {
156
- return directMatch[0];
157
- }
158
-
159
- const parsedDate = new Date(normalizedValue);
160
-
161
- if (Number.isNaN(parsedDate.getTime())) {
162
- return normalizedValue;
163
- }
164
-
165
- return parsedDate.toISOString().slice(0, 10);
166
- }
167
-
168
- function buildEmptyForm(
169
- collaborators: OperationsCollaborator[] = []
170
- ): ProjectFormState {
171
- return {
172
- contractId: 'none',
173
- managerCollaboratorId: 'none',
174
- code: '',
175
- name: '',
176
- clientName: '',
177
- summary: '',
178
- status: 'planning',
179
- progressPercent: '',
180
- deliveryModel: 'project_delivery',
181
- budgetAmount: '',
182
- startDate: '',
183
- endDate: '',
184
- billingModel: 'time_and_material',
185
- monthlyHourCap: '',
186
- contractCode: '',
187
- contractName: '',
188
- contractDescription: '',
189
- teamAssignments: collaborators.map((collaborator) => ({
190
- collaboratorId: collaborator.id,
191
- selected: false,
192
- projectRoleId: 'none',
193
- roleLabel: '',
194
- weeklyHours: '',
195
- allocationPercent: '',
196
- status: 'active',
197
- startDate: new Date().toISOString().split('T')[0],
198
- endDate: '',
199
- })),
200
- };
201
- }
202
-
203
- function toFormState(
204
- project: OperationsProjectDetails,
205
- collaborators: OperationsCollaborator[]
206
- ): ProjectFormState {
207
- const collaboratorOptions =
208
- collaborators.length > 0
209
- ? collaborators
210
- : (project.assignments ?? []).map((assignment) => ({
211
- id: assignment.collaboratorId,
212
- code: '',
213
- displayName: assignment.collaboratorName,
214
- department: null,
215
- title: null,
216
- status: 'active',
217
- }));
218
-
219
- const assignments = new Map(
220
- (project.assignments ?? []).map((assignment) => [
221
- assignment.collaboratorId,
222
- assignment,
223
- ])
224
- );
225
-
226
- return {
227
- contractId: project.relatedContract?.id
228
- ? String(project.relatedContract.id)
229
- : 'none',
230
- managerCollaboratorId: project.managerCollaboratorId
231
- ? String(project.managerCollaboratorId)
232
- : 'none',
233
- code: project.code ?? '',
234
- name: project.name ?? '',
235
- clientName: project.clientName ?? '',
236
- summary: project.summary ?? '',
237
- status: project.status ?? 'planning',
238
- progressPercent:
239
- project.progressPercent !== null && project.progressPercent !== undefined
240
- ? String(project.progressPercent)
241
- : '',
242
- deliveryModel: project.deliveryModel ?? 'project_delivery',
243
- budgetAmount:
244
- project.budgetAmount !== null && project.budgetAmount !== undefined
245
- ? String(project.budgetAmount)
246
- : '',
247
- startDate: normalizeDateInputValue(project.startDate),
248
- endDate: normalizeDateInputValue(project.endDate),
249
- billingModel: project.relatedContract?.billingModel ?? 'time_and_material',
250
- monthlyHourCap:
251
- project.relatedContract?.monthlyHourCap !== null &&
252
- project.relatedContract?.monthlyHourCap !== undefined
253
- ? String(project.relatedContract.monthlyHourCap)
254
- : '',
255
- contractCode: project.relatedContract?.code ?? '',
256
- contractName: project.relatedContract?.name ?? '',
257
- contractDescription: project.relatedContract?.description ?? '',
258
- teamAssignments: collaboratorOptions.map((collaborator) => {
259
- const assignment = assignments.get(collaborator.id);
260
- return {
261
- collaboratorId: collaborator.id,
262
- selected: Boolean(assignment),
263
- projectRoleId: assignment?.projectRoleId
264
- ? String(assignment.projectRoleId)
265
- : 'none',
266
- roleLabel: assignment?.roleLabel ?? '',
267
- weeklyHours:
268
- assignment?.weeklyHours !== null &&
269
- assignment?.weeklyHours !== undefined
270
- ? String(assignment.weeklyHours)
271
- : '',
272
- allocationPercent:
273
- assignment?.allocationPercent !== null &&
274
- assignment?.allocationPercent !== undefined
275
- ? String(assignment.allocationPercent)
276
- : '',
277
- status: assignment?.status ?? 'active',
278
- startDate: normalizeDateInputValue(assignment?.startDate) || new Date().toISOString().split('T')[0],
279
- endDate: normalizeDateInputValue(assignment?.endDate),
280
- };
281
- }),
282
- };
283
- }
284
-
285
- type SearchableSelectProps = {
286
- label: string;
287
- value: string;
288
- options: Array<{
289
- id: number;
290
- title: string;
291
- description?: string | null;
292
- avatarUrl?: string | null;
293
- }>;
294
- placeholder: string;
295
- searchPlaceholder: string;
296
- emptyLabel: string;
297
- onChange: (value: string) => void;
298
- };
299
-
300
- function SearchableSelect({
301
- label,
302
- value,
303
- options,
304
- placeholder,
305
- searchPlaceholder,
306
- emptyLabel,
307
- onChange,
308
- }: SearchableSelectProps) {
309
- const commonT = useTranslations('operations.Common');
310
- const [open, setOpen] = useState(false);
311
- const [search, setSearch] = useState('');
312
- const [visibleCount, setVisibleCount] = useState(OPTION_PAGE_SIZE);
313
-
314
- const filteredOptions = useMemo(() => {
315
- const normalizedSearch = search.trim().toLowerCase();
316
-
317
- if (!normalizedSearch) {
318
- return options;
319
- }
320
-
321
- return options.filter((option) =>
322
- [option.title, option.description]
323
- .filter(Boolean)
324
- .some((field) => String(field).toLowerCase().includes(normalizedSearch))
325
- );
326
- }, [options, search]);
327
-
328
- const selectedOption = options.find((option) => String(option.id) === value);
329
- const visibleOptions = filteredOptions.slice(0, visibleCount);
330
-
331
- return (
332
- <div className="grid gap-2">
333
- {label ? <Label>{label}</Label> : null}
334
-
335
- <Popover
336
- open={open}
337
- onOpenChange={(nextOpen) => {
338
- setOpen(nextOpen);
339
- setVisibleCount(OPTION_PAGE_SIZE);
340
-
341
- if (!nextOpen) {
342
- setSearch('');
343
- }
344
- }}
345
- >
346
- <PopoverTrigger asChild>
347
- <Button
348
- type="button"
349
- variant="outline"
350
- role="combobox"
351
- className="w-full justify-between overflow-hidden"
352
- >
353
- <span className="truncate text-left">
354
- {selectedOption?.title ?? emptyLabel}
355
- </span>
356
- <ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
357
- </Button>
358
- </PopoverTrigger>
359
- <PopoverContent
360
- className="p-0"
361
- style={{ width: 'var(--radix-popover-trigger-width)' }}
362
- >
363
- <Command shouldFilter={false}>
364
- <CommandInput
365
- placeholder={searchPlaceholder}
366
- value={search}
367
- onValueChange={(nextValue) => {
368
- setSearch(nextValue);
369
- setVisibleCount(OPTION_PAGE_SIZE);
370
- }}
371
- />
372
- <CommandList>
373
- <CommandEmpty>
374
- <div className="p-2 text-sm text-muted-foreground">
375
- {commonT('states.emptyDescription')}
376
- </div>
377
- </CommandEmpty>
378
-
379
- <CommandGroup>
380
- <CommandItem
381
- value="none"
382
- onSelect={() => {
383
- onChange('none');
384
- setOpen(false);
385
- }}
386
- >
387
- {value === 'none' ? (
388
- <Check className="mr-2 h-4 w-4" />
389
- ) : (
390
- <span className="mr-2 h-4 w-4" />
391
- )}
392
- {placeholder}
393
- </CommandItem>
394
-
395
- {visibleOptions.map((option) => (
396
- <CommandItem
397
- key={option.id}
398
- value={`${option.title} ${option.description ?? ''}`}
399
- onSelect={() => {
400
- onChange(String(option.id));
401
- setOpen(false);
402
- }}
403
- >
404
- {String(option.id) === value ? (
405
- <Check className="mr-2 h-4 w-4" />
406
- ) : (
407
- <span className="mr-2 h-4 w-4" />
408
- )}
409
- {option.avatarUrl !== undefined ? (
410
- <Avatar className="mr-2 h-6 w-6 shrink-0">
411
- {option.avatarUrl ? (
412
- <AvatarImage
413
- src={option.avatarUrl}
414
- alt={option.title}
415
- />
416
- ) : null}
417
- <AvatarFallback className="text-[9px] font-medium">
418
- {option.title
419
- .trim()
420
- .split(' ')
421
- .filter(Boolean)
422
- .slice(0, 2)
423
- .map((w) => w[0]!.toUpperCase())
424
- .join('')}
425
- </AvatarFallback>
426
- </Avatar>
427
- ) : null}
428
- <div className="min-w-0">
429
- <div className="truncate">{option.title}</div>
430
- {option.description ? (
431
- <div className="truncate text-xs text-muted-foreground">
432
- {option.description}
433
- </div>
434
- ) : null}
435
- </div>
436
- </CommandItem>
437
- ))}
438
- </CommandGroup>
439
-
440
- {filteredOptions.length > visibleCount ? (
441
- <div className="border-t p-2">
442
- <Button
443
- type="button"
444
- variant="ghost"
445
- className="w-full"
446
- onClick={() =>
447
- setVisibleCount((current) => current + OPTION_PAGE_SIZE)
448
- }
449
- >
450
- {commonT('actions.loadMore')}
451
- </Button>
452
- </div>
453
- ) : null}
454
- </CommandList>
455
- </Command>
456
- </PopoverContent>
457
- </Popover>
458
- </div>
459
- );
460
- }
461
-
462
- type ProjectFormScreenProps = {
463
- projectId?: number;
464
- onSaved?: (project: OperationsProjectDetails) => void | Promise<void>;
465
- onCancel?: () => void;
466
- };
467
-
468
- function FieldLabel({ label, hint }: { label: string; hint?: string }) {
469
- return (
470
- <div className="flex items-center gap-1.5">
471
- <Label>{label}</Label>
472
- {hint ? (
473
- <Tooltip>
474
- <TooltipTrigger asChild>
475
- <span className="inline-flex cursor-help text-muted-foreground">
476
- <Info className="h-3.5 w-3.5" />
477
- </span>
478
- </TooltipTrigger>
479
- <TooltipContent>
480
- <p>{hint}</p>
481
- </TooltipContent>
482
- </Tooltip>
483
- ) : null}
484
- </div>
485
- );
486
- }
487
-
488
- type ContractSelectWithCreateProps = {
489
- value: string;
490
- contracts: OperationsContract[];
491
- label: string;
492
- selectPlaceholder: string;
493
- searchPlaceholder: string;
494
- onChange: (value: string) => void;
495
- onCreated?: (
496
- contract: OperationsProjectDetails['relatedContract']
497
- ) => void | Promise<void>;
498
- initialValues?: {
499
- code?: string;
500
- name?: string;
501
- clientName?: string;
502
- contractCategory?: string;
503
- contractType?: string;
504
- signatureStatus?: string;
505
- billingModel?: string;
506
- budgetAmount?: string;
507
- monthlyHourCap?: string;
508
- startDate?: string;
509
- endDate?: string;
510
- description?: string;
511
- contentHtml?: string;
512
- };
513
- };
514
-
515
- function ContractSelectWithCreate({
516
- value,
517
- contracts,
518
- label,
519
- selectPlaceholder,
520
- searchPlaceholder,
521
- onChange,
522
- onCreated,
523
- initialValues,
524
- }: ContractSelectWithCreateProps) {
525
- const commonT = useTranslations('operations.Common');
526
- const contractT = useTranslations('operations.ContractFormPage');
527
- const selectedContract = contracts.find((item) => String(item.id) === value);
528
- const hasSelection = value !== 'none';
529
- const [isCreateSheetOpen, setIsCreateSheetOpen] = useState(false);
530
-
531
- return (
532
- <>
533
- <div className="space-y-2">
534
- <div className="grid min-w-0 grid-cols-[minmax(0,1fr)_auto] gap-2 sm:grid-cols-[minmax(0,1fr)_auto_auto]">
535
- <SearchableSelect
536
- label={label}
537
- value={value}
538
- options={contracts.map((contract) => ({
539
- id: contract.id,
540
- title:
541
- contract.name ||
542
- contract.code ||
543
- commonT('labels.notAvailable'),
544
- description: [
545
- contract.code,
546
- contract.clientName,
547
- contractT.has(`options.contractTypes.${contract.contractType}`)
548
- ? contractT(`options.contractTypes.${contract.contractType}`)
549
- : formatEnumLabel(contract.contractType),
550
- ]
551
- .filter(Boolean)
552
- .join(' • '),
553
- }))}
554
- placeholder={selectPlaceholder}
555
- searchPlaceholder={searchPlaceholder}
556
- emptyLabel={commonT('labels.notAssigned')}
557
- onChange={onChange}
558
- />
559
-
560
- {hasSelection ? (
561
- <Button
562
- type="button"
563
- variant="outline"
564
- size="icon"
565
- className="shrink-0"
566
- onClick={() => onChange('none')}
567
- aria-label={commonT('actions.clearSelection')}
568
- >
569
- <X className="size-4" />
570
- </Button>
571
- ) : null}
572
-
573
- <Button
574
- type="button"
575
- variant="outline"
576
- size="icon"
577
- className="shrink-0"
578
- onClick={() => setIsCreateSheetOpen(true)}
579
- aria-label={commonT('actions.create')}
580
- >
581
- <Plus className="size-4" />
582
- </Button>
583
- </div>
584
-
585
- {selectedContract ? (
586
- <Button
587
- type="button"
588
- variant="outline"
589
- size="sm"
590
- asChild
591
- className="w-fit"
592
- >
593
- <Link href={`/operations/contracts?edit=${selectedContract.id}`}>
594
- <FileText className="size-4" />
595
- {commonT('actions.openContract')}
596
- </Link>
597
- </Button>
598
- ) : null}
599
- </div>
600
-
601
- <Sheet open={isCreateSheetOpen} onOpenChange={setIsCreateSheetOpen}>
602
- <SheetContent className="w-full overflow-y-auto sm:max-w-7xl">
603
- <SheetHeader>
604
- <SheetTitle>{contractT('newTitle')}</SheetTitle>
605
- <SheetDescription>{contractT('description')}</SheetDescription>
606
- </SheetHeader>
607
-
608
- <ContractFormScreen
609
- initialValues={initialValues}
610
- onCancel={() => setIsCreateSheetOpen(false)}
611
- onSaved={async (contract) => {
612
- const createdContractId = contract?.id
613
- ? String(contract.id)
614
- : value;
615
- onChange(createdContractId);
616
- await onCreated?.(
617
- contract as OperationsProjectDetails['relatedContract']
618
- );
619
- setIsCreateSheetOpen(false);
620
- }}
621
- />
622
- </SheetContent>
623
- </Sheet>
624
- </>
625
- );
626
- }
627
-
628
- export function ProjectFormScreen({
629
- projectId,
630
- onSaved,
631
- onCancel,
632
- }: ProjectFormScreenProps) {
633
- const t = useTranslations('operations.ProjectFormPage');
634
- const commonT = useTranslations('operations.Common');
635
- const contractT = useTranslations('operations.ContractFormPage');
636
- const { request, showToastHandler, currentLocaleCode } = useApp();
637
- const access = useOperationsAccess();
638
- const router = useRouter();
639
- const [assignmentSearch, setAssignmentSearch] = useState('');
640
- const isSheetMode = Boolean(onCancel);
641
- const isCreateMode = !projectId;
642
- const [codeAutoMode, setCodeAutoMode] = useState(isCreateMode);
643
-
644
- const projectFormSchema = useMemo(
645
- () =>
646
- z.object({
647
- contractId: z.string(),
648
- managerCollaboratorId: z.string(),
649
- code: z.string().trim().min(1, t('messages.requiredFields')),
650
- name: z.string().trim().min(1, t('messages.requiredFields')),
651
- clientName: z.string().trim().min(1, t('messages.requiredFields')),
652
- summary: z.string(),
653
- status: z.string(),
654
- progressPercent: z
655
- .string()
656
- .refine(
657
- (value) =>
658
- !value ||
659
- (!Number.isNaN(Number(value)) &&
660
- Number(value) >= 0 &&
661
- Number(value) <= 100),
662
- t('hints.progressPercent')
663
- ),
664
- deliveryModel: z.string(),
665
- budgetAmount: z.string(),
666
- startDate: z.string(),
667
- endDate: z.string(),
668
- billingModel: z.string(),
669
- monthlyHourCap: z.string(),
670
- contractCode: z.string(),
671
- contractName: z.string(),
672
- contractDescription: z.string(),
673
- teamAssignments: z
674
- .array(
675
- z.object({
676
- collaboratorId: z.number(),
677
- selected: z.boolean(),
678
- projectRoleId: z.string(),
679
- roleLabel: z.string(),
680
- weeklyHours: z.string(),
681
- allocationPercent: z.string(),
682
- status: z.string(),
683
- startDate: z.string(),
684
- endDate: z.string(),
685
- })
686
- )
687
- .superRefine((assignments, ctx) => {
688
- assignments.forEach((assignment, index) => {
689
- if (assignment.selected && !assignment.roleLabel.trim()) {
690
- ctx.addIssue({
691
- code: z.ZodIssueCode.custom,
692
- message: t('messages.roleRequired'),
693
- path: [index, 'roleLabel'],
694
- });
695
- }
696
- });
697
- }),
698
- }),
699
- [t]
700
- );
701
-
702
- const formMethods = useForm<ProjectFormValues>({
703
- resolver: zodResolver(projectFormSchema),
704
- defaultValues: buildEmptyForm(),
705
- mode: 'onSubmit',
706
- reValidateMode: 'onChange',
707
- });
708
-
709
- const form = formMethods.watch();
710
- const setForm = (
711
- updater:
712
- | ProjectFormState
713
- | ((current: ProjectFormState) => ProjectFormState)
714
- ) => {
715
- const current = formMethods.getValues();
716
- const next = typeof updater === 'function' ? updater(current) : updater;
717
-
718
- formMethods.reset(next, {
719
- keepErrors: true,
720
- keepDirty: true,
721
- keepTouched: true,
722
- });
723
- };
724
-
725
- const { data: rawCollaborators } = useQuery<OperationsCollaborator[]>({
726
- queryKey: ['operations-project-form-collaborators', currentLocaleCode],
727
- enabled: access.isDirector,
728
- queryFn: () =>
729
- fetchOperations<OperationsCollaborator[]>(
730
- request,
731
- '/operations/collaborators'
732
- ),
733
- });
734
- // Stable reference prevents the useEffect(reset, [collaborators, project]) from
735
- // re-running on every render while the query is still loading (undefined → [] new ref).
736
- const collaborators = useMemo(
737
- () => rawCollaborators ?? [],
738
- [rawCollaborators]
739
- );
740
-
741
- const { data: contracts = [], refetch: refetchContracts } = useQuery<
742
- OperationsContract[]
743
- >({
744
- queryKey: ['operations-project-form-contracts', currentLocaleCode],
745
- enabled: access.isDirector,
746
- queryFn: () =>
747
- fetchOperations<OperationsContract[]>(request, '/operations/contracts'),
748
- });
749
-
750
- const { data: projectRoles = [], refetch: refetchProjectRoles } = useQuery<
751
- OperationsProjectRole[]
752
- >({
753
- queryKey: ['operations-project-form-project-roles', currentLocaleCode],
754
- enabled: access.isDirector,
755
- staleTime: 0,
756
- refetchOnMount: 'always',
757
- queryFn: () =>
758
- fetchOperations<OperationsProjectRole[]>(
759
- request,
760
- '/operations/project-roles'
761
- ),
762
- });
763
-
764
- const { data: project, isLoading: isLoadingProject } =
765
- useQuery<OperationsProjectDetails>({
766
- queryKey: ['operations-project-form', currentLocaleCode, projectId],
767
- enabled: Boolean(projectId),
768
- staleTime: 0,
769
- refetchOnMount: 'always',
770
- queryFn: () =>
771
- fetchOperations<OperationsProjectDetails>(
772
- request,
773
- `/operations/projects/${projectId}`
774
- ),
775
- });
776
-
777
- useEffect(() => {
778
- if (project) {
779
- formMethods.reset(toFormState(project, collaborators));
780
- return;
781
- }
782
-
783
- if (!collaborators.length) {
784
- return;
785
- }
786
-
787
- const currentValues = formMethods.getValues();
788
- if (!currentValues.teamAssignments.length) {
789
- formMethods.reset(buildEmptyForm(collaborators));
790
- }
791
- }, [collaborators, formMethods, project]);
792
-
793
- const availableCollaborators = useMemo(() => {
794
- const byId = new Map<number, OperationsCollaborator>();
795
-
796
- for (const collaborator of collaborators) {
797
- byId.set(collaborator.id, collaborator);
798
- }
799
-
800
- if (
801
- project?.managerCollaboratorId &&
802
- !byId.has(project.managerCollaboratorId)
803
- ) {
804
- byId.set(project.managerCollaboratorId, {
805
- id: project.managerCollaboratorId,
806
- code: '',
807
- displayName: project.managerName ?? `#${project.managerCollaboratorId}`,
808
- department: null,
809
- title: null,
810
- status: 'active',
811
- });
812
- }
813
-
814
- for (const assignment of project?.assignments ?? []) {
815
- if (!byId.has(assignment.collaboratorId)) {
816
- byId.set(assignment.collaboratorId, {
817
- id: assignment.collaboratorId,
818
- code: '',
819
- displayName: assignment.collaboratorName,
820
- department: null,
821
- title: null,
822
- status: 'active',
823
- });
824
- }
825
- }
826
-
827
- return Array.from(byId.values());
828
- }, [collaborators, project]);
829
-
830
- const availableContracts = useMemo(() => {
831
- if (!project?.relatedContract) {
832
- return contracts;
833
- }
834
-
835
- const hasSelectedContract = contracts.some(
836
- (contract) => contract.id === project.relatedContract?.id
837
- );
838
-
839
- return hasSelectedContract
840
- ? contracts
841
- : [project.relatedContract, ...contracts];
842
- }, [contracts, project]);
843
-
844
- const selectedContract = useMemo(
845
- () =>
846
- availableContracts.find(
847
- (contract) => String(contract.id) === form.contractId
848
- ) ?? null,
849
- [availableContracts, form.contractId]
850
- );
851
-
852
- const managerOptions = useMemo(
853
- () =>
854
- availableCollaborators.map((collaborator) => ({
855
- id: collaborator.id,
856
- title: collaborator.displayName,
857
- description: [collaborator.department, collaborator.title]
858
- .filter(Boolean)
859
- .join(' • '),
860
- avatarUrl:
861
- typeof collaborator.personAvatarId === 'number' &&
862
- collaborator.personAvatarId > 0
863
- ? `${process.env.NEXT_PUBLIC_API_BASE_URL}/person/avatar/${collaborator.personAvatarId}`
864
- : null,
865
- })),
866
- [availableCollaborators]
867
- );
868
-
869
- const projectRoleOptions = useMemo(
870
- () =>
871
- projectRoles.map((role) => ({
872
- id: role.id,
873
- name: role.name,
874
- code: role.code ?? null,
875
- description: role.description ?? null,
876
- })),
877
- [projectRoles]
878
- );
879
-
880
- const createProjectRole = async (projectRoleName: string) => {
881
- try {
882
- const createdRole = await mutateOperations<OperationsProjectRole>(
883
- request,
884
- '/operations/project-roles',
885
- 'POST',
886
- {
887
- name: projectRoleName,
888
- }
889
- );
890
-
891
- await refetchProjectRoles();
892
- return createdRole;
893
- } catch (error) {
894
- showToastHandler?.(
895
- 'error',
896
- getOperationsErrorMessage(error, t('messages.projectRoleSaveError'))
897
- );
898
- return null;
899
- }
900
- };
901
-
902
- const selectedAssignmentsCount = useMemo(
903
- () =>
904
- form.teamAssignments.filter((assignment) => assignment.selected).length,
905
- [form.teamAssignments]
906
- );
907
-
908
- const filteredAssignments = useMemo(() => {
909
- const normalizedSearch = assignmentSearch.trim().toLowerCase();
910
-
911
- return form.teamAssignments.filter((assignment) => {
912
- const collaborator = availableCollaborators.find(
913
- (item) => item.id === assignment.collaboratorId
914
- );
915
-
916
- if (!collaborator) {
917
- return false;
918
- }
919
-
920
- if (!normalizedSearch) {
921
- return true;
922
- }
923
-
924
- return [
925
- collaborator.displayName,
926
- collaborator.department,
927
- collaborator.title,
928
- collaborator.code,
929
- ]
930
- .filter(Boolean)
931
- .some((value) =>
932
- String(value).toLowerCase().includes(normalizedSearch)
933
- );
934
- });
935
- }, [assignmentSearch, availableCollaborators, form.teamAssignments]);
936
-
937
- const updateAssignment = (
938
- collaboratorId: number,
939
- patch: Partial<TeamAssignmentState>
940
- ) => {
941
- const nextAssignments = formMethods
942
- .getValues('teamAssignments')
943
- .map((assignment) =>
944
- assignment.collaboratorId === collaboratorId
945
- ? { ...assignment, ...patch }
946
- : assignment
947
- );
948
-
949
- formMethods.setValue('teamAssignments', nextAssignments, {
950
- shouldDirty: true,
951
- shouldValidate: true,
952
- });
953
- };
954
-
955
- const onSubmit = async (values: ProjectFormValues) => {
956
- const payload = {
957
- contractId:
958
- values.contractId === 'none'
959
- ? null
960
- : parseNumberInput(values.contractId),
961
- managerCollaboratorId:
962
- values.managerCollaboratorId === 'none'
963
- ? null
964
- : parseNumberInput(values.managerCollaboratorId),
965
- code: values.code.trim(),
966
- name: values.name.trim(),
967
- clientName: trimToNull(values.clientName),
968
- summary: trimToNull(values.summary),
969
- status: values.status,
970
- progressPercent: parseNumberInput(values.progressPercent),
971
- deliveryModel: trimToNull(values.deliveryModel) ?? 'project_delivery',
972
- budgetAmount: parseNumberInput(values.budgetAmount),
973
- startDate: trimToNull(values.startDate),
974
- endDate: trimToNull(values.endDate),
975
- billingModel: values.billingModel,
976
- monthlyHourCap: parseNumberInput(values.monthlyHourCap),
977
- contractCode: trimToNull(values.contractCode),
978
- contractName: trimToNull(values.contractName),
979
- contractDescription: trimToNull(values.contractDescription),
980
- teamAssignments: values.teamAssignments
981
- .filter((assignment) => assignment.selected)
982
- .map((assignment) => ({
983
- collaboratorId: assignment.collaboratorId,
984
- projectRoleId:
985
- assignment.projectRoleId === 'none'
986
- ? null
987
- : parseNumberInput(assignment.projectRoleId),
988
- roleLabel: trimToNull(assignment.roleLabel),
989
- weeklyHours: parseNumberInput(assignment.weeklyHours),
990
- allocationPercent: parseNumberInput(assignment.allocationPercent),
991
- status: assignment.status,
992
- startDate: trimToNull(assignment.startDate),
993
- endDate: trimToNull(assignment.endDate),
994
- })),
995
- };
996
-
997
- try {
998
- const response = projectId
999
- ? await mutateOperations<OperationsProjectDetails>(
1000
- request,
1001
- `/operations/projects/${projectId}`,
1002
- 'PATCH',
1003
- payload
1004
- )
1005
- : await mutateOperations<OperationsProjectDetails>(
1006
- request,
1007
- '/operations/projects',
1008
- 'POST',
1009
- payload
1010
- );
1011
-
1012
- showToastHandler?.(
1013
- 'success',
1014
- projectId ? t('messages.updateSuccess') : t('messages.createSuccess')
1015
- );
1016
-
1017
- if (onSaved) {
1018
- await onSaved(response);
1019
- return;
1020
- }
1021
-
1022
- router.push(`/operations/projects/${response.id}`);
1023
- } catch (error) {
1024
- showToastHandler?.(
1025
- 'error',
1026
- getOperationsErrorMessage(
1027
- error,
1028
- projectId ? t('messages.updateError') : t('messages.createError')
1029
- )
1030
- );
1031
- }
1032
- };
1033
-
1034
- const handleInvalidSubmit = () => {
1035
- showToastHandler?.('error', t('messages.requiredFields'));
1036
- };
1037
-
1038
- const noAccessState = (
1039
- <EmptyState
1040
- icon={<FolderKanban className="size-12" />}
1041
- title={commonT('states.noAccessTitle')}
1042
- description={t('noAccessDescription')}
1043
- actionLabel={commonT('actions.refresh')}
1044
- onAction={() => router.refresh()}
1045
- />
1046
- );
1047
-
1048
- if (!access.isDirector && !access.isLoading) {
1049
- if (isSheetMode) {
1050
- return <div className="pt-4">{noAccessState}</div>;
1051
- }
1052
-
1053
- return (
1054
- <Page>
1055
- <OperationsHeader
1056
- title={t(projectId ? 'editTitle' : 'newTitle')}
1057
- description={t('description')}
1058
- current={t('breadcrumb')}
1059
- />
1060
- {noAccessState}
1061
- </Page>
1062
- );
1063
- }
1064
-
1065
- const formContent = (
1066
- <Form {...formMethods}>
1067
- <form
1068
- onSubmit={formMethods.handleSubmit(onSubmit, handleInvalidSubmit)}
1069
- className="min-w-0 space-y-5 overflow-x-hidden px-4"
1070
- >
1071
- <section className="space-y-3">
1072
- <div className="space-y-0.5">
1073
- <h3 className="text-xs font-semibold uppercase tracking-wide text-muted-foreground">
1074
- {t('sections.basicInfo')}
1075
- </h3>
1076
- <p className="text-[11px] text-muted-foreground/80">
1077
- {t(
1078
- isCreateMode
1079
- ? 'sections.basicInfoCreateDescription'
1080
- : 'sections.basicInfoDescription'
1081
- )}
1082
- </p>
1083
- </div>
1084
- <FormField
1085
- control={formMethods.control}
1086
- name="name"
1087
- render={({ field }) => (
1088
- <FormItem className="min-w-0">
1089
- <FormLabel>{t('fields.name')}</FormLabel>
1090
- <FormControl>
1091
- <Input
1092
- {...field}
1093
- placeholder={t('placeholders.name')}
1094
- autoFocus
1095
- onChange={(e) => {
1096
- field.onChange(e);
1097
- if (codeAutoMode) {
1098
- formMethods.setValue(
1099
- 'code',
1100
- generateProjectCode(e.target.value)
1101
- );
1102
- }
1103
- }}
1104
- />
1105
- </FormControl>
1106
- <FormMessage />
1107
- </FormItem>
1108
- )}
1109
- />
1110
- <div className="grid min-w-0 gap-3 lg:grid-cols-6">
1111
- <FormField
1112
- control={formMethods.control}
1113
- name="code"
1114
- render={({ field }) => (
1115
- <FormItem className="min-w-0 lg:col-span-1">
1116
- <FormLabel>{t('fields.code')}</FormLabel>
1117
- <FormControl>
1118
- <Input
1119
- {...field}
1120
- placeholder={t('placeholders.code')}
1121
- onChange={(e) => {
1122
- setCodeAutoMode(false);
1123
- field.onChange(e);
1124
- }}
1125
- />
1126
- </FormControl>
1127
- <FormMessage />
1128
- </FormItem>
1129
- )}
1130
- />
1131
- <FormField
1132
- control={formMethods.control}
1133
- name="clientName"
1134
- render={({ field, fieldState }) => (
1135
- <FormItem className="min-w-0 lg:col-span-3">
1136
- <FormLabel>{t('fields.clientName')}</FormLabel>
1137
- <FormControl>
1138
- <div
1139
- className={
1140
- fieldState.error
1141
- ? 'rounded-md border border-destructive p-1'
1142
- : ''
1143
- }
1144
- >
1145
- <PersonSelectWithCreate
1146
- label=""
1147
- entityLabel={t('fields.clientName')}
1148
- value={null}
1149
- initialSelectedLabel={field.value}
1150
- selectPlaceholder={t('placeholders.clientName')}
1151
- onChange={(_, personName) =>
1152
- field.onChange(personName ?? '')
1153
- }
1154
- personTypeFilter="all"
1155
- createType="company"
1156
- />
1157
- </div>
1158
- </FormControl>
1159
- <FormMessage />
1160
- </FormItem>
1161
- )}
1162
- />
1163
-
1164
- <FormField
1165
- control={formMethods.control}
1166
- name="deliveryModel"
1167
- render={({ field }) => (
1168
- <FormItem className="min-w-0 lg:col-span-2">
1169
- <FormLabel>{t('fields.deliveryModel')}</FormLabel>
1170
- <Select value={field.value} onValueChange={field.onChange}>
1171
- <FormControl>
1172
- <SelectTrigger className="w-full">
1173
- <SelectValue />
1174
- </SelectTrigger>
1175
- </FormControl>
1176
- <SelectContent>
1177
- <SelectItem value="project_delivery">
1178
- {t('options.deliveryModels.project_delivery')}
1179
- </SelectItem>
1180
- <SelectItem value="dedicated_team">
1181
- {t('options.deliveryModels.dedicated_team')}
1182
- </SelectItem>
1183
- <SelectItem value="shared_team">
1184
- {t('options.deliveryModels.shared_team')}
1185
- </SelectItem>
1186
- <SelectItem value="support">
1187
- {t('options.deliveryModels.support')}
1188
- </SelectItem>
1189
- </SelectContent>
1190
- </Select>
1191
- <FormMessage />
1192
- </FormItem>
1193
- )}
1194
- />
1195
- <FormField
1196
- control={formMethods.control}
1197
- name="summary"
1198
- render={({ field }) => (
1199
- <FormItem className="min-w-0 lg:col-span-6">
1200
- <FormLabel>{t('fields.summary')}</FormLabel>
1201
- <FormControl>
1202
- <Textarea
1203
- {...field}
1204
- rows={3}
1205
- placeholder={t('placeholders.summary')}
1206
- />
1207
- </FormControl>
1208
- <FormMessage />
1209
- </FormItem>
1210
- )}
1211
- />
1212
- </div>
1213
- </section>
1214
-
1215
- <section className="space-y-3">
1216
- <div className="space-y-0.5">
1217
- <h3 className="text-xs font-semibold uppercase tracking-wide text-muted-foreground">
1218
- {t('sections.governance')}
1219
- </h3>
1220
- <p className="text-[11px] text-muted-foreground/80">
1221
- {t(
1222
- isCreateMode
1223
- ? 'sections.governanceCreateDescription'
1224
- : 'sections.governanceDescription'
1225
- )}
1226
- </p>
1227
- </div>
1228
- <div className="grid min-w-0 gap-3 md:grid-cols-2 xl:grid-cols-5">
1229
- <div className="min-w-0 space-y-2">
1230
- <FieldLabel label={commonT('labels.manager')} />
1231
- <SearchableSelect
1232
- label=""
1233
- value={form.managerCollaboratorId}
1234
- options={managerOptions}
1235
- placeholder={commonT('labels.notAssigned')}
1236
- searchPlaceholder={t('placeholders.managerSearch')}
1237
- emptyLabel={commonT('labels.notAssigned')}
1238
- onChange={(value) =>
1239
- setForm((current) => ({
1240
- ...current,
1241
- managerCollaboratorId: value,
1242
- }))
1243
- }
1244
- />
1245
- </div>
1246
- <div className="min-w-0 space-y-2">
1247
- <FieldLabel label={commonT('labels.startDate')} />
1248
- <Input
1249
- type="date"
1250
- value={form.startDate}
1251
- onChange={(event) =>
1252
- setForm((current) => ({
1253
- ...current,
1254
- startDate: event.target.value,
1255
- }))
1256
- }
1257
- />
1258
- </div>
1259
- {!isCreateMode ? (
1260
- <>
1261
- <div className="min-w-0 space-y-2">
1262
- <FieldLabel label={commonT('labels.status')} />
1263
- <Select
1264
- value={form.status}
1265
- onValueChange={(value) =>
1266
- setForm((current) => ({ ...current, status: value }))
1267
- }
1268
- >
1269
- <SelectTrigger className="w-full">
1270
- <SelectValue />
1271
- </SelectTrigger>
1272
- <SelectContent>
1273
- <SelectItem value="planning">
1274
- {t('options.statuses.planning')}
1275
- </SelectItem>
1276
- <SelectItem value="active">
1277
- {t('options.statuses.active')}
1278
- </SelectItem>
1279
- <SelectItem value="at_risk">
1280
- {t('options.statuses.at_risk')}
1281
- </SelectItem>
1282
- <SelectItem value="paused">
1283
- {t('options.statuses.paused')}
1284
- </SelectItem>
1285
- <SelectItem value="completed">
1286
- {t('options.statuses.completed')}
1287
- </SelectItem>
1288
- <SelectItem value="archived">
1289
- {t('options.statuses.archived')}
1290
- </SelectItem>
1291
- </SelectContent>
1292
- </Select>
1293
- </div>
1294
- <div className="min-w-0 space-y-2">
1295
- <FieldLabel label={commonT('labels.endDate')} />
1296
- <Input
1297
- type="date"
1298
- value={form.endDate}
1299
- onChange={(event) =>
1300
- setForm((current) => ({
1301
- ...current,
1302
- endDate: event.target.value,
1303
- }))
1304
- }
1305
- />
1306
- </div>
1307
- <FormField
1308
- control={formMethods.control}
1309
- name="progressPercent"
1310
- render={({ field }) => (
1311
- <FormItem className="min-w-0 gap-0">
1312
- <FormLabel>{t('fields.progressPercent')}</FormLabel>
1313
- <FormControl>
1314
- <Input
1315
- {...field}
1316
- type="text"
1317
- inputMode="decimal"
1318
- placeholder={t('placeholders.progressPercent')}
1319
- value={field.value ?? ''}
1320
- onChange={(event) =>
1321
- field.onChange(
1322
- normalizePercentInput(event.target.value)
1323
- )
1324
- }
1325
- />
1326
- </FormControl>
1327
- <FormMessage />
1328
- </FormItem>
1329
- )}
1330
- />
1331
- </>
1332
- ) : null}
1333
- </div>
1334
- </section>
1335
-
1336
- {!isCreateMode ? (
1337
- <>
1338
- <section className="space-y-3">
1339
- <div className="space-y-0.5">
1340
- <h3 className="text-xs font-semibold uppercase tracking-wide text-muted-foreground">
1341
- {t('sections.financials')}
1342
- </h3>
1343
- <p className="text-[11px] text-muted-foreground/80">
1344
- {t('sections.financialsDescription')}
1345
- </p>
1346
- </div>
1347
- <div className="grid min-w-0 gap-3 md:grid-cols-2 xl:grid-cols-4">
1348
- <div className="min-w-0 space-y-2">
1349
- <FieldLabel label={commonT('labels.budget')} />
1350
- <InputMoney
1351
- value={
1352
- form.budgetAmount === '' ? '' : Number(form.budgetAmount)
1353
- }
1354
- onValueChange={(value) =>
1355
- setForm((current) => ({
1356
- ...current,
1357
- budgetAmount: value !== null ? String(value) : '',
1358
- }))
1359
- }
1360
- />
1361
- </div>
1362
- <div className="min-w-0 space-y-2">
1363
- <FieldLabel
1364
- label={commonT('labels.monthlyHourCap')}
1365
- hint={t('hints.monthlyHourCap')}
1366
- />
1367
- <Input
1368
- type="text"
1369
- inputMode="numeric"
1370
- placeholder={t('placeholders.monthlyHourCap')}
1371
- value={form.monthlyHourCap}
1372
- onChange={(event) => {
1373
- const raw = event.target.value.replace(/[^0-9]/g, '');
1374
- setForm((current) => ({
1375
- ...current,
1376
- monthlyHourCap: raw,
1377
- }));
1378
- }}
1379
- />
1380
- </div>
1381
- <div className="min-w-0 space-y-2">
1382
- <FieldLabel label={commonT('labels.billingModel')} />
1383
- <Select
1384
- value={form.billingModel}
1385
- onValueChange={(value) =>
1386
- setForm((current) => ({
1387
- ...current,
1388
- billingModel: value,
1389
- }))
1390
- }
1391
- >
1392
- <SelectTrigger className="w-full">
1393
- <SelectValue />
1394
- </SelectTrigger>
1395
- <SelectContent>
1396
- <SelectItem value="time_and_material">
1397
- {t('options.billingModels.time_and_material')}
1398
- </SelectItem>
1399
- <SelectItem value="monthly_retainer">
1400
- {t('options.billingModels.monthly_retainer')}
1401
- </SelectItem>
1402
- <SelectItem value="fixed_price">
1403
- {t('options.billingModels.fixed_price')}
1404
- </SelectItem>
1405
- </SelectContent>
1406
- </Select>
1407
- </div>
1408
- <div className="min-w-0 space-y-2">
1409
- <FieldLabel
1410
- label={commonT('labels.contract')}
1411
- hint={t('hints.contract')}
1412
- />
1413
- <ContractSelectWithCreate
1414
- label=""
1415
- value={form.contractId}
1416
- contracts={availableContracts}
1417
- selectPlaceholder={commonT('labels.notAssigned')}
1418
- searchPlaceholder={t('placeholders.contractSearch')}
1419
- onChange={(value) =>
1420
- setForm((current) => ({ ...current, contractId: value }))
1421
- }
1422
- onCreated={async (contract) => {
1423
- await refetchContracts();
1424
- setForm((current) => ({
1425
- ...current,
1426
- contractId: contract?.id
1427
- ? String(contract.id)
1428
- : current.contractId,
1429
- billingModel:
1430
- contract?.billingModel ?? current.billingModel,
1431
- monthlyHourCap:
1432
- contract?.monthlyHourCap !== null &&
1433
- contract?.monthlyHourCap !== undefined
1434
- ? String(contract.monthlyHourCap)
1435
- : current.monthlyHourCap,
1436
- }));
1437
- }}
1438
- initialValues={{
1439
- code: form.code ? `PRJ-${form.code}` : '',
1440
- name: form.name ? `${form.name} Service Agreement` : '',
1441
- clientName: form.clientName,
1442
- contractCategory: 'client',
1443
- contractType: 'service_agreement',
1444
- signatureStatus: 'not_started',
1445
- billingModel: form.billingModel,
1446
- budgetAmount: form.budgetAmount,
1447
- monthlyHourCap: form.monthlyHourCap,
1448
- startDate: form.startDate,
1449
- endDate: form.endDate,
1450
- description: form.summary,
1451
- contentHtml: '',
1452
- }}
1453
- />
1454
- </div>
1455
- </div>
1456
- </section>
1457
-
1458
- <section className="space-y-3">
1459
- <div className="space-y-0.5">
1460
- <h3 className="text-xs font-semibold uppercase tracking-wide text-muted-foreground">
1461
- {t('sections.team')}
1462
- </h3>
1463
- <p className="text-[11px] text-muted-foreground/80">
1464
- {t('sections.teamDescription', {
1465
- count: selectedAssignmentsCount,
1466
- })}
1467
- </p>
1468
- </div>
1469
- <div className="space-y-3">
1470
- <div className="relative">
1471
- <Search className="pointer-events-none absolute top-1/2 left-3 h-4 w-4 -translate-y-1/2 text-muted-foreground" />
1472
- <Input
1473
- className="pl-9"
1474
- value={assignmentSearch}
1475
- placeholder={t('placeholders.assignmentSearch')}
1476
- onChange={(event) =>
1477
- setAssignmentSearch(event.target.value)
1478
- }
1479
- />
1480
- </div>
1481
-
1482
- <div className="space-y-2">
1483
- {filteredAssignments.map((assignment) => {
1484
- const collaborator = availableCollaborators.find(
1485
- (item) => item.id === assignment.collaboratorId
1486
- );
1487
- const assignmentIndex = form.teamAssignments.findIndex(
1488
- (item) =>
1489
- item.collaboratorId === assignment.collaboratorId
1490
- );
1491
- const roleError =
1492
- assignmentIndex >= 0
1493
- ? formMethods.formState.errors.teamAssignments?.[
1494
- assignmentIndex
1495
- ]?.roleLabel
1496
- : undefined;
1497
-
1498
- if (!collaborator) {
1499
- return null;
1500
- }
1501
-
1502
- return (
1503
- <div
1504
- key={assignment.collaboratorId}
1505
- className="grid min-w-0 gap-2 rounded-lg border px-3 py-2 xl:grid-cols-[minmax(0,1.25fr)_minmax(0,1.2fr)_110px_110px]"
1506
- >
1507
- <label className="flex cursor-pointer items-start gap-3 py-1">
1508
- <Checkbox
1509
- checked={assignment.selected}
1510
- onCheckedChange={(checked) =>
1511
- updateAssignment(assignment.collaboratorId, {
1512
- selected: checked === true,
1513
- })
1514
- }
1515
- />
1516
- <div className="min-w-0">
1517
- <div className="truncate font-medium">
1518
- {collaborator.displayName}
1519
- </div>
1520
- <div className="truncate text-xs text-muted-foreground">
1521
- {[
1522
- collaborator.department,
1523
- collaborator.title,
1524
- collaborator.code,
1525
- ]
1526
- .filter(Boolean)
1527
- .join(' • ') || commonT('labels.notAvailable')}
1528
- </div>
1529
- </div>
1530
- </label>
1531
- <div className="space-y-1">
1532
- <DepartmentSelectWithCreate
1533
- label=""
1534
- value={assignment.roleLabel}
1535
- options={projectRoleOptions}
1536
- disabled={!assignment.selected}
1537
- selectPlaceholder={t('placeholders.roleLabel')}
1538
- createDescription={t('fields.roleLabel')}
1539
- createPlaceholder={t(
1540
- 'placeholders.roleLabelCreate'
1541
- )}
1542
- onChange={(role) =>
1543
- updateAssignment(assignment.collaboratorId, {
1544
- projectRoleId: role.id
1545
- ? String(role.id)
1546
- : 'none',
1547
- roleLabel: role.name,
1548
- })
1549
- }
1550
- onCreate={createProjectRole}
1551
- />
1552
- {roleError?.message ? (
1553
- <p className="text-sm text-destructive">
1554
- {String(roleError.message)}
1555
- </p>
1556
- ) : null}
1557
- </div>
1558
- <Input
1559
- className="h-9 mt-2 self-start"
1560
- type="number"
1561
- min="0"
1562
- step="0.5"
1563
- placeholder={t('fields.weeklyHours')}
1564
- value={assignment.weeklyHours}
1565
- disabled={!assignment.selected}
1566
- onChange={(event) => {
1567
- const hours = event.target.value;
1568
- const updates: Partial<TeamAssignmentState> = {
1569
- weeklyHours: hours,
1570
- };
1571
- const cap = collaborator.weeklyCapacityHours;
1572
- if (cap && hours && Number(hours) > 0) {
1573
- const pct = Math.round(
1574
- (Number(hours) / cap) * 100
1575
- );
1576
- updates.allocationPercent = String(
1577
- Math.min(pct, 100)
1578
- );
1579
- }
1580
- updateAssignment(
1581
- assignment.collaboratorId,
1582
- updates
1583
- );
1584
- }}
1585
- />
1586
- <Input
1587
- className="h-9 mt-2 self-start"
1588
- type="text"
1589
- inputMode="decimal"
1590
- placeholder={t('fields.allocationPercent')}
1591
- value={assignment.allocationPercent}
1592
- disabled={!assignment.selected}
1593
- onChange={(event) => {
1594
- const pct = normalizePercentInput(
1595
- event.target.value
1596
- );
1597
- const updates: Partial<TeamAssignmentState> = {
1598
- allocationPercent: pct,
1599
- };
1600
- const cap = collaborator.weeklyCapacityHours;
1601
- if (cap && pct && Number(pct) > 0) {
1602
- const hours = Math.round(
1603
- (Number(pct) / 100) * cap
1604
- );
1605
- updates.weeklyHours = String(hours);
1606
- }
1607
- updateAssignment(
1608
- assignment.collaboratorId,
1609
- updates
1610
- );
1611
- }}
1612
- />
1613
- <div className="flex items-center gap-2 xl:col-span-4">
1614
- <div className="flex-1">
1615
- <label className="text-xs text-muted-foreground">{t('fields.assignmentStartDate')}</label>
1616
- <Input
1617
- className="h-9"
1618
- type="date"
1619
- value={assignment.startDate}
1620
- disabled={!assignment.selected}
1621
- onChange={(event) =>
1622
- updateAssignment(assignment.collaboratorId, {
1623
- startDate: event.target.value,
1624
- })
1625
- }
1626
- />
1627
- </div>
1628
- <div className="flex-1">
1629
- <label className="text-xs text-muted-foreground">{t('fields.assignmentEndDate')}</label>
1630
- <Input
1631
- className="h-9"
1632
- type="date"
1633
- value={assignment.endDate}
1634
- disabled={!assignment.selected}
1635
- onChange={(event) =>
1636
- updateAssignment(assignment.collaboratorId, {
1637
- endDate: event.target.value,
1638
- })
1639
- }
1640
- />
1641
- </div>
1642
- </div>
1643
- </div>
1644
- );
1645
- })}
1646
- </div>
1647
- </div>
1648
- </section>
1649
- </>
1650
- ) : (
1651
- <section className="space-y-3 rounded-lg border border-dashed bg-muted/20 px-4 py-4">
1652
- <div className="space-y-0.5">
1653
- <h3 className="text-xs font-semibold uppercase tracking-wide text-muted-foreground">
1654
- {t('sections.nextSteps')}
1655
- </h3>
1656
- <p className="text-[11px] text-muted-foreground/80">
1657
- {t('sections.nextStepsDescription')}
1658
- </p>
1659
- </div>
1660
- </section>
1661
- )}
1662
- </form>
1663
- </Form>
1664
- );
1665
- const loadingState =
1666
- projectId && isLoadingProject ? (
1667
- <div className="text-sm text-muted-foreground">{t('loading')}</div>
1668
- ) : null;
1669
-
1670
- const contractStatusState = project ? (
1671
- <div className="text-xs text-muted-foreground">
1672
- {t('messages.currentContractStatus', {
1673
- status: project.contractStatus
1674
- ? project.contractStatus
1675
- : commonT('labels.notAssigned'),
1676
- })}
1677
- </div>
1678
- ) : null;
1679
-
1680
- if (isSheetMode) {
1681
- return (
1682
- <div className="mt-6 space-y-4 pb-6">
1683
- {formContent}
1684
- <div className="space-y-2 px-4">
1685
- {loadingState}
1686
- {contractStatusState}
1687
- </div>
1688
-
1689
- <FormActions
1690
- sheet
1691
- cancelLabel={commonT('actions.cancel')}
1692
- onCancel={onCancel}
1693
- onSubmit={() =>
1694
- void formMethods.handleSubmit(onSubmit, handleInvalidSubmit)()
1695
- }
1696
- submitIcon={<Save className="size-4" />}
1697
- submitLabel={commonT('actions.save')}
1698
- submitSize="lg"
1699
- />
1700
- </div>
1701
- );
1702
- }
1703
-
1704
- return (
1705
- <Page>
1706
- <OperationsHeader
1707
- title={t(projectId ? 'editTitle' : 'newTitle')}
1708
- description={t('description')}
1709
- current={t('breadcrumb')}
1710
- actions={
1711
- <div className="flex gap-2">
1712
- <Button variant="outline" size="sm" asChild>
1713
- <Link
1714
- href={
1715
- projectId
1716
- ? `/operations/projects/${projectId}`
1717
- : '/operations/projects'
1718
- }
1719
- >
1720
- <ArrowLeft className="size-4" />
1721
- {commonT('actions.back')}
1722
- </Link>
1723
- </Button>
1724
- <Button
1725
- size="sm"
1726
- type="button"
1727
- onClick={() =>
1728
- void formMethods.handleSubmit(onSubmit, handleInvalidSubmit)()
1729
- }
1730
- >
1731
- <Save className="size-4" />
1732
- {commonT('actions.save')}
1733
- </Button>
1734
- </div>
1735
- }
1736
- />
1737
-
1738
- {formContent}
1739
- <div className="space-y-2">
1740
- {loadingState}
1741
- {contractStatusState}
1742
- </div>
1743
- </Page>
1744
- );
1745
- }