@hed-hog/operations 0.0.327 → 0.0.329

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 (571) hide show
  1. package/dist/controllers/operations-tasks.controller.d.ts +3 -3
  2. package/dist/operations.service.d.ts +3 -3
  3. package/hedhog/frontend/app/_components/collaborator-form-screen.tsx.ejs +7 -7
  4. package/hedhog/frontend/app/_components/department-picker.tsx.ejs +125 -0
  5. package/hedhog/frontend/app/_components/department-select-with-create.tsx.ejs +64 -325
  6. package/hedhog/frontend/app/_components/project-form-screen.tsx.ejs +16 -16
  7. package/hedhog/frontend/app/_components/system-user-picker.tsx.ejs +198 -0
  8. package/hedhog/frontend/app/_components/system-user-select-with-create.tsx.ejs +107 -569
  9. package/hedhog/frontend/messages/en.json +79 -10
  10. package/hedhog/frontend/messages/operations/en.json +67 -3
  11. package/hedhog/frontend/messages/operations/pt.json +67 -3
  12. package/hedhog/frontend/messages/pt.json +77 -8
  13. package/package.json +5 -5
  14. package/hedhog/frontend/app/_components/collaborator-details-screen.tsx.ejs +0 -476
  15. package/hedhog/frontend/app/_components/collaborator-select-with-create.tsx.ejs +0 -261
  16. package/hedhog/frontend/app/_components/contract-content-editor.tsx.ejs +0 -258
  17. package/hedhog/frontend/app/_components/person-select-with-create.tsx.ejs +0 -1
  18. package/hedhog/frontend/messages/en.json.ejs +0 -2060
  19. package/hedhog/frontend/messages/operations/operations/en.json +0 -2102
  20. package/hedhog/frontend/messages/operations/operations/pt.json +0 -2111
  21. package/hedhog/frontend/messages/pt.json.ejs +0 -2067
  22. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/async-options-combobox.d.ts +0 -29
  23. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/async-options-combobox.d.ts.map +0 -1
  24. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/async-options-combobox.js +0 -95
  25. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/async-options-combobox.js.map +0 -1
  26. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/async-options-combobox.tsx +0 -233
  27. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/collaborator-costs-section.d.ts +0 -10
  28. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/collaborator-costs-section.d.ts.map +0 -1
  29. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/collaborator-costs-section.js +0 -577
  30. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/collaborator-costs-section.js.map +0 -1
  31. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/collaborator-costs-section.tsx +0 -868
  32. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/collaborator-details-screen.d.ts +0 -4
  33. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/collaborator-details-screen.d.ts.map +0 -1
  34. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/collaborator-details-screen.js +0 -337
  35. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/collaborator-details-screen.js.map +0 -1
  36. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/collaborator-details-screen.tsx +0 -476
  37. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/collaborator-form-screen.d.ts +0 -9
  38. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/collaborator-form-screen.d.ts.map +0 -1
  39. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/collaborator-form-screen.js +0 -1348
  40. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/collaborator-form-screen.js.map +0 -1
  41. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/collaborator-form-screen.tsx +0 -2233
  42. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/collaborator-select-with-create.d.ts +0 -12
  43. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/collaborator-select-with-create.d.ts.map +0 -1
  44. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/collaborator-select-with-create.js +0 -162
  45. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/collaborator-select-with-create.js.map +0 -1
  46. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/collaborator-select-with-create.tsx +0 -261
  47. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/contract-content-editor.d.ts +0 -18
  48. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/contract-content-editor.d.ts.map +0 -1
  49. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/contract-content-editor.js +0 -145
  50. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/contract-content-editor.js.map +0 -1
  51. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/contract-content-editor.tsx +0 -258
  52. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/contract-details-screen.d.ts +0 -4
  53. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/contract-details-screen.d.ts.map +0 -1
  54. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/contract-details-screen.js +0 -223
  55. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/contract-details-screen.js.map +0 -1
  56. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/contract-details-screen.tsx +0 -342
  57. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/contract-form-screen.d.ts +0 -58
  58. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/contract-form-screen.d.ts.map +0 -1
  59. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/contract-form-screen.js +0 -438
  60. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/contract-form-screen.js.map +0 -1
  61. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/contract-form-screen.tsx +0 -698
  62. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/department-select-with-create.d.ts +0 -20
  63. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/department-select-with-create.d.ts.map +0 -1
  64. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/department-select-with-create.js +0 -233
  65. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/department-select-with-create.js.map +0 -1
  66. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/department-select-with-create.tsx +0 -392
  67. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/my-project-summary-screen.d.ts +0 -4
  68. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/my-project-summary-screen.d.ts.map +0 -1
  69. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/my-project-summary-screen.js +0 -814
  70. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/my-project-summary-screen.js.map +0 -1
  71. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/my-project-summary-screen.tsx +0 -1288
  72. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/operations-calendar-view.d.ts +0 -21
  73. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/operations-calendar-view.d.ts.map +0 -1
  74. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/operations-calendar-view.js +0 -174
  75. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/operations-calendar-view.js.map +0 -1
  76. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/operations-calendar-view.tsx +0 -306
  77. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/operations-header.d.ts +0 -10
  78. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/operations-header.d.ts.map +0 -1
  79. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/operations-header.js +0 -12
  80. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/operations-header.js.map +0 -1
  81. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/operations-header.tsx +0 -29
  82. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/person-select-with-create.d.ts +0 -15
  83. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/person-select-with-create.d.ts.map +0 -1
  84. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/person-select-with-create.js +0 -501
  85. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/person-select-with-create.js.map +0 -1
  86. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/person-select-with-create.tsx +0 -853
  87. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/project-costs-section.d.ts +0 -6
  88. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/project-costs-section.d.ts.map +0 -1
  89. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/project-costs-section.js +0 -847
  90. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/project-costs-section.js.map +0 -1
  91. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/project-costs-section.tsx +0 -1340
  92. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/project-details-screen.d.ts +0 -4
  93. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/project-details-screen.d.ts.map +0 -1
  94. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/project-details-screen.js +0 -2930
  95. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/project-details-screen.js.map +0 -1
  96. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/project-details-screen.tsx +0 -4378
  97. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/project-form-screen.d.ts +0 -9
  98. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/project-form-screen.d.ts.map +0 -1
  99. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/project-form-screen.js +0 -1013
  100. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/project-form-screen.js.map +0 -1
  101. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/project-form-screen.tsx +0 -1745
  102. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/section-card.d.ts +0 -13
  103. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/section-card.d.ts.map +0 -1
  104. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/section-card.js +0 -38
  105. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/section-card.js.map +0 -1
  106. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/section-card.tsx +0 -74
  107. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/status-badge.d.ts +0 -7
  108. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/status-badge.d.ts.map +0 -1
  109. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/status-badge.js +0 -11
  110. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/status-badge.js.map +0 -1
  111. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/status-badge.tsx +0 -15
  112. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/system-user-select-with-create.d.ts +0 -18
  113. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/system-user-select-with-create.d.ts.map +0 -1
  114. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/system-user-select-with-create.js +0 -406
  115. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/system-user-select-with-create.js.map +0 -1
  116. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/system-user-select-with-create.tsx +0 -660
  117. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/task-detail-sheet.d.ts +0 -26
  118. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/task-detail-sheet.d.ts.map +0 -1
  119. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/task-detail-sheet.js +0 -332
  120. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/task-detail-sheet.js.map +0 -1
  121. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/task-detail-sheet.tsx +0 -518
  122. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/task-file-attachments.d.ts +0 -6
  123. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/task-file-attachments.d.ts.map +0 -1
  124. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/task-file-attachments.js +0 -255
  125. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/task-file-attachments.js.map +0 -1
  126. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/task-file-attachments.tsx +0 -388
  127. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/timesheet-task-create-sheet.d.ts +0 -10
  128. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/timesheet-task-create-sheet.d.ts.map +0 -1
  129. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/timesheet-task-create-sheet.js +0 -131
  130. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/timesheet-task-create-sheet.js.map +0 -1
  131. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_components/timesheet-task-create-sheet.tsx +0 -214
  132. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_lib/api.d.ts +0 -108
  133. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_lib/api.d.ts.map +0 -1
  134. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_lib/api.js +0 -162
  135. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_lib/api.js.map +0 -1
  136. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_lib/api.ts +0 -428
  137. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_lib/hooks/use-operations-access.d.ts +0 -8
  138. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_lib/hooks/use-operations-access.d.ts.map +0 -1
  139. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_lib/hooks/use-operations-access.js +0 -36
  140. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_lib/hooks/use-operations-access.js.map +0 -1
  141. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_lib/hooks/use-operations-access.ts +0 -44
  142. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_lib/types.d.ts +0 -837
  143. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_lib/types.d.ts.map +0 -1
  144. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_lib/types.js +0 -3
  145. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_lib/types.js.map +0 -1
  146. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_lib/types.ts +0 -861
  147. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_lib/utils/format.d.ts +0 -16
  148. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_lib/utils/format.d.ts.map +0 -1
  149. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_lib/utils/format.js +0 -182
  150. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_lib/utils/format.js.map +0 -1
  151. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_lib/utils/format.ts +0 -250
  152. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_lib/utils/forms.d.ts +0 -4
  153. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_lib/utils/forms.d.ts.map +0 -1
  154. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_lib/utils/forms.js +0 -51
  155. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_lib/utils/forms.js.map +0 -1
  156. package/hedhog/frontend/src/app/(app)/(libraries)/operations/_lib/utils/forms.ts +0 -61
  157. package/hedhog/frontend/src/app/(app)/(libraries)/operations/approvals/page.d.ts +0 -2
  158. package/hedhog/frontend/src/app/(app)/(libraries)/operations/approvals/page.d.ts.map +0 -1
  159. package/hedhog/frontend/src/app/(app)/(libraries)/operations/approvals/page.js +0 -954
  160. package/hedhog/frontend/src/app/(app)/(libraries)/operations/approvals/page.js.map +0 -1
  161. package/hedhog/frontend/src/app/(app)/(libraries)/operations/approvals/page.tsx +0 -1277
  162. package/hedhog/frontend/src/app/(app)/(libraries)/operations/collaborator-types/page.d.ts +0 -2
  163. package/hedhog/frontend/src/app/(app)/(libraries)/operations/collaborator-types/page.d.ts.map +0 -1
  164. package/hedhog/frontend/src/app/(app)/(libraries)/operations/collaborator-types/page.js +0 -488
  165. package/hedhog/frontend/src/app/(app)/(libraries)/operations/collaborator-types/page.js.map +0 -1
  166. package/hedhog/frontend/src/app/(app)/(libraries)/operations/collaborator-types/page.tsx +0 -805
  167. package/hedhog/frontend/src/app/(app)/(libraries)/operations/collaborators/[id]/edit/page.d.ts +0 -6
  168. package/hedhog/frontend/src/app/(app)/(libraries)/operations/collaborators/[id]/edit/page.d.ts.map +0 -1
  169. package/hedhog/frontend/src/app/(app)/(libraries)/operations/collaborators/[id]/edit/page.js +0 -9
  170. package/hedhog/frontend/src/app/(app)/(libraries)/operations/collaborators/[id]/edit/page.js.map +0 -1
  171. package/hedhog/frontend/src/app/(app)/(libraries)/operations/collaborators/[id]/edit/page.tsx +0 -11
  172. package/hedhog/frontend/src/app/(app)/(libraries)/operations/collaborators/[id]/page.d.ts +0 -6
  173. package/hedhog/frontend/src/app/(app)/(libraries)/operations/collaborators/[id]/page.d.ts.map +0 -1
  174. package/hedhog/frontend/src/app/(app)/(libraries)/operations/collaborators/[id]/page.js +0 -9
  175. package/hedhog/frontend/src/app/(app)/(libraries)/operations/collaborators/[id]/page.js.map +0 -1
  176. package/hedhog/frontend/src/app/(app)/(libraries)/operations/collaborators/[id]/page.tsx +0 -11
  177. package/hedhog/frontend/src/app/(app)/(libraries)/operations/collaborators/new/page.d.ts +0 -2
  178. package/hedhog/frontend/src/app/(app)/(libraries)/operations/collaborators/new/page.d.ts.map +0 -1
  179. package/hedhog/frontend/src/app/(app)/(libraries)/operations/collaborators/new/page.js +0 -8
  180. package/hedhog/frontend/src/app/(app)/(libraries)/operations/collaborators/new/page.js.map +0 -1
  181. package/hedhog/frontend/src/app/(app)/(libraries)/operations/collaborators/new/page.tsx +0 -5
  182. package/hedhog/frontend/src/app/(app)/(libraries)/operations/collaborators/page.d.ts +0 -2
  183. package/hedhog/frontend/src/app/(app)/(libraries)/operations/collaborators/page.d.ts.map +0 -1
  184. package/hedhog/frontend/src/app/(app)/(libraries)/operations/collaborators/page.js +0 -612
  185. package/hedhog/frontend/src/app/(app)/(libraries)/operations/collaborators/page.js.map +0 -1
  186. package/hedhog/frontend/src/app/(app)/(libraries)/operations/collaborators/page.tsx +0 -939
  187. package/hedhog/frontend/src/app/(app)/(libraries)/operations/contracts/[id]/edit/page.d.ts +0 -6
  188. package/hedhog/frontend/src/app/(app)/(libraries)/operations/contracts/[id]/edit/page.d.ts.map +0 -1
  189. package/hedhog/frontend/src/app/(app)/(libraries)/operations/contracts/[id]/edit/page.js +0 -9
  190. package/hedhog/frontend/src/app/(app)/(libraries)/operations/contracts/[id]/edit/page.js.map +0 -1
  191. package/hedhog/frontend/src/app/(app)/(libraries)/operations/contracts/[id]/edit/page.tsx +0 -11
  192. package/hedhog/frontend/src/app/(app)/(libraries)/operations/contracts/[id]/page.d.ts +0 -6
  193. package/hedhog/frontend/src/app/(app)/(libraries)/operations/contracts/[id]/page.d.ts.map +0 -1
  194. package/hedhog/frontend/src/app/(app)/(libraries)/operations/contracts/[id]/page.js +0 -9
  195. package/hedhog/frontend/src/app/(app)/(libraries)/operations/contracts/[id]/page.js.map +0 -1
  196. package/hedhog/frontend/src/app/(app)/(libraries)/operations/contracts/[id]/page.tsx +0 -11
  197. package/hedhog/frontend/src/app/(app)/(libraries)/operations/contracts/new/page.d.ts +0 -6
  198. package/hedhog/frontend/src/app/(app)/(libraries)/operations/contracts/new/page.d.ts.map +0 -1
  199. package/hedhog/frontend/src/app/(app)/(libraries)/operations/contracts/new/page.js +0 -9
  200. package/hedhog/frontend/src/app/(app)/(libraries)/operations/contracts/new/page.js.map +0 -1
  201. package/hedhog/frontend/src/app/(app)/(libraries)/operations/contracts/new/page.tsx +0 -17
  202. package/hedhog/frontend/src/app/(app)/(libraries)/operations/contracts/page.d.ts +0 -2
  203. package/hedhog/frontend/src/app/(app)/(libraries)/operations/contracts/page.d.ts.map +0 -1
  204. package/hedhog/frontend/src/app/(app)/(libraries)/operations/contracts/page.js +0 -348
  205. package/hedhog/frontend/src/app/(app)/(libraries)/operations/contracts/page.js.map +0 -1
  206. package/hedhog/frontend/src/app/(app)/(libraries)/operations/contracts/page.tsx +0 -536
  207. package/hedhog/frontend/src/app/(app)/(libraries)/operations/departments/page.d.ts +0 -2
  208. package/hedhog/frontend/src/app/(app)/(libraries)/operations/departments/page.d.ts.map +0 -1
  209. package/hedhog/frontend/src/app/(app)/(libraries)/operations/departments/page.js +0 -401
  210. package/hedhog/frontend/src/app/(app)/(libraries)/operations/departments/page.js.map +0 -1
  211. package/hedhog/frontend/src/app/(app)/(libraries)/operations/departments/page.tsx +0 -607
  212. package/hedhog/frontend/src/app/(app)/(libraries)/operations/layout.d.ts +0 -5
  213. package/hedhog/frontend/src/app/(app)/(libraries)/operations/layout.d.ts.map +0 -1
  214. package/hedhog/frontend/src/app/(app)/(libraries)/operations/layout.js +0 -7
  215. package/hedhog/frontend/src/app/(app)/(libraries)/operations/layout.js.map +0 -1
  216. package/hedhog/frontend/src/app/(app)/(libraries)/operations/layout.tsx +0 -9
  217. package/hedhog/frontend/src/app/(app)/(libraries)/operations/my-projects/[id]/page.d.ts +0 -6
  218. package/hedhog/frontend/src/app/(app)/(libraries)/operations/my-projects/[id]/page.d.ts.map +0 -1
  219. package/hedhog/frontend/src/app/(app)/(libraries)/operations/my-projects/[id]/page.js +0 -9
  220. package/hedhog/frontend/src/app/(app)/(libraries)/operations/my-projects/[id]/page.js.map +0 -1
  221. package/hedhog/frontend/src/app/(app)/(libraries)/operations/my-projects/[id]/page.tsx +0 -11
  222. package/hedhog/frontend/src/app/(app)/(libraries)/operations/my-projects/page.d.ts +0 -2
  223. package/hedhog/frontend/src/app/(app)/(libraries)/operations/my-projects/page.d.ts.map +0 -1
  224. package/hedhog/frontend/src/app/(app)/(libraries)/operations/my-projects/page.js +0 -321
  225. package/hedhog/frontend/src/app/(app)/(libraries)/operations/my-projects/page.js.map +0 -1
  226. package/hedhog/frontend/src/app/(app)/(libraries)/operations/my-projects/page.tsx +0 -440
  227. package/hedhog/frontend/src/app/(app)/(libraries)/operations/my-tasks/page.d.ts +0 -2
  228. package/hedhog/frontend/src/app/(app)/(libraries)/operations/my-tasks/page.d.ts.map +0 -1
  229. package/hedhog/frontend/src/app/(app)/(libraries)/operations/my-tasks/page.js +0 -939
  230. package/hedhog/frontend/src/app/(app)/(libraries)/operations/my-tasks/page.js.map +0 -1
  231. package/hedhog/frontend/src/app/(app)/(libraries)/operations/my-tasks/page.tsx +0 -1499
  232. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/async-options-combobox.d.ts +0 -29
  233. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/async-options-combobox.d.ts.map +0 -1
  234. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/async-options-combobox.js +0 -95
  235. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/async-options-combobox.js.map +0 -1
  236. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/async-options-combobox.tsx +0 -233
  237. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/collaborator-costs-section.d.ts +0 -10
  238. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/collaborator-costs-section.d.ts.map +0 -1
  239. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/collaborator-costs-section.js +0 -577
  240. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/collaborator-costs-section.js.map +0 -1
  241. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/collaborator-costs-section.tsx +0 -868
  242. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/collaborator-details-screen.d.ts +0 -4
  243. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/collaborator-details-screen.d.ts.map +0 -1
  244. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/collaborator-details-screen.js +0 -337
  245. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/collaborator-details-screen.js.map +0 -1
  246. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/collaborator-details-screen.tsx +0 -476
  247. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/collaborator-form-screen.d.ts +0 -9
  248. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/collaborator-form-screen.d.ts.map +0 -1
  249. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/collaborator-form-screen.js +0 -1348
  250. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/collaborator-form-screen.js.map +0 -1
  251. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/collaborator-form-screen.tsx +0 -2233
  252. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/collaborator-select-with-create.d.ts +0 -12
  253. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/collaborator-select-with-create.d.ts.map +0 -1
  254. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/collaborator-select-with-create.js +0 -162
  255. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/collaborator-select-with-create.js.map +0 -1
  256. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/collaborator-select-with-create.tsx +0 -261
  257. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/contract-content-editor.d.ts +0 -18
  258. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/contract-content-editor.d.ts.map +0 -1
  259. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/contract-content-editor.js +0 -145
  260. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/contract-content-editor.js.map +0 -1
  261. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/contract-content-editor.tsx +0 -258
  262. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/contract-details-screen.d.ts +0 -4
  263. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/contract-details-screen.d.ts.map +0 -1
  264. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/contract-details-screen.js +0 -223
  265. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/contract-details-screen.js.map +0 -1
  266. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/contract-details-screen.tsx +0 -342
  267. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/contract-form-screen.d.ts +0 -58
  268. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/contract-form-screen.d.ts.map +0 -1
  269. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/contract-form-screen.js +0 -438
  270. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/contract-form-screen.js.map +0 -1
  271. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/contract-form-screen.tsx +0 -698
  272. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/department-select-with-create.d.ts +0 -20
  273. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/department-select-with-create.d.ts.map +0 -1
  274. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/department-select-with-create.js +0 -233
  275. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/department-select-with-create.js.map +0 -1
  276. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/department-select-with-create.tsx +0 -392
  277. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/my-project-summary-screen.d.ts +0 -4
  278. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/my-project-summary-screen.d.ts.map +0 -1
  279. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/my-project-summary-screen.js +0 -814
  280. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/my-project-summary-screen.js.map +0 -1
  281. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/my-project-summary-screen.tsx +0 -1288
  282. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/operations-calendar-view.d.ts +0 -21
  283. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/operations-calendar-view.d.ts.map +0 -1
  284. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/operations-calendar-view.js +0 -174
  285. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/operations-calendar-view.js.map +0 -1
  286. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/operations-calendar-view.tsx +0 -306
  287. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/operations-header.d.ts +0 -10
  288. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/operations-header.d.ts.map +0 -1
  289. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/operations-header.js +0 -12
  290. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/operations-header.js.map +0 -1
  291. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/operations-header.tsx +0 -29
  292. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/person-select-with-create.d.ts +0 -15
  293. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/person-select-with-create.d.ts.map +0 -1
  294. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/person-select-with-create.js +0 -501
  295. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/person-select-with-create.js.map +0 -1
  296. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/person-select-with-create.tsx +0 -853
  297. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/project-cost-report-screen.d.ts +0 -6
  298. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/project-cost-report-screen.d.ts.map +0 -1
  299. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/project-cost-report-screen.js +0 -459
  300. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/project-cost-report-screen.js.map +0 -1
  301. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/project-cost-report-screen.tsx +0 -598
  302. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/project-costs-section.d.ts +0 -6
  303. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/project-costs-section.d.ts.map +0 -1
  304. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/project-costs-section.js +0 -876
  305. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/project-costs-section.js.map +0 -1
  306. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/project-costs-section.tsx +0 -1368
  307. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/project-details-screen.d.ts +0 -4
  308. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/project-details-screen.d.ts.map +0 -1
  309. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/project-details-screen.js +0 -2930
  310. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/project-details-screen.js.map +0 -1
  311. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/project-details-screen.tsx +0 -4378
  312. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/project-form-screen.d.ts +0 -9
  313. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/project-form-screen.d.ts.map +0 -1
  314. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/project-form-screen.js +0 -1013
  315. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/project-form-screen.js.map +0 -1
  316. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/project-form-screen.tsx +0 -1745
  317. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/section-card.d.ts +0 -13
  318. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/section-card.d.ts.map +0 -1
  319. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/section-card.js +0 -38
  320. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/section-card.js.map +0 -1
  321. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/section-card.tsx +0 -74
  322. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/status-badge.d.ts +0 -7
  323. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/status-badge.d.ts.map +0 -1
  324. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/status-badge.js +0 -11
  325. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/status-badge.js.map +0 -1
  326. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/status-badge.tsx +0 -15
  327. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/system-user-select-with-create.d.ts +0 -18
  328. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/system-user-select-with-create.d.ts.map +0 -1
  329. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/system-user-select-with-create.js +0 -406
  330. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/system-user-select-with-create.js.map +0 -1
  331. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/system-user-select-with-create.tsx +0 -660
  332. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/task-detail-sheet.d.ts +0 -26
  333. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/task-detail-sheet.d.ts.map +0 -1
  334. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/task-detail-sheet.js +0 -332
  335. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/task-detail-sheet.js.map +0 -1
  336. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/task-detail-sheet.tsx +0 -518
  337. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/task-file-attachments.d.ts +0 -6
  338. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/task-file-attachments.d.ts.map +0 -1
  339. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/task-file-attachments.js +0 -255
  340. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/task-file-attachments.js.map +0 -1
  341. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/task-file-attachments.tsx +0 -388
  342. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/timesheet-task-create-sheet.d.ts +0 -10
  343. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/timesheet-task-create-sheet.d.ts.map +0 -1
  344. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/timesheet-task-create-sheet.js +0 -131
  345. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/timesheet-task-create-sheet.js.map +0 -1
  346. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_components/timesheet-task-create-sheet.tsx +0 -214
  347. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_lib/api.d.ts +0 -108
  348. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_lib/api.d.ts.map +0 -1
  349. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_lib/api.js +0 -162
  350. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_lib/api.js.map +0 -1
  351. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_lib/api.ts +0 -428
  352. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_lib/hooks/use-operations-access.d.ts +0 -8
  353. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_lib/hooks/use-operations-access.d.ts.map +0 -1
  354. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_lib/hooks/use-operations-access.js +0 -36
  355. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_lib/hooks/use-operations-access.js.map +0 -1
  356. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_lib/hooks/use-operations-access.ts +0 -44
  357. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_lib/types.d.ts +0 -837
  358. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_lib/types.d.ts.map +0 -1
  359. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_lib/types.js +0 -3
  360. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_lib/types.js.map +0 -1
  361. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_lib/types.ts +0 -861
  362. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_lib/utils/format.d.ts +0 -16
  363. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_lib/utils/format.d.ts.map +0 -1
  364. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_lib/utils/format.js +0 -182
  365. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_lib/utils/format.js.map +0 -1
  366. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_lib/utils/format.ts +0 -250
  367. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_lib/utils/forms.d.ts +0 -4
  368. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_lib/utils/forms.d.ts.map +0 -1
  369. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_lib/utils/forms.js +0 -51
  370. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_lib/utils/forms.js.map +0 -1
  371. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/_lib/utils/forms.ts +0 -61
  372. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/approvals/page.d.ts +0 -2
  373. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/approvals/page.d.ts.map +0 -1
  374. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/approvals/page.js +0 -954
  375. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/approvals/page.js.map +0 -1
  376. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/approvals/page.tsx +0 -1277
  377. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/collaborator-types/page.d.ts +0 -2
  378. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/collaborator-types/page.d.ts.map +0 -1
  379. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/collaborator-types/page.js +0 -488
  380. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/collaborator-types/page.js.map +0 -1
  381. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/collaborator-types/page.tsx +0 -805
  382. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/collaborators/[id]/edit/page.d.ts +0 -6
  383. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/collaborators/[id]/edit/page.d.ts.map +0 -1
  384. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/collaborators/[id]/edit/page.js +0 -9
  385. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/collaborators/[id]/edit/page.js.map +0 -1
  386. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/collaborators/[id]/edit/page.tsx +0 -11
  387. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/collaborators/[id]/page.d.ts +0 -6
  388. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/collaborators/[id]/page.d.ts.map +0 -1
  389. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/collaborators/[id]/page.js +0 -9
  390. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/collaborators/[id]/page.js.map +0 -1
  391. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/collaborators/[id]/page.tsx +0 -11
  392. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/collaborators/new/page.d.ts +0 -2
  393. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/collaborators/new/page.d.ts.map +0 -1
  394. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/collaborators/new/page.js +0 -8
  395. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/collaborators/new/page.js.map +0 -1
  396. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/collaborators/new/page.tsx +0 -5
  397. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/collaborators/page.d.ts +0 -2
  398. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/collaborators/page.d.ts.map +0 -1
  399. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/collaborators/page.js +0 -612
  400. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/collaborators/page.js.map +0 -1
  401. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/collaborators/page.tsx +0 -939
  402. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/contracts/[id]/edit/page.d.ts +0 -6
  403. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/contracts/[id]/edit/page.d.ts.map +0 -1
  404. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/contracts/[id]/edit/page.js +0 -9
  405. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/contracts/[id]/edit/page.js.map +0 -1
  406. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/contracts/[id]/edit/page.tsx +0 -11
  407. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/contracts/[id]/page.d.ts +0 -6
  408. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/contracts/[id]/page.d.ts.map +0 -1
  409. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/contracts/[id]/page.js +0 -9
  410. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/contracts/[id]/page.js.map +0 -1
  411. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/contracts/[id]/page.tsx +0 -11
  412. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/contracts/new/page.d.ts +0 -6
  413. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/contracts/new/page.d.ts.map +0 -1
  414. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/contracts/new/page.js +0 -9
  415. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/contracts/new/page.js.map +0 -1
  416. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/contracts/new/page.tsx +0 -17
  417. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/contracts/page.d.ts +0 -2
  418. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/contracts/page.d.ts.map +0 -1
  419. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/contracts/page.js +0 -348
  420. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/contracts/page.js.map +0 -1
  421. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/contracts/page.tsx +0 -536
  422. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/departments/page.d.ts +0 -2
  423. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/departments/page.d.ts.map +0 -1
  424. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/departments/page.js +0 -401
  425. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/departments/page.js.map +0 -1
  426. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/departments/page.tsx +0 -607
  427. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/layout.d.ts +0 -5
  428. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/layout.d.ts.map +0 -1
  429. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/layout.js +0 -7
  430. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/layout.js.map +0 -1
  431. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/layout.tsx +0 -9
  432. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/my-projects/[id]/page.d.ts +0 -6
  433. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/my-projects/[id]/page.d.ts.map +0 -1
  434. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/my-projects/[id]/page.js +0 -9
  435. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/my-projects/[id]/page.js.map +0 -1
  436. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/my-projects/[id]/page.tsx +0 -11
  437. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/my-projects/page.d.ts +0 -2
  438. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/my-projects/page.d.ts.map +0 -1
  439. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/my-projects/page.js +0 -321
  440. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/my-projects/page.js.map +0 -1
  441. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/my-projects/page.tsx +0 -440
  442. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/my-tasks/page.d.ts +0 -2
  443. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/my-tasks/page.d.ts.map +0 -1
  444. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/my-tasks/page.js +0 -939
  445. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/my-tasks/page.js.map +0 -1
  446. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/my-tasks/page.tsx +0 -1499
  447. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/page.d.ts +0 -2
  448. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/page.d.ts.map +0 -1
  449. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/page.js +0 -8
  450. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/page.js.map +0 -1
  451. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/page.tsx +0 -5
  452. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/project-cost-categories/page.d.ts +0 -2
  453. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/project-cost-categories/page.d.ts.map +0 -1
  454. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/project-cost-categories/page.js +0 -436
  455. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/project-cost-categories/page.js.map +0 -1
  456. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/project-cost-categories/page.tsx +0 -675
  457. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/project-cost-types/page.d.ts +0 -2
  458. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/project-cost-types/page.d.ts.map +0 -1
  459. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/project-cost-types/page.js +0 -563
  460. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/project-cost-types/page.js.map +0 -1
  461. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/project-cost-types/page.tsx +0 -846
  462. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/projects/[id]/costs-report/page.d.ts +0 -6
  463. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/projects/[id]/costs-report/page.d.ts.map +0 -1
  464. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/projects/[id]/costs-report/page.js +0 -9
  465. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/projects/[id]/costs-report/page.js.map +0 -1
  466. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/projects/[id]/costs-report/page.tsx +0 -10
  467. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/projects/[id]/edit/page.d.ts +0 -6
  468. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/projects/[id]/edit/page.d.ts.map +0 -1
  469. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/projects/[id]/edit/page.js +0 -9
  470. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/projects/[id]/edit/page.js.map +0 -1
  471. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/projects/[id]/edit/page.tsx +0 -11
  472. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/projects/[id]/page.d.ts +0 -6
  473. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/projects/[id]/page.d.ts.map +0 -1
  474. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/projects/[id]/page.js +0 -9
  475. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/projects/[id]/page.js.map +0 -1
  476. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/projects/[id]/page.tsx +0 -11
  477. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/projects/new/page.d.ts +0 -2
  478. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/projects/new/page.d.ts.map +0 -1
  479. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/projects/new/page.js +0 -8
  480. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/projects/new/page.js.map +0 -1
  481. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/projects/new/page.tsx +0 -5
  482. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/projects/page.d.ts +0 -2
  483. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/projects/page.d.ts.map +0 -1
  484. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/projects/page.js +0 -492
  485. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/projects/page.js.map +0 -1
  486. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/projects/page.tsx +0 -757
  487. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/reports/collaborators/page.d.ts +0 -2
  488. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/reports/collaborators/page.d.ts.map +0 -1
  489. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/reports/collaborators/page.js +0 -342
  490. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/reports/collaborators/page.js.map +0 -1
  491. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/reports/collaborators/page.tsx +0 -430
  492. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/reports/projects/page.d.ts +0 -2
  493. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/reports/projects/page.d.ts.map +0 -1
  494. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/reports/projects/page.js +0 -338
  495. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/reports/projects/page.js.map +0 -1
  496. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/reports/projects/page.tsx +0 -428
  497. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/schedule-adjustments/page.d.ts +0 -2
  498. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/schedule-adjustments/page.d.ts.map +0 -1
  499. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/schedule-adjustments/page.js +0 -660
  500. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/schedule-adjustments/page.js.map +0 -1
  501. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/schedule-adjustments/page.tsx +0 -992
  502. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/time-off/page.d.ts +0 -2
  503. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/time-off/page.d.ts.map +0 -1
  504. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/time-off/page.js +0 -515
  505. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/time-off/page.js.map +0 -1
  506. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/time-off/page.tsx +0 -707
  507. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/timesheets/page.d.ts +0 -2
  508. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/timesheets/page.d.ts.map +0 -1
  509. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/timesheets/page.js +0 -1141
  510. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/timesheets/page.js.map +0 -1
  511. package/hedhog/frontend/src/app/(app)/(libraries)/operations/operations/timesheets/page.tsx +0 -1705
  512. package/hedhog/frontend/src/app/(app)/(libraries)/operations/page.d.ts +0 -2
  513. package/hedhog/frontend/src/app/(app)/(libraries)/operations/page.d.ts.map +0 -1
  514. package/hedhog/frontend/src/app/(app)/(libraries)/operations/page.js +0 -8
  515. package/hedhog/frontend/src/app/(app)/(libraries)/operations/page.js.map +0 -1
  516. package/hedhog/frontend/src/app/(app)/(libraries)/operations/page.tsx +0 -5
  517. package/hedhog/frontend/src/app/(app)/(libraries)/operations/project-cost-categories/page.d.ts +0 -2
  518. package/hedhog/frontend/src/app/(app)/(libraries)/operations/project-cost-categories/page.d.ts.map +0 -1
  519. package/hedhog/frontend/src/app/(app)/(libraries)/operations/project-cost-categories/page.js +0 -436
  520. package/hedhog/frontend/src/app/(app)/(libraries)/operations/project-cost-categories/page.js.map +0 -1
  521. package/hedhog/frontend/src/app/(app)/(libraries)/operations/project-cost-categories/page.tsx +0 -675
  522. package/hedhog/frontend/src/app/(app)/(libraries)/operations/project-cost-types/page.d.ts +0 -2
  523. package/hedhog/frontend/src/app/(app)/(libraries)/operations/project-cost-types/page.d.ts.map +0 -1
  524. package/hedhog/frontend/src/app/(app)/(libraries)/operations/project-cost-types/page.js +0 -563
  525. package/hedhog/frontend/src/app/(app)/(libraries)/operations/project-cost-types/page.js.map +0 -1
  526. package/hedhog/frontend/src/app/(app)/(libraries)/operations/project-cost-types/page.tsx +0 -846
  527. package/hedhog/frontend/src/app/(app)/(libraries)/operations/projects/[id]/edit/page.d.ts +0 -6
  528. package/hedhog/frontend/src/app/(app)/(libraries)/operations/projects/[id]/edit/page.d.ts.map +0 -1
  529. package/hedhog/frontend/src/app/(app)/(libraries)/operations/projects/[id]/edit/page.js +0 -9
  530. package/hedhog/frontend/src/app/(app)/(libraries)/operations/projects/[id]/edit/page.js.map +0 -1
  531. package/hedhog/frontend/src/app/(app)/(libraries)/operations/projects/[id]/edit/page.tsx +0 -11
  532. package/hedhog/frontend/src/app/(app)/(libraries)/operations/projects/[id]/page.d.ts +0 -6
  533. package/hedhog/frontend/src/app/(app)/(libraries)/operations/projects/[id]/page.d.ts.map +0 -1
  534. package/hedhog/frontend/src/app/(app)/(libraries)/operations/projects/[id]/page.js +0 -9
  535. package/hedhog/frontend/src/app/(app)/(libraries)/operations/projects/[id]/page.js.map +0 -1
  536. package/hedhog/frontend/src/app/(app)/(libraries)/operations/projects/[id]/page.tsx +0 -11
  537. package/hedhog/frontend/src/app/(app)/(libraries)/operations/projects/new/page.d.ts +0 -2
  538. package/hedhog/frontend/src/app/(app)/(libraries)/operations/projects/new/page.d.ts.map +0 -1
  539. package/hedhog/frontend/src/app/(app)/(libraries)/operations/projects/new/page.js +0 -8
  540. package/hedhog/frontend/src/app/(app)/(libraries)/operations/projects/new/page.js.map +0 -1
  541. package/hedhog/frontend/src/app/(app)/(libraries)/operations/projects/new/page.tsx +0 -5
  542. package/hedhog/frontend/src/app/(app)/(libraries)/operations/projects/page.d.ts +0 -2
  543. package/hedhog/frontend/src/app/(app)/(libraries)/operations/projects/page.d.ts.map +0 -1
  544. package/hedhog/frontend/src/app/(app)/(libraries)/operations/projects/page.js +0 -492
  545. package/hedhog/frontend/src/app/(app)/(libraries)/operations/projects/page.js.map +0 -1
  546. package/hedhog/frontend/src/app/(app)/(libraries)/operations/projects/page.tsx +0 -757
  547. package/hedhog/frontend/src/app/(app)/(libraries)/operations/reports/collaborators/page.d.ts +0 -2
  548. package/hedhog/frontend/src/app/(app)/(libraries)/operations/reports/collaborators/page.d.ts.map +0 -1
  549. package/hedhog/frontend/src/app/(app)/(libraries)/operations/reports/collaborators/page.js +0 -342
  550. package/hedhog/frontend/src/app/(app)/(libraries)/operations/reports/collaborators/page.js.map +0 -1
  551. package/hedhog/frontend/src/app/(app)/(libraries)/operations/reports/collaborators/page.tsx +0 -430
  552. package/hedhog/frontend/src/app/(app)/(libraries)/operations/reports/projects/page.d.ts +0 -2
  553. package/hedhog/frontend/src/app/(app)/(libraries)/operations/reports/projects/page.d.ts.map +0 -1
  554. package/hedhog/frontend/src/app/(app)/(libraries)/operations/reports/projects/page.js +0 -338
  555. package/hedhog/frontend/src/app/(app)/(libraries)/operations/reports/projects/page.js.map +0 -1
  556. package/hedhog/frontend/src/app/(app)/(libraries)/operations/reports/projects/page.tsx +0 -428
  557. package/hedhog/frontend/src/app/(app)/(libraries)/operations/schedule-adjustments/page.d.ts +0 -2
  558. package/hedhog/frontend/src/app/(app)/(libraries)/operations/schedule-adjustments/page.d.ts.map +0 -1
  559. package/hedhog/frontend/src/app/(app)/(libraries)/operations/schedule-adjustments/page.js +0 -660
  560. package/hedhog/frontend/src/app/(app)/(libraries)/operations/schedule-adjustments/page.js.map +0 -1
  561. package/hedhog/frontend/src/app/(app)/(libraries)/operations/schedule-adjustments/page.tsx +0 -992
  562. package/hedhog/frontend/src/app/(app)/(libraries)/operations/time-off/page.d.ts +0 -2
  563. package/hedhog/frontend/src/app/(app)/(libraries)/operations/time-off/page.d.ts.map +0 -1
  564. package/hedhog/frontend/src/app/(app)/(libraries)/operations/time-off/page.js +0 -515
  565. package/hedhog/frontend/src/app/(app)/(libraries)/operations/time-off/page.js.map +0 -1
  566. package/hedhog/frontend/src/app/(app)/(libraries)/operations/time-off/page.tsx +0 -707
  567. package/hedhog/frontend/src/app/(app)/(libraries)/operations/timesheets/page.d.ts +0 -2
  568. package/hedhog/frontend/src/app/(app)/(libraries)/operations/timesheets/page.d.ts.map +0 -1
  569. package/hedhog/frontend/src/app/(app)/(libraries)/operations/timesheets/page.js +0 -1141
  570. package/hedhog/frontend/src/app/(app)/(libraries)/operations/timesheets/page.js.map +0 -1
  571. package/hedhog/frontend/src/app/(app)/(libraries)/operations/timesheets/page.tsx +0 -1705
@@ -1,1705 +0,0 @@
1
- 'use client';
2
-
3
- import {
4
- EmptyState,
5
- Page,
6
- PaginationFooter,
7
- SearchBar,
8
- } from '@/components/entity-list';
9
- import {
10
- AlertDialog,
11
- AlertDialogAction,
12
- AlertDialogCancel,
13
- AlertDialogContent,
14
- AlertDialogDescription,
15
- AlertDialogFooter,
16
- AlertDialogHeader,
17
- AlertDialogTitle,
18
- } from '@/components/ui/alert-dialog';
19
- import { Button } from '@/components/ui/button';
20
- import {
21
- Form,
22
- FormControl,
23
- FormField,
24
- FormItem,
25
- FormLabel,
26
- FormMessage,
27
- } from '@/components/ui/form';
28
- import { FormActions } from '@/components/ui/form-actions';
29
- import { Input } from '@/components/ui/input';
30
- import { KpiCardsGrid } from '@/components/ui/kpi-cards-grid';
31
- import {
32
- Sheet,
33
- SheetContent,
34
- SheetDescription,
35
- SheetHeader,
36
- SheetTitle,
37
- } from '@/components/ui/sheet';
38
- import { Switch } from '@/components/ui/switch';
39
- import {
40
- Table,
41
- TableBody,
42
- TableCell,
43
- TableHead,
44
- TableHeader,
45
- TableRow,
46
- } from '@/components/ui/table';
47
- import { Textarea } from '@/components/ui/textarea';
48
- import { ToggleGroup, ToggleGroupItem } from '@/components/ui/toggle-group';
49
- import { useApp, useQuery } from '@hed-hog/next-app-provider';
50
- import { zodResolver } from '@hookform/resolvers/zod';
51
- import {
52
- CalendarDays,
53
- ClipboardList,
54
- Clock3,
55
- Eye,
56
- LayoutGrid,
57
- List,
58
- Loader2,
59
- Pencil,
60
- Plus,
61
- Send,
62
- Trash2,
63
- } from 'lucide-react';
64
- import { useTranslations } from 'next-intl';
65
- import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
66
- import { useForm, useWatch } from 'react-hook-form';
67
- import { z } from 'zod';
68
-
69
- import { AsyncOptionsCombobox } from '../_components/async-options-combobox';
70
- import {
71
- OperationsCalendarView,
72
- type OperationsCalendarItem,
73
- } from '../_components/operations-calendar-view';
74
- import { OperationsHeader } from '../_components/operations-header';
75
- import { StatusBadge } from '../_components/status-badge';
76
- import { TimesheetTaskCreateSheet } from '../_components/timesheet-task-create-sheet';
77
- import {
78
- fetchOperations,
79
- getOperationsErrorMessage,
80
- mutateOperations,
81
- } from '../_lib/api';
82
- import { useOperationsAccess } from '../_lib/hooks/use-operations-access';
83
- import type {
84
- OperationsCollaborator,
85
- OperationsProjectOption,
86
- OperationsTaskOption,
87
- OperationsTimesheet,
88
- OperationsTimesheetEntry,
89
- PaginatedResponse,
90
- } from '../_lib/types';
91
- import {
92
- formatDate,
93
- formatEnumLabel,
94
- formatHours,
95
- getStatusBadgeClass,
96
- } from '../_lib/utils/format';
97
- import { trimToNull } from '../_lib/utils/forms';
98
-
99
- type QuickEntryFormValues = {
100
- projectId?: number;
101
- taskId?: number;
102
- workDate: string;
103
- duration?: number;
104
- unit: 'hours' | 'minutes';
105
- description: string;
106
- };
107
-
108
- const getTodayDate = () => {
109
- const now = new Date();
110
- return `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')}`;
111
- };
112
-
113
- const buildDefaultFormValues = (): QuickEntryFormValues => ({
114
- projectId: undefined,
115
- taskId: undefined,
116
- workDate: getTodayDate(),
117
- duration: undefined,
118
- unit: 'hours',
119
- description: '',
120
- });
121
-
122
- const positiveNumberField = (message: string) =>
123
- z.preprocess(
124
- (value) => {
125
- if (value === '' || value === null || value === undefined) {
126
- return undefined;
127
- }
128
-
129
- if (typeof value === 'number') {
130
- return value;
131
- }
132
-
133
- const parsed = Number(value);
134
- return Number.isNaN(parsed) ? value : parsed;
135
- },
136
- z.number({ required_error: message }).positive(message)
137
- );
138
-
139
- function appendUniqueById<T extends { id: number | string }>(
140
- current: T[],
141
- next: T[]
142
- ) {
143
- const unique = new Map<string, T>();
144
-
145
- [...current, ...next].forEach((item) => {
146
- unique.set(String(item.id), item);
147
- });
148
-
149
- return Array.from(unique.values());
150
- }
151
-
152
- function formatDateLabel(value?: string | null) {
153
- if (!value) {
154
- return '—';
155
- }
156
-
157
- // Always extract just the YYYY-MM-DD part to avoid UTC offset shifting the date
158
- const match = String(value).match(/(\d{4}-\d{2}-\d{2})/);
159
- if (!match) {
160
- return value;
161
- }
162
-
163
- const date = new Date(`${match[1]}T12:00:00`);
164
-
165
- if (Number.isNaN(date.getTime())) {
166
- return value;
167
- }
168
-
169
- return new Intl.DateTimeFormat(undefined, {
170
- day: '2-digit',
171
- month: 'short',
172
- year: 'numeric',
173
- }).format(date);
174
- }
175
-
176
- function formatEntryDuration(minutes?: number | null, hours?: number | null) {
177
- if (typeof minutes === 'number' && Number.isFinite(minutes) && minutes > 0) {
178
- const wholeHours = Math.floor(minutes / 60);
179
- const remainingMinutes = minutes % 60;
180
-
181
- if (!wholeHours) {
182
- return `${remainingMinutes}m`;
183
- }
184
-
185
- if (!remainingMinutes) {
186
- return `${wholeHours}h`;
187
- }
188
-
189
- return `${wholeHours}h ${remainingMinutes}m`;
190
- }
191
-
192
- return formatHours(Number(hours ?? 0));
193
- }
194
-
195
- function buildFollowUpFormValues(
196
- current: QuickEntryFormValues,
197
- keepContextOnSave: boolean
198
- ): QuickEntryFormValues {
199
- if (!keepContextOnSave) {
200
- return buildDefaultFormValues();
201
- }
202
-
203
- return {
204
- projectId: current.projectId,
205
- taskId: current.taskId,
206
- workDate: current.workDate || getTodayDate(),
207
- duration: 0,
208
- unit: current.unit ?? 'hours',
209
- description: '',
210
- };
211
- }
212
-
213
- function buildEntryFormValues(
214
- entry: OperationsTimesheetEntry
215
- ): QuickEntryFormValues {
216
- return {
217
- projectId: entry.projectId ?? undefined,
218
- taskId: entry.taskId ?? undefined,
219
- workDate: String(entry.workDate).match(/(\d{4}-\d{2}-\d{2})/)?.[1] ?? '',
220
- duration:
221
- typeof entry.durationMinutes === 'number' && entry.durationMinutes > 0
222
- ? Number((entry.durationMinutes / 60).toFixed(2))
223
- : Number(entry.hours ?? 0),
224
- unit: 'hours',
225
- description: entry.description ?? '',
226
- };
227
- }
228
-
229
- export default function OperationsTimesheetsPage() {
230
- const t = useTranslations('operations.TimesheetsPage');
231
- const commonT = useTranslations('operations.Common');
232
- const { request, showToastHandler, currentLocaleCode } = useApp();
233
- const access = useOperationsAccess();
234
- const [search, setSearch] = useState('');
235
- const [statusFilter, setStatusFilter] = useState('all');
236
- const [dateFrom, setDateFrom] = useState('');
237
- const [dateTo, setDateTo] = useState('');
238
- const [calendarYear, setCalendarYear] = useState(() =>
239
- new Date().getFullYear()
240
- );
241
- const [calendarMonth, setCalendarMonth] = useState(
242
- () => new Date().getMonth() + 1
243
- );
244
- const [page, setPage] = useState(1);
245
- const [pageSize, setPageSize] = useState(12);
246
- const [viewMode, setViewMode] = useState<'table' | 'cards' | 'calendar'>(
247
- () => {
248
- if (typeof window === 'undefined') return 'table';
249
- const saved = window.localStorage.getItem(
250
- 'operations-timesheets-view-mode'
251
- );
252
- return saved === 'cards' || saved === 'calendar' ? saved : 'table';
253
- }
254
- );
255
- const [isSheetOpen, setIsSheetOpen] = useState(false);
256
- const [isDetailsOpen, setIsDetailsOpen] = useState(false);
257
- const [isTaskCreateSheetOpen, setIsTaskCreateSheetOpen] = useState(false);
258
- const [keepContextOnSave, setKeepContextOnSave] = useState(true);
259
- const [editingEntry, setEditingEntry] =
260
- useState<OperationsTimesheetEntry | null>(null);
261
- const [entryToDelete, setEntryToDelete] =
262
- useState<OperationsTimesheetEntry | null>(null);
263
- const [selectedTimesheet, setSelectedTimesheet] =
264
- useState<OperationsTimesheet | null>(null);
265
- const [isDeletingEntry, setIsDeletingEntry] = useState(false);
266
- const [projectQuery, setProjectQuery] = useState({ search: '', page: 1 });
267
- const [projectOptions, setProjectOptions] = useState<
268
- OperationsProjectOption[]
269
- >([]);
270
- const [taskQuery, setTaskQuery] = useState({ search: '', page: 1 });
271
- const [taskRefreshKey, setTaskRefreshKey] = useState(0);
272
- const [taskOptions, setTaskOptions] = useState<OperationsTaskOption[]>([]);
273
- const previousProjectIdRef = useRef<number | undefined>(undefined);
274
-
275
- const quickEntrySchema = useMemo(
276
- () =>
277
- z.object({
278
- projectId: positiveNumberField(t('messages.selectProjectRequired')),
279
- taskId: positiveNumberField(t('messages.selectTaskRequired')),
280
- workDate: z.string().min(1, t('messages.requiredFields')),
281
- duration: positiveNumberField(t('messages.entryValidation')),
282
- unit: z.enum(['hours', 'minutes']),
283
- description: z
284
- .string()
285
- .trim()
286
- .max(500, t('sheet.validation.descriptionMaxLength'))
287
- .optional()
288
- .or(z.literal('')),
289
- }),
290
- [t]
291
- );
292
-
293
- const form = useForm<QuickEntryFormValues>({
294
- resolver: zodResolver(quickEntrySchema),
295
- defaultValues: buildDefaultFormValues(),
296
- });
297
-
298
- const selectedProjectId = useWatch({
299
- control: form.control,
300
- name: 'projectId',
301
- });
302
-
303
- const selectedTaskId = useWatch({
304
- control: form.control,
305
- name: 'taskId',
306
- });
307
-
308
- const unitValue = useWatch({
309
- control: form.control,
310
- name: 'unit',
311
- });
312
-
313
- const { data: timesheetsResponse, refetch } = useQuery<
314
- PaginatedResponse<OperationsTimesheet>
315
- >({
316
- queryKey: [
317
- 'operations-timesheets',
318
- currentLocaleCode,
319
- search,
320
- statusFilter,
321
- dateFrom,
322
- dateTo,
323
- page,
324
- pageSize,
325
- ],
326
- queryFn: () => {
327
- const params = new URLSearchParams({
328
- page: String(page),
329
- pageSize: String(pageSize),
330
- });
331
- if (search.trim()) params.set('search', search.trim());
332
- if (statusFilter !== 'all') params.set('status', statusFilter);
333
- if (dateFrom) params.set('dateFrom', dateFrom);
334
- if (dateTo) params.set('dateTo', dateTo);
335
- return fetchOperations<PaginatedResponse<OperationsTimesheet>>(
336
- request,
337
- `/operations/timesheets?${params.toString()}`
338
- );
339
- },
340
- placeholderData: (previous) => previous,
341
- });
342
-
343
- const timesheets = timesheetsResponse?.data ?? [];
344
-
345
- const calendarDateFrom = `${String(calendarYear)}-${String(calendarMonth).padStart(2, '0')}-01`;
346
- const calendarDateTo = (() => {
347
- const lastDay = new Date(calendarYear, calendarMonth, 0).getDate();
348
- return `${String(calendarYear)}-${String(calendarMonth).padStart(2, '0')}-${String(lastDay).padStart(2, '0')}`;
349
- })();
350
-
351
- const { data: calendarTimesheetsResponse } = useQuery<
352
- PaginatedResponse<OperationsTimesheet>
353
- >({
354
- queryKey: [
355
- 'operations-timesheets-calendar',
356
- currentLocaleCode,
357
- search,
358
- statusFilter,
359
- calendarYear,
360
- calendarMonth,
361
- ],
362
- enabled: viewMode === 'calendar',
363
- queryFn: () => {
364
- const params = new URLSearchParams({
365
- sortField: 'weekStartDate',
366
- sortOrder: 'desc',
367
- dateFrom: calendarDateFrom,
368
- dateTo: calendarDateTo,
369
- });
370
- if (search.trim()) params.set('search', search.trim());
371
- if (statusFilter !== 'all') params.set('status', statusFilter);
372
- return fetchOperations<PaginatedResponse<OperationsTimesheet>>(
373
- request,
374
- `/operations/timesheets?${params.toString()}`
375
- );
376
- },
377
- placeholderData: (previous) => previous,
378
- });
379
- const calendarTimesheets = useMemo(
380
- () => calendarTimesheetsResponse?.data ?? [],
381
- [calendarTimesheetsResponse]
382
- );
383
-
384
- const getTimesheetStatusLabel = useCallback(
385
- (status?: string | null) => {
386
- if (!status) {
387
- return commonT('labels.notAvailable');
388
- }
389
-
390
- return t.has(`statuses.${status}`)
391
- ? t(`statuses.${status}`)
392
- : formatEnumLabel(status);
393
- },
394
- [commonT, t]
395
- );
396
-
397
- const handleViewModeChange = (value: string) => {
398
- if (value !== 'table' && value !== 'cards' && value !== 'calendar') return;
399
- setViewMode(value as 'table' | 'cards' | 'calendar');
400
- if (typeof window !== 'undefined') {
401
- window.localStorage.setItem('operations-timesheets-view-mode', value);
402
- }
403
- };
404
-
405
- const { data: me } = useQuery<OperationsCollaborator>({
406
- queryKey: ['operations-timesheets-me', currentLocaleCode],
407
- enabled: access.isCollaborator,
408
- queryFn: () =>
409
- fetchOperations<OperationsCollaborator>(
410
- request,
411
- '/operations/collaborators/me'
412
- ),
413
- });
414
-
415
- const { refetch: refetchRecentEntries } = useQuery<
416
- PaginatedResponse<OperationsTimesheetEntry>
417
- >({
418
- queryKey: [
419
- 'operations-timesheet-recent-entries',
420
- currentLocaleCode,
421
- search,
422
- statusFilter,
423
- ],
424
- enabled: access.isCollaborator,
425
- queryFn: () => {
426
- const params = new URLSearchParams({
427
- page: '1',
428
- pageSize: '8',
429
- sortField: 'workDate',
430
- sortOrder: 'desc',
431
- });
432
-
433
- if (search.trim()) {
434
- params.set('search', search.trim());
435
- }
436
-
437
- if (statusFilter !== 'all') {
438
- params.set('status', statusFilter);
439
- }
440
-
441
- return fetchOperations<PaginatedResponse<OperationsTimesheetEntry>>(
442
- request,
443
- `/operations/timesheet-entries?${params.toString()}`
444
- );
445
- },
446
- placeholderData: (previous) => previous,
447
- });
448
-
449
- const {
450
- data: projectOptionsResponse,
451
- isLoading: isProjectOptionsLoading,
452
- error: projectOptionsError,
453
- } = useQuery<PaginatedResponse<OperationsProjectOption>>({
454
- queryKey: [
455
- 'operations-timesheet-project-options',
456
- currentLocaleCode,
457
- projectQuery.search,
458
- projectQuery.page,
459
- ],
460
- enabled: access.isCollaborator && isSheetOpen,
461
- queryFn: () => {
462
- const params = new URLSearchParams({
463
- page: String(projectQuery.page),
464
- pageSize: '20',
465
- });
466
-
467
- if (projectQuery.search.trim()) {
468
- params.set('search', projectQuery.search.trim());
469
- }
470
-
471
- return fetchOperations<PaginatedResponse<OperationsProjectOption>>(
472
- request,
473
- `/operations/projects/options?${params.toString()}`
474
- );
475
- },
476
- placeholderData: (previous) => previous,
477
- });
478
-
479
- const selectedProject =
480
- projectOptions.find((option) => option.id === selectedProjectId) ?? null;
481
-
482
- const {
483
- data: taskOptionsResponse,
484
- isLoading: isTaskOptionsLoading,
485
- error: taskOptionsError,
486
- } = useQuery<PaginatedResponse<OperationsTaskOption>>({
487
- queryKey: [
488
- 'operations-timesheet-task-options',
489
- currentLocaleCode,
490
- selectedProjectId,
491
- taskQuery.search,
492
- taskQuery.page,
493
- taskRefreshKey,
494
- ],
495
- enabled: access.isCollaborator && isSheetOpen && Boolean(selectedProjectId),
496
- queryFn: () => {
497
- const params = new URLSearchParams({
498
- page: String(taskQuery.page),
499
- pageSize: '20',
500
- });
501
-
502
- if (taskQuery.search.trim()) {
503
- params.set('search', taskQuery.search.trim());
504
- }
505
-
506
- if (selectedProjectId) {
507
- params.set('projectId', String(selectedProjectId));
508
- }
509
-
510
- return fetchOperations<PaginatedResponse<OperationsTaskOption>>(
511
- request,
512
- `/operations/tasks?${params.toString()}`
513
- );
514
- },
515
- });
516
-
517
- useEffect(() => {
518
- if (!projectOptionsResponse) {
519
- return;
520
- }
521
-
522
- setProjectOptions((current) =>
523
- projectQuery.page === 1
524
- ? editingEntry
525
- ? appendUniqueById(current, projectOptionsResponse.data ?? [])
526
- : (projectOptionsResponse.data ?? [])
527
- : appendUniqueById(current, projectOptionsResponse.data ?? [])
528
- );
529
- }, [editingEntry, projectOptionsResponse, projectQuery.page]);
530
-
531
- useEffect(() => {
532
- if (!selectedProjectId) {
533
- setTaskOptions([]);
534
- return;
535
- }
536
-
537
- if (!taskOptionsResponse) {
538
- return;
539
- }
540
-
541
- setTaskOptions((current) =>
542
- taskQuery.page === 1
543
- ? editingEntry
544
- ? appendUniqueById(
545
- current,
546
- (taskOptionsResponse.data ?? []).filter(
547
- (option) => option.projectId === selectedProjectId
548
- )
549
- )
550
- : (taskOptionsResponse.data ?? []).filter(
551
- (option) => option.projectId === selectedProjectId
552
- )
553
- : appendUniqueById(
554
- current,
555
- (taskOptionsResponse.data ?? []).filter(
556
- (option) => option.projectId === selectedProjectId
557
- )
558
- )
559
- );
560
- }, [editingEntry, selectedProjectId, taskOptionsResponse, taskQuery.page]);
561
-
562
- useEffect(() => {
563
- const previousProjectId = previousProjectIdRef.current;
564
- previousProjectIdRef.current = selectedProjectId;
565
-
566
- if (
567
- previousProjectId === undefined ||
568
- previousProjectId === selectedProjectId
569
- ) {
570
- return;
571
- }
572
-
573
- setTaskOptions([]);
574
- setTaskQuery({ search: '', page: 1 });
575
- form.setValue('taskId', undefined, {
576
- shouldDirty: true,
577
- shouldTouch: true,
578
- shouldValidate: false,
579
- });
580
- }, [form, selectedProjectId]);
581
-
582
- useEffect(() => {
583
- if (!projectOptionsError) {
584
- return;
585
- }
586
-
587
- showToastHandler?.(
588
- 'error',
589
- getOperationsErrorMessage(
590
- projectOptionsError,
591
- t('messages.projectLoadError')
592
- )
593
- );
594
- }, [projectOptionsError, showToastHandler, t]);
595
-
596
- useEffect(() => {
597
- if (!taskOptionsError) {
598
- return;
599
- }
600
-
601
- showToastHandler?.(
602
- 'error',
603
- getOperationsErrorMessage(taskOptionsError, t('messages.taskLoadError'))
604
- );
605
- }, [showToastHandler, t, taskOptionsError]);
606
-
607
- const filteredTaskOptions = selectedProjectId
608
- ? taskOptions.filter((option) => option.projectId === selectedProjectId)
609
- : [];
610
- const selectedTask =
611
- filteredTaskOptions.find((option) => option.id === selectedTaskId) ?? null;
612
- const isEditingEntry = Boolean(editingEntry);
613
-
614
- const filteredRows = timesheets;
615
- const calendarItems = useMemo<OperationsCalendarItem[]>(
616
- () =>
617
- calendarTimesheets.map((timesheet) => ({
618
- id: `timesheet-${timesheet.id}`,
619
- date:
620
- String(timesheet.weekStartDate).match(/(\d{4}-\d{2}-\d{2})/)?.[1] ??
621
- timesheet.weekStartDate,
622
- kind: 'timesheet',
623
- title: `${formatHours(timesheet.totalHours)} • ${timesheet.collaboratorName}`,
624
- subtitle:
625
- (timesheet.entries ?? [])
626
- .slice(0, 2)
627
- .map(
628
- (entry) =>
629
- [entry.projectName, entry.taskName || entry.activityLabel]
630
- .filter(Boolean)
631
- .join(' • ') || commonT('labels.unassigned')
632
- )
633
- .join(', ') || commonT('labels.unassigned'),
634
- meta: `${timesheet.entries?.length ?? 0} ${commonT('labels.lines')}`,
635
- statusLabel: getTimesheetStatusLabel(timesheet.status),
636
- badgeClassName: getStatusBadgeClass(timesheet.status),
637
- })),
638
- [calendarTimesheets, commonT, getTimesheetStatusLabel]
639
- );
640
-
641
- const cards = [
642
- {
643
- key: 'all',
644
- title: t('cards.visible'),
645
- description: t('cards.visibleDescription'),
646
- value: timesheets.length,
647
- },
648
- {
649
- key: 'pending',
650
- title: t('cards.pending'),
651
- description: t('cards.pendingDescription'),
652
- value: timesheets.filter((item) => item.status === 'submitted').length,
653
- },
654
- {
655
- key: 'hours',
656
- title: t('cards.hours'),
657
- description: t('cards.hoursDescription'),
658
- value: formatHours(
659
- timesheets.reduce(
660
- (total, item) => total + Number(item.totalHours ?? 0),
661
- 0
662
- )
663
- ),
664
- },
665
- ];
666
-
667
- const openCreate = () => {
668
- setEditingEntry(null);
669
- form.reset(buildDefaultFormValues());
670
- setProjectQuery({ search: '', page: 1 });
671
- setTaskQuery({ search: '', page: 1 });
672
- setProjectOptions([]);
673
- setTaskOptions([]);
674
- setIsTaskCreateSheetOpen(false);
675
- setIsSheetOpen(true);
676
- };
677
-
678
- const closeCreateSheet = () => {
679
- setIsSheetOpen(false);
680
- setEditingEntry(null);
681
- setIsTaskCreateSheetOpen(false);
682
- form.reset(buildDefaultFormValues());
683
- setProjectQuery({ search: '', page: 1 });
684
- setTaskQuery({ search: '', page: 1 });
685
- setProjectOptions([]);
686
- setTaskOptions([]);
687
- };
688
-
689
- const openDetails = (timesheet: OperationsTimesheet) => {
690
- setSelectedTimesheet(timesheet);
691
- setIsDetailsOpen(true);
692
- };
693
-
694
- const openEditEntry = (entry: OperationsTimesheetEntry) => {
695
- setEditingEntry(entry);
696
- form.reset(buildEntryFormValues(entry));
697
- setProjectQuery({ search: '', page: 1 });
698
- setTaskQuery({ search: '', page: 1 });
699
- setProjectOptions((current) =>
700
- appendUniqueById(
701
- current,
702
- entry.projectId && entry.projectName
703
- ? [
704
- {
705
- id: entry.projectId,
706
- label:
707
- [entry.projectCode, entry.projectName]
708
- .filter(Boolean)
709
- .join(' • ') || entry.projectName,
710
- name: entry.projectName,
711
- code: entry.projectCode,
712
- status: entry.status ?? 'submitted',
713
- },
714
- ]
715
- : []
716
- )
717
- );
718
- setTaskOptions((current) =>
719
- appendUniqueById(
720
- current,
721
- entry.taskId && entry.projectId
722
- ? [
723
- {
724
- id: entry.taskId,
725
- label:
726
- entry.taskName ||
727
- entry.activityLabel ||
728
- commonT('labels.unassigned'),
729
- name:
730
- entry.taskName ||
731
- entry.activityLabel ||
732
- commonT('labels.unassigned'),
733
- status: entry.status ?? 'submitted',
734
- projectId: entry.projectId,
735
- projectAssignmentId: entry.projectAssignmentId ?? 0,
736
- projectName:
737
- entry.projectName || commonT('labels.unassigned'),
738
- },
739
- ]
740
- : []
741
- )
742
- );
743
- setEntryToDelete(null);
744
- setIsDetailsOpen(false);
745
- setIsTaskCreateSheetOpen(false);
746
- setIsSheetOpen(true);
747
- };
748
-
749
- const openTimesheetForDate = (date: string) => {
750
- const existingTimesheet =
751
- calendarTimesheets.find((item) => item.weekStartDate === date) ??
752
- timesheets.find((item) => item.weekStartDate === date);
753
-
754
- if (existingTimesheet) {
755
- openDetails(existingTimesheet);
756
- return;
757
- }
758
-
759
- setEditingEntry(null);
760
- form.reset({
761
- ...buildDefaultFormValues(),
762
- workDate: date,
763
- });
764
- setProjectQuery({ search: '', page: 1 });
765
- setTaskQuery({ search: '', page: 1 });
766
- setProjectOptions([]);
767
- setTaskOptions([]);
768
- setIsTaskCreateSheetOpen(false);
769
- setIsSheetOpen(true);
770
- };
771
-
772
- const canManageRow = (timesheet: OperationsTimesheet) => {
773
- return Boolean(
774
- me?.id &&
775
- timesheet.collaboratorId === me.id &&
776
- timesheet.status !== 'approved'
777
- );
778
- };
779
-
780
- const canSubmitTimesheet = (timesheet: OperationsTimesheet) => {
781
- return Boolean(
782
- me?.id &&
783
- timesheet.collaboratorId === me.id &&
784
- ['draft', 'rejected'].includes(timesheet.status)
785
- );
786
- };
787
-
788
- const handleQuickEntrySubmit = async (values: QuickEntryFormValues) => {
789
- const payload = {
790
- projectId: values.projectId,
791
- taskId: values.taskId,
792
- workDate: values.workDate,
793
- duration: values.duration,
794
- unit: values.unit,
795
- description: trimToNull(values.description),
796
- };
797
-
798
- try {
799
- if (editingEntry?.id) {
800
- await mutateOperations(
801
- request,
802
- `/operations/timesheet-entries/${editingEntry.id}`,
803
- 'PATCH',
804
- payload
805
- );
806
- } else {
807
- await mutateOperations(
808
- request,
809
- '/operations/timesheet-entries',
810
- 'POST',
811
- payload
812
- );
813
- }
814
-
815
- showToastHandler?.(
816
- 'success',
817
- editingEntry ? t('messages.updateSuccess') : t('messages.saveSuccess')
818
- );
819
-
820
- if (!editingEntry && keepContextOnSave) {
821
- form.reset(buildFollowUpFormValues(values, true));
822
- setProjectQuery({ search: '', page: 1 });
823
- setTaskQuery({ search: '', page: 1 });
824
- setIsTaskCreateSheetOpen(false);
825
- setTimeout(() => form.setFocus('duration'), 0);
826
- } else {
827
- closeCreateSheet();
828
- }
829
-
830
- await Promise.all([refetch(), refetchRecentEntries()]);
831
- } catch (error) {
832
- showToastHandler?.(
833
- 'error',
834
- getOperationsErrorMessage(
835
- error,
836
- editingEntry ? t('messages.updateError') : t('messages.saveError')
837
- )
838
- );
839
- }
840
- };
841
-
842
- const submitTimesheet = async (timesheetId: number) => {
843
- try {
844
- await request({
845
- url: `/operations/timesheets/${timesheetId}/submit`,
846
- method: 'POST',
847
- });
848
- showToastHandler?.('success', t('messages.submitSuccess'));
849
- await Promise.all([refetch(), refetchRecentEntries()]);
850
- } catch (error) {
851
- showToastHandler?.(
852
- 'error',
853
- getOperationsErrorMessage(error, t('messages.submitError'))
854
- );
855
- }
856
- };
857
-
858
- const openTaskCreateSheet = () => {
859
- if (!selectedProjectId || !selectedProject) {
860
- showToastHandler?.('error', t('messages.selectProjectFirst'));
861
- return;
862
- }
863
-
864
- setIsTaskCreateSheetOpen(true);
865
- };
866
-
867
- const handleTaskCreated = (task: OperationsTaskOption) => {
868
- setTaskOptions((current) => [
869
- task,
870
- ...current.filter((item) => item.id !== task.id),
871
- ]);
872
- form.setValue('taskId', task.id, {
873
- shouldDirty: true,
874
- shouldTouch: true,
875
- shouldValidate: true,
876
- });
877
- setTaskQuery({ search: '', page: 1 });
878
- setTaskRefreshKey((current) => current + 1);
879
- };
880
-
881
- const handleDeleteEntry = async () => {
882
- if (!entryToDelete?.id) {
883
- return;
884
- }
885
-
886
- try {
887
- setIsDeletingEntry(true);
888
- await mutateOperations(
889
- request,
890
- `/operations/timesheet-entries/${entryToDelete.id}`,
891
- 'DELETE'
892
- );
893
- showToastHandler?.('success', t('messages.deleteSuccess'));
894
- setEntryToDelete(null);
895
- await Promise.all([refetch(), refetchRecentEntries()]);
896
- } catch (error) {
897
- showToastHandler?.(
898
- 'error',
899
- getOperationsErrorMessage(error, t('messages.deleteError'))
900
- );
901
- } finally {
902
- setIsDeletingEntry(false);
903
- }
904
- };
905
-
906
- return (
907
- <Page>
908
- <OperationsHeader
909
- title={t('title')}
910
- description={t('description')}
911
- current={t('breadcrumb')}
912
- actions={
913
- access.isCollaborator ? (
914
- <Button size="sm" onClick={openCreate}>
915
- <Plus className="size-4" />
916
- {commonT('actions.create')}
917
- </Button>
918
- ) : undefined
919
- }
920
- />
921
-
922
- <div className="flex min-w-0 flex-col gap-4 xl:flex-row xl:items-center">
923
- <div className="flex-1">
924
- <SearchBar
925
- searchQuery={search}
926
- onSearchChange={(value) => {
927
- setSearch(value);
928
- setPage(1);
929
- }}
930
- showSearchButton={false}
931
- debounceMs={500}
932
- placeholder={t('searchPlaceholder')}
933
- controls={[
934
- {
935
- id: 'status',
936
- type: 'select',
937
- value: statusFilter,
938
- onChange: (value) => {
939
- setStatusFilter(value);
940
- setPage(1);
941
- },
942
- placeholder: commonT('labels.status'),
943
- options: [
944
- { value: 'all', label: commonT('filters.allStatuses') },
945
- { value: 'draft', label: getTimesheetStatusLabel('draft') },
946
- {
947
- value: 'submitted',
948
- label: getTimesheetStatusLabel('submitted'),
949
- },
950
- {
951
- value: 'approved',
952
- label: getTimesheetStatusLabel('approved'),
953
- },
954
- {
955
- value: 'rejected',
956
- label: getTimesheetStatusLabel('rejected'),
957
- },
958
- ],
959
- },
960
- {
961
- id: 'dateFrom',
962
- type: 'date',
963
- value: dateFrom,
964
- onChange: (value) => {
965
- setDateFrom(value);
966
- setPage(1);
967
- },
968
- label: commonT('filters.dateFrom'),
969
- },
970
- {
971
- id: 'dateTo',
972
- type: 'date',
973
- value: dateTo,
974
- onChange: (value) => {
975
- setDateTo(value);
976
- setPage(1);
977
- },
978
- label: commonT('filters.dateTo'),
979
- },
980
- ]}
981
- />
982
- </div>
983
-
984
- <div className="flex items-center justify-between gap-3 xl:justify-end">
985
- <span className="text-xs font-medium text-muted-foreground">
986
- {t('viewMode')}
987
- </span>
988
- <ToggleGroup
989
- type="single"
990
- value={viewMode}
991
- onValueChange={handleViewModeChange}
992
- variant="outline"
993
- size="sm"
994
- >
995
- <ToggleGroupItem value="table" className="gap-1.5 px-2.5">
996
- <List className="h-4 w-4" />
997
- <span className="hidden sm:inline">{t('viewModeTable')}</span>
998
- </ToggleGroupItem>
999
- <ToggleGroupItem value="cards" className="gap-1.5 px-2.5">
1000
- <LayoutGrid className="h-4 w-4" />
1001
- <span className="hidden sm:inline">{t('viewModeCards')}</span>
1002
- </ToggleGroupItem>
1003
- <ToggleGroupItem value="calendar" className="gap-1.5 px-2.5">
1004
- <CalendarDays className="h-4 w-4" />
1005
- <span className="hidden sm:inline">{t('viewModeCalendar')}</span>
1006
- </ToggleGroupItem>
1007
- </ToggleGroup>
1008
- </div>
1009
- </div>
1010
-
1011
- <KpiCardsGrid items={cards} columns={3} />
1012
-
1013
- {(viewMode === 'calendar' ? true : timesheets.length > 0) ? (
1014
- viewMode === 'calendar' ? (
1015
- <OperationsCalendarView
1016
- locale={currentLocaleCode}
1017
- items={calendarItems}
1018
- emptyLabel={t('emptyDescription')}
1019
- actionLabel={t('actions.viewDetails')}
1020
- onMonthChange={(year, month) => {
1021
- setCalendarYear(year);
1022
- setCalendarMonth(month);
1023
- }}
1024
- onOpenItem={(item) => {
1025
- openTimesheetForDate(item.date);
1026
- }}
1027
- onDateSelect={(date, items) => {
1028
- if (items.some((item) => item.kind === 'timesheet')) {
1029
- openTimesheetForDate(date);
1030
- }
1031
- }}
1032
- />
1033
- ) : viewMode === 'cards' ? (
1034
- <div className="grid gap-4 md:grid-cols-2 2xl:grid-cols-3">
1035
- {timesheets.map((timesheet) => (
1036
- <div
1037
- key={timesheet.id}
1038
- className="rounded-lg border bg-card shadow-sm p-4 space-y-3"
1039
- >
1040
- <div className="flex items-start justify-between gap-3">
1041
- <div className="min-w-0">
1042
- <div className="truncate font-semibold">
1043
- {timesheet.collaboratorName}
1044
- </div>
1045
- <div className="truncate text-xs text-muted-foreground">
1046
- {formatDate(timesheet.weekStartDate)}
1047
- </div>
1048
- </div>
1049
- <StatusBadge
1050
- label={getTimesheetStatusLabel(timesheet.status)}
1051
- className={getStatusBadgeClass(timesheet.status)}
1052
- />
1053
- </div>
1054
- <div className="grid grid-cols-2 gap-2 text-sm text-muted-foreground">
1055
- <div>
1056
- <span className="font-medium text-foreground">
1057
- {commonT('labels.totalHours')}:
1058
- </span>{' '}
1059
- {formatHours(timesheet.totalHours)}
1060
- </div>
1061
- <div>
1062
- <span className="font-medium text-foreground">
1063
- {commonT('labels.entries')}:
1064
- </span>{' '}
1065
- {timesheet.entries?.length ?? 0}
1066
- </div>
1067
- </div>
1068
- {timesheet.approverName ? (
1069
- <div className="text-sm text-muted-foreground">
1070
- <span className="font-medium text-foreground">
1071
- {commonT('labels.approver')}:
1072
- </span>{' '}
1073
- {timesheet.approverName}
1074
- </div>
1075
- ) : null}
1076
- {canManageRow(timesheet) ? (
1077
- <div className="flex justify-end gap-2 border-t border-border/60 pt-3">
1078
- <Button
1079
- variant="outline"
1080
- size="sm"
1081
- className="cursor-pointer"
1082
- onClick={() => openDetails(timesheet)}
1083
- >
1084
- <Eye className="size-4" />
1085
- {t('actions.viewDetails')}
1086
- </Button>
1087
- {canSubmitTimesheet(timesheet) ? (
1088
- <Button
1089
- size="sm"
1090
- onClick={() => void submitTimesheet(timesheet.id)}
1091
- >
1092
- <Send className="size-4" />
1093
- {commonT('actions.submit')}
1094
- </Button>
1095
- ) : null}
1096
- </div>
1097
- ) : (
1098
- <div className="flex justify-end border-t border-border/60 pt-3">
1099
- <Button
1100
- variant="outline"
1101
- size="sm"
1102
- className="cursor-pointer"
1103
- onClick={() => openDetails(timesheet)}
1104
- >
1105
- <Eye className="size-4" />
1106
- {t('actions.viewDetails')}
1107
- </Button>
1108
- </div>
1109
- )}
1110
- </div>
1111
- ))}
1112
- </div>
1113
- ) : (
1114
- <div className="overflow-x-auto rounded-md border">
1115
- <Table>
1116
- <TableHeader>
1117
- <TableRow>
1118
- <TableHead>{commonT('labels.collaborator')}</TableHead>
1119
- <TableHead>{commonT('labels.workDate')}</TableHead>
1120
- <TableHead>{commonT('labels.entries')}</TableHead>
1121
- <TableHead>{commonT('labels.totalHours')}</TableHead>
1122
- <TableHead>{commonT('labels.approver')}</TableHead>
1123
- <TableHead>{commonT('labels.decisionNote')}</TableHead>
1124
- <TableHead>{commonT('labels.status')}</TableHead>
1125
- <TableHead>{commonT('labels.actions')}</TableHead>
1126
- </TableRow>
1127
- </TableHeader>
1128
- <TableBody>
1129
- {filteredRows.map((timesheet) => (
1130
- <TableRow key={timesheet.id} className="hover:bg-muted/30">
1131
- <TableCell>
1132
- <div className="font-medium">
1133
- {timesheet.collaboratorName}
1134
- </div>
1135
- <div className="text-xs text-muted-foreground">
1136
- {timesheet.notes || commonT('labels.noNotes')}
1137
- </div>
1138
- </TableCell>
1139
- <TableCell>{formatDate(timesheet.weekStartDate)}</TableCell>
1140
- <TableCell>
1141
- <div className="font-medium">
1142
- {timesheet.entries?.length ?? 0}{' '}
1143
- {commonT('labels.lines')}
1144
- </div>
1145
- <div className="text-xs text-muted-foreground">
1146
- {(timesheet.entries ?? [])
1147
- .slice(0, 2)
1148
- .map(
1149
- (entry) =>
1150
- [
1151
- entry.projectName,
1152
- entry.taskName || entry.activityLabel,
1153
- ]
1154
- .filter(Boolean)
1155
- .join(' • ') || commonT('labels.unassigned')
1156
- )
1157
- .join(', ') || commonT('labels.unassigned')}
1158
- </div>
1159
- </TableCell>
1160
- <TableCell>{formatHours(timesheet.totalHours)}</TableCell>
1161
- <TableCell>
1162
- {timesheet.approverName || commonT('labels.notAssigned')}
1163
- </TableCell>
1164
- <TableCell>
1165
- <div className="text-sm text-muted-foreground">
1166
- {timesheet.decisionNote || commonT('labels.noNotes')}
1167
- </div>
1168
- </TableCell>
1169
- <TableCell>
1170
- <StatusBadge
1171
- label={getTimesheetStatusLabel(timesheet.status)}
1172
- className={getStatusBadgeClass(timesheet.status)}
1173
- />
1174
- </TableCell>
1175
- <TableCell>
1176
- <div className="flex justify-end gap-2">
1177
- {canManageRow(timesheet) ? (
1178
- <>
1179
- <Button
1180
- variant="outline"
1181
- size="sm"
1182
- className="cursor-pointer"
1183
- onClick={() => openDetails(timesheet)}
1184
- >
1185
- <Eye className="size-4" />
1186
- {t('actions.viewDetails')}
1187
- </Button>
1188
- {canSubmitTimesheet(timesheet) ? (
1189
- <Button
1190
- size="icon"
1191
- onClick={() => void submitTimesheet(timesheet.id)}
1192
- >
1193
- <Send className="size-4" />
1194
- </Button>
1195
- ) : null}
1196
- </>
1197
- ) : (
1198
- <Button
1199
- variant="outline"
1200
- size="sm"
1201
- className="cursor-pointer"
1202
- onClick={() => openDetails(timesheet)}
1203
- >
1204
- <Eye className="size-4" />
1205
- {t('actions.viewDetails')}
1206
- </Button>
1207
- )}
1208
- </div>
1209
- </TableCell>
1210
- </TableRow>
1211
- ))}
1212
- </TableBody>
1213
- </Table>
1214
- </div>
1215
- )
1216
- ) : (
1217
- <EmptyState
1218
- icon={<ClipboardList className="size-12" />}
1219
- title={commonT('states.emptyTitle')}
1220
- description={t('emptyDescription')}
1221
- actionLabel={
1222
- access.isCollaborator
1223
- ? commonT('actions.create')
1224
- : commonT('actions.refresh')
1225
- }
1226
- onAction={access.isCollaborator ? openCreate : () => void refetch()}
1227
- />
1228
- )}
1229
-
1230
- <PaginationFooter
1231
- currentPage={page}
1232
- pageSize={pageSize}
1233
- totalItems={timesheetsResponse?.total ?? 0}
1234
- pageSizeOptions={[12, 24, 48]}
1235
- onPageChange={setPage}
1236
- onPageSizeChange={(size) => {
1237
- setPageSize(size);
1238
- setPage(1);
1239
- }}
1240
- />
1241
-
1242
- <Sheet
1243
- open={isSheetOpen}
1244
- onOpenChange={(open) => {
1245
- if (form.formState.isSubmitting && !open) {
1246
- return;
1247
- }
1248
-
1249
- if (!open) {
1250
- closeCreateSheet();
1251
- return;
1252
- }
1253
-
1254
- setIsSheetOpen(true);
1255
- }}
1256
- >
1257
- <SheetContent className="flex h-full w-full flex-col gap-0 overflow-hidden p-0 sm:max-w-2xl">
1258
- <SheetHeader className="border-b px-4 py-4 text-left">
1259
- <div className="flex items-start gap-3">
1260
- <div className="flex h-10 w-10 shrink-0 items-center justify-center rounded-xl bg-primary/10 text-primary">
1261
- <Clock3 className="size-5" />
1262
- </div>
1263
-
1264
- <div className="space-y-1">
1265
- <SheetTitle>
1266
- {isEditingEntry
1267
- ? t('sheet.editTitle')
1268
- : t('sheet.createTitle')}
1269
- </SheetTitle>
1270
- <SheetDescription>{t('sheet.description')}</SheetDescription>
1271
- </div>
1272
- </div>
1273
- </SheetHeader>
1274
-
1275
- <Form {...form}>
1276
- <form
1277
- onSubmit={form.handleSubmit(handleQuickEntrySubmit)}
1278
- className="flex min-h-0 flex-1 flex-col"
1279
- >
1280
- <div className="flex-1 space-y-5 overflow-y-auto px-4 py-4">
1281
- <div className="grid gap-4 lg:grid-cols-2">
1282
- <FormField
1283
- control={form.control}
1284
- name="projectId"
1285
- render={({ field }) => (
1286
- <FormItem>
1287
- <FormLabel>{t('sheet.fields.project')}</FormLabel>
1288
- <FormControl>
1289
- <AsyncOptionsCombobox
1290
- value={field.value}
1291
- selectedOption={selectedProject}
1292
- options={projectOptions}
1293
- onSelect={(option) => {
1294
- field.onChange(option?.id);
1295
- form.setValue('taskId', undefined, {
1296
- shouldDirty: true,
1297
- shouldTouch: true,
1298
- });
1299
- setTaskQuery({ search: '', page: 1 });
1300
- setTaskOptions([]);
1301
- }}
1302
- searchValue={projectQuery.search}
1303
- onSearchValueChange={(value) =>
1304
- setProjectQuery({ search: value, page: 1 })
1305
- }
1306
- placeholder={t('sheet.placeholders.project')}
1307
- searchPlaceholder={t(
1308
- 'sheet.placeholders.projectSearch'
1309
- )}
1310
- emptyLabel={t('entries.projectHint')}
1311
- loadMoreLabel={commonT('actions.loadMore')}
1312
- clearLabel={commonT('actions.clearSelection')}
1313
- isLoading={isProjectOptionsLoading}
1314
- hasMore={Boolean(projectOptionsResponse?.next)}
1315
- onLoadMore={() =>
1316
- setProjectQuery((current) => ({
1317
- ...current,
1318
- page: current.page + 1,
1319
- }))
1320
- }
1321
- />
1322
- </FormControl>
1323
- <FormMessage />
1324
- </FormItem>
1325
- )}
1326
- />
1327
-
1328
- <FormField
1329
- control={form.control}
1330
- name="taskId"
1331
- render={({ field }) => (
1332
- <FormItem>
1333
- <FormLabel>{t('sheet.fields.task')}</FormLabel>
1334
- <FormControl>
1335
- <AsyncOptionsCombobox
1336
- value={field.value}
1337
- selectedOption={selectedTask}
1338
- options={filteredTaskOptions}
1339
- onSelect={(option) => field.onChange(option?.id)}
1340
- searchValue={taskQuery.search}
1341
- onSearchValueChange={(value) =>
1342
- setTaskQuery({ search: value, page: 1 })
1343
- }
1344
- placeholder={t('sheet.placeholders.task')}
1345
- searchPlaceholder={t(
1346
- 'sheet.placeholders.taskSearch'
1347
- )}
1348
- emptyLabel={
1349
- selectedProjectId
1350
- ? t('sheet.helper.task')
1351
- : t('sheet.helper.selectProjectFirst')
1352
- }
1353
- loadMoreLabel={commonT('actions.loadMore')}
1354
- clearLabel={commonT('actions.clearSelection')}
1355
- createLabel={t('sheet.task.createAction')}
1356
- onCreateClick={openTaskCreateSheet}
1357
- isLoading={isTaskOptionsLoading}
1358
- hasMore={Boolean(taskOptionsResponse?.next)}
1359
- onLoadMore={() =>
1360
- setTaskQuery((current) => ({
1361
- ...current,
1362
- page: current.page + 1,
1363
- }))
1364
- }
1365
- disabled={!selectedProjectId}
1366
- />
1367
- </FormControl>
1368
-
1369
- <FormMessage />
1370
- </FormItem>
1371
- )}
1372
- />
1373
- </div>
1374
-
1375
- <div className="grid gap-4 md:grid-cols-[1fr_1fr_220px]">
1376
- <FormField
1377
- control={form.control}
1378
- name="workDate"
1379
- render={({ field }) => (
1380
- <FormItem>
1381
- <FormLabel>{commonT('labels.workDate')}</FormLabel>
1382
- <FormControl>
1383
- <Input type="date" {...field} />
1384
- </FormControl>
1385
- <FormMessage />
1386
- </FormItem>
1387
- )}
1388
- />
1389
-
1390
- <FormField
1391
- control={form.control}
1392
- name="duration"
1393
- render={({ field }) => (
1394
- <FormItem>
1395
- <FormLabel>{t('sheet.fields.duration')}</FormLabel>
1396
- <FormControl>
1397
- <Input
1398
- type="number"
1399
- min="0"
1400
- step={unitValue === 'minutes' ? '5' : '0.25'}
1401
- placeholder={t('sheet.placeholders.duration')}
1402
- value={field.value ?? ''}
1403
- onChange={(event) => {
1404
- const nextValue = event.target.value;
1405
- field.onChange(
1406
- nextValue === '' ? undefined : Number(nextValue)
1407
- );
1408
- }}
1409
- />
1410
- </FormControl>
1411
- <FormMessage />
1412
- </FormItem>
1413
- )}
1414
- />
1415
-
1416
- <FormField
1417
- control={form.control}
1418
- name="unit"
1419
- render={({ field }) => (
1420
- <FormItem>
1421
- <FormLabel>{t('sheet.fields.unit')}</FormLabel>
1422
- <FormControl>
1423
- <ToggleGroup
1424
- type="single"
1425
- value={field.value}
1426
- className="w-full"
1427
- onValueChange={(value) => {
1428
- if (value === 'hours' || value === 'minutes') {
1429
- field.onChange(value);
1430
- }
1431
- }}
1432
- >
1433
- <ToggleGroupItem value="hours" className="flex-1">
1434
- {t('sheet.fields.hours')}
1435
- </ToggleGroupItem>
1436
- <ToggleGroupItem value="minutes" className="flex-1">
1437
- {t('sheet.fields.minutes')}
1438
- </ToggleGroupItem>
1439
- </ToggleGroup>
1440
- </FormControl>
1441
- <FormMessage />
1442
- </FormItem>
1443
- )}
1444
- />
1445
- </div>
1446
-
1447
- <FormField
1448
- control={form.control}
1449
- name="description"
1450
- render={({ field }) => (
1451
- <FormItem>
1452
- <FormLabel>{commonT('labels.description')}</FormLabel>
1453
- <FormControl>
1454
- <Textarea
1455
- {...field}
1456
- rows={4}
1457
- placeholder={t('sheet.placeholders.description')}
1458
- />
1459
- </FormControl>
1460
- <FormMessage />
1461
- </FormItem>
1462
- )}
1463
- />
1464
-
1465
- <div className="flex items-center justify-between rounded-lg border bg-background p-3">
1466
- <div className="space-y-1 pr-3">
1467
- <p className="text-sm font-medium text-foreground">
1468
- {t('sheet.helper.keepContext')}
1469
- </p>
1470
- <p className="text-xs text-muted-foreground">
1471
- {t('sheet.helper.keepContextDescription')}
1472
- </p>
1473
- </div>
1474
-
1475
- <Switch
1476
- checked={keepContextOnSave}
1477
- onCheckedChange={setKeepContextOnSave}
1478
- aria-label={t('sheet.helper.keepContext')}
1479
- />
1480
- </div>
1481
- </div>
1482
-
1483
- <FormActions
1484
- sheet
1485
- onCancel={closeCreateSheet}
1486
- cancelLabel={commonT('actions.cancel')}
1487
- submitType="submit"
1488
- submitLabel={
1489
- isEditingEntry
1490
- ? commonT('actions.save')
1491
- : commonT('actions.submit')
1492
- }
1493
- submitDisabled={form.formState.isSubmitting}
1494
- />
1495
- </form>
1496
- </Form>
1497
- </SheetContent>
1498
- </Sheet>
1499
-
1500
- <TimesheetTaskCreateSheet
1501
- open={isTaskCreateSheetOpen}
1502
- onOpenChange={setIsTaskCreateSheetOpen}
1503
- project={selectedProject}
1504
- onCreated={handleTaskCreated}
1505
- />
1506
-
1507
- <Sheet open={isDetailsOpen} onOpenChange={setIsDetailsOpen}>
1508
- <SheetContent className="w-full overflow-y-auto sm:max-w-2xl">
1509
- <SheetHeader>
1510
- <SheetTitle>{t('details.title')}</SheetTitle>
1511
- <SheetDescription>{t('details.description')}</SheetDescription>
1512
- </SheetHeader>
1513
-
1514
- {selectedTimesheet ? (
1515
- <div className="mt-6 space-y-5 px-4 pb-8">
1516
- <div className="rounded-lg border bg-muted/20 p-4">
1517
- <div className="flex flex-wrap items-start justify-between gap-3">
1518
- <div>
1519
- <div className="text-lg font-semibold">
1520
- {selectedTimesheet.collaboratorName}
1521
- </div>
1522
- <div className="mt-1 text-sm text-muted-foreground">
1523
- {formatDate(selectedTimesheet.weekStartDate)}
1524
- </div>
1525
- </div>
1526
- <StatusBadge
1527
- label={
1528
- t.has(`statuses.${selectedTimesheet.status}`)
1529
- ? t(`statuses.${selectedTimesheet.status}`)
1530
- : formatEnumLabel(selectedTimesheet.status)
1531
- }
1532
- className={getStatusBadgeClass(selectedTimesheet.status)}
1533
- />
1534
- </div>
1535
- </div>
1536
-
1537
- <div className="grid gap-4 sm:grid-cols-2">
1538
- <div>
1539
- <div className="text-xs font-medium uppercase text-muted-foreground">
1540
- {commonT('labels.totalHours')}
1541
- </div>
1542
- <div className="mt-1 text-sm">
1543
- {formatHours(selectedTimesheet.totalHours)}
1544
- </div>
1545
- </div>
1546
- <div>
1547
- <div className="text-xs font-medium uppercase text-muted-foreground">
1548
- {commonT('labels.entries')}
1549
- </div>
1550
- <div className="mt-1 text-sm">
1551
- {selectedTimesheet.entries?.length ?? 0}
1552
- </div>
1553
- </div>
1554
- <div>
1555
- <div className="text-xs font-medium uppercase text-muted-foreground">
1556
- {commonT('labels.approver')}
1557
- </div>
1558
- <div className="mt-1 text-sm">
1559
- {selectedTimesheet.approverName ||
1560
- commonT('labels.notAssigned')}
1561
- </div>
1562
- </div>
1563
- <div>
1564
- <div className="text-xs font-medium uppercase text-muted-foreground">
1565
- {t('details.period')}
1566
- </div>
1567
- <div className="mt-1 text-sm">
1568
- {formatDateLabel(selectedTimesheet.weekStartDate)}
1569
- </div>
1570
- </div>
1571
- </div>
1572
-
1573
- <div>
1574
- <div className="text-xs font-medium uppercase text-muted-foreground">
1575
- {commonT('labels.notes')}
1576
- </div>
1577
- <div className="mt-1 rounded-lg border p-3 text-sm">
1578
- {selectedTimesheet.notes || commonT('labels.noNotes')}
1579
- </div>
1580
- </div>
1581
-
1582
- <div>
1583
- <div className="text-xs font-medium uppercase text-muted-foreground">
1584
- {commonT('labels.decisionNote')}
1585
- </div>
1586
- <div className="mt-1 rounded-lg border p-3 text-sm">
1587
- {selectedTimesheet.decisionNote || commonT('labels.noNotes')}
1588
- </div>
1589
- </div>
1590
-
1591
- <div>
1592
- <div className="text-xs font-medium uppercase text-muted-foreground">
1593
- {t('details.entriesTitle')}
1594
- </div>
1595
- <div className="mt-2 space-y-3">
1596
- {(selectedTimesheet.entries ?? []).length ? (
1597
- (selectedTimesheet.entries ?? []).map((entry) => (
1598
- <div key={entry.id} className="rounded-lg border p-3">
1599
- <div className="flex flex-wrap items-start justify-between gap-3">
1600
- <div>
1601
- <div className="font-medium">
1602
- {entry.taskName ||
1603
- entry.activityLabel ||
1604
- commonT('labels.unassigned')}
1605
- </div>
1606
- <div className="text-xs text-muted-foreground">
1607
- {[entry.projectName, entry.roleLabel]
1608
- .filter(Boolean)
1609
- .join(' • ') || commonT('labels.unassigned')}
1610
- </div>
1611
- </div>
1612
- <div className="text-sm text-muted-foreground">
1613
- {formatEntryDuration(
1614
- entry.durationMinutes,
1615
- entry.hours
1616
- )}
1617
- </div>
1618
- </div>
1619
- <div className="mt-2 text-xs text-muted-foreground">
1620
- {formatDateLabel(entry.workDate)}
1621
- </div>
1622
- <div className="mt-2 text-sm">
1623
- {entry.description || commonT('labels.noNotes')}
1624
- </div>
1625
- {canManageRow(selectedTimesheet) ? (
1626
- <div className="mt-3 flex justify-end gap-2 border-t border-border/60 pt-3">
1627
- <Button
1628
- type="button"
1629
- variant="outline"
1630
- size="sm"
1631
- className="cursor-pointer"
1632
- onClick={() => openEditEntry(entry)}
1633
- >
1634
- <Pencil className="size-4" />
1635
- {commonT('actions.edit')}
1636
- </Button>
1637
- <Button
1638
- type="button"
1639
- variant="outline"
1640
- size="sm"
1641
- className="cursor-pointer text-destructive hover:bg-destructive/10"
1642
- onClick={() => setEntryToDelete(entry)}
1643
- >
1644
- <Trash2 className="size-4" />
1645
- {commonT('actions.delete')}
1646
- </Button>
1647
- </div>
1648
- ) : null}
1649
- </div>
1650
- ))
1651
- ) : (
1652
- <div className="rounded-lg border p-3 text-sm text-muted-foreground">
1653
- {t('details.noEntries')}
1654
- </div>
1655
- )}
1656
- </div>
1657
- </div>
1658
- </div>
1659
- ) : null}
1660
- </SheetContent>
1661
- </Sheet>
1662
-
1663
- <AlertDialog
1664
- open={Boolean(entryToDelete)}
1665
- onOpenChange={(open) => {
1666
- if (!open && !isDeletingEntry) {
1667
- setEntryToDelete(null);
1668
- }
1669
- }}
1670
- >
1671
- <AlertDialogContent>
1672
- <AlertDialogHeader>
1673
- <AlertDialogTitle>
1674
- {t('messages.confirmDeleteTitle')}
1675
- </AlertDialogTitle>
1676
- <AlertDialogDescription>
1677
- {t('messages.confirmDeleteDescription', {
1678
- name:
1679
- entryToDelete?.taskName ||
1680
- entryToDelete?.activityLabel ||
1681
- entryToDelete?.projectName ||
1682
- `#${entryToDelete?.id ?? ''}`,
1683
- })}
1684
- </AlertDialogDescription>
1685
- </AlertDialogHeader>
1686
-
1687
- <AlertDialogFooter>
1688
- <AlertDialogCancel disabled={isDeletingEntry}>
1689
- {commonT('actions.cancel')}
1690
- </AlertDialogCancel>
1691
- <AlertDialogAction
1692
- onClick={() => void handleDeleteEntry()}
1693
- disabled={isDeletingEntry}
1694
- >
1695
- {isDeletingEntry ? (
1696
- <Loader2 className="size-4 animate-spin" />
1697
- ) : null}
1698
- {commonT('actions.delete')}
1699
- </AlertDialogAction>
1700
- </AlertDialogFooter>
1701
- </AlertDialogContent>
1702
- </AlertDialog>
1703
- </Page>
1704
- );
1705
- }