@hed-hog/operations 0.0.322 → 0.0.325

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 (689) hide show
  1. package/dist/controllers/operations-collaborators.controller.d.ts +9 -0
  2. package/dist/controllers/operations-collaborators.controller.d.ts.map +1 -1
  3. package/dist/controllers/operations-collaborators.controller.js +25 -0
  4. package/dist/controllers/operations-collaborators.controller.js.map +1 -1
  5. package/dist/controllers/operations-project-costs.controller.d.ts +422 -0
  6. package/dist/controllers/operations-project-costs.controller.d.ts.map +1 -0
  7. package/dist/controllers/operations-project-costs.controller.js +250 -0
  8. package/dist/controllers/operations-project-costs.controller.js.map +1 -0
  9. package/dist/controllers/operations-reports.controller.d.ts +9 -0
  10. package/dist/controllers/operations-reports.controller.d.ts.map +1 -1
  11. package/dist/controllers/operations-tasks.controller.d.ts +42 -0
  12. package/dist/controllers/operations-tasks.controller.d.ts.map +1 -1
  13. package/dist/controllers/operations-tasks.controller.js +48 -0
  14. package/dist/controllers/operations-tasks.controller.js.map +1 -1
  15. package/dist/controllers/operations-timesheets.controller.d.ts +1 -0
  16. package/dist/controllers/operations-timesheets.controller.d.ts.map +1 -1
  17. package/dist/dto/create-collaborator-project-assignment.dto.d.ts +5 -0
  18. package/dist/dto/create-collaborator-project-assignment.dto.d.ts.map +1 -0
  19. package/dist/dto/create-collaborator-project-assignment.dto.js +30 -0
  20. package/dist/dto/create-collaborator-project-assignment.dto.js.map +1 -0
  21. package/dist/dto/create-project-cost-category.dto.d.ts +10 -0
  22. package/dist/dto/create-project-cost-category.dto.d.ts.map +1 -0
  23. package/dist/dto/create-project-cost-category.dto.js +59 -0
  24. package/dist/dto/create-project-cost-category.dto.js.map +1 -0
  25. package/dist/dto/create-project-cost-type.dto.d.ts +14 -0
  26. package/dist/dto/create-project-cost-type.dto.d.ts.map +1 -0
  27. package/dist/dto/create-project-cost-type.dto.js +87 -0
  28. package/dist/dto/create-project-cost-type.dto.js.map +1 -0
  29. package/dist/dto/create-project-cost.dto.d.ts +22 -0
  30. package/dist/dto/create-project-cost.dto.d.ts.map +1 -0
  31. package/dist/dto/create-project-cost.dto.js +135 -0
  32. package/dist/dto/create-project-cost.dto.js.map +1 -0
  33. package/dist/dto/get-project-cost-report.dto.d.ts +10 -0
  34. package/dist/dto/get-project-cost-report.dto.d.ts.map +1 -0
  35. package/dist/dto/get-project-cost-report.dto.js +65 -0
  36. package/dist/dto/get-project-cost-report.dto.js.map +1 -0
  37. package/dist/dto/list-project-cost-categories.dto.d.ts +6 -0
  38. package/dist/dto/list-project-cost-categories.dto.d.ts.map +1 -0
  39. package/dist/dto/list-project-cost-categories.dto.js +34 -0
  40. package/dist/dto/list-project-cost-categories.dto.js.map +1 -0
  41. package/dist/dto/list-project-cost-types.dto.d.ts +8 -0
  42. package/dist/dto/list-project-cost-types.dto.d.ts.map +1 -0
  43. package/dist/dto/list-project-cost-types.dto.js +45 -0
  44. package/dist/dto/list-project-cost-types.dto.js.map +1 -0
  45. package/dist/dto/list-project-costs.dto.d.ts +14 -0
  46. package/dist/dto/list-project-costs.dto.d.ts.map +1 -0
  47. package/dist/dto/list-project-costs.dto.js +81 -0
  48. package/dist/dto/list-project-costs.dto.js.map +1 -0
  49. package/dist/dto/list-tasks.dto.d.ts +1 -0
  50. package/dist/dto/list-tasks.dto.d.ts.map +1 -1
  51. package/dist/dto/list-tasks.dto.js +6 -0
  52. package/dist/dto/list-tasks.dto.js.map +1 -1
  53. package/dist/dto/list-timesheets.dto.d.ts +1 -0
  54. package/dist/dto/list-timesheets.dto.d.ts.map +1 -1
  55. package/dist/dto/list-timesheets.dto.js +7 -0
  56. package/dist/dto/list-timesheets.dto.js.map +1 -1
  57. package/dist/dto/update-collaborator-project-assignment.dto.d.ts +11 -0
  58. package/dist/dto/update-collaborator-project-assignment.dto.d.ts.map +1 -0
  59. package/dist/dto/update-collaborator-project-assignment.dto.js +65 -0
  60. package/dist/dto/update-collaborator-project-assignment.dto.js.map +1 -0
  61. package/dist/dto/update-project-cost-category.dto.d.ts +6 -0
  62. package/dist/dto/update-project-cost-category.dto.d.ts.map +1 -0
  63. package/dist/dto/update-project-cost-category.dto.js +9 -0
  64. package/dist/dto/update-project-cost-category.dto.js.map +1 -0
  65. package/dist/dto/update-project-cost-type.dto.d.ts +6 -0
  66. package/dist/dto/update-project-cost-type.dto.d.ts.map +1 -0
  67. package/dist/dto/update-project-cost-type.dto.js +9 -0
  68. package/dist/dto/update-project-cost-type.dto.js.map +1 -0
  69. package/dist/dto/update-project-cost.dto.d.ts +6 -0
  70. package/dist/dto/update-project-cost.dto.d.ts.map +1 -0
  71. package/dist/dto/update-project-cost.dto.js +9 -0
  72. package/dist/dto/update-project-cost.dto.js.map +1 -0
  73. package/dist/operations.module.d.ts.map +1 -1
  74. package/dist/operations.module.js +2 -0
  75. package/dist/operations.module.js.map +1 -1
  76. package/dist/operations.service.d.ts +562 -0
  77. package/dist/operations.service.d.ts.map +1 -1
  78. package/dist/operations.service.js +1657 -47
  79. package/dist/operations.service.js.map +1 -1
  80. package/hedhog/data/menu.yaml +52 -0
  81. package/hedhog/data/operations_project_cost_category.yaml +80 -0
  82. package/hedhog/data/operations_project_cost_type.yaml +503 -0
  83. package/hedhog/data/route.yaml +274 -0
  84. package/hedhog/frontend/app/_components/collaborator-costs-section.tsx.ejs +2 -18
  85. package/hedhog/frontend/app/_components/collaborator-form-screen.tsx.ejs +185 -276
  86. package/hedhog/frontend/app/_components/collaborator-tasks-tab.tsx.ejs +358 -0
  87. package/hedhog/frontend/app/_components/collaborator-timesheets-tab.tsx.ejs +242 -0
  88. package/hedhog/frontend/app/_components/my-project-summary-screen.tsx.ejs +167 -59
  89. package/hedhog/frontend/app/_components/person-select-with-create.tsx.ejs +1 -853
  90. package/hedhog/frontend/app/_components/project-assignments-tab.tsx.ejs +450 -0
  91. package/hedhog/frontend/app/_components/project-cost-report-screen.tsx.ejs +602 -0
  92. package/hedhog/frontend/app/_components/project-costs-section.tsx.ejs +1401 -0
  93. package/hedhog/frontend/app/_components/project-details-screen.tsx.ejs +2003 -1846
  94. package/hedhog/frontend/app/_components/project-form-screen.tsx.ejs +56 -11
  95. package/hedhog/frontend/app/_components/task-detail-sheet.tsx.ejs +297 -2
  96. package/hedhog/frontend/app/_components/task-form-sheet.tsx.ejs +530 -0
  97. package/hedhog/frontend/app/_lib/api.ts.ejs +247 -0
  98. package/hedhog/frontend/app/_lib/types.ts.ejs +196 -7
  99. package/hedhog/frontend/app/_lib/utils/format.ts.ejs +9 -3
  100. package/hedhog/frontend/app/collaborators/page.tsx.ejs +18 -7
  101. package/hedhog/frontend/app/my-tasks/page.tsx.ejs +219 -122
  102. package/hedhog/frontend/app/project-cost-categories/page.tsx.ejs +674 -0
  103. package/hedhog/frontend/app/project-cost-types/page.tsx.ejs +845 -0
  104. package/hedhog/frontend/app/projects/[id]/costs-report/page.tsx.ejs +10 -0
  105. package/hedhog/frontend/app/reports/collaborators/page.tsx.ejs +20 -349
  106. package/hedhog/frontend/app/reports/projects/page.tsx.ejs +192 -484
  107. package/hedhog/frontend/messages/en.json +279 -10
  108. package/hedhog/frontend/messages/en.json.ejs +2043 -0
  109. package/hedhog/frontend/messages/operations/en.json +2068 -0
  110. package/hedhog/frontend/messages/operations/operations/en.json +2102 -0
  111. package/hedhog/frontend/messages/operations/operations/pt.json +2111 -0
  112. package/hedhog/frontend/messages/operations/pt.json +2072 -0
  113. package/hedhog/frontend/messages/pt.json +284 -13
  114. package/hedhog/frontend/messages/pt.json.ejs +2056 -0
  115. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/async-options-combobox.d.ts +29 -0
  116. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/async-options-combobox.d.ts.map +1 -0
  117. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/async-options-combobox.js +95 -0
  118. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/async-options-combobox.js.map +1 -0
  119. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/async-options-combobox.tsx +233 -0
  120. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/collaborator-costs-section.d.ts +10 -0
  121. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/collaborator-costs-section.d.ts.map +1 -0
  122. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/collaborator-costs-section.js +577 -0
  123. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/collaborator-costs-section.js.map +1 -0
  124. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/collaborator-costs-section.tsx +868 -0
  125. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/collaborator-details-screen.d.ts +4 -0
  126. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/collaborator-details-screen.d.ts.map +1 -0
  127. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/collaborator-details-screen.js +337 -0
  128. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/collaborator-details-screen.js.map +1 -0
  129. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/collaborator-details-screen.tsx +476 -0
  130. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/collaborator-form-screen.d.ts +9 -0
  131. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/collaborator-form-screen.d.ts.map +1 -0
  132. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/collaborator-form-screen.js +1348 -0
  133. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/collaborator-form-screen.js.map +1 -0
  134. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/collaborator-form-screen.tsx +2233 -0
  135. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/collaborator-select-with-create.d.ts +12 -0
  136. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/collaborator-select-with-create.d.ts.map +1 -0
  137. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/collaborator-select-with-create.js +162 -0
  138. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/collaborator-select-with-create.js.map +1 -0
  139. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/collaborator-select-with-create.tsx +261 -0
  140. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/contract-content-editor.d.ts +18 -0
  141. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/contract-content-editor.d.ts.map +1 -0
  142. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/contract-content-editor.js +145 -0
  143. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/contract-content-editor.js.map +1 -0
  144. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/contract-content-editor.tsx +258 -0
  145. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/contract-details-screen.d.ts +4 -0
  146. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/contract-details-screen.d.ts.map +1 -0
  147. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/contract-details-screen.js +223 -0
  148. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/contract-details-screen.js.map +1 -0
  149. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/contract-details-screen.tsx +342 -0
  150. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/contract-form-screen.d.ts +58 -0
  151. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/contract-form-screen.d.ts.map +1 -0
  152. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/contract-form-screen.js +438 -0
  153. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/contract-form-screen.js.map +1 -0
  154. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/contract-form-screen.tsx +698 -0
  155. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/department-select-with-create.d.ts +20 -0
  156. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/department-select-with-create.d.ts.map +1 -0
  157. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/department-select-with-create.js +233 -0
  158. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/department-select-with-create.js.map +1 -0
  159. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/department-select-with-create.tsx +392 -0
  160. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/my-project-summary-screen.d.ts +4 -0
  161. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/my-project-summary-screen.d.ts.map +1 -0
  162. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/my-project-summary-screen.js +814 -0
  163. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/my-project-summary-screen.js.map +1 -0
  164. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/my-project-summary-screen.tsx +1288 -0
  165. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/operations-calendar-view.d.ts +21 -0
  166. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/operations-calendar-view.d.ts.map +1 -0
  167. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/operations-calendar-view.js +174 -0
  168. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/operations-calendar-view.js.map +1 -0
  169. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/operations-calendar-view.tsx +306 -0
  170. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/operations-header.d.ts +10 -0
  171. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/operations-header.d.ts.map +1 -0
  172. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/operations-header.js +12 -0
  173. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/operations-header.js.map +1 -0
  174. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/operations-header.tsx +29 -0
  175. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/person-select-with-create.d.ts +15 -0
  176. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/person-select-with-create.d.ts.map +1 -0
  177. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/person-select-with-create.js +501 -0
  178. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/person-select-with-create.js.map +1 -0
  179. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/person-select-with-create.tsx +853 -0
  180. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/project-costs-section.d.ts +6 -0
  181. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/project-costs-section.d.ts.map +1 -0
  182. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/project-costs-section.js +847 -0
  183. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/project-costs-section.js.map +1 -0
  184. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/project-costs-section.tsx +1340 -0
  185. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/project-details-screen.d.ts +4 -0
  186. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/project-details-screen.d.ts.map +1 -0
  187. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/project-details-screen.js +2930 -0
  188. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/project-details-screen.js.map +1 -0
  189. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/project-details-screen.tsx +4378 -0
  190. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/project-form-screen.d.ts +9 -0
  191. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/project-form-screen.d.ts.map +1 -0
  192. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/project-form-screen.js +1013 -0
  193. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/project-form-screen.js.map +1 -0
  194. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/project-form-screen.tsx +1745 -0
  195. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/section-card.d.ts +13 -0
  196. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/section-card.d.ts.map +1 -0
  197. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/section-card.js +38 -0
  198. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/section-card.js.map +1 -0
  199. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/section-card.tsx +74 -0
  200. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/status-badge.d.ts +7 -0
  201. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/status-badge.d.ts.map +1 -0
  202. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/status-badge.js +11 -0
  203. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/status-badge.js.map +1 -0
  204. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/status-badge.tsx +15 -0
  205. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/system-user-select-with-create.d.ts +18 -0
  206. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/system-user-select-with-create.d.ts.map +1 -0
  207. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/system-user-select-with-create.js +406 -0
  208. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/system-user-select-with-create.js.map +1 -0
  209. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/system-user-select-with-create.tsx +660 -0
  210. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/task-detail-sheet.d.ts +26 -0
  211. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/task-detail-sheet.d.ts.map +1 -0
  212. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/task-detail-sheet.js +332 -0
  213. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/task-detail-sheet.js.map +1 -0
  214. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/task-detail-sheet.tsx +518 -0
  215. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/task-file-attachments.d.ts +6 -0
  216. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/task-file-attachments.d.ts.map +1 -0
  217. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/task-file-attachments.js +255 -0
  218. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/task-file-attachments.js.map +1 -0
  219. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/task-file-attachments.tsx +388 -0
  220. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/timesheet-task-create-sheet.d.ts +10 -0
  221. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/timesheet-task-create-sheet.d.ts.map +1 -0
  222. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/timesheet-task-create-sheet.js +131 -0
  223. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/timesheet-task-create-sheet.js.map +1 -0
  224. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/timesheet-task-create-sheet.tsx +214 -0
  225. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_lib/api.d.ts +108 -0
  226. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_lib/api.d.ts.map +1 -0
  227. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_lib/api.js +162 -0
  228. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_lib/api.js.map +1 -0
  229. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_lib/api.ts +428 -0
  230. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_lib/hooks/use-operations-access.d.ts +8 -0
  231. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_lib/hooks/use-operations-access.d.ts.map +1 -0
  232. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_lib/hooks/use-operations-access.js +36 -0
  233. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_lib/hooks/use-operations-access.js.map +1 -0
  234. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_lib/hooks/use-operations-access.ts +44 -0
  235. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_lib/types.d.ts +836 -0
  236. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_lib/types.d.ts.map +1 -0
  237. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_lib/types.js +3 -0
  238. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_lib/types.js.map +1 -0
  239. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_lib/types.ts +860 -0
  240. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_lib/utils/format.d.ts +16 -0
  241. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_lib/utils/format.d.ts.map +1 -0
  242. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_lib/utils/format.js +182 -0
  243. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_lib/utils/format.js.map +1 -0
  244. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_lib/utils/format.ts +250 -0
  245. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_lib/utils/forms.d.ts +4 -0
  246. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_lib/utils/forms.d.ts.map +1 -0
  247. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_lib/utils/forms.js +51 -0
  248. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_lib/utils/forms.js.map +1 -0
  249. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_lib/utils/forms.ts +61 -0
  250. package/hedhog/frontend/src/app/(app)/(libraries)/operations/approvals/page.d.ts +2 -0
  251. package/hedhog/frontend/src/app/(app)/(libraries)/operations/approvals/page.d.ts.map +1 -0
  252. package/hedhog/frontend/src/app/(app)/(libraries)/operations/approvals/page.js +954 -0
  253. package/hedhog/frontend/src/app/(app)/(libraries)/operations/approvals/page.js.map +1 -0
  254. package/hedhog/frontend/src/app/(app)/(libraries)/operations/approvals/page.tsx +1277 -0
  255. package/hedhog/frontend/src/app/(app)/(libraries)/operations/collaborator-types/page.d.ts +2 -0
  256. package/hedhog/frontend/src/app/(app)/(libraries)/operations/collaborator-types/page.d.ts.map +1 -0
  257. package/hedhog/frontend/src/app/(app)/(libraries)/operations/collaborator-types/page.js +488 -0
  258. package/hedhog/frontend/src/app/(app)/(libraries)/operations/collaborator-types/page.js.map +1 -0
  259. package/hedhog/frontend/src/app/(app)/(libraries)/operations/collaborator-types/page.tsx +805 -0
  260. package/hedhog/frontend/src/app/(app)/(libraries)/operations/collaborators/[id]/edit/page.d.ts +6 -0
  261. package/hedhog/frontend/src/app/(app)/(libraries)/operations/collaborators/[id]/edit/page.d.ts.map +1 -0
  262. package/hedhog/frontend/src/app/(app)/(libraries)/operations/collaborators/[id]/edit/page.js +9 -0
  263. package/hedhog/frontend/src/app/(app)/(libraries)/operations/collaborators/[id]/edit/page.js.map +1 -0
  264. package/hedhog/frontend/src/app/(app)/(libraries)/operations/collaborators/[id]/edit/page.tsx +11 -0
  265. package/hedhog/frontend/src/app/(app)/(libraries)/operations/collaborators/[id]/page.d.ts +6 -0
  266. package/hedhog/frontend/src/app/(app)/(libraries)/operations/collaborators/[id]/page.d.ts.map +1 -0
  267. package/hedhog/frontend/src/app/(app)/(libraries)/operations/collaborators/[id]/page.js +9 -0
  268. package/hedhog/frontend/src/app/(app)/(libraries)/operations/collaborators/[id]/page.js.map +1 -0
  269. package/hedhog/frontend/src/app/(app)/(libraries)/operations/collaborators/[id]/page.tsx +11 -0
  270. package/hedhog/frontend/src/app/(app)/(libraries)/operations/collaborators/new/page.d.ts +2 -0
  271. package/hedhog/frontend/src/app/(app)/(libraries)/operations/collaborators/new/page.d.ts.map +1 -0
  272. package/hedhog/frontend/src/app/(app)/(libraries)/operations/collaborators/new/page.js +8 -0
  273. package/hedhog/frontend/src/app/(app)/(libraries)/operations/collaborators/new/page.js.map +1 -0
  274. package/hedhog/frontend/src/app/(app)/(libraries)/operations/collaborators/new/page.tsx +5 -0
  275. package/hedhog/frontend/src/app/(app)/(libraries)/operations/collaborators/page.d.ts +2 -0
  276. package/hedhog/frontend/src/app/(app)/(libraries)/operations/collaborators/page.d.ts.map +1 -0
  277. package/hedhog/frontend/src/app/(app)/(libraries)/operations/collaborators/page.js +612 -0
  278. package/hedhog/frontend/src/app/(app)/(libraries)/operations/collaborators/page.js.map +1 -0
  279. package/hedhog/frontend/src/app/(app)/(libraries)/operations/collaborators/page.tsx +939 -0
  280. package/hedhog/frontend/src/app/(app)/(libraries)/operations/contracts/[id]/edit/page.d.ts +6 -0
  281. package/hedhog/frontend/src/app/(app)/(libraries)/operations/contracts/[id]/edit/page.d.ts.map +1 -0
  282. package/hedhog/frontend/src/app/(app)/(libraries)/operations/contracts/[id]/edit/page.js +9 -0
  283. package/hedhog/frontend/src/app/(app)/(libraries)/operations/contracts/[id]/edit/page.js.map +1 -0
  284. package/hedhog/frontend/src/app/(app)/(libraries)/operations/contracts/[id]/edit/page.tsx +11 -0
  285. package/hedhog/frontend/src/app/(app)/(libraries)/operations/contracts/[id]/page.d.ts +6 -0
  286. package/hedhog/frontend/src/app/(app)/(libraries)/operations/contracts/[id]/page.d.ts.map +1 -0
  287. package/hedhog/frontend/src/app/(app)/(libraries)/operations/contracts/[id]/page.js +9 -0
  288. package/hedhog/frontend/src/app/(app)/(libraries)/operations/contracts/[id]/page.js.map +1 -0
  289. package/hedhog/frontend/src/app/(app)/(libraries)/operations/contracts/[id]/page.tsx +11 -0
  290. package/hedhog/frontend/src/app/(app)/(libraries)/operations/contracts/new/page.d.ts +6 -0
  291. package/hedhog/frontend/src/app/(app)/(libraries)/operations/contracts/new/page.d.ts.map +1 -0
  292. package/hedhog/frontend/src/app/(app)/(libraries)/operations/contracts/new/page.js +9 -0
  293. package/hedhog/frontend/src/app/(app)/(libraries)/operations/contracts/new/page.js.map +1 -0
  294. package/hedhog/frontend/src/app/(app)/(libraries)/operations/contracts/new/page.tsx +17 -0
  295. package/hedhog/frontend/src/app/(app)/(libraries)/operations/contracts/page.d.ts +2 -0
  296. package/hedhog/frontend/src/app/(app)/(libraries)/operations/contracts/page.d.ts.map +1 -0
  297. package/hedhog/frontend/src/app/(app)/(libraries)/operations/contracts/page.js +348 -0
  298. package/hedhog/frontend/src/app/(app)/(libraries)/operations/contracts/page.js.map +1 -0
  299. package/hedhog/frontend/src/app/(app)/(libraries)/operations/contracts/page.tsx +536 -0
  300. package/hedhog/frontend/src/app/(app)/(libraries)/operations/departments/page.d.ts +2 -0
  301. package/hedhog/frontend/src/app/(app)/(libraries)/operations/departments/page.d.ts.map +1 -0
  302. package/hedhog/frontend/src/app/(app)/(libraries)/operations/departments/page.js +401 -0
  303. package/hedhog/frontend/src/app/(app)/(libraries)/operations/departments/page.js.map +1 -0
  304. package/hedhog/frontend/src/app/(app)/(libraries)/operations/departments/page.tsx +607 -0
  305. package/hedhog/frontend/src/app/(app)/(libraries)/operations/layout.d.ts +5 -0
  306. package/hedhog/frontend/src/app/(app)/(libraries)/operations/layout.d.ts.map +1 -0
  307. package/hedhog/frontend/src/app/(app)/(libraries)/operations/layout.js +7 -0
  308. package/hedhog/frontend/src/app/(app)/(libraries)/operations/layout.js.map +1 -0
  309. package/hedhog/frontend/src/app/(app)/(libraries)/operations/layout.tsx +9 -0
  310. package/hedhog/frontend/src/app/(app)/(libraries)/operations/my-projects/[id]/page.d.ts +6 -0
  311. package/hedhog/frontend/src/app/(app)/(libraries)/operations/my-projects/[id]/page.d.ts.map +1 -0
  312. package/hedhog/frontend/src/app/(app)/(libraries)/operations/my-projects/[id]/page.js +9 -0
  313. package/hedhog/frontend/src/app/(app)/(libraries)/operations/my-projects/[id]/page.js.map +1 -0
  314. package/hedhog/frontend/src/app/(app)/(libraries)/operations/my-projects/[id]/page.tsx +11 -0
  315. package/hedhog/frontend/src/app/(app)/(libraries)/operations/my-projects/page.d.ts +2 -0
  316. package/hedhog/frontend/src/app/(app)/(libraries)/operations/my-projects/page.d.ts.map +1 -0
  317. package/hedhog/frontend/src/app/(app)/(libraries)/operations/my-projects/page.js +321 -0
  318. package/hedhog/frontend/src/app/(app)/(libraries)/operations/my-projects/page.js.map +1 -0
  319. package/hedhog/frontend/src/app/(app)/(libraries)/operations/my-projects/page.tsx +440 -0
  320. package/hedhog/frontend/src/app/(app)/(libraries)/operations/my-tasks/page.d.ts +2 -0
  321. package/hedhog/frontend/src/app/(app)/(libraries)/operations/my-tasks/page.d.ts.map +1 -0
  322. package/hedhog/frontend/src/app/(app)/(libraries)/operations/my-tasks/page.js +939 -0
  323. package/hedhog/frontend/src/app/(app)/(libraries)/operations/my-tasks/page.js.map +1 -0
  324. package/hedhog/frontend/src/app/(app)/(libraries)/operations/my-tasks/page.tsx +1499 -0
  325. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/async-options-combobox.d.ts +29 -0
  326. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/async-options-combobox.d.ts.map +1 -0
  327. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/async-options-combobox.js +95 -0
  328. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/async-options-combobox.js.map +1 -0
  329. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/async-options-combobox.tsx +233 -0
  330. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/collaborator-costs-section.d.ts +10 -0
  331. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/collaborator-costs-section.d.ts.map +1 -0
  332. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/collaborator-costs-section.js +577 -0
  333. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/collaborator-costs-section.js.map +1 -0
  334. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/collaborator-costs-section.tsx +868 -0
  335. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/collaborator-details-screen.d.ts +4 -0
  336. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/collaborator-details-screen.d.ts.map +1 -0
  337. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/collaborator-details-screen.js +337 -0
  338. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/collaborator-details-screen.js.map +1 -0
  339. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/collaborator-details-screen.tsx +476 -0
  340. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/collaborator-form-screen.d.ts +9 -0
  341. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/collaborator-form-screen.d.ts.map +1 -0
  342. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/collaborator-form-screen.js +1348 -0
  343. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/collaborator-form-screen.js.map +1 -0
  344. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/collaborator-form-screen.tsx +2233 -0
  345. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/collaborator-select-with-create.d.ts +12 -0
  346. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/collaborator-select-with-create.d.ts.map +1 -0
  347. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/collaborator-select-with-create.js +162 -0
  348. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/collaborator-select-with-create.js.map +1 -0
  349. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/collaborator-select-with-create.tsx +261 -0
  350. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/contract-content-editor.d.ts +18 -0
  351. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/contract-content-editor.d.ts.map +1 -0
  352. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/contract-content-editor.js +145 -0
  353. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/contract-content-editor.js.map +1 -0
  354. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/contract-content-editor.tsx +258 -0
  355. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/contract-details-screen.d.ts +4 -0
  356. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/contract-details-screen.d.ts.map +1 -0
  357. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/contract-details-screen.js +223 -0
  358. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/contract-details-screen.js.map +1 -0
  359. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/contract-details-screen.tsx +342 -0
  360. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/contract-form-screen.d.ts +58 -0
  361. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/contract-form-screen.d.ts.map +1 -0
  362. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/contract-form-screen.js +438 -0
  363. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/contract-form-screen.js.map +1 -0
  364. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/contract-form-screen.tsx +698 -0
  365. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/department-select-with-create.d.ts +20 -0
  366. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/department-select-with-create.d.ts.map +1 -0
  367. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/department-select-with-create.js +233 -0
  368. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/department-select-with-create.js.map +1 -0
  369. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/department-select-with-create.tsx +392 -0
  370. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/my-project-summary-screen.d.ts +4 -0
  371. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/my-project-summary-screen.d.ts.map +1 -0
  372. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/my-project-summary-screen.js +814 -0
  373. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/my-project-summary-screen.js.map +1 -0
  374. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/my-project-summary-screen.tsx +1288 -0
  375. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/operations-calendar-view.d.ts +21 -0
  376. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/operations-calendar-view.d.ts.map +1 -0
  377. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/operations-calendar-view.js +174 -0
  378. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/operations-calendar-view.js.map +1 -0
  379. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/operations-calendar-view.tsx +306 -0
  380. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/operations-header.d.ts +10 -0
  381. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/operations-header.d.ts.map +1 -0
  382. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/operations-header.js +12 -0
  383. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/operations-header.js.map +1 -0
  384. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/operations-header.tsx +29 -0
  385. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/person-select-with-create.d.ts +15 -0
  386. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/person-select-with-create.d.ts.map +1 -0
  387. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/person-select-with-create.js +501 -0
  388. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/person-select-with-create.js.map +1 -0
  389. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/person-select-with-create.tsx +853 -0
  390. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/project-cost-report-screen.d.ts +6 -0
  391. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/project-cost-report-screen.d.ts.map +1 -0
  392. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/project-cost-report-screen.js +459 -0
  393. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/project-cost-report-screen.js.map +1 -0
  394. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/project-cost-report-screen.tsx +598 -0
  395. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/project-costs-section.d.ts +6 -0
  396. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/project-costs-section.d.ts.map +1 -0
  397. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/project-costs-section.js +876 -0
  398. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/project-costs-section.js.map +1 -0
  399. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/project-costs-section.tsx +1368 -0
  400. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/project-details-screen.d.ts +4 -0
  401. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/project-details-screen.d.ts.map +1 -0
  402. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/project-details-screen.js +2930 -0
  403. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/project-details-screen.js.map +1 -0
  404. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/project-details-screen.tsx +4378 -0
  405. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/project-form-screen.d.ts +9 -0
  406. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/project-form-screen.d.ts.map +1 -0
  407. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/project-form-screen.js +1013 -0
  408. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/project-form-screen.js.map +1 -0
  409. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/project-form-screen.tsx +1745 -0
  410. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/section-card.d.ts +13 -0
  411. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/section-card.d.ts.map +1 -0
  412. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/section-card.js +38 -0
  413. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/section-card.js.map +1 -0
  414. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/section-card.tsx +74 -0
  415. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/status-badge.d.ts +7 -0
  416. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/status-badge.d.ts.map +1 -0
  417. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/status-badge.js +11 -0
  418. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/status-badge.js.map +1 -0
  419. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/status-badge.tsx +15 -0
  420. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/system-user-select-with-create.d.ts +18 -0
  421. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/system-user-select-with-create.d.ts.map +1 -0
  422. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/system-user-select-with-create.js +406 -0
  423. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/system-user-select-with-create.js.map +1 -0
  424. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/system-user-select-with-create.tsx +660 -0
  425. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/task-detail-sheet.d.ts +26 -0
  426. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/task-detail-sheet.d.ts.map +1 -0
  427. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/task-detail-sheet.js +332 -0
  428. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/task-detail-sheet.js.map +1 -0
  429. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/task-detail-sheet.tsx +518 -0
  430. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/task-file-attachments.d.ts +6 -0
  431. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/task-file-attachments.d.ts.map +1 -0
  432. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/task-file-attachments.js +255 -0
  433. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/task-file-attachments.js.map +1 -0
  434. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/task-file-attachments.tsx +388 -0
  435. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/timesheet-task-create-sheet.d.ts +10 -0
  436. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/timesheet-task-create-sheet.d.ts.map +1 -0
  437. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/timesheet-task-create-sheet.js +131 -0
  438. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/timesheet-task-create-sheet.js.map +1 -0
  439. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/timesheet-task-create-sheet.tsx +214 -0
  440. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_lib/api.d.ts +108 -0
  441. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_lib/api.d.ts.map +1 -0
  442. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_lib/api.js +162 -0
  443. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_lib/api.js.map +1 -0
  444. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_lib/api.ts +428 -0
  445. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_lib/hooks/use-operations-access.d.ts +8 -0
  446. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_lib/hooks/use-operations-access.d.ts.map +1 -0
  447. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_lib/hooks/use-operations-access.js +36 -0
  448. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_lib/hooks/use-operations-access.js.map +1 -0
  449. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_lib/hooks/use-operations-access.ts +44 -0
  450. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_lib/types.d.ts +836 -0
  451. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_lib/types.d.ts.map +1 -0
  452. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_lib/types.js +3 -0
  453. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_lib/types.js.map +1 -0
  454. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_lib/types.ts +860 -0
  455. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_lib/utils/format.d.ts +16 -0
  456. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_lib/utils/format.d.ts.map +1 -0
  457. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_lib/utils/format.js +182 -0
  458. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_lib/utils/format.js.map +1 -0
  459. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_lib/utils/format.ts +250 -0
  460. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_lib/utils/forms.d.ts +4 -0
  461. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_lib/utils/forms.d.ts.map +1 -0
  462. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_lib/utils/forms.js +51 -0
  463. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_lib/utils/forms.js.map +1 -0
  464. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_lib/utils/forms.ts +61 -0
  465. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/approvals/page.d.ts +2 -0
  466. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/approvals/page.d.ts.map +1 -0
  467. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/approvals/page.js +954 -0
  468. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/approvals/page.js.map +1 -0
  469. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/approvals/page.tsx +1277 -0
  470. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/collaborator-types/page.d.ts +2 -0
  471. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/collaborator-types/page.d.ts.map +1 -0
  472. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/collaborator-types/page.js +488 -0
  473. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/collaborator-types/page.js.map +1 -0
  474. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/collaborator-types/page.tsx +805 -0
  475. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/collaborators/[id]/edit/page.d.ts +6 -0
  476. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/collaborators/[id]/edit/page.d.ts.map +1 -0
  477. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/collaborators/[id]/edit/page.js +9 -0
  478. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/collaborators/[id]/edit/page.js.map +1 -0
  479. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/collaborators/[id]/edit/page.tsx +11 -0
  480. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/collaborators/[id]/page.d.ts +6 -0
  481. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/collaborators/[id]/page.d.ts.map +1 -0
  482. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/collaborators/[id]/page.js +9 -0
  483. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/collaborators/[id]/page.js.map +1 -0
  484. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/collaborators/[id]/page.tsx +11 -0
  485. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/collaborators/new/page.d.ts +2 -0
  486. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/collaborators/new/page.d.ts.map +1 -0
  487. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/collaborators/new/page.js +8 -0
  488. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/collaborators/new/page.js.map +1 -0
  489. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/collaborators/new/page.tsx +5 -0
  490. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/collaborators/page.d.ts +2 -0
  491. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/collaborators/page.d.ts.map +1 -0
  492. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/collaborators/page.js +612 -0
  493. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/collaborators/page.js.map +1 -0
  494. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/collaborators/page.tsx +939 -0
  495. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/contracts/[id]/edit/page.d.ts +6 -0
  496. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/contracts/[id]/edit/page.d.ts.map +1 -0
  497. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/contracts/[id]/edit/page.js +9 -0
  498. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/contracts/[id]/edit/page.js.map +1 -0
  499. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/contracts/[id]/edit/page.tsx +11 -0
  500. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/contracts/[id]/page.d.ts +6 -0
  501. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/contracts/[id]/page.d.ts.map +1 -0
  502. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/contracts/[id]/page.js +9 -0
  503. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/contracts/[id]/page.js.map +1 -0
  504. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/contracts/[id]/page.tsx +11 -0
  505. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/contracts/new/page.d.ts +6 -0
  506. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/contracts/new/page.d.ts.map +1 -0
  507. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/contracts/new/page.js +9 -0
  508. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/contracts/new/page.js.map +1 -0
  509. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/contracts/new/page.tsx +17 -0
  510. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/contracts/page.d.ts +2 -0
  511. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/contracts/page.d.ts.map +1 -0
  512. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/contracts/page.js +348 -0
  513. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/contracts/page.js.map +1 -0
  514. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/contracts/page.tsx +536 -0
  515. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/departments/page.d.ts +2 -0
  516. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/departments/page.d.ts.map +1 -0
  517. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/departments/page.js +401 -0
  518. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/departments/page.js.map +1 -0
  519. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/departments/page.tsx +607 -0
  520. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/layout.d.ts +5 -0
  521. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/layout.d.ts.map +1 -0
  522. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/layout.js +7 -0
  523. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/layout.js.map +1 -0
  524. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/layout.tsx +9 -0
  525. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/my-projects/[id]/page.d.ts +6 -0
  526. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/my-projects/[id]/page.d.ts.map +1 -0
  527. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/my-projects/[id]/page.js +9 -0
  528. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/my-projects/[id]/page.js.map +1 -0
  529. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/my-projects/[id]/page.tsx +11 -0
  530. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/my-projects/page.d.ts +2 -0
  531. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/my-projects/page.d.ts.map +1 -0
  532. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/my-projects/page.js +321 -0
  533. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/my-projects/page.js.map +1 -0
  534. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/my-projects/page.tsx +440 -0
  535. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/my-tasks/page.d.ts +2 -0
  536. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/my-tasks/page.d.ts.map +1 -0
  537. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/my-tasks/page.js +939 -0
  538. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/my-tasks/page.js.map +1 -0
  539. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/my-tasks/page.tsx +1499 -0
  540. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/page.d.ts +2 -0
  541. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/page.d.ts.map +1 -0
  542. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/page.js +8 -0
  543. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/page.js.map +1 -0
  544. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/page.tsx +5 -0
  545. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/project-cost-categories/page.d.ts +2 -0
  546. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/project-cost-categories/page.d.ts.map +1 -0
  547. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/project-cost-categories/page.js +436 -0
  548. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/project-cost-categories/page.js.map +1 -0
  549. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/project-cost-categories/page.tsx +675 -0
  550. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/project-cost-types/page.d.ts +2 -0
  551. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/project-cost-types/page.d.ts.map +1 -0
  552. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/project-cost-types/page.js +563 -0
  553. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/project-cost-types/page.js.map +1 -0
  554. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/project-cost-types/page.tsx +846 -0
  555. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/projects/[id]/costs-report/page.d.ts +6 -0
  556. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/projects/[id]/costs-report/page.d.ts.map +1 -0
  557. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/projects/[id]/costs-report/page.js +9 -0
  558. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/projects/[id]/costs-report/page.js.map +1 -0
  559. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/projects/[id]/costs-report/page.tsx +10 -0
  560. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/projects/[id]/edit/page.d.ts +6 -0
  561. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/projects/[id]/edit/page.d.ts.map +1 -0
  562. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/projects/[id]/edit/page.js +9 -0
  563. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/projects/[id]/edit/page.js.map +1 -0
  564. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/projects/[id]/edit/page.tsx +11 -0
  565. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/projects/[id]/page.d.ts +6 -0
  566. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/projects/[id]/page.d.ts.map +1 -0
  567. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/projects/[id]/page.js +9 -0
  568. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/projects/[id]/page.js.map +1 -0
  569. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/projects/[id]/page.tsx +11 -0
  570. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/projects/new/page.d.ts +2 -0
  571. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/projects/new/page.d.ts.map +1 -0
  572. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/projects/new/page.js +8 -0
  573. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/projects/new/page.js.map +1 -0
  574. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/projects/new/page.tsx +5 -0
  575. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/projects/page.d.ts +2 -0
  576. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/projects/page.d.ts.map +1 -0
  577. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/projects/page.js +492 -0
  578. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/projects/page.js.map +1 -0
  579. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/projects/page.tsx +757 -0
  580. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/reports/collaborators/page.d.ts +2 -0
  581. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/reports/collaborators/page.d.ts.map +1 -0
  582. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/reports/collaborators/page.js +342 -0
  583. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/reports/collaborators/page.js.map +1 -0
  584. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/reports/collaborators/page.tsx +430 -0
  585. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/reports/projects/page.d.ts +2 -0
  586. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/reports/projects/page.d.ts.map +1 -0
  587. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/reports/projects/page.js +338 -0
  588. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/reports/projects/page.js.map +1 -0
  589. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/reports/projects/page.tsx +428 -0
  590. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/schedule-adjustments/page.d.ts +2 -0
  591. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/schedule-adjustments/page.d.ts.map +1 -0
  592. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/schedule-adjustments/page.js +660 -0
  593. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/schedule-adjustments/page.js.map +1 -0
  594. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/schedule-adjustments/page.tsx +992 -0
  595. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/time-off/page.d.ts +2 -0
  596. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/time-off/page.d.ts.map +1 -0
  597. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/time-off/page.js +515 -0
  598. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/time-off/page.js.map +1 -0
  599. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/time-off/page.tsx +707 -0
  600. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/timesheets/page.d.ts +2 -0
  601. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/timesheets/page.d.ts.map +1 -0
  602. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/timesheets/page.js +1141 -0
  603. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/timesheets/page.js.map +1 -0
  604. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/timesheets/page.tsx +1705 -0
  605. package/hedhog/frontend/src/app/(app)/(libraries)/operations/page.d.ts +2 -0
  606. package/hedhog/frontend/src/app/(app)/(libraries)/operations/page.d.ts.map +1 -0
  607. package/hedhog/frontend/src/app/(app)/(libraries)/operations/page.js +8 -0
  608. package/hedhog/frontend/src/app/(app)/(libraries)/operations/page.js.map +1 -0
  609. package/hedhog/frontend/src/app/(app)/(libraries)/operations/page.tsx +5 -0
  610. package/hedhog/frontend/src/app/(app)/(libraries)/operations/project-cost-categories/page.d.ts +2 -0
  611. package/hedhog/frontend/src/app/(app)/(libraries)/operations/project-cost-categories/page.d.ts.map +1 -0
  612. package/hedhog/frontend/src/app/(app)/(libraries)/operations/project-cost-categories/page.js +436 -0
  613. package/hedhog/frontend/src/app/(app)/(libraries)/operations/project-cost-categories/page.js.map +1 -0
  614. package/hedhog/frontend/src/app/(app)/(libraries)/operations/project-cost-categories/page.tsx +675 -0
  615. package/hedhog/frontend/src/app/(app)/(libraries)/operations/project-cost-types/page.d.ts +2 -0
  616. package/hedhog/frontend/src/app/(app)/(libraries)/operations/project-cost-types/page.d.ts.map +1 -0
  617. package/hedhog/frontend/src/app/(app)/(libraries)/operations/project-cost-types/page.js +563 -0
  618. package/hedhog/frontend/src/app/(app)/(libraries)/operations/project-cost-types/page.js.map +1 -0
  619. package/hedhog/frontend/src/app/(app)/(libraries)/operations/project-cost-types/page.tsx +846 -0
  620. package/hedhog/frontend/src/app/(app)/(libraries)/operations/projects/[id]/edit/page.d.ts +6 -0
  621. package/hedhog/frontend/src/app/(app)/(libraries)/operations/projects/[id]/edit/page.d.ts.map +1 -0
  622. package/hedhog/frontend/src/app/(app)/(libraries)/operations/projects/[id]/edit/page.js +9 -0
  623. package/hedhog/frontend/src/app/(app)/(libraries)/operations/projects/[id]/edit/page.js.map +1 -0
  624. package/hedhog/frontend/src/app/(app)/(libraries)/operations/projects/[id]/edit/page.tsx +11 -0
  625. package/hedhog/frontend/src/app/(app)/(libraries)/operations/projects/[id]/page.d.ts +6 -0
  626. package/hedhog/frontend/src/app/(app)/(libraries)/operations/projects/[id]/page.d.ts.map +1 -0
  627. package/hedhog/frontend/src/app/(app)/(libraries)/operations/projects/[id]/page.js +9 -0
  628. package/hedhog/frontend/src/app/(app)/(libraries)/operations/projects/[id]/page.js.map +1 -0
  629. package/hedhog/frontend/src/app/(app)/(libraries)/operations/projects/[id]/page.tsx +11 -0
  630. package/hedhog/frontend/src/app/(app)/(libraries)/operations/projects/new/page.d.ts +2 -0
  631. package/hedhog/frontend/src/app/(app)/(libraries)/operations/projects/new/page.d.ts.map +1 -0
  632. package/hedhog/frontend/src/app/(app)/(libraries)/operations/projects/new/page.js +8 -0
  633. package/hedhog/frontend/src/app/(app)/(libraries)/operations/projects/new/page.js.map +1 -0
  634. package/hedhog/frontend/src/app/(app)/(libraries)/operations/projects/new/page.tsx +5 -0
  635. package/hedhog/frontend/src/app/(app)/(libraries)/operations/projects/page.d.ts +2 -0
  636. package/hedhog/frontend/src/app/(app)/(libraries)/operations/projects/page.d.ts.map +1 -0
  637. package/hedhog/frontend/src/app/(app)/(libraries)/operations/projects/page.js +492 -0
  638. package/hedhog/frontend/src/app/(app)/(libraries)/operations/projects/page.js.map +1 -0
  639. package/hedhog/frontend/src/app/(app)/(libraries)/operations/projects/page.tsx +757 -0
  640. package/hedhog/frontend/src/app/(app)/(libraries)/operations/reports/collaborators/page.d.ts +2 -0
  641. package/hedhog/frontend/src/app/(app)/(libraries)/operations/reports/collaborators/page.d.ts.map +1 -0
  642. package/hedhog/frontend/src/app/(app)/(libraries)/operations/reports/collaborators/page.js +342 -0
  643. package/hedhog/frontend/src/app/(app)/(libraries)/operations/reports/collaborators/page.js.map +1 -0
  644. package/hedhog/frontend/src/app/(app)/(libraries)/operations/reports/collaborators/page.tsx +430 -0
  645. package/hedhog/frontend/src/app/(app)/(libraries)/operations/reports/projects/page.d.ts +2 -0
  646. package/hedhog/frontend/src/app/(app)/(libraries)/operations/reports/projects/page.d.ts.map +1 -0
  647. package/hedhog/frontend/src/app/(app)/(libraries)/operations/reports/projects/page.js +338 -0
  648. package/hedhog/frontend/src/app/(app)/(libraries)/operations/reports/projects/page.js.map +1 -0
  649. package/hedhog/frontend/src/app/(app)/(libraries)/operations/reports/projects/page.tsx +428 -0
  650. package/hedhog/frontend/src/app/(app)/(libraries)/operations/schedule-adjustments/page.d.ts +2 -0
  651. package/hedhog/frontend/src/app/(app)/(libraries)/operations/schedule-adjustments/page.d.ts.map +1 -0
  652. package/hedhog/frontend/src/app/(app)/(libraries)/operations/schedule-adjustments/page.js +660 -0
  653. package/hedhog/frontend/src/app/(app)/(libraries)/operations/schedule-adjustments/page.js.map +1 -0
  654. package/hedhog/frontend/src/app/(app)/(libraries)/operations/schedule-adjustments/page.tsx +992 -0
  655. package/hedhog/frontend/src/app/(app)/(libraries)/operations/time-off/page.d.ts +2 -0
  656. package/hedhog/frontend/src/app/(app)/(libraries)/operations/time-off/page.d.ts.map +1 -0
  657. package/hedhog/frontend/src/app/(app)/(libraries)/operations/time-off/page.js +515 -0
  658. package/hedhog/frontend/src/app/(app)/(libraries)/operations/time-off/page.js.map +1 -0
  659. package/hedhog/frontend/src/app/(app)/(libraries)/operations/time-off/page.tsx +707 -0
  660. package/hedhog/frontend/src/app/(app)/(libraries)/operations/timesheets/page.d.ts +2 -0
  661. package/hedhog/frontend/src/app/(app)/(libraries)/operations/timesheets/page.d.ts.map +1 -0
  662. package/hedhog/frontend/src/app/(app)/(libraries)/operations/timesheets/page.js +1141 -0
  663. package/hedhog/frontend/src/app/(app)/(libraries)/operations/timesheets/page.js.map +1 -0
  664. package/hedhog/frontend/src/app/(app)/(libraries)/operations/timesheets/page.tsx +1705 -0
  665. package/hedhog/table/operations_project_assignment.yaml +1 -0
  666. package/hedhog/table/operations_project_cost.yaml +93 -0
  667. package/hedhog/table/operations_project_cost_category.yaml +37 -0
  668. package/hedhog/table/operations_project_cost_type.yaml +55 -0
  669. package/hedhog/table/operations_task_comment.yaml +26 -0
  670. package/package.json +6 -6
  671. package/src/controllers/operations-collaborators.controller.ts +26 -0
  672. package/src/controllers/operations-project-costs.controller.ts +249 -0
  673. package/src/controllers/operations-tasks.controller.ts +49 -0
  674. package/src/dto/create-collaborator-project-assignment.dto.ts +14 -0
  675. package/src/dto/create-project-cost-category.dto.ts +37 -0
  676. package/src/dto/create-project-cost-type.dto.ts +64 -0
  677. package/src/dto/create-project-cost.dto.ts +126 -0
  678. package/src/dto/get-project-cost-report.dto.ts +46 -0
  679. package/src/dto/list-project-cost-categories.dto.ts +17 -0
  680. package/src/dto/list-project-cost-types.dto.ts +28 -0
  681. package/src/dto/list-project-costs.dto.ts +59 -0
  682. package/src/dto/list-tasks.dto.ts +7 -0
  683. package/src/dto/list-timesheets.dto.ts +7 -1
  684. package/src/dto/update-collaborator-project-assignment.dto.ts +58 -0
  685. package/src/dto/update-project-cost-category.dto.ts +4 -0
  686. package/src/dto/update-project-cost-type.dto.ts +4 -0
  687. package/src/dto/update-project-cost.dto.ts +4 -0
  688. package/src/operations.module.ts +2 -0
  689. package/src/operations.service.ts +2274 -39
@@ -0,0 +1,2233 @@
1
+ 'use client';
2
+
3
+ import { PersonFormSheet } from '@/app/(app)/(libraries)/contact/person/_components/person-form-sheet';
4
+ import type {
5
+ ContactTypeOption,
6
+ DocumentTypeOption,
7
+ Person,
8
+ } from '@/app/(app)/(libraries)/contact/person/_components/person-types';
9
+ import { EmptyState, Page } from '@/components/entity-list';
10
+ import {
11
+ Accordion,
12
+ AccordionContent,
13
+ AccordionItem,
14
+ AccordionTrigger,
15
+ } from '@/components/ui/accordion';
16
+ import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar';
17
+ import { Button } from '@/components/ui/button';
18
+ import {
19
+ Command,
20
+ CommandEmpty,
21
+ CommandGroup,
22
+ CommandInput,
23
+ CommandItem,
24
+ CommandList,
25
+ } from '@/components/ui/command';
26
+ import { EntityPicker } from '@/components/ui/entity-picker';
27
+ import { FormActions } from '@/components/ui/form-actions';
28
+ import { Input } from '@/components/ui/input';
29
+ import { InputMoney } from '@/components/ui/input-money';
30
+ import { Label } from '@/components/ui/label';
31
+ import {
32
+ Popover,
33
+ PopoverContent,
34
+ PopoverTrigger,
35
+ } from '@/components/ui/popover';
36
+ import {
37
+ Select,
38
+ SelectContent,
39
+ SelectItem,
40
+ SelectTrigger,
41
+ SelectValue,
42
+ } from '@/components/ui/select';
43
+ import { Switch } from '@/components/ui/switch';
44
+ import { Textarea } from '@/components/ui/textarea';
45
+ import {
46
+ Tooltip,
47
+ TooltipContent,
48
+ TooltipTrigger,
49
+ } from '@/components/ui/tooltip';
50
+ import { useApp, useQuery } from '@hed-hog/next-app-provider';
51
+ import {
52
+ ArrowLeft,
53
+ Check,
54
+ ChevronsUpDown,
55
+ Info,
56
+ Pencil,
57
+ Save,
58
+ UserRound,
59
+ } from 'lucide-react';
60
+ import { useTranslations } from 'next-intl';
61
+ import Link from 'next/link';
62
+ import { useRouter } from 'next/navigation';
63
+ import { useEffect, useMemo, useState } from 'react';
64
+ import {
65
+ fetchOperations,
66
+ getOperationsErrorMessage,
67
+ mutateOperations,
68
+ } from '../_lib/api';
69
+ import { useOperationsAccess } from '../_lib/hooks/use-operations-access';
70
+ import type {
71
+ OperationsCollaborator,
72
+ OperationsCollaboratorDetails,
73
+ OperationsCollaboratorType,
74
+ OperationsContract,
75
+ OperationsDepartment,
76
+ OperationsJobTitle,
77
+ OperationsWeeklyScheduleDay,
78
+ PaginatedResponse,
79
+ } from '../_lib/types';
80
+ import {
81
+ formatDate,
82
+ formatDateRange,
83
+ formatEnumLabel,
84
+ formatHours,
85
+ formatWeekdayLabel,
86
+ getStatusBadgeClass,
87
+ } from '../_lib/utils/format';
88
+ import {
89
+ normalizePercentInput,
90
+ parseNumberInput,
91
+ trimToNull,
92
+ } from '../_lib/utils/forms';
93
+ import { CollaboratorCostsSection } from './collaborator-costs-section';
94
+ import { DepartmentSelectWithCreate } from './department-select-with-create';
95
+ import { OperationsHeader } from './operations-header';
96
+ import { PersonSelectWithCreate } from './person-select-with-create';
97
+ import { StatusBadge } from './status-badge';
98
+ import {
99
+ SystemUserSelectWithCreate,
100
+ type SystemUserOption,
101
+ } from './system-user-select-with-create';
102
+
103
+ const weekdays = [
104
+ 'monday',
105
+ 'tuesday',
106
+ 'wednesday',
107
+ 'thursday',
108
+ 'friday',
109
+ 'saturday',
110
+ 'sunday',
111
+ ] as const;
112
+
113
+ const SUPERVISOR_PAGE_SIZE = 10;
114
+ const COLLABORATOR_LEVEL_OPTIONS = [
115
+ 'junior',
116
+ 'mid',
117
+ 'senior',
118
+ 'coordinator',
119
+ 'manager',
120
+ ] as const;
121
+
122
+ type CollaboratorLevel = (typeof COLLABORATOR_LEVEL_OPTIONS)[number];
123
+
124
+ function normalizeCollaboratorLevel(
125
+ value?: string | null
126
+ ): CollaboratorLevel | '' {
127
+ const normalizedValue = String(value ?? '')
128
+ .trim()
129
+ .toLowerCase()
130
+ .normalize('NFD')
131
+ .replace(/[\u0300-\u036f]/g, '');
132
+
133
+ switch (normalizedValue) {
134
+ case 'junior':
135
+ case 'junior level':
136
+ return 'junior';
137
+ case 'mid':
138
+ case 'middle':
139
+ case 'pleno':
140
+ return 'mid';
141
+ case 'senior':
142
+ return 'senior';
143
+ case 'coordinator':
144
+ case 'coordenador':
145
+ return 'coordinator';
146
+ case 'manager':
147
+ case 'gerente':
148
+ return 'manager';
149
+ default:
150
+ return '';
151
+ }
152
+ }
153
+
154
+ function getPersonAvatarUrl(avatarId?: number | null) {
155
+ return typeof avatarId === 'number' && avatarId > 0
156
+ ? `${process.env.NEXT_PUBLIC_API_BASE_URL}/person/avatar/${avatarId}`
157
+ : '/placeholder.png';
158
+ }
159
+
160
+ function getInitials(value?: string | null) {
161
+ const parts = String(value ?? '')
162
+ .trim()
163
+ .split(/\s+/)
164
+ .filter(Boolean)
165
+ .slice(0, 2);
166
+
167
+ if (!parts.length) {
168
+ return '??';
169
+ }
170
+
171
+ return parts.map((part) => part[0]?.toUpperCase() ?? '').join('');
172
+ }
173
+
174
+ function normalizeTimeValue(value?: string | null, fallback = '') {
175
+ if (!value) {
176
+ return fallback;
177
+ }
178
+
179
+ const directMatch = String(value).match(/(\d{2}:\d{2})(?::\d{2})?/);
180
+
181
+ if (directMatch?.[1]) {
182
+ return directMatch[1];
183
+ }
184
+
185
+ const parsedDate = new Date(value);
186
+
187
+ if (!Number.isNaN(parsedDate.getTime())) {
188
+ return parsedDate.toISOString().slice(11, 16);
189
+ }
190
+
191
+ return fallback || String(value);
192
+ }
193
+
194
+ function normalizeDateInputValue(value?: string | null) {
195
+ if (!value) {
196
+ return '';
197
+ }
198
+
199
+ const normalizedValue = String(value).trim();
200
+
201
+ if (!normalizedValue) {
202
+ return '';
203
+ }
204
+
205
+ const directMatch = normalizedValue.match(/^\d{4}-\d{2}-\d{2}/);
206
+
207
+ if (directMatch?.[0]) {
208
+ return directMatch[0];
209
+ }
210
+
211
+ const parsedDate = new Date(normalizedValue);
212
+
213
+ if (Number.isNaN(parsedDate.getTime())) {
214
+ return normalizedValue;
215
+ }
216
+
217
+ return parsedDate.toISOString().slice(0, 10);
218
+ }
219
+
220
+ const EQUITY_ENABLED_TYPE_SLUGS = new Set([
221
+ 'socio',
222
+ 'acionista',
223
+ 'administrador',
224
+ 'diretor',
225
+ 'conselheiro',
226
+ 'parceiro',
227
+ ]);
228
+
229
+ type CollaboratorFormState = {
230
+ userId: string;
231
+ personId: string;
232
+ displayName: string;
233
+ collaboratorTypeId: string;
234
+ departmentId: string;
235
+ jobTitleId: string;
236
+ title: string;
237
+ levelLabel: string;
238
+ weeklyCapacityHours: string;
239
+ status: string;
240
+ joinedAt: string;
241
+ leftAt: string;
242
+ supervisorCollaboratorId: string;
243
+ compensationAmount: string;
244
+ contractId: string;
245
+ notes: string;
246
+ equityParticipation: {
247
+ participationType: string;
248
+ percentage: string;
249
+ votingPower: string;
250
+ startDate: string;
251
+ endDate: string;
252
+ notes: string;
253
+ };
254
+ weeklySchedule: Array<{
255
+ weekday: string;
256
+ isWorkingDay: boolean;
257
+ startTime: string;
258
+ endTime: string;
259
+ breakMinutes: string;
260
+ }>;
261
+ };
262
+
263
+ function defaultSchedule(): CollaboratorFormState['weeklySchedule'] {
264
+ return weekdays.map((weekday) => ({
265
+ weekday,
266
+ isWorkingDay: !['saturday', 'sunday'].includes(weekday),
267
+ startTime: '09:00',
268
+ endTime: '18:00',
269
+ breakMinutes: '60',
270
+ }));
271
+ }
272
+
273
+ function buildEmptyForm(): CollaboratorFormState {
274
+ return {
275
+ userId: '',
276
+ personId: '',
277
+ displayName: '',
278
+ collaboratorTypeId: '',
279
+ departmentId: '',
280
+ jobTitleId: '',
281
+ title: '',
282
+ levelLabel: '',
283
+ weeklyCapacityHours: '40',
284
+ status: 'active',
285
+ joinedAt: '',
286
+ leftAt: '',
287
+ supervisorCollaboratorId: 'none',
288
+ compensationAmount: '',
289
+ contractId: '',
290
+ notes: '',
291
+ equityParticipation: {
292
+ participationType: 'partner_quota_holder',
293
+ percentage: '',
294
+ votingPower: '',
295
+ startDate: '',
296
+ endDate: '',
297
+ notes: '',
298
+ },
299
+ weeklySchedule: defaultSchedule(),
300
+ };
301
+ }
302
+
303
+ function normalizeSchedule(
304
+ weeklySchedule?: OperationsWeeklyScheduleDay[]
305
+ ): CollaboratorFormState['weeklySchedule'] {
306
+ const byWeekday = new Map(
307
+ (weeklySchedule ?? []).map((item) => [item.weekday, item])
308
+ );
309
+
310
+ return weekdays.map((weekday) => {
311
+ const item = byWeekday.get(weekday);
312
+
313
+ return {
314
+ weekday,
315
+ isWorkingDay:
316
+ item?.isWorkingDay ?? !['saturday', 'sunday'].includes(weekday),
317
+ startTime: normalizeTimeValue(item?.startTime, '09:00'),
318
+ endTime: normalizeTimeValue(item?.endTime, '18:00'),
319
+ breakMinutes:
320
+ item?.breakMinutes !== null && item?.breakMinutes !== undefined
321
+ ? String(item.breakMinutes)
322
+ : '60',
323
+ };
324
+ });
325
+ }
326
+
327
+ function toFormState(
328
+ collaborator: OperationsCollaboratorDetails
329
+ ): CollaboratorFormState {
330
+ return {
331
+ userId: collaborator.userId ? String(collaborator.userId) : '',
332
+ personId: collaborator.personId ? String(collaborator.personId) : '',
333
+ displayName: collaborator.displayName ?? '',
334
+ collaboratorTypeId: collaborator.collaboratorTypeId
335
+ ? String(collaborator.collaboratorTypeId)
336
+ : '',
337
+ departmentId: collaborator.departmentId
338
+ ? String(collaborator.departmentId)
339
+ : '',
340
+ jobTitleId: collaborator.jobTitleId ? String(collaborator.jobTitleId) : '',
341
+ title: collaborator.title ?? '',
342
+ levelLabel: normalizeCollaboratorLevel(collaborator.levelLabel),
343
+ weeklyCapacityHours:
344
+ collaborator.weeklyCapacityHours !== null &&
345
+ collaborator.weeklyCapacityHours !== undefined
346
+ ? String(collaborator.weeklyCapacityHours)
347
+ : '',
348
+ status: collaborator.status ?? 'active',
349
+ joinedAt: normalizeDateInputValue(collaborator.joinedAt),
350
+ leftAt: normalizeDateInputValue(collaborator.leftAt),
351
+ supervisorCollaboratorId: collaborator.supervisorId
352
+ ? String(collaborator.supervisorId)
353
+ : 'none',
354
+ compensationAmount:
355
+ collaborator.compensationAmount !== null &&
356
+ collaborator.compensationAmount !== undefined
357
+ ? String(collaborator.compensationAmount)
358
+ : collaborator.relatedContracts?.[0]?.budgetAmount !== null &&
359
+ collaborator.relatedContracts?.[0]?.budgetAmount !== undefined
360
+ ? String(collaborator.relatedContracts[0].budgetAmount)
361
+ : '',
362
+ contractId: collaborator.relatedContracts?.[0]?.id
363
+ ? String(collaborator.relatedContracts[0].id)
364
+ : '',
365
+ notes: collaborator.notes ?? '',
366
+ equityParticipation: {
367
+ participationType:
368
+ collaborator.equityParticipation?.participationType ??
369
+ 'partner_quota_holder',
370
+ percentage:
371
+ collaborator.equityParticipation?.percentage !== null &&
372
+ collaborator.equityParticipation?.percentage !== undefined
373
+ ? String(collaborator.equityParticipation.percentage)
374
+ : '',
375
+ votingPower:
376
+ collaborator.equityParticipation?.votingPower !== null &&
377
+ collaborator.equityParticipation?.votingPower !== undefined
378
+ ? String(collaborator.equityParticipation.votingPower)
379
+ : '',
380
+ startDate: normalizeDateInputValue(
381
+ collaborator.equityParticipation?.startDate
382
+ ),
383
+ endDate: normalizeDateInputValue(
384
+ collaborator.equityParticipation?.endDate
385
+ ),
386
+ notes: collaborator.equityParticipation?.notes ?? '',
387
+ },
388
+ weeklySchedule: normalizeSchedule(collaborator.weeklySchedule),
389
+ };
390
+ }
391
+
392
+ type SupervisorAutocompleteProps = {
393
+ label: string;
394
+ value: string;
395
+ options: OperationsCollaborator[];
396
+ placeholder: string;
397
+ emptyLabel: string;
398
+ onChange: (value: string) => void;
399
+ };
400
+
401
+ function SupervisorAutocomplete({
402
+ label,
403
+ value,
404
+ options,
405
+ placeholder,
406
+ emptyLabel,
407
+ onChange,
408
+ }: SupervisorAutocompleteProps) {
409
+ const commonT = useTranslations('operations.Common');
410
+ const [open, setOpen] = useState(false);
411
+ const [search, setSearch] = useState('');
412
+ const [visibleCount, setVisibleCount] = useState(SUPERVISOR_PAGE_SIZE);
413
+
414
+ const filteredOptions = useMemo(() => {
415
+ const normalizedSearch = search.trim().toLowerCase();
416
+
417
+ if (!normalizedSearch) {
418
+ return options;
419
+ }
420
+
421
+ return options.filter((option) =>
422
+ [option.displayName, option.code, option.department, option.title]
423
+ .filter(Boolean)
424
+ .some((field) => String(field).toLowerCase().includes(normalizedSearch))
425
+ );
426
+ }, [options, search]);
427
+
428
+ const selectedOption = options.find((option) => String(option.id) === value);
429
+ const visibleOptions = filteredOptions.slice(0, visibleCount);
430
+
431
+ return (
432
+ <div className="grid gap-2">
433
+ <Label>{label}</Label>
434
+
435
+ <Popover
436
+ open={open}
437
+ onOpenChange={(nextOpen) => {
438
+ setOpen(nextOpen);
439
+ setVisibleCount(SUPERVISOR_PAGE_SIZE);
440
+
441
+ if (!nextOpen) {
442
+ setSearch('');
443
+ }
444
+ }}
445
+ >
446
+ <PopoverTrigger asChild>
447
+ <Button
448
+ type="button"
449
+ variant="outline"
450
+ role="combobox"
451
+ className="w-full justify-between overflow-hidden"
452
+ >
453
+ <span className="truncate text-left">
454
+ {selectedOption?.displayName ?? emptyLabel}
455
+ </span>
456
+ <ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
457
+ </Button>
458
+ </PopoverTrigger>
459
+ <PopoverContent
460
+ className="p-0"
461
+ style={{ width: 'var(--radix-popover-trigger-width)' }}
462
+ >
463
+ <Command shouldFilter={false}>
464
+ <CommandInput
465
+ placeholder={placeholder}
466
+ value={search}
467
+ onValueChange={(value) => {
468
+ setSearch(value);
469
+ setVisibleCount(SUPERVISOR_PAGE_SIZE);
470
+ }}
471
+ />
472
+ <CommandList>
473
+ <CommandEmpty>
474
+ <div className="p-2 text-sm text-muted-foreground">
475
+ {commonT('states.emptyDescription')}
476
+ </div>
477
+ </CommandEmpty>
478
+
479
+ <CommandGroup>
480
+ <CommandItem
481
+ value="none"
482
+ onSelect={() => {
483
+ onChange('none');
484
+ setOpen(false);
485
+ }}
486
+ >
487
+ {value === 'none' ? (
488
+ <Check className="mr-2 h-4 w-4" />
489
+ ) : (
490
+ <span className="mr-2 h-4 w-4" />
491
+ )}
492
+ {emptyLabel}
493
+ </CommandItem>
494
+
495
+ {visibleOptions.map((option) => (
496
+ <CommandItem
497
+ key={option.id}
498
+ value={`${option.displayName} ${option.code ?? ''} ${option.department ?? ''} ${option.title ?? ''}`}
499
+ onSelect={() => {
500
+ onChange(String(option.id));
501
+ setOpen(false);
502
+ }}
503
+ >
504
+ {String(option.id) === value ? (
505
+ <Check className="mr-2 h-4 w-4" />
506
+ ) : (
507
+ <span className="mr-2 h-4 w-4" />
508
+ )}
509
+ <div className="min-w-0">
510
+ <div className="truncate">{option.displayName}</div>
511
+ <div className="truncate text-xs text-muted-foreground">
512
+ {[option.code, option.department, option.title]
513
+ .filter(Boolean)
514
+ .join(' • ') || commonT('labels.notAvailable')}
515
+ </div>
516
+ </div>
517
+ </CommandItem>
518
+ ))}
519
+ </CommandGroup>
520
+
521
+ {filteredOptions.length > visibleCount ? (
522
+ <div className="border-t p-2">
523
+ <Button
524
+ type="button"
525
+ variant="ghost"
526
+ className="w-full"
527
+ onClick={() =>
528
+ setVisibleCount(
529
+ (current) => current + SUPERVISOR_PAGE_SIZE
530
+ )
531
+ }
532
+ >
533
+ {commonT('actions.loadMore')}
534
+ </Button>
535
+ </div>
536
+ ) : null}
537
+ </CommandList>
538
+ </Command>
539
+ </PopoverContent>
540
+ </Popover>
541
+ </div>
542
+ );
543
+ }
544
+
545
+ type CollaboratorFormScreenProps = {
546
+ collaboratorId?: number;
547
+ onSaved?: (
548
+ collaborator: OperationsCollaboratorDetails
549
+ ) => void | Promise<void>;
550
+ onCancel?: () => void;
551
+ };
552
+
553
+ export function CollaboratorFormScreen({
554
+ collaboratorId,
555
+ onSaved,
556
+ onCancel,
557
+ }: CollaboratorFormScreenProps) {
558
+ const t = useTranslations('operations.CollaboratorFormPage');
559
+ const commonT = useTranslations('operations.Common');
560
+ const detailsT = useTranslations('operations.CollaboratorDetailsPage');
561
+ const { request, showToastHandler, currentLocaleCode } = useApp();
562
+ const access = useOperationsAccess();
563
+ const router = useRouter();
564
+ const [form, setForm] = useState<CollaboratorFormState>(buildEmptyForm());
565
+ const isSheetMode = Boolean(onCancel);
566
+ const isCreateMode = !collaboratorId;
567
+
568
+ const getStatusLabel = (value?: string | null) => {
569
+ switch (value) {
570
+ case 'active':
571
+ return t('options.statuses.active');
572
+ case 'on_leave':
573
+ return t('options.statuses.on_leave');
574
+ case 'inactive':
575
+ return t('options.statuses.inactive');
576
+ case 'draft':
577
+ return t('options.statuses.draft');
578
+ default:
579
+ return formatEnumLabel(value);
580
+ }
581
+ };
582
+
583
+ const {
584
+ data: collaborator,
585
+ isLoading: isLoadingCollaborator,
586
+ refetch: refetchCollaborator,
587
+ } = useQuery<OperationsCollaboratorDetails>({
588
+ queryKey: [
589
+ 'operations-collaborator-form',
590
+ currentLocaleCode,
591
+ collaboratorId,
592
+ ],
593
+ enabled: Boolean(collaboratorId),
594
+ staleTime: 0,
595
+ refetchOnMount: 'always',
596
+ queryFn: () =>
597
+ fetchOperations<OperationsCollaboratorDetails>(
598
+ request,
599
+ `/operations/collaborators/${collaboratorId}`
600
+ ),
601
+ });
602
+
603
+ const { data: systemUsers = [], refetch: refetchSystemUsers } = useQuery<
604
+ SystemUserOption[]
605
+ >({
606
+ queryKey: ['operations-collaborator-form-system-users', currentLocaleCode],
607
+ enabled: access.isDirector,
608
+ staleTime: 0,
609
+ refetchOnMount: 'always',
610
+ queryFn: async () => {
611
+ const response = await request<{
612
+ paginate: {
613
+ data: Array<{
614
+ id: number;
615
+ name: string | null;
616
+ photo_id?: number | null;
617
+ }>;
618
+ };
619
+ }>({
620
+ url: '/user?pageSize=100',
621
+ method: 'GET',
622
+ });
623
+
624
+ const raw = response.data?.paginate?.data ?? [];
625
+ const options: SystemUserOption[] = raw.map((u) => ({
626
+ id: u.id,
627
+ name: u.name || `#${u.id}`,
628
+ photoId: u.photo_id ?? null,
629
+ }));
630
+
631
+ return options.sort((left, right) => left.name.localeCompare(right.name));
632
+ },
633
+ });
634
+
635
+ const {
636
+ data: collaboratorTypes = [],
637
+ refetch: refetchCollaboratorTypes,
638
+ isLoading: isLoadingCollaboratorTypes,
639
+ } = useQuery<OperationsCollaboratorType[]>({
640
+ queryKey: ['operations-collaborator-types', currentLocaleCode],
641
+ enabled: access.isDirector,
642
+ staleTime: 0,
643
+ refetchOnMount: 'always',
644
+ queryFn: () =>
645
+ fetchOperations<OperationsCollaboratorType[]>(
646
+ request,
647
+ '/operations/collaborator-types?active=true'
648
+ ),
649
+ });
650
+
651
+ const { data: collaborators = [], refetch: refetchCollaborators } = useQuery<
652
+ OperationsCollaborator[]
653
+ >({
654
+ queryKey: ['operations-collaborator-form-supervisors', currentLocaleCode],
655
+ enabled: access.isDirector,
656
+ staleTime: 0,
657
+ refetchOnMount: 'always',
658
+ queryFn: () =>
659
+ fetchOperations<OperationsCollaborator[]>(
660
+ request,
661
+ '/operations/collaborators'
662
+ ),
663
+ });
664
+
665
+ const { data: departments = [], refetch: refetchDepartments } = useQuery<
666
+ OperationsDepartment[]
667
+ >({
668
+ queryKey: ['operations-collaborator-form-departments', currentLocaleCode],
669
+ enabled: access.isDirector,
670
+ staleTime: 0,
671
+ refetchOnMount: 'always',
672
+ queryFn: () =>
673
+ fetchOperations<OperationsDepartment[]>(
674
+ request,
675
+ '/operations/departments'
676
+ ),
677
+ });
678
+
679
+ const { data: jobTitles = [], refetch: refetchJobTitles } = useQuery<
680
+ OperationsJobTitle[]
681
+ >({
682
+ queryKey: ['operations-collaborator-form-job-titles', currentLocaleCode],
683
+ enabled: access.isDirector,
684
+ staleTime: 0,
685
+ refetchOnMount: 'always',
686
+ queryFn: () =>
687
+ fetchOperations<OperationsJobTitle[]>(request, '/operations/job-titles'),
688
+ });
689
+
690
+ const [personSheetOpen, setPersonSheetOpen] = useState(false);
691
+ const [personToEdit, setPersonToEdit] = useState<Person | null>(null);
692
+
693
+ const { data: contactTypes = [] } = useQuery<ContactTypeOption[]>({
694
+ queryKey: ['contact-person-contact-types', currentLocaleCode],
695
+ enabled: personSheetOpen,
696
+ queryFn: async () => {
697
+ const response = await request<{ data: ContactTypeOption[] }>({
698
+ url: '/person-contact-type?pageSize=100',
699
+ method: 'GET',
700
+ });
701
+ return response.data.data || [];
702
+ },
703
+ placeholderData: (previous) => previous ?? [],
704
+ });
705
+
706
+ const { data: documentTypes = [] } = useQuery<DocumentTypeOption[]>({
707
+ queryKey: ['contact-person-document-types', currentLocaleCode],
708
+ enabled: personSheetOpen,
709
+ queryFn: async () => {
710
+ const response = await request<{ data: DocumentTypeOption[] }>({
711
+ url: '/person-document-type?pageSize=100',
712
+ method: 'GET',
713
+ });
714
+ return response.data.data || [];
715
+ },
716
+ placeholderData: (previous) => previous ?? [],
717
+ });
718
+
719
+ const handleOpenPersonSheet = async () => {
720
+ if (!collaborator?.personId) return;
721
+ try {
722
+ const response = await request<Person>({
723
+ url: `/person/${collaborator.personId}`,
724
+ method: 'GET',
725
+ });
726
+ setPersonToEdit(response.data);
727
+ setPersonSheetOpen(true);
728
+ } catch {
729
+ showToastHandler?.('error', t('messages.updateError'));
730
+ }
731
+ };
732
+
733
+ useEffect(() => {
734
+ if (collaborator) {
735
+ // eslint-disable-next-line react-hooks/set-state-in-effect
736
+ setForm(toFormState(collaborator));
737
+ }
738
+ }, [collaborator]);
739
+
740
+ useEffect(() => {
741
+ if (
742
+ collaboratorId ||
743
+ form.collaboratorTypeId ||
744
+ !collaboratorTypes.length
745
+ ) {
746
+ return;
747
+ }
748
+
749
+ const defaultType =
750
+ collaboratorTypes.find((item) => item.slug === 'clt') ??
751
+ collaboratorTypes[0];
752
+
753
+ if (!defaultType) {
754
+ return;
755
+ }
756
+
757
+ // eslint-disable-next-line react-hooks/set-state-in-effect
758
+ setForm((current) => ({
759
+ ...current,
760
+ collaboratorTypeId: String(defaultType.id),
761
+ }));
762
+ }, [collaboratorId, collaboratorTypes, form.collaboratorTypeId]);
763
+
764
+ const selectedCollaboratorType = useMemo(() => {
765
+ const availableTypes = [...collaboratorTypes];
766
+
767
+ if (
768
+ collaborator?.collaboratorTypeId &&
769
+ collaborator.collaboratorType &&
770
+ !availableTypes.some(
771
+ (item) => item.id === collaborator.collaboratorTypeId
772
+ )
773
+ ) {
774
+ availableTypes.push({
775
+ id: collaborator.collaboratorTypeId,
776
+ slug: collaborator.collaboratorTypeSlug ?? '',
777
+ name: collaborator.collaboratorType,
778
+ status: 'active',
779
+ });
780
+ }
781
+
782
+ return (
783
+ availableTypes.find(
784
+ (item) => String(item.id) === String(form.collaboratorTypeId)
785
+ ) ?? null
786
+ );
787
+ }, [collaborator, collaboratorTypes, form.collaboratorTypeId]);
788
+
789
+ const supervisorOptions = useMemo(() => {
790
+ const options = new Map<number, OperationsCollaborator>();
791
+
792
+ for (const item of collaborators) {
793
+ if (item.id !== collaboratorId) {
794
+ options.set(item.id, item);
795
+ }
796
+ }
797
+
798
+ if (
799
+ collaborator?.supervisorId &&
800
+ collaborator.supervisorName &&
801
+ collaborator.supervisorId !== collaboratorId &&
802
+ !options.has(collaborator.supervisorId)
803
+ ) {
804
+ options.set(collaborator.supervisorId, {
805
+ id: collaborator.supervisorId,
806
+ code: '',
807
+ displayName: collaborator.supervisorName,
808
+ department: null,
809
+ title: null,
810
+ status: 'active',
811
+ });
812
+ }
813
+
814
+ return Array.from(options.values()).sort((left, right) =>
815
+ left.displayName.localeCompare(right.displayName)
816
+ );
817
+ }, [collaborator, collaboratorId, collaborators]);
818
+
819
+ const shouldShowEquitySection =
820
+ !isCreateMode &&
821
+ Boolean(
822
+ selectedCollaboratorType?.slug &&
823
+ EQUITY_ENABLED_TYPE_SLUGS.has(selectedCollaboratorType.slug)
824
+ );
825
+
826
+ const getCollaboratorTypeLabel = (
827
+ value?: string | null,
828
+ fallbackName?: string | null
829
+ ) => {
830
+ const normalizedValue = String(value ?? '').trim();
831
+
832
+ if (fallbackName) {
833
+ return fallbackName;
834
+ }
835
+
836
+ const matchedType = collaboratorTypes.find(
837
+ (item) =>
838
+ item.slug === normalizedValue || String(item.id) === normalizedValue
839
+ );
840
+
841
+ if (matchedType?.name) {
842
+ return matchedType.name;
843
+ }
844
+
845
+ return formatEnumLabel(normalizedValue);
846
+ };
847
+
848
+ const departmentOptions = useMemo(() => {
849
+ return departments
850
+ .filter((item) => item.status === 'active')
851
+ .map((item) => ({
852
+ id: item.id,
853
+ name: item.name,
854
+ code: item.code ?? null,
855
+ description: item.description ?? null,
856
+ }))
857
+ .sort((left, right) => left.name.localeCompare(right.name));
858
+ }, [departments]);
859
+
860
+ const titleOptions = useMemo(() => {
861
+ const selectedTitle = trimToNull(form.title);
862
+ const options: Array<{
863
+ id?: number | null;
864
+ name: string;
865
+ code?: string | null;
866
+ description?: string | null;
867
+ }> = jobTitles
868
+ .filter((item) => item.status === 'active' || item.name === selectedTitle)
869
+ .map((item) => ({
870
+ id: item.id,
871
+ name: item.name,
872
+ code: item.code ?? null,
873
+ description: item.description ?? null,
874
+ }));
875
+
876
+ if (selectedTitle) {
877
+ const alreadyIncluded = options.some(
878
+ (item) => item.name === selectedTitle
879
+ );
880
+
881
+ if (!alreadyIncluded) {
882
+ options.push({
883
+ id: form.jobTitleId ? Number(form.jobTitleId) : undefined,
884
+ name: selectedTitle,
885
+ code: null,
886
+ description: null,
887
+ });
888
+ }
889
+ }
890
+
891
+ return options.sort((left, right) => left.name.localeCompare(right.name));
892
+ }, [jobTitles, form.title, form.jobTitleId]);
893
+
894
+ const createJobTitle = async (jobTitleName: string) => {
895
+ try {
896
+ const createdJobTitle = await mutateOperations<OperationsJobTitle>(
897
+ request,
898
+ '/operations/job-titles',
899
+ 'POST',
900
+ {
901
+ name: jobTitleName,
902
+ }
903
+ );
904
+
905
+ await refetchJobTitles();
906
+
907
+ return {
908
+ id: createdJobTitle.id,
909
+ name: createdJobTitle.name,
910
+ code: createdJobTitle.code ?? null,
911
+ description: createdJobTitle.description ?? null,
912
+ };
913
+ } catch (error) {
914
+ showToastHandler?.(
915
+ 'error',
916
+ getOperationsErrorMessage(error, 'Unable to create the job title.')
917
+ );
918
+ return null;
919
+ }
920
+ };
921
+
922
+ const createSystemUser = async (
923
+ name: string,
924
+ email: string,
925
+ password: string
926
+ ): Promise<SystemUserOption | null> => {
927
+ try {
928
+ const response = await request<{ id: number; name: string }>({
929
+ url: '/user',
930
+ method: 'POST',
931
+ data: { name, email, password },
932
+ });
933
+ await refetchSystemUsers();
934
+ showToastHandler?.('success', t('messages.createUserSuccess'));
935
+ return { id: response.data.id, name: response.data.name };
936
+ } catch (error) {
937
+ showToastHandler?.(
938
+ 'error',
939
+ getOperationsErrorMessage(error, t('messages.createUserError'))
940
+ );
941
+ return null;
942
+ }
943
+ };
944
+
945
+ const updateScheduleDay = (
946
+ weekday: string,
947
+ patch: Partial<CollaboratorFormState['weeklySchedule'][number]>
948
+ ) => {
949
+ setForm((current) => ({
950
+ ...current,
951
+ weeklySchedule: current.weeklySchedule.map((day) => {
952
+ if (day.weekday !== weekday) {
953
+ return day;
954
+ }
955
+
956
+ const nextIsWorkingDay = patch.isWorkingDay ?? day.isWorkingDay;
957
+
958
+ return {
959
+ ...day,
960
+ ...patch,
961
+ startTime:
962
+ patch.startTime !== undefined
963
+ ? normalizeTimeValue(patch.startTime)
964
+ : nextIsWorkingDay
965
+ ? normalizeTimeValue(day.startTime, '09:00')
966
+ : normalizeTimeValue(day.startTime),
967
+ endTime:
968
+ patch.endTime !== undefined
969
+ ? normalizeTimeValue(patch.endTime)
970
+ : nextIsWorkingDay
971
+ ? normalizeTimeValue(day.endTime, '18:00')
972
+ : normalizeTimeValue(day.endTime),
973
+ };
974
+ }),
975
+ }));
976
+ };
977
+
978
+ const onSubmit = async () => {
979
+ const userId = parseNumberInput(form.userId);
980
+ const personId = parseNumberInput(form.personId);
981
+ const compensationAmount = parseNumberInput(form.compensationAmount);
982
+
983
+ if (!personId) {
984
+ showToastHandler?.('error', t('messages.personRequired'));
985
+ return;
986
+ }
987
+
988
+ const departmentId = parseNumberInput(form.departmentId);
989
+ const jobTitleId = parseNumberInput(form.jobTitleId);
990
+ const collaboratorTypeId = parseNumberInput(form.collaboratorTypeId);
991
+
992
+ if (!collaboratorTypeId) {
993
+ showToastHandler?.('error', t('messages.collaboratorTypeRequired'));
994
+ return;
995
+ }
996
+
997
+ const payload = {
998
+ userId: userId ?? undefined,
999
+ personId: personId ?? undefined,
1000
+ displayName: trimToNull(form.displayName),
1001
+ collaboratorTypeId,
1002
+ departmentId: departmentId ?? undefined,
1003
+ jobTitleId: jobTitleId ?? undefined,
1004
+ title: trimToNull(form.title),
1005
+ levelLabel: trimToNull(form.levelLabel),
1006
+ weeklyCapacityHours: parseNumberInput(form.weeklyCapacityHours),
1007
+ status: form.status,
1008
+ joinedAt: trimToNull(form.joinedAt),
1009
+ leftAt: trimToNull(form.leftAt),
1010
+ supervisorCollaboratorId:
1011
+ form.supervisorCollaboratorId === 'none'
1012
+ ? null
1013
+ : parseNumberInput(form.supervisorCollaboratorId),
1014
+ compensationAmount:
1015
+ compensationAmount !== null ? compensationAmount : null,
1016
+ contractId: parseNumberInput(form.contractId),
1017
+ notes: trimToNull(form.notes),
1018
+ equityParticipation: shouldShowEquitySection
1019
+ ? {
1020
+ participationType: form.equityParticipation.participationType,
1021
+ percentage: parseNumberInput(form.equityParticipation.percentage),
1022
+ votingPower: parseNumberInput(form.equityParticipation.votingPower),
1023
+ startDate: trimToNull(form.equityParticipation.startDate),
1024
+ endDate: trimToNull(form.equityParticipation.endDate),
1025
+ notes: trimToNull(form.equityParticipation.notes),
1026
+ }
1027
+ : null,
1028
+ weeklySchedule: form.weeklySchedule.map((day) => ({
1029
+ weekday: day.weekday,
1030
+ isWorkingDay: day.isWorkingDay,
1031
+ startTime: day.isWorkingDay
1032
+ ? trimToNull(normalizeTimeValue(day.startTime, '09:00'))
1033
+ : null,
1034
+ endTime: day.isWorkingDay
1035
+ ? trimToNull(normalizeTimeValue(day.endTime, '18:00'))
1036
+ : null,
1037
+ breakMinutes: day.isWorkingDay ? parseNumberInput(day.breakMinutes) : 0,
1038
+ })),
1039
+ };
1040
+
1041
+ try {
1042
+ const response = collaboratorId
1043
+ ? await mutateOperations<OperationsCollaboratorDetails>(
1044
+ request,
1045
+ `/operations/collaborators/${collaboratorId}`,
1046
+ 'PATCH',
1047
+ payload
1048
+ )
1049
+ : await mutateOperations<OperationsCollaboratorDetails>(
1050
+ request,
1051
+ '/operations/collaborators',
1052
+ 'POST',
1053
+ payload
1054
+ );
1055
+
1056
+ setForm(toFormState(response));
1057
+
1058
+ await Promise.all([
1059
+ collaboratorId ? refetchCollaborator() : Promise.resolve(),
1060
+ refetchCollaboratorTypes(),
1061
+ refetchDepartments(),
1062
+ refetchCollaborators(),
1063
+ refetchJobTitles(),
1064
+ ]);
1065
+
1066
+ showToastHandler?.(
1067
+ 'success',
1068
+ collaboratorId
1069
+ ? t('messages.updateSuccess')
1070
+ : t('messages.createSuccess')
1071
+ );
1072
+
1073
+ if (onSaved) {
1074
+ await onSaved(response);
1075
+ return;
1076
+ }
1077
+
1078
+ router.push(`/operations/collaborators/${response.id}`);
1079
+ } catch (error) {
1080
+ showToastHandler?.(
1081
+ 'error',
1082
+ getOperationsErrorMessage(
1083
+ error,
1084
+ collaboratorId ? t('messages.updateError') : t('messages.createError')
1085
+ )
1086
+ );
1087
+ }
1088
+ };
1089
+
1090
+ const noAccessState = (
1091
+ <EmptyState
1092
+ icon={<UserRound className="size-12" />}
1093
+ title={commonT('states.noAccessTitle')}
1094
+ description={t('noAccessDescription')}
1095
+ actionLabel={commonT('actions.refresh')}
1096
+ onAction={() => router.refresh()}
1097
+ />
1098
+ );
1099
+
1100
+ const collaboratorSummary =
1101
+ collaborator && isSheetMode ? (
1102
+ <div className="mx-4 rounded-xl border bg-muted/30 px-4 py-3">
1103
+ <div className="flex flex-col gap-3 lg:flex-row lg:items-start lg:justify-between">
1104
+ <div className="flex min-w-0 items-center gap-3">
1105
+ <Avatar className="h-12 w-12 border border-border/60 bg-background">
1106
+ <AvatarImage
1107
+ src={getPersonAvatarUrl(collaborator.personAvatarId)}
1108
+ alt={collaborator.displayName}
1109
+ />
1110
+ <AvatarFallback className="bg-muted text-sm font-semibold text-foreground">
1111
+ {getInitials(collaborator.displayName)}
1112
+ </AvatarFallback>
1113
+ </Avatar>
1114
+ <div className="min-w-0">
1115
+ <div className="truncate text-base font-semibold">
1116
+ {collaborator.displayName}
1117
+ </div>
1118
+ <div className="truncate text-xs text-muted-foreground">
1119
+ {[
1120
+ collaborator.code,
1121
+ collaborator.department,
1122
+ collaborator.title,
1123
+ ]
1124
+ .filter(Boolean)
1125
+ .join(' • ') || commonT('labels.notAvailable')}
1126
+ </div>
1127
+ </div>
1128
+ </div>
1129
+
1130
+ <div className="flex flex-wrap items-center gap-2">
1131
+ <StatusBadge
1132
+ label={getStatusLabel(collaborator.status)}
1133
+ className={getStatusBadgeClass(collaborator.status)}
1134
+ />
1135
+ <span className="inline-flex items-center rounded-full bg-primary/10 px-2.5 py-1 text-xs font-medium text-primary">
1136
+ {getCollaboratorTypeLabel(
1137
+ collaborator.collaboratorTypeSlug ??
1138
+ collaborator.collaboratorType,
1139
+ collaborator.collaboratorTypeName
1140
+ )}
1141
+ </span>
1142
+ {collaborator.personId ? (
1143
+ <Tooltip>
1144
+ <TooltipTrigger asChild>
1145
+ <Button
1146
+ variant="outline"
1147
+ size="icon"
1148
+ className="h-7 w-7"
1149
+ onClick={() => void handleOpenPersonSheet()}
1150
+ >
1151
+ <Pencil className="size-3.5" />
1152
+ </Button>
1153
+ </TooltipTrigger>
1154
+ <TooltipContent side="bottom">
1155
+ {t('actions.editPersonCrm')}
1156
+ </TooltipContent>
1157
+ </Tooltip>
1158
+ ) : null}
1159
+ </div>
1160
+ </div>
1161
+
1162
+ <div className="mt-3 grid gap-2 text-sm md:grid-cols-2 xl:grid-cols-4">
1163
+ <div>
1164
+ <div className="text-[11px] uppercase tracking-wide text-muted-foreground">
1165
+ {commonT('labels.supervisor')}
1166
+ </div>
1167
+ <div className="font-medium">
1168
+ {collaborator.supervisorName || commonT('labels.notAssigned')}
1169
+ </div>
1170
+ </div>
1171
+ <div>
1172
+ <div className="text-[11px] uppercase tracking-wide text-muted-foreground">
1173
+ {commonT('labels.weeklyCapacity')}
1174
+ </div>
1175
+ <div className="font-medium">
1176
+ {formatHours(collaborator.weeklyCapacityHours)}
1177
+ </div>
1178
+ </div>
1179
+ <div>
1180
+ <div className="text-[11px] uppercase tracking-wide text-muted-foreground">
1181
+ {commonT('labels.startDate')}
1182
+ </div>
1183
+ <div className="font-medium">
1184
+ {formatDate(collaborator.joinedAt)}
1185
+ </div>
1186
+ </div>
1187
+ <div>
1188
+ <div className="text-[11px] uppercase tracking-wide text-muted-foreground">
1189
+ {commonT('labels.projectCount')}
1190
+ </div>
1191
+ <div className="font-medium">
1192
+ {collaborator.assignedProjects.length}
1193
+ </div>
1194
+ </div>
1195
+ </div>
1196
+ </div>
1197
+ ) : null;
1198
+
1199
+ if (!access.isDirector && !access.isLoading) {
1200
+ if (isSheetMode) {
1201
+ return <div className="pt-4">{noAccessState}</div>;
1202
+ }
1203
+
1204
+ return (
1205
+ <Page>
1206
+ <OperationsHeader
1207
+ title={t(collaboratorId ? 'editTitle' : 'newTitle')}
1208
+ description={t('description')}
1209
+ current={t('breadcrumb')}
1210
+ />
1211
+ {noAccessState}
1212
+ </Page>
1213
+ );
1214
+ }
1215
+
1216
+ const basicInfoSection = (
1217
+ <div className="space-y-2">
1218
+ <div className="space-y-0.5">
1219
+ <h3 className="text-xs font-semibold uppercase tracking-wide text-muted-foreground">
1220
+ {t('sections.basicInfo')}
1221
+ </h3>
1222
+ <p className="text-[11px] text-muted-foreground/80">
1223
+ {t('sections.basicInfoDescription')}
1224
+ </p>
1225
+ </div>
1226
+ <div className="grid gap-3 md:grid-cols-2 xl:grid-cols-4">
1227
+ <div className="space-y-2 md:col-span-2">
1228
+ <PersonSelectWithCreate
1229
+ label={t('fields.person')}
1230
+ entityLabel={t('fields.personEntityLabel')}
1231
+ value={form.personId ? Number(form.personId) : null}
1232
+ initialSelectedLabel={collaborator?.personName ?? form.displayName}
1233
+ selectPlaceholder={t('placeholders.person')}
1234
+ onChange={(personId, personName) =>
1235
+ setForm((current) => ({
1236
+ ...current,
1237
+ personId: personId ? String(personId) : '',
1238
+ displayName: personName,
1239
+ }))
1240
+ }
1241
+ />
1242
+ </div>
1243
+ <div className="space-y-2 md:col-span-2 xl:col-span-2">
1244
+ <SystemUserSelectWithCreate
1245
+ label={t('fields.userIdOptional')}
1246
+ value={form.userId}
1247
+ options={systemUsers}
1248
+ placeholder={t('placeholders.userIdOptional')}
1249
+ emptyLabel={commonT('labels.notAssigned')}
1250
+ onChange={(value) =>
1251
+ setForm((current) => ({
1252
+ ...current,
1253
+ userId: value,
1254
+ }))
1255
+ }
1256
+ onCreate={createSystemUser}
1257
+ />
1258
+ <p className="text-xs text-muted-foreground">
1259
+ {t('fields.userIdDescription')}
1260
+ </p>
1261
+ </div>
1262
+
1263
+ {!isCreateMode ? (
1264
+ <div className="space-y-2">
1265
+ <Label>{t('fields.levelLabel')}</Label>
1266
+ <Select
1267
+ value={form.levelLabel}
1268
+ onValueChange={(value) =>
1269
+ setForm((current) => ({
1270
+ ...current,
1271
+ levelLabel: value,
1272
+ }))
1273
+ }
1274
+ >
1275
+ <SelectTrigger className="w-full">
1276
+ <SelectValue placeholder={t('placeholders.levelLabel')} />
1277
+ </SelectTrigger>
1278
+ <SelectContent>
1279
+ {COLLABORATOR_LEVEL_OPTIONS.map((level) => (
1280
+ <SelectItem key={level} value={level}>
1281
+ {t(`options.levels.${level}`)}
1282
+ </SelectItem>
1283
+ ))}
1284
+ </SelectContent>
1285
+ </Select>
1286
+ </div>
1287
+ ) : null}
1288
+ <div className="space-y-2 xl:col-span-1">
1289
+ <DepartmentSelectWithCreate
1290
+ label={t('fields.department')}
1291
+ value={
1292
+ departmentOptions.find((d) => String(d.id) === form.departmentId)
1293
+ ?.name ?? ''
1294
+ }
1295
+ options={departmentOptions}
1296
+ selectPlaceholder={t('placeholders.department')}
1297
+ createDescription={t('fields.departmentDescription')}
1298
+ createPlaceholder={t('placeholders.departmentCreate')}
1299
+ onChange={(department) =>
1300
+ setForm((current) => ({
1301
+ ...current,
1302
+ departmentId: department.id ? String(department.id) : '',
1303
+ }))
1304
+ }
1305
+ />
1306
+ </div>
1307
+ <div className="space-y-2 xl:col-span-1">
1308
+ <DepartmentSelectWithCreate
1309
+ label={t('fields.title')}
1310
+ value={form.title}
1311
+ options={titleOptions}
1312
+ onCreate={createJobTitle}
1313
+ selectPlaceholder={t('placeholders.title')}
1314
+ createDescription={t('fields.titleDescription')}
1315
+ createPlaceholder={t('placeholders.titleCreate')}
1316
+ onChange={(titleOption) =>
1317
+ setForm((current) => ({
1318
+ ...current,
1319
+ jobTitleId: titleOption.id ? String(titleOption.id) : '',
1320
+ title: titleOption.name,
1321
+ }))
1322
+ }
1323
+ />
1324
+ </div>
1325
+ <div className="space-y-2 xl:col-span-1">
1326
+ <label className="text-sm font-medium">{t('fields.contract')}</label>
1327
+ <EntityPicker<OperationsContract>
1328
+ value={form.contractId ? Number(form.contractId) : null}
1329
+ onChange={(v) =>
1330
+ setForm((current) => ({
1331
+ ...current,
1332
+ contractId: v ? String(v) : '',
1333
+ }))
1334
+ }
1335
+ placeholder={t('fields.contractPlaceholder')}
1336
+ emptyLabel={t('fields.contractEmpty')}
1337
+ initialSelectedLabel={
1338
+ form.contractId
1339
+ ? (collaborator?.relatedContracts.find(
1340
+ (c) => String(c.id) === form.contractId
1341
+ )?.name ??
1342
+ collaborator?.relatedContracts.find(
1343
+ (c) => String(c.id) === form.contractId
1344
+ )?.code ??
1345
+ undefined)
1346
+ : undefined
1347
+ }
1348
+ clearable
1349
+ showCreateButton
1350
+ createTitle={t('fields.contractCreateTitle')}
1351
+ createDescription={t('fields.contractCreateDescription')}
1352
+ createFields={[
1353
+ {
1354
+ name: 'name',
1355
+ label: t('fields.contractNameField'),
1356
+ placeholder: t('fields.contractNameField'),
1357
+ required: true,
1358
+ },
1359
+ ]}
1360
+ loadOptions={async ({ page, pageSize, search }) => {
1361
+ const params = new URLSearchParams({
1362
+ page: String(page),
1363
+ pageSize: String(pageSize),
1364
+ });
1365
+ if (search.trim()) params.set('search', search.trim());
1366
+ const res = await fetchOperations<
1367
+ PaginatedResponse<OperationsContract>
1368
+ >(request, `/operations/contracts?${params.toString()}`);
1369
+ return {
1370
+ items: res.data ?? [],
1371
+ hasMore: res.page < res.lastPage,
1372
+ };
1373
+ }}
1374
+ getOptionValue={(c) => c.id}
1375
+ getOptionLabel={(c) => (c.name || c.code) as string}
1376
+ getOptionDescription={(c) =>
1377
+ [c.code, c.status].filter(Boolean).join(' • ') || undefined
1378
+ }
1379
+ onCreate={async (values) => {
1380
+ return mutateOperations<OperationsContract>(
1381
+ request,
1382
+ '/operations/contracts',
1383
+ 'POST',
1384
+ {
1385
+ name: values.name,
1386
+ billingModel: 'time_and_material',
1387
+ }
1388
+ );
1389
+ }}
1390
+ />
1391
+ </div>
1392
+ </div>
1393
+ </div>
1394
+ );
1395
+
1396
+ const employmentInfoSection = (
1397
+ <div className="space-y-2">
1398
+ <div className="space-y-0.5">
1399
+ <h3 className="text-xs font-semibold uppercase tracking-wide text-muted-foreground">
1400
+ {t('sections.employmentInfo')}
1401
+ </h3>
1402
+ <p className="text-[11px] text-muted-foreground/80">
1403
+ {isCreateMode
1404
+ ? t('sections.employmentInfoCreateDescription')
1405
+ : t('sections.employmentInfoDescription')}
1406
+ </p>
1407
+ </div>
1408
+ <div className="grid gap-3 md:grid-cols-2 xl:grid-cols-4">
1409
+ <div className="space-y-2 xl:col-span-1">
1410
+ <label className="text-sm font-medium">
1411
+ {t('fields.collaboratorType')}
1412
+ </label>
1413
+
1414
+ <Select
1415
+ value={form.collaboratorTypeId}
1416
+ onValueChange={(value) =>
1417
+ setForm((current) => ({
1418
+ ...current,
1419
+ collaboratorTypeId: value,
1420
+ }))
1421
+ }
1422
+ >
1423
+ <SelectTrigger className="w-full">
1424
+ <SelectValue
1425
+ placeholder={
1426
+ isLoadingCollaboratorTypes
1427
+ ? t('states.loadingCollaboratorTypes')
1428
+ : t('placeholders.collaboratorType')
1429
+ }
1430
+ />
1431
+ </SelectTrigger>
1432
+ <SelectContent>
1433
+ {collaboratorTypes.map((collaboratorType) => (
1434
+ <SelectItem
1435
+ key={collaboratorType.id}
1436
+ value={String(collaboratorType.id)}
1437
+ >
1438
+ {collaboratorType.name}
1439
+ </SelectItem>
1440
+ ))}
1441
+ </SelectContent>
1442
+ </Select>
1443
+ </div>
1444
+ <div className="space-y-2">
1445
+ <label className="text-sm font-medium">
1446
+ {commonT('labels.status')}
1447
+ </label>
1448
+ <Select
1449
+ value={form.status}
1450
+ onValueChange={(value) =>
1451
+ setForm((current) => ({ ...current, status: value }))
1452
+ }
1453
+ >
1454
+ <SelectTrigger className="w-full">
1455
+ <SelectValue />
1456
+ </SelectTrigger>
1457
+ <SelectContent>
1458
+ <SelectItem value="active">
1459
+ {t('options.statuses.active')}
1460
+ </SelectItem>
1461
+ <SelectItem value="on_leave">
1462
+ {t('options.statuses.on_leave')}
1463
+ </SelectItem>
1464
+ <SelectItem value="inactive">
1465
+ {t('options.statuses.inactive')}
1466
+ </SelectItem>
1467
+ <SelectItem value="draft">
1468
+ {t('options.statuses.draft')}
1469
+ </SelectItem>
1470
+ </SelectContent>
1471
+ </Select>
1472
+ </div>
1473
+ <div className="space-y-2">
1474
+ <label className="text-sm font-medium">
1475
+ {commonT('labels.startDate')}
1476
+ </label>
1477
+ <Input
1478
+ type="date"
1479
+ value={form.joinedAt}
1480
+ onChange={(event) =>
1481
+ setForm((current) => ({
1482
+ ...current,
1483
+ joinedAt: event.target.value,
1484
+ }))
1485
+ }
1486
+ />
1487
+ </div>
1488
+ <div className="space-y-2">
1489
+ <label className="text-sm font-medium">
1490
+ {commonT('labels.endDate')}
1491
+ </label>
1492
+ <Input
1493
+ type="date"
1494
+ value={form.leftAt}
1495
+ onChange={(event) =>
1496
+ setForm((current) => ({
1497
+ ...current,
1498
+ leftAt: event.target.value,
1499
+ }))
1500
+ }
1501
+ />
1502
+ </div>
1503
+ {isCreateMode ? (
1504
+ <>
1505
+ <div className="space-y-2">
1506
+ <label className="text-sm font-medium">
1507
+ {t('fields.weeklyCapacityHours')}
1508
+ </label>
1509
+ <Input
1510
+ type="number"
1511
+ step="0.5"
1512
+ value={form.weeklyCapacityHours}
1513
+ onChange={(event) =>
1514
+ setForm((current) => ({
1515
+ ...current,
1516
+ weeklyCapacityHours: event.target.value,
1517
+ }))
1518
+ }
1519
+ />
1520
+ </div>
1521
+ <div className="space-y-2">
1522
+ <label className="text-sm font-medium">
1523
+ {t('fields.compensationAmount')}
1524
+ </label>
1525
+ <InputMoney
1526
+ step="0.01"
1527
+ value={
1528
+ form.compensationAmount === ''
1529
+ ? ''
1530
+ : Number(form.compensationAmount)
1531
+ }
1532
+ onValueChange={(value) =>
1533
+ setForm((current) => ({
1534
+ ...current,
1535
+ compensationAmount: value !== null ? String(value) : '',
1536
+ }))
1537
+ }
1538
+ />
1539
+ </div>
1540
+ </>
1541
+ ) : null}
1542
+ </div>
1543
+ </div>
1544
+ );
1545
+
1546
+ const equitySection = shouldShowEquitySection ? (
1547
+ <div className="space-y-2">
1548
+ <div className="space-y-0.5">
1549
+ <h3 className="text-xs font-semibold uppercase tracking-wide text-muted-foreground">
1550
+ {t('sections.equity')}
1551
+ </h3>
1552
+ <p className="text-[11px] text-muted-foreground/80">
1553
+ {t('sections.equityDescription')}
1554
+ </p>
1555
+ </div>
1556
+ <div className="grid gap-3 md:grid-cols-2 xl:grid-cols-4">
1557
+ <div className="space-y-2 xl:col-span-2">
1558
+ <label className="text-sm font-medium">
1559
+ {t('fields.equityParticipationType')}
1560
+ </label>
1561
+ <Select
1562
+ value={form.equityParticipation.participationType}
1563
+ onValueChange={(value) =>
1564
+ setForm((current) => ({
1565
+ ...current,
1566
+ equityParticipation: {
1567
+ ...current.equityParticipation,
1568
+ participationType: value,
1569
+ },
1570
+ }))
1571
+ }
1572
+ >
1573
+ <SelectTrigger className="w-full">
1574
+ <SelectValue />
1575
+ </SelectTrigger>
1576
+ <SelectContent>
1577
+ <SelectItem value="partner_quota_holder">
1578
+ {t('options.equityParticipationTypes.partner_quota_holder')}
1579
+ </SelectItem>
1580
+ <SelectItem value="common_shareholder">
1581
+ {t('options.equityParticipationTypes.common_shareholder')}
1582
+ </SelectItem>
1583
+ <SelectItem value="preferred_shareholder">
1584
+ {t('options.equityParticipationTypes.preferred_shareholder')}
1585
+ </SelectItem>
1586
+ <SelectItem value="administrator">
1587
+ {t('options.equityParticipationTypes.administrator')}
1588
+ </SelectItem>
1589
+ <SelectItem value="other">
1590
+ {t('options.equityParticipationTypes.other')}
1591
+ </SelectItem>
1592
+ </SelectContent>
1593
+ </Select>
1594
+ </div>
1595
+ <div className="space-y-2">
1596
+ <Label>{t('fields.equityPercentage')}</Label>
1597
+ <Input
1598
+ type="text"
1599
+ inputMode="decimal"
1600
+ placeholder={t('placeholders.equityPercentage')}
1601
+ value={form.equityParticipation.percentage}
1602
+ onChange={(event) =>
1603
+ setForm((current) => ({
1604
+ ...current,
1605
+ equityParticipation: {
1606
+ ...current.equityParticipation,
1607
+ percentage: normalizePercentInput(event.target.value),
1608
+ },
1609
+ }))
1610
+ }
1611
+ />
1612
+ </div>
1613
+ <div className="space-y-2">
1614
+ <Label>{t('fields.votingPower')}</Label>
1615
+ <Input
1616
+ type="text"
1617
+ inputMode="decimal"
1618
+ placeholder={t('placeholders.votingPower')}
1619
+ value={form.equityParticipation.votingPower}
1620
+ onChange={(event) =>
1621
+ setForm((current) => ({
1622
+ ...current,
1623
+ equityParticipation: {
1624
+ ...current.equityParticipation,
1625
+ votingPower: normalizePercentInput(event.target.value),
1626
+ },
1627
+ }))
1628
+ }
1629
+ />
1630
+ </div>
1631
+ <div className="space-y-2">
1632
+ <Label>{commonT('labels.startDate')}</Label>
1633
+ <Input
1634
+ type="date"
1635
+ value={form.equityParticipation.startDate}
1636
+ onChange={(event) =>
1637
+ setForm((current) => ({
1638
+ ...current,
1639
+ equityParticipation: {
1640
+ ...current.equityParticipation,
1641
+ startDate: event.target.value,
1642
+ },
1643
+ }))
1644
+ }
1645
+ />
1646
+ </div>
1647
+ <div className="space-y-2">
1648
+ <Label>{commonT('labels.endDate')}</Label>
1649
+ <Input
1650
+ type="date"
1651
+ value={form.equityParticipation.endDate}
1652
+ onChange={(event) =>
1653
+ setForm((current) => ({
1654
+ ...current,
1655
+ equityParticipation: {
1656
+ ...current.equityParticipation,
1657
+ endDate: event.target.value,
1658
+ },
1659
+ }))
1660
+ }
1661
+ />
1662
+ </div>
1663
+ <div className="space-y-2 md:col-span-2 xl:col-span-4">
1664
+ <Label>{t('fields.equityNotes')}</Label>
1665
+ <Textarea
1666
+ rows={4}
1667
+ placeholder={t('placeholders.equityNotes')}
1668
+ value={form.equityParticipation.notes}
1669
+ onChange={(event) =>
1670
+ setForm((current) => ({
1671
+ ...current,
1672
+ equityParticipation: {
1673
+ ...current.equityParticipation,
1674
+ notes: event.target.value,
1675
+ },
1676
+ }))
1677
+ }
1678
+ />
1679
+ </div>
1680
+ </div>
1681
+ </div>
1682
+ ) : null;
1683
+
1684
+ const supervisorSection = (
1685
+ <div className="space-y-2">
1686
+ <div className="space-y-0.5">
1687
+ <h3 className="text-xs font-semibold uppercase tracking-wide text-muted-foreground">
1688
+ {t('sections.supervisor')}
1689
+ </h3>
1690
+ <p className="text-[11px] text-muted-foreground/80">
1691
+ {t('sections.supervisorDescription')}
1692
+ </p>
1693
+ </div>
1694
+ <SupervisorAutocomplete
1695
+ label={commonT('labels.supervisor')}
1696
+ value={form.supervisorCollaboratorId}
1697
+ options={supervisorOptions}
1698
+ placeholder={t('placeholders.supervisor')}
1699
+ emptyLabel={commonT('labels.notAssigned')}
1700
+ onChange={(value) =>
1701
+ setForm((current) => ({
1702
+ ...current,
1703
+ supervisorCollaboratorId: value,
1704
+ }))
1705
+ }
1706
+ />
1707
+ </div>
1708
+ );
1709
+
1710
+ const contractSection = (
1711
+ <div className="space-y-2">
1712
+ <div className="space-y-0.5">
1713
+ <h3 className="text-xs font-semibold uppercase tracking-wide text-muted-foreground">
1714
+ {t('sections.contract')}
1715
+ </h3>
1716
+ <p className="text-[11px] text-muted-foreground/80">
1717
+ {t('sections.contractDescription')}
1718
+ </p>
1719
+ </div>
1720
+ <div className="grid gap-3 md:grid-cols-3">
1721
+ <div className="space-y-2">
1722
+ <label className="text-sm font-medium">
1723
+ {t('fields.weeklyCapacityHours')}
1724
+ </label>
1725
+ <Input
1726
+ type="number"
1727
+ step="0.5"
1728
+ value={form.weeklyCapacityHours}
1729
+ onChange={(event) =>
1730
+ setForm((current) => ({
1731
+ ...current,
1732
+ weeklyCapacityHours: event.target.value,
1733
+ }))
1734
+ }
1735
+ />
1736
+ </div>
1737
+ <div className="space-y-2">
1738
+ <label className="text-sm font-medium">
1739
+ {t('fields.compensationAmount')}
1740
+ </label>
1741
+ <InputMoney
1742
+ step="0.01"
1743
+ value={
1744
+ form.compensationAmount === ''
1745
+ ? ''
1746
+ : Number(form.compensationAmount)
1747
+ }
1748
+ onValueChange={(value) =>
1749
+ setForm((current) => ({
1750
+ ...current,
1751
+ compensationAmount: value !== null ? String(value) : '',
1752
+ }))
1753
+ }
1754
+ />
1755
+ </div>
1756
+ <div className="space-y-2">
1757
+ <SupervisorAutocomplete
1758
+ label={commonT('labels.supervisor')}
1759
+ value={form.supervisorCollaboratorId}
1760
+ options={supervisorOptions}
1761
+ placeholder={t('placeholders.supervisor')}
1762
+ emptyLabel={commonT('labels.notAssigned')}
1763
+ onChange={(value) =>
1764
+ setForm((current) => ({
1765
+ ...current,
1766
+ supervisorCollaboratorId: value,
1767
+ }))
1768
+ }
1769
+ />
1770
+ </div>
1771
+ </div>
1772
+ </div>
1773
+ );
1774
+
1775
+ const scheduleSection = (
1776
+ <div className="space-y-2">
1777
+ <div className="space-y-0.5">
1778
+ <h3 className="text-xs font-semibold uppercase tracking-wide text-muted-foreground">
1779
+ {t('sections.schedule')}
1780
+ </h3>
1781
+ <p className="text-[11px] text-muted-foreground/80">
1782
+ {t('sections.scheduleDescription')}
1783
+ </p>
1784
+ </div>
1785
+ <div className="space-y-1.5">
1786
+ {form.weeklySchedule.map((day) => (
1787
+ <div
1788
+ key={day.weekday}
1789
+ className="grid gap-2 rounded-md border px-3 py-2 md:grid-cols-[minmax(108px,0.9fr)_auto_repeat(3,minmax(88px,1fr))] md:items-center"
1790
+ >
1791
+ <div className="space-y-0.5 md:pr-1">
1792
+ <div className="text-sm font-medium leading-none">
1793
+ {formatWeekdayLabel(day.weekday, currentLocaleCode)}
1794
+ </div>
1795
+ <div className="text-[10px] leading-none text-muted-foreground">
1796
+ {day.isWorkingDay
1797
+ ? commonT('labels.workingDay')
1798
+ : commonT('labels.dayOff')}
1799
+ </div>
1800
+ </div>
1801
+ <div className="flex items-center justify-between gap-2 rounded-md bg-muted/30 px-2 py-1.5 md:justify-center md:bg-transparent md:p-0">
1802
+ <span className="text-[10px] font-medium uppercase tracking-wide text-muted-foreground md:hidden">
1803
+ {commonT('labels.workingDay')}
1804
+ </span>
1805
+ <Switch
1806
+ checked={day.isWorkingDay}
1807
+ onCheckedChange={(checked) =>
1808
+ updateScheduleDay(day.weekday, { isWorkingDay: checked })
1809
+ }
1810
+ />
1811
+ </div>
1812
+ <div className="space-y-0.5">
1813
+ <div className="text-[10px] uppercase tracking-wide text-muted-foreground">
1814
+ {t('fields.startTime')}
1815
+ </div>
1816
+ <Input
1817
+ className="h-8"
1818
+ type="time"
1819
+ value={normalizeTimeValue(
1820
+ day.startTime,
1821
+ day.isWorkingDay ? '09:00' : ''
1822
+ )}
1823
+ disabled={!day.isWorkingDay}
1824
+ onChange={(event) =>
1825
+ updateScheduleDay(day.weekday, {
1826
+ startTime: event.target.value,
1827
+ })
1828
+ }
1829
+ />
1830
+ </div>
1831
+ <div className="space-y-0.5">
1832
+ <div className="text-[10px] uppercase tracking-wide text-muted-foreground">
1833
+ {t('fields.endTime')}
1834
+ </div>
1835
+ <Input
1836
+ className="h-8"
1837
+ type="time"
1838
+ value={normalizeTimeValue(
1839
+ day.endTime,
1840
+ day.isWorkingDay ? '18:00' : ''
1841
+ )}
1842
+ disabled={!day.isWorkingDay}
1843
+ onChange={(event) =>
1844
+ updateScheduleDay(day.weekday, {
1845
+ endTime: event.target.value,
1846
+ })
1847
+ }
1848
+ />
1849
+ </div>
1850
+ <div className="space-y-0.5">
1851
+ <div className="flex items-center gap-1 text-[10px] uppercase tracking-wide text-muted-foreground">
1852
+ <span>{t('fields.breakMinutes')}</span>
1853
+ <Tooltip>
1854
+ <TooltipTrigger asChild>
1855
+ <span className="inline-flex cursor-help">
1856
+ <Info className="h-3.5 w-3.5" />
1857
+ </span>
1858
+ </TooltipTrigger>
1859
+ <TooltipContent>
1860
+ <p>{t('fields.breakMinutesDescription')}</p>
1861
+ </TooltipContent>
1862
+ </Tooltip>
1863
+ </div>
1864
+ <Input
1865
+ className="h-8"
1866
+ type="number"
1867
+ min="0"
1868
+ step="5"
1869
+ placeholder="60"
1870
+ title={t('fields.breakMinutesDescription')}
1871
+ aria-label={t('fields.breakMinutes')}
1872
+ value={day.breakMinutes}
1873
+ disabled={!day.isWorkingDay}
1874
+ onChange={(event) =>
1875
+ updateScheduleDay(day.weekday, {
1876
+ breakMinutes: event.target.value,
1877
+ })
1878
+ }
1879
+ />
1880
+ </div>
1881
+ </div>
1882
+ ))}
1883
+ </div>
1884
+
1885
+ <div className="space-y-2 pt-1">
1886
+ <Label>{t('fields.notes')}</Label>
1887
+ <Textarea
1888
+ rows={4}
1889
+ value={form.notes}
1890
+ onChange={(event) =>
1891
+ setForm((current) => ({
1892
+ ...current,
1893
+ notes: event.target.value,
1894
+ }))
1895
+ }
1896
+ />
1897
+ </div>
1898
+ </div>
1899
+ );
1900
+
1901
+ const activitySection = collaborator ? (
1902
+ <div className="space-y-4">
1903
+ <div className="grid gap-3 sm:grid-cols-2 xl:grid-cols-4">
1904
+ <div className="rounded-xl border bg-muted/20 px-4 py-3">
1905
+ <div className="text-[11px] uppercase tracking-wide text-muted-foreground">
1906
+ {detailsT('cards.timesheets')}
1907
+ </div>
1908
+ <div className="mt-1 text-xl font-semibold">
1909
+ {collaborator.timesheetSummary.totalTimesheets}
1910
+ </div>
1911
+ <p className="text-xs text-muted-foreground">
1912
+ {detailsT('cards.timesheetsDescription', {
1913
+ pending: collaborator.timesheetSummary.pendingTimesheets,
1914
+ })}
1915
+ </p>
1916
+ </div>
1917
+
1918
+ <div className="rounded-xl border bg-muted/20 px-4 py-3">
1919
+ <div className="text-[11px] uppercase tracking-wide text-muted-foreground">
1920
+ {detailsT('cards.loggedHours')}
1921
+ </div>
1922
+ <div className="mt-1 text-xl font-semibold">
1923
+ {formatHours(collaborator.timesheetSummary.totalHours)}
1924
+ </div>
1925
+ <p className="text-xs text-muted-foreground">
1926
+ {detailsT('cards.loggedHoursDescription')}
1927
+ </p>
1928
+ </div>
1929
+
1930
+ <div className="rounded-xl border bg-muted/20 px-4 py-3">
1931
+ <div className="text-[11px] uppercase tracking-wide text-muted-foreground">
1932
+ {detailsT('cards.timeOff')}
1933
+ </div>
1934
+ <div className="mt-1 text-xl font-semibold">
1935
+ {collaborator.timeOffSummary.totalRequests}
1936
+ </div>
1937
+ <p className="text-xs text-muted-foreground">
1938
+ {detailsT('cards.timeOffDescription', {
1939
+ pending: collaborator.timeOffSummary.pendingRequests,
1940
+ })}
1941
+ </p>
1942
+ </div>
1943
+
1944
+ <div className="rounded-xl border bg-muted/20 px-4 py-3">
1945
+ <div className="text-[11px] uppercase tracking-wide text-muted-foreground">
1946
+ {detailsT('sections.scheduleAdjustments')}
1947
+ </div>
1948
+ <div className="mt-1 text-xl font-semibold">
1949
+ {collaborator.scheduleAdjustmentRequests.length}
1950
+ </div>
1951
+ <p className="text-xs text-muted-foreground">
1952
+ {detailsT('sections.scheduleAdjustmentsDescription')}
1953
+ </p>
1954
+ </div>
1955
+ </div>
1956
+
1957
+ <div className="grid gap-4 xl:grid-cols-2">
1958
+ <div className="rounded-xl border px-4 py-3">
1959
+ <div className="mb-3 space-y-0.5">
1960
+ <h3 className="text-xs font-semibold uppercase tracking-wide text-muted-foreground">
1961
+ {detailsT('sections.projects')}
1962
+ </h3>
1963
+ <p className="text-[11px] text-muted-foreground/80">
1964
+ {detailsT('sections.projectsDescription')}
1965
+ </p>
1966
+ </div>
1967
+
1968
+ {collaborator.assignedProjects.length > 0 ? (
1969
+ <div className="space-y-2">
1970
+ {collaborator.assignedProjects.slice(0, 6).map((project) => (
1971
+ <div
1972
+ key={project.id}
1973
+ className="flex flex-col gap-2 rounded-lg border px-3 py-2.5"
1974
+ >
1975
+ <div className="flex items-start justify-between gap-3">
1976
+ <div className="min-w-0">
1977
+ <div className="truncate font-medium">{project.name}</div>
1978
+ <div className="truncate text-xs text-muted-foreground">
1979
+ {[
1980
+ project.code,
1981
+ project.roleLabel || commonT('labels.notAssigned'),
1982
+ project.weeklyHours !== null &&
1983
+ project.weeklyHours !== undefined
1984
+ ? formatHours(project.weeklyHours)
1985
+ : null,
1986
+ project.allocationPercent !== null &&
1987
+ project.allocationPercent !== undefined
1988
+ ? `${project.allocationPercent}%`
1989
+ : null,
1990
+ ]
1991
+ .filter(Boolean)
1992
+ .join(' • ')}
1993
+ </div>
1994
+ </div>
1995
+ <StatusBadge
1996
+ label={formatEnumLabel(project.status)}
1997
+ className={getStatusBadgeClass(project.status)}
1998
+ />
1999
+ </div>
2000
+ <div className="text-xs text-muted-foreground">
2001
+ {formatDateRange(project.startDate, project.endDate)}
2002
+ </div>
2003
+ </div>
2004
+ ))}
2005
+ </div>
2006
+ ) : (
2007
+ <p className="text-sm text-muted-foreground">
2008
+ {detailsT('noProjects')}
2009
+ </p>
2010
+ )}
2011
+ </div>
2012
+
2013
+ <div className="space-y-4">
2014
+ <div className="rounded-xl border px-4 py-3">
2015
+ <div className="mb-3 space-y-0.5">
2016
+ <h3 className="text-xs font-semibold uppercase tracking-wide text-muted-foreground">
2017
+ {detailsT('sections.primaryContract')}
2018
+ </h3>
2019
+ <p className="text-[11px] text-muted-foreground/80">
2020
+ {t('sections.contractDescription')}
2021
+ </p>
2022
+ </div>
2023
+
2024
+ {collaborator.relatedContracts.length > 0 ? (
2025
+ <div className="space-y-2">
2026
+ {collaborator.relatedContracts.slice(0, 3).map((contract) => (
2027
+ <Link
2028
+ key={contract.id}
2029
+ href={`/operations/contracts?edit=${contract.id}`}
2030
+ className="flex cursor-pointer items-center justify-between gap-3 rounded-lg border px-3 py-2.5 transition-colors hover:bg-muted/20"
2031
+ >
2032
+ <div className="min-w-0">
2033
+ <div className="truncate font-medium">
2034
+ {contract.name || contract.code}
2035
+ </div>
2036
+ <div className="truncate text-xs text-muted-foreground">
2037
+ {[
2038
+ contract.code,
2039
+ formatEnumLabel(contract.contractCategory),
2040
+ ]
2041
+ .filter(Boolean)
2042
+ .join(' • ')}
2043
+ </div>
2044
+ </div>
2045
+ <StatusBadge
2046
+ label={formatEnumLabel(contract.status)}
2047
+ className={getStatusBadgeClass(contract.status)}
2048
+ />
2049
+ </Link>
2050
+ ))}
2051
+ </div>
2052
+ ) : (
2053
+ <p className="text-sm text-muted-foreground">
2054
+ {detailsT('noContracts')}
2055
+ </p>
2056
+ )}
2057
+ </div>
2058
+
2059
+ <div className="rounded-xl border px-4 py-3">
2060
+ <div className="mb-3 space-y-0.5">
2061
+ <h3 className="text-xs font-semibold uppercase tracking-wide text-muted-foreground">
2062
+ {detailsT('sections.scheduleAdjustments')}
2063
+ </h3>
2064
+ <p className="text-[11px] text-muted-foreground/80">
2065
+ {detailsT('sections.scheduleAdjustmentsDescription')}
2066
+ </p>
2067
+ </div>
2068
+
2069
+ {collaborator.scheduleAdjustmentRequests.length > 0 ? (
2070
+ <div className="space-y-2">
2071
+ {collaborator.scheduleAdjustmentRequests
2072
+ .slice(0, 4)
2073
+ .map((request) => (
2074
+ <div
2075
+ key={request.id}
2076
+ className="flex items-center justify-between gap-3 rounded-lg border px-3 py-2.5"
2077
+ >
2078
+ <div className="min-w-0">
2079
+ <div className="font-medium">
2080
+ {formatEnumLabel(request.requestScope)}
2081
+ </div>
2082
+ <div className="truncate text-xs text-muted-foreground">
2083
+ {formatDateRange(
2084
+ request.effectiveStartDate,
2085
+ request.effectiveEndDate
2086
+ )}
2087
+ </div>
2088
+ </div>
2089
+ <StatusBadge
2090
+ label={formatEnumLabel(request.status)}
2091
+ className={getStatusBadgeClass(request.status)}
2092
+ />
2093
+ </div>
2094
+ ))}
2095
+ </div>
2096
+ ) : (
2097
+ <p className="text-sm text-muted-foreground">
2098
+ {detailsT('noScheduleAdjustments')}
2099
+ </p>
2100
+ )}
2101
+ </div>
2102
+ </div>
2103
+ </div>
2104
+ </div>
2105
+ ) : null;
2106
+
2107
+ const profileContent = (
2108
+ <div className="space-y-4">
2109
+ {basicInfoSection}
2110
+ {employmentInfoSection}
2111
+ {!isCreateMode ? equitySection : null}
2112
+ </div>
2113
+ );
2114
+
2115
+ const costsSection = (
2116
+ <Accordion
2117
+ type="single"
2118
+ collapsible
2119
+ defaultValue={isCreateMode ? undefined : 'costs'}
2120
+ >
2121
+ <AccordionItem value="costs" className="rounded-xl border px-4">
2122
+ <AccordionTrigger className="py-3 text-xs font-semibold uppercase tracking-wide text-muted-foreground hover:no-underline">
2123
+ {t('sections.costs')}
2124
+ </AccordionTrigger>
2125
+ <AccordionContent className="pb-4">
2126
+ {isCreateMode || !collaborator ? (
2127
+ <p className="text-sm text-muted-foreground">
2128
+ {t('sections.costsSaveBefore')}
2129
+ </p>
2130
+ ) : (
2131
+ <CollaboratorCostsSection
2132
+ collaboratorId={collaborator.id}
2133
+ disabled={!access.isDirector}
2134
+ weeklyCapacity={collaborator.weeklyCapacityHours ?? undefined}
2135
+ remunerationValue={
2136
+ collaborator.compensationAmount != null
2137
+ ? Number(collaborator.compensationAmount)
2138
+ : undefined
2139
+ }
2140
+ />
2141
+ )}
2142
+ </AccordionContent>
2143
+ </AccordionItem>
2144
+ </Accordion>
2145
+ );
2146
+
2147
+ const formContent = isSheetMode ? (
2148
+ <div className="space-y-4 px-4">
2149
+ {profileContent}
2150
+ {contractSection}
2151
+ {!isCreateMode ? costsSection : null}
2152
+ {!isCreateMode ? scheduleSection : null}
2153
+ {activitySection}
2154
+ </div>
2155
+ ) : (
2156
+ <div className="space-y-4 px-4">
2157
+ {profileContent}
2158
+ {contractSection}
2159
+ {!isCreateMode ? costsSection : null}
2160
+ {!isCreateMode ? scheduleSection : null}
2161
+ </div>
2162
+ );
2163
+
2164
+ const loadingState =
2165
+ collaboratorId && isLoadingCollaborator ? (
2166
+ <div className="text-sm text-muted-foreground">{t('loading')}</div>
2167
+ ) : null;
2168
+
2169
+ if (isSheetMode) {
2170
+ return (
2171
+ <div className="mt-6 space-y-4 pb-6">
2172
+ {collaboratorSummary}
2173
+ {formContent}
2174
+ {loadingState}
2175
+
2176
+ <FormActions
2177
+ sheet
2178
+ cancelLabel={commonT('actions.cancel')}
2179
+ onCancel={onCancel}
2180
+ onSubmit={() => void onSubmit()}
2181
+ submitIcon={<Save className="size-4" />}
2182
+ submitLabel={commonT('actions.save')}
2183
+ submitSize="lg"
2184
+ />
2185
+
2186
+ <PersonFormSheet
2187
+ open={personSheetOpen}
2188
+ person={personToEdit}
2189
+ contactTypes={contactTypes}
2190
+ documentTypes={documentTypes}
2191
+ onOpenChange={(nextOpen) => {
2192
+ setPersonSheetOpen(nextOpen);
2193
+ if (!nextOpen) setPersonToEdit(null);
2194
+ }}
2195
+ onSuccess={() => void refetchCollaborator()}
2196
+ />
2197
+ </div>
2198
+ );
2199
+ }
2200
+
2201
+ return (
2202
+ <Page>
2203
+ <OperationsHeader
2204
+ title={t(collaboratorId ? 'editTitle' : 'newTitle')}
2205
+ description={isCreateMode ? t('descriptionCreate') : t('description')}
2206
+ current={t('breadcrumb')}
2207
+ actions={
2208
+ <div className="flex gap-2">
2209
+ <Button variant="outline" size="sm" asChild>
2210
+ <Link
2211
+ href={
2212
+ collaboratorId
2213
+ ? `/operations/collaborators/${collaboratorId}`
2214
+ : '/operations/collaborators'
2215
+ }
2216
+ >
2217
+ <ArrowLeft className="size-4" />
2218
+ {commonT('actions.back')}
2219
+ </Link>
2220
+ </Button>
2221
+ <Button size="sm" onClick={() => void onSubmit()}>
2222
+ <Save className="size-4" />
2223
+ {commonT('actions.save')}
2224
+ </Button>
2225
+ </div>
2226
+ }
2227
+ />
2228
+
2229
+ {formContent}
2230
+ {loadingState}
2231
+ </Page>
2232
+ );
2233
+ }