@kelpie/ui 0.11.0 → 0.13.0

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 (333) hide show
  1. package/dist/api/resources/attendances.d.ts +13 -0
  2. package/dist/api/resources/attendances.d.ts.map +1 -0
  3. package/dist/api/resources/attendances.js +34 -0
  4. package/dist/api/resources/attendances.js.map +1 -0
  5. package/dist/api/resources/eventAssociations.d.ts +12 -0
  6. package/dist/api/resources/eventAssociations.d.ts.map +1 -0
  7. package/dist/api/resources/eventAssociations.js +25 -0
  8. package/dist/api/resources/eventAssociations.js.map +1 -0
  9. package/dist/api/resources/events.d.ts +17 -0
  10. package/dist/api/resources/events.d.ts.map +1 -0
  11. package/dist/api/resources/events.js +40 -0
  12. package/dist/api/resources/events.js.map +1 -0
  13. package/dist/api/resources/handbookSeed.d.ts +11 -0
  14. package/dist/api/resources/handbookSeed.d.ts.map +1 -0
  15. package/dist/api/resources/handbookSeed.js +43 -0
  16. package/dist/api/resources/handbookSeed.js.map +1 -0
  17. package/dist/api/resources/moduleSettings.d.ts +10 -0
  18. package/dist/api/resources/moduleSettings.d.ts.map +1 -1
  19. package/dist/api/resources/moduleSettings.js +21 -0
  20. package/dist/api/resources/moduleSettings.js.map +1 -1
  21. package/dist/api/resources/planItems.d.ts +4 -4
  22. package/dist/api/resources/planItems.d.ts.map +1 -1
  23. package/dist/api/resources/planItems.js +1 -1
  24. package/dist/api/resources/planItems.js.map +1 -1
  25. package/dist/api/resources/publicConfig.js +3 -3
  26. package/dist/api/resources/sampleData.d.ts.map +1 -1
  27. package/dist/api/resources/sampleData.js +2 -0
  28. package/dist/api/resources/sampleData.js.map +1 -1
  29. package/dist/api/resources/session.d.ts +22 -1
  30. package/dist/api/resources/session.d.ts.map +1 -1
  31. package/dist/api/resources/session.js +43 -1
  32. package/dist/api/resources/session.js.map +1 -1
  33. package/dist/api/resources/workspace.d.ts.map +1 -1
  34. package/dist/api/resources/workspace.js +2 -3
  35. package/dist/api/resources/workspace.js.map +1 -1
  36. package/dist/app/KelpieApp.d.ts.map +1 -1
  37. package/dist/app/KelpieApp.js +5 -1
  38. package/dist/app/KelpieApp.js.map +1 -1
  39. package/dist/components/ActivitiesPanel.d.ts.map +1 -1
  40. package/dist/components/ActivitiesPanel.js +2 -0
  41. package/dist/components/ActivitiesPanel.js.map +1 -1
  42. package/dist/components/AddressesField.d.ts +23 -0
  43. package/dist/components/AddressesField.d.ts.map +1 -0
  44. package/dist/components/AddressesField.js +215 -0
  45. package/dist/components/AddressesField.js.map +1 -0
  46. package/dist/components/CountrySearch.d.ts +16 -0
  47. package/dist/components/CountrySearch.d.ts.map +1 -0
  48. package/dist/components/CountrySearch.js +30 -0
  49. package/dist/components/CountrySearch.js.map +1 -0
  50. package/dist/components/EnvironmentBanner.d.ts +0 -12
  51. package/dist/components/EnvironmentBanner.d.ts.map +1 -1
  52. package/dist/components/EnvironmentBanner.js +21 -6
  53. package/dist/components/EnvironmentBanner.js.map +1 -1
  54. package/dist/components/InlineEdit.d.ts +7 -1
  55. package/dist/components/InlineEdit.d.ts.map +1 -1
  56. package/dist/components/InlineEdit.js +8 -1
  57. package/dist/components/InlineEdit.js.map +1 -1
  58. package/dist/components/LinkedEventsPanel.d.ts +11 -0
  59. package/dist/components/LinkedEventsPanel.d.ts.map +1 -0
  60. package/dist/components/LinkedEventsPanel.js +18 -0
  61. package/dist/components/LinkedEventsPanel.js.map +1 -0
  62. package/dist/components/NotesPanel.d.ts +4 -6
  63. package/dist/components/NotesPanel.d.ts.map +1 -1
  64. package/dist/components/NotesPanel.js +39 -3
  65. package/dist/components/NotesPanel.js.map +1 -1
  66. package/dist/components/PlanAttention.d.ts.map +1 -1
  67. package/dist/components/PlanAttention.js +3 -2
  68. package/dist/components/PlanAttention.js.map +1 -1
  69. package/dist/components/PlanPanel.d.ts +3 -3
  70. package/dist/components/PlanPanel.d.ts.map +1 -1
  71. package/dist/components/Shell.d.ts.map +1 -1
  72. package/dist/components/Shell.js +8 -2
  73. package/dist/components/Shell.js.map +1 -1
  74. package/dist/components/SocialNetworkIcon.d.ts +17 -0
  75. package/dist/components/SocialNetworkIcon.d.ts.map +1 -0
  76. package/dist/components/SocialNetworkIcon.js +39 -0
  77. package/dist/components/SocialNetworkIcon.js.map +1 -0
  78. package/dist/components/SocialProfilesField.d.ts +8 -0
  79. package/dist/components/SocialProfilesField.d.ts.map +1 -1
  80. package/dist/components/SocialProfilesField.js +19 -5
  81. package/dist/components/SocialProfilesField.js.map +1 -1
  82. package/dist/components/TimezoneSearch.d.ts +21 -0
  83. package/dist/components/TimezoneSearch.d.ts.map +1 -0
  84. package/dist/components/TimezoneSearch.js +27 -0
  85. package/dist/components/TimezoneSearch.js.map +1 -0
  86. package/dist/components/WorkspaceSwitcher.d.ts +8 -0
  87. package/dist/components/WorkspaceSwitcher.d.ts.map +1 -0
  88. package/dist/components/WorkspaceSwitcher.js +67 -0
  89. package/dist/components/WorkspaceSwitcher.js.map +1 -0
  90. package/dist/components/environmentTone.d.ts +10 -0
  91. package/dist/components/environmentTone.d.ts.map +1 -0
  92. package/dist/components/environmentTone.js +35 -0
  93. package/dist/components/environmentTone.js.map +1 -0
  94. package/dist/index.d.ts +25 -6
  95. package/dist/index.d.ts.map +1 -1
  96. package/dist/index.js +17 -3
  97. package/dist/index.js.map +1 -1
  98. package/dist/lib/timezones.d.ts +17 -0
  99. package/dist/lib/timezones.d.ts.map +1 -0
  100. package/dist/lib/timezones.js +39 -0
  101. package/dist/lib/timezones.js.map +1 -0
  102. package/dist/pages/CompaniesPage.d.ts.map +1 -1
  103. package/dist/pages/CompaniesPage.js +12 -11
  104. package/dist/pages/CompaniesPage.js.map +1 -1
  105. package/dist/pages/CompanyDetail.d.ts.map +1 -1
  106. package/dist/pages/CompanyDetail.js +23 -12
  107. package/dist/pages/CompanyDetail.js.map +1 -1
  108. package/dist/pages/DealDetail.d.ts.map +1 -1
  109. package/dist/pages/DealDetail.js +5 -1
  110. package/dist/pages/DealDetail.js.map +1 -1
  111. package/dist/pages/DecisionsPage.d.ts.map +1 -1
  112. package/dist/pages/DecisionsPage.js +7 -0
  113. package/dist/pages/DecisionsPage.js.map +1 -1
  114. package/dist/pages/EnquiryDetail.d.ts.map +1 -1
  115. package/dist/pages/EnquiryDetail.js +5 -1
  116. package/dist/pages/EnquiryDetail.js.map +1 -1
  117. package/dist/pages/EventDetail.d.ts +2 -0
  118. package/dist/pages/EventDetail.d.ts.map +1 -0
  119. package/dist/pages/EventDetail.js +332 -0
  120. package/dist/pages/EventDetail.js.map +1 -0
  121. package/dist/pages/EventsPage.d.ts +2 -0
  122. package/dist/pages/EventsPage.d.ts.map +1 -0
  123. package/dist/pages/EventsPage.js +176 -0
  124. package/dist/pages/EventsPage.js.map +1 -0
  125. package/dist/pages/ListDetail.d.ts.map +1 -1
  126. package/dist/pages/ListDetail.js +17 -0
  127. package/dist/pages/ListDetail.js.map +1 -1
  128. package/dist/pages/OpportunityDetail.d.ts.map +1 -1
  129. package/dist/pages/OpportunityDetail.js +5 -1
  130. package/dist/pages/OpportunityDetail.js.map +1 -1
  131. package/dist/pages/PartnershipDetail.d.ts.map +1 -1
  132. package/dist/pages/PartnershipDetail.js +5 -1
  133. package/dist/pages/PartnershipDetail.js.map +1 -1
  134. package/dist/pages/PeoplePage.d.ts.map +1 -1
  135. package/dist/pages/PeoplePage.js +13 -5
  136. package/dist/pages/PeoplePage.js.map +1 -1
  137. package/dist/pages/PersonDetail.d.ts.map +1 -1
  138. package/dist/pages/PersonDetail.js +94 -28
  139. package/dist/pages/PersonDetail.js.map +1 -1
  140. package/dist/pages/PlanningPage.d.ts.map +1 -1
  141. package/dist/pages/PlanningPage.js +6 -3
  142. package/dist/pages/PlanningPage.js.map +1 -1
  143. package/dist/pages/RaiseDetail.d.ts.map +1 -1
  144. package/dist/pages/RaiseDetail.js +5 -1
  145. package/dist/pages/RaiseDetail.js.map +1 -1
  146. package/dist/pages/RoleDetail.d.ts.map +1 -1
  147. package/dist/pages/RoleDetail.js +4 -1
  148. package/dist/pages/RoleDetail.js.map +1 -1
  149. package/dist/pages/SearchPage.d.ts.map +1 -1
  150. package/dist/pages/SearchPage.js +2 -1
  151. package/dist/pages/SearchPage.js.map +1 -1
  152. package/dist/pages/account/PreferencesPage.d.ts.map +1 -1
  153. package/dist/pages/account/PreferencesPage.js +2 -28
  154. package/dist/pages/account/PreferencesPage.js.map +1 -1
  155. package/dist/pages/account/SecurityPage.js +2 -2
  156. package/dist/pages/account/SecurityPage.js.map +1 -1
  157. package/dist/pages/admin/DataPage.js +10 -9
  158. package/dist/pages/admin/DataPage.js.map +1 -1
  159. package/dist/pages/admin/FieldsPage.js +1 -1
  160. package/dist/pages/admin/FieldsPage.js.map +1 -1
  161. package/dist/pages/admin/ModulesPage.d.ts.map +1 -1
  162. package/dist/pages/admin/ModulesPage.js +1 -0
  163. package/dist/pages/admin/ModulesPage.js.map +1 -1
  164. package/dist/pages/admin/WorkspaceSettingsPage.d.ts +12 -0
  165. package/dist/pages/admin/WorkspaceSettingsPage.d.ts.map +1 -1
  166. package/dist/pages/admin/WorkspaceSettingsPage.js +2 -21
  167. package/dist/pages/admin/WorkspaceSettingsPage.js.map +1 -1
  168. package/dist/pages/auth/AuthForm.d.ts +18 -0
  169. package/dist/pages/auth/AuthForm.d.ts.map +1 -1
  170. package/dist/pages/auth/AuthForm.js +17 -0
  171. package/dist/pages/auth/AuthForm.js.map +1 -1
  172. package/dist/pages/auth/AuthLayout.d.ts +5 -4
  173. package/dist/pages/auth/AuthLayout.d.ts.map +1 -1
  174. package/dist/pages/auth/AuthLayout.js +7 -5
  175. package/dist/pages/auth/AuthLayout.js.map +1 -1
  176. package/dist/pages/auth/AuthMethods.d.ts +12 -0
  177. package/dist/pages/auth/AuthMethods.d.ts.map +1 -0
  178. package/dist/pages/auth/AuthMethods.js +20 -0
  179. package/dist/pages/auth/AuthMethods.js.map +1 -0
  180. package/dist/pages/auth/RegionSwitcher.d.ts +10 -0
  181. package/dist/pages/auth/RegionSwitcher.d.ts.map +1 -0
  182. package/dist/pages/auth/RegionSwitcher.js +28 -0
  183. package/dist/pages/auth/RegionSwitcher.js.map +1 -0
  184. package/dist/pages/auth/SignInPage.d.ts +7 -0
  185. package/dist/pages/auth/SignInPage.d.ts.map +1 -1
  186. package/dist/pages/auth/SignInPage.js +5 -8
  187. package/dist/pages/auth/SignInPage.js.map +1 -1
  188. package/dist/pages/auth/SignUpPage.d.ts.map +1 -1
  189. package/dist/pages/auth/SignUpPage.js +9 -1
  190. package/dist/pages/auth/SignUpPage.js.map +1 -1
  191. package/dist/pages/auth/nextPath.d.ts +15 -0
  192. package/dist/pages/auth/nextPath.d.ts.map +1 -0
  193. package/dist/pages/auth/nextPath.js +17 -0
  194. package/dist/pages/auth/nextPath.js.map +1 -0
  195. package/dist/pages/auth/regionHref.d.ts +6 -0
  196. package/dist/pages/auth/regionHref.d.ts.map +1 -0
  197. package/dist/pages/auth/regionHref.js +8 -0
  198. package/dist/pages/auth/regionHref.js.map +1 -0
  199. package/dist/pages/dashboard/DashboardPage.d.ts +8 -0
  200. package/dist/pages/dashboard/DashboardPage.d.ts.map +1 -1
  201. package/dist/pages/dashboard/DashboardPage.js +5 -13
  202. package/dist/pages/dashboard/DashboardPage.js.map +1 -1
  203. package/dist/pages/dashboard/attention.d.ts +1 -8
  204. package/dist/pages/dashboard/attention.d.ts.map +1 -1
  205. package/dist/pages/dashboard/attention.js +21 -54
  206. package/dist/pages/dashboard/attention.js.map +1 -1
  207. package/dist/pages/dashboard/sections.d.ts.map +1 -1
  208. package/dist/pages/dashboard/sections.js +3 -2
  209. package/dist/pages/dashboard/sections.js.map +1 -1
  210. package/dist/pages/forms/FormActions.d.ts.map +1 -1
  211. package/dist/pages/forms/FormActions.js +7 -3
  212. package/dist/pages/forms/FormActions.js.map +1 -1
  213. package/dist/pages/onboarding/HandbookStepPage.d.ts +4 -8
  214. package/dist/pages/onboarding/HandbookStepPage.d.ts.map +1 -1
  215. package/dist/pages/onboarding/HandbookStepPage.js +13 -13
  216. package/dist/pages/onboarding/HandbookStepPage.js.map +1 -1
  217. package/dist/pages/onboarding/InvitesStepPage.d.ts.map +1 -1
  218. package/dist/pages/onboarding/InvitesStepPage.js +13 -7
  219. package/dist/pages/onboarding/InvitesStepPage.js.map +1 -1
  220. package/dist/pages/onboarding/ModulesStepPage.d.ts +11 -0
  221. package/dist/pages/onboarding/ModulesStepPage.d.ts.map +1 -0
  222. package/dist/pages/onboarding/ModulesStepPage.js +80 -0
  223. package/dist/pages/onboarding/ModulesStepPage.js.map +1 -0
  224. package/dist/pages/onboarding/OnboardingNav.d.ts +17 -0
  225. package/dist/pages/onboarding/OnboardingNav.d.ts.map +1 -0
  226. package/dist/pages/onboarding/OnboardingNav.js +37 -0
  227. package/dist/pages/onboarding/OnboardingNav.js.map +1 -0
  228. package/dist/pages/onboarding/OrganisationStepPage.d.ts +13 -0
  229. package/dist/pages/onboarding/OrganisationStepPage.d.ts.map +1 -0
  230. package/dist/pages/onboarding/OrganisationStepPage.js +59 -0
  231. package/dist/pages/onboarding/OrganisationStepPage.js.map +1 -0
  232. package/dist/pages/onboarding/WorkspaceStepPage.d.ts.map +1 -1
  233. package/dist/pages/onboarding/WorkspaceStepPage.js +25 -20
  234. package/dist/pages/onboarding/WorkspaceStepPage.js.map +1 -1
  235. package/dist/pages/onboarding/handbookTemplates.d.ts +19 -0
  236. package/dist/pages/onboarding/handbookTemplates.d.ts.map +1 -0
  237. package/dist/pages/onboarding/handbookTemplates.js +57 -0
  238. package/dist/pages/onboarding/handbookTemplates.js.map +1 -0
  239. package/dist/pages/onboarding/onboardingModules.d.ts +23 -0
  240. package/dist/pages/onboarding/onboardingModules.d.ts.map +1 -0
  241. package/dist/pages/onboarding/onboardingModules.js +153 -0
  242. package/dist/pages/onboarding/onboardingModules.js.map +1 -0
  243. package/dist/pages/onboarding/onboardingRerun.d.ts +21 -0
  244. package/dist/pages/onboarding/onboardingRerun.d.ts.map +1 -0
  245. package/dist/pages/onboarding/onboardingRerun.js +33 -0
  246. package/dist/pages/onboarding/onboardingRerun.js.map +1 -0
  247. package/dist/registry/context.d.ts +3 -1
  248. package/dist/registry/context.d.ts.map +1 -1
  249. package/dist/registry/context.js +4 -0
  250. package/dist/registry/context.js.map +1 -1
  251. package/dist/registry/contributions.d.ts +24 -0
  252. package/dist/registry/contributions.d.ts.map +1 -1
  253. package/dist/registry/contributions.js.map +1 -1
  254. package/dist/registry/registry.d.ts +4 -1
  255. package/dist/registry/registry.d.ts.map +1 -1
  256. package/dist/registry/registry.js +6 -0
  257. package/dist/registry/registry.js.map +1 -1
  258. package/package.json +4 -3
  259. package/src/api/resources/attendances.ts +54 -0
  260. package/src/api/resources/eventAssociations.ts +43 -0
  261. package/src/api/resources/events.ts +70 -0
  262. package/src/api/resources/handbookSeed.ts +63 -0
  263. package/src/api/resources/moduleSettings.ts +25 -0
  264. package/src/api/resources/planItems.ts +5 -5
  265. package/src/api/resources/publicConfig.ts +3 -3
  266. package/src/api/resources/sampleData.ts +2 -0
  267. package/src/api/resources/session.ts +59 -0
  268. package/src/api/resources/workspace.ts +2 -3
  269. package/src/app/KelpieApp.tsx +11 -3
  270. package/src/components/ActivitiesPanel.tsx +2 -0
  271. package/src/components/AddressesField.tsx +502 -0
  272. package/src/components/CountrySearch.tsx +71 -0
  273. package/src/components/EnvironmentBanner.tsx +23 -6
  274. package/src/components/InlineEdit.tsx +35 -1
  275. package/src/components/LinkedEventsPanel.tsx +50 -0
  276. package/src/components/NotesPanel.tsx +132 -15
  277. package/src/components/PlanAttention.tsx +5 -4
  278. package/src/components/PlanPanel.tsx +3 -3
  279. package/src/components/Shell.tsx +16 -1
  280. package/src/components/SocialNetworkIcon.tsx +88 -0
  281. package/src/components/SocialProfilesField.tsx +57 -10
  282. package/src/components/TimezoneSearch.tsx +67 -0
  283. package/src/components/WorkspaceSwitcher.tsx +136 -0
  284. package/src/components/environmentTone.ts +40 -0
  285. package/src/index.ts +49 -3
  286. package/src/lib/timezones.ts +43 -0
  287. package/src/pages/CompaniesPage.tsx +14 -13
  288. package/src/pages/CompanyDetail.tsx +59 -27
  289. package/src/pages/DealDetail.tsx +5 -0
  290. package/src/pages/DecisionsPage.tsx +7 -0
  291. package/src/pages/EnquiryDetail.tsx +7 -0
  292. package/src/pages/EventDetail.tsx +794 -0
  293. package/src/pages/EventsPage.tsx +382 -0
  294. package/src/pages/ListDetail.tsx +24 -0
  295. package/src/pages/OpportunityDetail.tsx +7 -0
  296. package/src/pages/PartnershipDetail.tsx +7 -0
  297. package/src/pages/PeoplePage.tsx +18 -5
  298. package/src/pages/PersonDetail.tsx +300 -100
  299. package/src/pages/PlanningPage.tsx +17 -14
  300. package/src/pages/RaiseDetail.tsx +5 -0
  301. package/src/pages/RoleDetail.tsx +8 -0
  302. package/src/pages/SearchPage.tsx +2 -1
  303. package/src/pages/account/PreferencesPage.tsx +2 -37
  304. package/src/pages/account/SecurityPage.tsx +6 -1
  305. package/src/pages/admin/DataPage.tsx +63 -21
  306. package/src/pages/admin/FieldsPage.tsx +1 -1
  307. package/src/pages/admin/ModulesPage.tsx +1 -0
  308. package/src/pages/admin/WorkspaceSettingsPage.tsx +10 -33
  309. package/src/pages/auth/AuthForm.tsx +38 -0
  310. package/src/pages/auth/AuthLayout.tsx +8 -4
  311. package/src/pages/auth/AuthMethods.tsx +29 -0
  312. package/src/pages/auth/RegionSwitcher.tsx +56 -0
  313. package/src/pages/auth/SignInPage.tsx +13 -14
  314. package/src/pages/auth/SignUpPage.tsx +32 -0
  315. package/src/pages/auth/nextPath.ts +17 -0
  316. package/src/pages/auth/regionHref.ts +10 -0
  317. package/src/pages/dashboard/DashboardPage.tsx +16 -48
  318. package/src/pages/dashboard/attention.ts +24 -78
  319. package/src/pages/dashboard/sections.tsx +8 -2
  320. package/src/pages/forms/FormActions.tsx +14 -8
  321. package/src/pages/onboarding/HandbookStepPage.tsx +21 -24
  322. package/src/pages/onboarding/InvitesStepPage.tsx +27 -19
  323. package/src/pages/onboarding/ModulesStepPage.tsx +145 -0
  324. package/src/pages/onboarding/OnboardingNav.tsx +97 -0
  325. package/src/pages/onboarding/OrganisationStepPage.tsx +130 -0
  326. package/src/pages/onboarding/WorkspaceStepPage.tsx +53 -38
  327. package/src/pages/onboarding/handbookTemplates.ts +77 -0
  328. package/src/pages/onboarding/onboardingModules.ts +202 -0
  329. package/src/pages/onboarding/onboardingRerun.ts +41 -0
  330. package/src/registry/context.ts +6 -0
  331. package/src/registry/contributions.ts +26 -0
  332. package/src/registry/registry.ts +12 -0
  333. package/src/styles.css +30 -0
@@ -1,3 +1,4 @@
1
+ import { ATTENDANCE_STATUS_LABELS, PERSON_ADDRESS_KIND_LABELS, PERSON_ADDRESS_KINDS } from '@kelpie/schemas'
1
2
  import { CONSENT_PURPOSE_STATUS_LABELS, IN_PROCESS, PREFERRED_CHANNELS } from '@kelpie/schemas'
2
3
  import type {
3
4
  Candidate,
@@ -13,11 +14,14 @@ import { Link, useNavigate, useParams } from 'react-router'
13
14
  import { usePatch } from '../api/resource.ts'
14
15
  import type { PatchResult } from '../api/resource.ts'
15
16
  import { useCandidates } from '../api/resources/candidates.ts'
17
+ import { useAttendances, useCreateAttendance } from '../api/resources/attendances.ts'
18
+ import { useEvents } from '../api/resources/events.ts'
16
19
  import { useCompanies } from '../api/resources/companies.ts'
17
20
  import { useDeals } from '../api/resources/deals.ts'
18
21
  import { useEnquiries } from '../api/resources/enquiries.ts'
19
22
  import { useFormSubmissionsForRecord } from '../api/resources/forms.ts'
20
23
  import { usePartnerships } from '../api/resources/partnerships.ts'
24
+ import { useModuleEnabled } from '../api/resources/moduleSettings.ts'
21
25
  import { useDeletePerson, usePerson, useUpdatePerson } from '../api/resources/people.ts'
22
26
  import {
23
27
  useCreatePosition,
@@ -25,6 +29,7 @@ import {
25
29
  usePositions,
26
30
  useUpdatePositionTitle,
27
31
  } from '../api/resources/positions.ts'
32
+ import { AddressSidebarLink, AddressesField } from '../components/AddressesField.tsx'
28
33
  import { ActivitiesPanel, LatestActivity } from '../components/ActivitiesPanel.tsx'
29
34
  import { AgentTasks } from '../components/AgentTasks.tsx'
30
35
  import { Chip } from '../components/Chip.tsx'
@@ -39,11 +44,13 @@ import { NotesPanel } from '../components/NotesPanel.tsx'
39
44
  import { RelatedPlanAttention } from '../components/PlanAttention.tsx'
40
45
  import { ErrorPanel, LoadingPanel, NotFoundPanel } from '../components/QueryState.tsx'
41
46
  import { ListsPanel } from '../components/ListsPanel.tsx'
47
+ import { LinkedEventsPanel } from '../components/LinkedEventsPanel.tsx'
42
48
  import { RecordTabs } from '../components/RecordTabs.tsx'
43
49
  import type { RecordTabDescriptor } from '../components/RecordTabs.tsx'
44
50
  import { SectionHeader } from '../components/SectionHeader.tsx'
45
51
  import { SidebarField } from '../components/SidebarField.tsx'
46
- import { SocialProfilesField } from '../components/SocialProfilesField.tsx'
52
+ import { SocialProfileIcons, SocialProfilesField } from '../components/SocialProfilesField.tsx'
53
+ import { TimezoneSearch } from '../components/TimezoneSearch.tsx'
47
54
  import { PhonesField } from '../components/PhonesField.tsx'
48
55
  import { SummaryBlock } from '../components/SummaryBlock.tsx'
49
56
  import { useRecordTabs } from '../registry/context.ts'
@@ -59,14 +66,15 @@ import { usePersonNames, useRoleTitles } from './hiringDirectory.ts'
59
66
  /**
60
67
  * One person.
61
68
  *
62
- * The mockup carried eight tabs. Overview, Activity, Notes, Decisions and Hiring
63
- * are here; the remaining three read Deals, Opportunities or Partnerships, and
64
- * return with their pages. A UI module can add its own through the `person`
65
- * record-tab slot.
69
+ * The mockup carried eight tabs. Overview, Addresses, Social, Positions,
70
+ * Activity, Notes, Decisions and Hiring are here; the remaining three read
71
+ * Deals, Opportunities or Partnerships, and return with their pages. A UI
72
+ * module can add its own through the `person` record-tab slot.
66
73
  *
67
74
  * Hiring appears only when this person is up for a role, which is the mockup's
68
75
  * rule: a Person carries no hiring fields, so with no candidacy there is nothing
69
- * for the tab to hold.
76
+ * for the tab to hold. Events appears only when the workspace has that module
77
+ * on: the attendances list answers 403 otherwise.
70
78
  *
71
79
  * Influence and relationship warmth are not on this page. They are Person
72
80
  * columns in the API and fields on the mockup's own `Person` type, but the
@@ -82,11 +90,20 @@ export function PersonDetail(): React.JSX.Element {
82
90
  const deletePerson = useDeletePerson()
83
91
  const moduleTabs = inSlotOrder(useRecordTabs('person'))
84
92
  const hasCustomFields = useHasCustomFields('person')
93
+ const eventsEnabled = useModuleEnabled('events')
85
94
  const [activeTab, setActiveTab] = useState('overview')
86
95
  const candidacies = useCandidates({ personIds: id === undefined ? [] : [id] }, {
87
96
  enabled: id !== undefined,
88
97
  })
98
+ const positions = usePositions(
99
+ { personIds: id === undefined ? [] : [id] },
100
+ { enabled: id !== undefined },
101
+ )
89
102
  const formSubmissions = useFormSubmissionsForRecord('person', id)
103
+ const attendances = useAttendances(
104
+ { personIds: id === undefined ? [] : [id] },
105
+ { enabled: id !== undefined && eventsEnabled },
106
+ )
90
107
 
91
108
  if (isNotFound) {
92
109
  return <NotFoundPanel label="Person" backTo="/people" />
@@ -102,11 +119,17 @@ export function PersonDetail(): React.JSX.Element {
102
119
 
103
120
  const tabs: readonly RecordTabDescriptor<string>[] = [
104
121
  { id: 'overview', label: 'Overview' },
122
+ { id: 'addresses', label: 'Addresses', count: record.addresses.length },
123
+ { id: 'social', label: 'Social', count: record.socialProfiles.length },
124
+ { id: 'positions', label: 'Positions', count: positions.records.length },
105
125
  ...(hasCustomFields ? [{ id: 'fields', label: 'Fields' }] : []),
106
126
  { id: 'activity', label: 'Activity' },
107
127
  ...(candidacies.records.length === 0
108
128
  ? []
109
129
  : [{ id: 'hiring', label: 'Hiring', count: candidacies.records.length }]),
130
+ ...(eventsEnabled
131
+ ? [{ id: 'events', label: 'Events', count: attendances.records.length }]
132
+ : []),
110
133
  { id: 'notes', label: 'Notes' },
111
134
  { id: 'decisions', label: 'Decisions' },
112
135
  { id: 'lists', label: 'Lists' },
@@ -129,7 +152,12 @@ export function PersonDetail(): React.JSX.Element {
129
152
 
130
153
  <div className="grid items-start gap-8 lg:grid-cols-[minmax(0,1fr)_280px]">
131
154
  <div className="min-w-0 space-y-8">
132
- <PersonHeading person={record} />
155
+ <PersonHeading
156
+ person={record}
157
+ onOpenPositions={() => {
158
+ setActiveTab('positions')
159
+ }}
160
+ />
133
161
 
134
162
  <div className="flex justify-end gap-2">
135
163
  <AgentTasks targetType="person" targetId={record.id} targetLabel={record.name} />
@@ -149,11 +177,15 @@ export function PersonDetail(): React.JSX.Element {
149
177
 
150
178
  <RecordTabs tabs={tabs} active={active} onChange={setActiveTab} ariaLabel="Person sections">
151
179
  {active === 'overview' && <PersonOverview person={record} />}
180
+ {active === 'addresses' && <PersonAddresses person={record} />}
181
+ {active === 'social' && <PersonSocial person={record} />}
182
+ {active === 'positions' && <PersonPositions person={record} />}
152
183
  {active === 'fields' && <PersonFields person={record} />}
153
184
  {active === 'activity' && <ActivitiesPanel targetType="person" targetId={record.id} />}
154
185
  {active === 'hiring' && (
155
186
  <PersonHiring candidacies={candidacies.records} personName={record.name} />
156
187
  )}
188
+ {active === 'events' && <PersonEvents personId={record.id} />}
157
189
  {active === 'notes' && <NotesPanel targetType="person" targetId={record.id} />}
158
190
  {active === 'decisions' && <DecisionsPanel targetType="person" targetId={record.id} />}
159
191
  {active === 'lists' && <ListsPanel targetType="person" targetId={record.id} />}
@@ -164,9 +196,13 @@ export function PersonDetail(): React.JSX.Element {
164
196
 
165
197
  <aside className="space-y-4 text-[12px] lg:sticky lg:top-6">
166
198
  <PersonNameParts person={record} />
167
- <PersonSidebar person={record} />
199
+ <PersonSidebar
200
+ person={record}
201
+ onOpenAddresses={() => {
202
+ setActiveTab('addresses')
203
+ }}
204
+ />
168
205
  <PersonConsents person={record} />
169
- <PersonPositions person={record} />
170
206
  </aside>
171
207
  </div>
172
208
  </div>
@@ -178,8 +214,17 @@ function usePersonPatch(person: Person): PatchResult<PersonInput> {
178
214
  return usePatch(useUpdatePerson, person)
179
215
  }
180
216
 
181
- function PersonHeading({ person }: { readonly person: Person }): React.JSX.Element {
217
+ function PersonHeading({
218
+ person,
219
+ onOpenPositions,
220
+ }: {
221
+ readonly person: Person
222
+ readonly onOpenPositions: () => void
223
+ }): React.JSX.Element {
182
224
  const { patch, error } = usePersonPatch(person)
225
+ const positions = usePositions({ personIds: [person.id] })
226
+ const companies = useCompanies({ personIds: [person.id] })
227
+ const companyNameById = new Map(companies.records.map((company) => [company.id, company.name]))
183
228
 
184
229
  return (
185
230
  <div className="min-w-0 flex-1">
@@ -188,14 +233,50 @@ function PersonHeading({ person }: { readonly person: Person }): React.JSX.Eleme
188
233
  <ErrorPanel error={error} />
189
234
  </div>
190
235
  )}
191
- <InlineEdit
192
- value={person.name}
193
- onChange={(name) => {
194
- patch({ name })
195
- }}
196
- displayClassName="text-[22px] font-semibold tracking-tight text-ink not-italic"
197
- emptyLabel="Untitled"
198
- />
236
+ <div className="flex items-center gap-3">
237
+ <div className="min-w-0 flex-1">
238
+ <InlineEdit
239
+ value={person.name}
240
+ onChange={(name) => {
241
+ patch({ name })
242
+ }}
243
+ displayClassName="text-[22px] font-semibold tracking-tight text-ink not-italic"
244
+ emptyLabel="Untitled"
245
+ />
246
+ </div>
247
+ <SocialProfileIcons profiles={person.socialProfiles} />
248
+ </div>
249
+ {positions.records.length > 0 && (
250
+ <ul className="mt-1 space-y-0.5">
251
+ {positions.records.map((position) => {
252
+ const companyName = companyNameById.get(position.companyId) ?? 'Unknown'
253
+ const title = position.title.trim()
254
+
255
+ return (
256
+ <li key={position.id} className="text-[13px] text-ink-muted">
257
+ {title.length > 0 && (
258
+ <>
259
+ <button
260
+ type="button"
261
+ onClick={onOpenPositions}
262
+ className="font-medium text-accent transition hover:text-accent-hover hover:underline"
263
+ >
264
+ {title}
265
+ </button>
266
+ <span> at </span>
267
+ </>
268
+ )}
269
+ <Link
270
+ to={`/companies/${position.companyId}`}
271
+ className="font-medium text-accent transition hover:text-accent-hover hover:underline"
272
+ >
273
+ {companyName}
274
+ </Link>
275
+ </li>
276
+ )
277
+ })}
278
+ </ul>
279
+ )}
199
280
  <div className="mt-1">
200
281
  <InlineEdit
201
282
  value={person.email ?? ''}
@@ -207,6 +288,15 @@ function PersonHeading({ person }: { readonly person: Person }): React.JSX.Eleme
207
288
  emptyLabel="Add email…"
208
289
  />
209
290
  </div>
291
+ {person.phones.length > 0 && (
292
+ <ul className="mt-1 space-y-0.5" aria-label="Phone numbers">
293
+ {person.phones.map((phone, index) => (
294
+ <li key={`${phone}-${String(index)}`} className="text-[13px] text-ink-muted">
295
+ {phone}
296
+ </li>
297
+ ))}
298
+ </ul>
299
+ )}
210
300
  </div>
211
301
  )
212
302
  }
@@ -243,6 +333,95 @@ function PersonOverview({ person }: { readonly person: Person }): React.JSX.Elem
243
333
  )
244
334
  }
245
335
 
336
+ function PersonEvents({ personId }: { readonly personId: string }): React.JSX.Element {
337
+ const attendances = useAttendances({ personIds: [personId], limit: 200 })
338
+ const createAttendance = useCreateAttendance()
339
+ const [eventId, setEventId] = useState('')
340
+ const [search, setSearch] = useState('')
341
+ const searchable = useEvents({
342
+ term: search.trim().length > 0 ? search.trim() : undefined,
343
+ statuses: ['draft', 'scheduled'],
344
+ limit: 50,
345
+ })
346
+ const directory = useEvents({ limit: 200 })
347
+ const nameById = new Map(directory.records.map((record) => [record.id, record.name]))
348
+ const registered = new Set(attendances.records.map((row) => row.eventId))
349
+
350
+ function add(submitEvent: FormEvent): void {
351
+ submitEvent.preventDefault()
352
+
353
+ if (eventId.length === 0 || registered.has(eventId)) {
354
+ return
355
+ }
356
+
357
+ createAttendance.run({ eventId, personId, source: 'manual' })
358
+ setEventId('')
359
+ setSearch('')
360
+ }
361
+
362
+ return (
363
+ <div className="space-y-8">
364
+ <section>
365
+ <SectionHeader title="Attendance" />
366
+ {createAttendance.error !== null && (
367
+ <div className="mb-3">
368
+ <ErrorPanel error={createAttendance.error} />
369
+ </div>
370
+ )}
371
+ {attendances.error !== null && <ErrorPanel error={attendances.error} />}
372
+ {attendances.isLoading ? (
373
+ <p className="text-[13px] text-ink-faint">Loading events…</p>
374
+ ) : attendances.records.length === 0 ? (
375
+ <p className="text-[13px] text-ink-faint">Not registered for any events yet.</p>
376
+ ) : (
377
+ <ul className="divide-y divide-border overflow-hidden rounded-md border border-border">
378
+ {attendances.records.map((row) => (
379
+ <li key={row.id} className="flex flex-wrap items-center justify-between gap-2 px-3 py-2">
380
+ <Link
381
+ to={`/events/${row.eventId}`}
382
+ className="text-[13px] font-medium text-accent hover:underline"
383
+ >
384
+ {nameById.get(row.eventId) ?? row.eventId}
385
+ </Link>
386
+ <span className="text-[12px] text-ink-muted">
387
+ {ATTENDANCE_STATUS_LABELS[row.status]}
388
+ </span>
389
+ </li>
390
+ ))}
391
+ </ul>
392
+ )}
393
+ <form onSubmit={add} className="mt-3 flex flex-wrap items-end gap-2">
394
+ <div className="min-w-[220px] flex-1">
395
+ <EntitySearch
396
+ options={searchable.records
397
+ .filter((record) => !registered.has(record.id))
398
+ .map((record) => ({
399
+ id: record.id,
400
+ label: record.name,
401
+ meta: record.kind.length > 0 ? record.kind : undefined,
402
+ }))}
403
+ value={eventId}
404
+ onChange={setEventId}
405
+ onQueryChange={setSearch}
406
+ placeholder="Register for an event…"
407
+ emptyMessage="No events match"
408
+ size="sm"
409
+ />
410
+ </div>
411
+ <button
412
+ type="submit"
413
+ disabled={createAttendance.isPending || eventId.length === 0}
414
+ className="rounded-md bg-accent px-3 py-1.5 text-[12px] font-semibold text-accent-fg hover:bg-accent-hover disabled:opacity-50"
415
+ >
416
+ Register
417
+ </button>
418
+ </form>
419
+ </section>
420
+ <LinkedEventsPanel targetType="person" targetId={personId} />
421
+ </div>
422
+ )
423
+ }
424
+
246
425
  /**
247
426
  * Every role this person is up for, one card each.
248
427
  *
@@ -363,7 +542,13 @@ function PersonNameParts({ person }: { readonly person: Person }): React.JSX.Ele
363
542
  )
364
543
  }
365
544
 
366
- function PersonSidebar({ person }: { readonly person: Person }): React.JSX.Element {
545
+ function PersonSidebar({
546
+ person,
547
+ onOpenAddresses,
548
+ }: {
549
+ readonly person: Person
550
+ readonly onOpenAddresses: () => void
551
+ }): React.JSX.Element {
367
552
  const { patch, error } = usePersonPatch(person)
368
553
 
369
554
  return (
@@ -384,23 +569,14 @@ function PersonSidebar({ person }: { readonly person: Person }): React.JSX.Eleme
384
569
  />
385
570
  </SidebarField>
386
571
  <SidebarField label="Timezone">
387
- <InlineEdit
572
+ <TimezoneSearch
388
573
  value={person.timezone ?? ''}
389
574
  onChange={(timezone) => {
390
575
  patch({ timezone: timezone.length > 0 ? timezone : null })
391
576
  }}
392
- displayClassName="not-italic normal-case text-[12px]"
393
- />
394
- </SidebarField>
395
- <SidebarField label="Location">
396
- <InlineEdit
397
- value={person.location ?? ''}
398
- onChange={(location) => {
399
- patch({ location: location.length > 0 ? location : null })
400
- }}
401
- displayClassName="not-italic normal-case text-[12px]"
402
577
  />
403
578
  </SidebarField>
579
+ <AddressSidebarLink addresses={person.addresses} onOpen={onOpenAddresses} />
404
580
  <SidebarField label="Phone">
405
581
  <PhonesField
406
582
  value={person.phones}
@@ -409,14 +585,6 @@ function PersonSidebar({ person }: { readonly person: Person }): React.JSX.Eleme
409
585
  }}
410
586
  />
411
587
  </SidebarField>
412
- <SidebarField label="Social profiles">
413
- <SocialProfilesField
414
- value={person.socialProfiles}
415
- onChange={(socialProfiles) => {
416
- patch({ socialProfiles })
417
- }}
418
- />
419
- </SidebarField>
420
588
  <SidebarField label="Tags">
421
589
  <InlineEdit
422
590
  value={person.tags.join(', ')}
@@ -442,6 +610,48 @@ function PersonSidebar({ person }: { readonly person: Person }): React.JSX.Eleme
442
610
  )
443
611
  }
444
612
 
613
+ function PersonAddresses({ person }: { readonly person: Person }): React.JSX.Element {
614
+ const { patch, error } = usePersonPatch(person)
615
+
616
+ return (
617
+ <div className="max-w-lg space-y-4">
618
+ {error !== null && <ErrorPanel error={error} />}
619
+ <SectionHeader
620
+ title="Addresses"
621
+ description="One address per kind. Mark one as primary for lists and the sidebar."
622
+ />
623
+ <AddressesField
624
+ value={person.addresses}
625
+ kinds={PERSON_ADDRESS_KINDS}
626
+ kindLabels={PERSON_ADDRESS_KIND_LABELS}
627
+ onChange={(addresses) => {
628
+ patch({ addresses })
629
+ }}
630
+ />
631
+ </div>
632
+ )
633
+ }
634
+
635
+ function PersonSocial({ person }: { readonly person: Person }): React.JSX.Element {
636
+ const { patch, error } = usePersonPatch(person)
637
+
638
+ return (
639
+ <div className="max-w-lg space-y-4">
640
+ {error !== null && <ErrorPanel error={error} />}
641
+ <SectionHeader
642
+ title="Social profiles"
643
+ description="One profile per network. Icons beside the name open each profile."
644
+ />
645
+ <SocialProfilesField
646
+ value={person.socialProfiles}
647
+ onChange={(socialProfiles) => {
648
+ patch({ socialProfiles })
649
+ }}
650
+ />
651
+ </div>
652
+ )
653
+ }
654
+
445
655
  function PersonFields({ person }: { readonly person: Person }): React.JSX.Element {
446
656
  const { patch, error } = usePersonPatch(person)
447
657
  return (
@@ -499,69 +709,21 @@ function PersonPositions({ person }: { readonly person: Person }): React.JSX.Ele
499
709
  }
500
710
 
501
711
  return (
502
- <section className="rounded-md border border-border">
503
- <div className="border-b border-border px-3.5 py-2.5">
504
- <SectionHeader
505
- title="Positions"
506
- onAdd={() => {
507
- setAdding((current) => !current)
508
- }}
509
- addLabel="Add position"
510
- compact
511
- />
512
- </div>
513
-
514
- {createPosition.error !== null && (
515
- <div className="px-3.5 py-2">
516
- <ErrorPanel error={createPosition.error} />
517
- </div>
518
- )}
519
- {deletePosition.error !== null && (
520
- <div className="px-3.5 py-2">
521
- <ErrorPanel error={deletePosition.error} />
522
- </div>
523
- )}
712
+ <div className="space-y-4">
713
+ <SectionHeader
714
+ title="Positions"
715
+ description="Titles this person holds at companies."
716
+ onAdd={() => {
717
+ setAdding((current) => !current)
718
+ }}
719
+ addLabel="Add position"
720
+ />
524
721
 
525
- <ul className="divide-y divide-border">
526
- {positions.isLoading && (
527
- <li className="px-3.5 py-4 text-[12px] text-ink-faint">Loading positions…</li>
528
- )}
529
- {!positions.isLoading && positions.records.length === 0 && !adding && (
530
- <li className="px-3.5 py-4 text-[12px] text-ink-faint">No positions yet.</li>
531
- )}
532
- {positions.records.map((position) => (
533
- <li key={position.id} className="space-y-1 px-3.5 py-2.5">
534
- <div className="flex items-start justify-between gap-2">
535
- <Link
536
- to={`/companies/${position.companyId}`}
537
- className="text-[13px] font-medium text-ink hover:text-accent"
538
- >
539
- {companyNameById.get(position.companyId) ?? 'Unknown'}
540
- </Link>
541
- <button
542
- type="button"
543
- onClick={() => {
544
- deletePosition.run(position.id)
545
- }}
546
- className="text-[11px] font-medium text-danger hover:underline"
547
- >
548
- Remove
549
- </button>
550
- </div>
551
- <InlineEdit
552
- value={position.title}
553
- onChange={(next) => {
554
- updateTitle.run({ id: position.id, changes: { title: next } })
555
- }}
556
- displayClassName="not-italic text-[12px]"
557
- emptyLabel="Add position title…"
558
- />
559
- </li>
560
- ))}
561
- </ul>
722
+ {createPosition.error !== null && <ErrorPanel error={createPosition.error} />}
723
+ {deletePosition.error !== null && <ErrorPanel error={deletePosition.error} />}
562
724
 
563
725
  {adding && (
564
- <form onSubmit={submit} className="space-y-2 border-t border-border bg-surface px-3.5 py-3">
726
+ <form onSubmit={submit} className="space-y-2 rounded-md border border-border bg-surface p-3">
565
727
  <EntitySearch
566
728
  options={searchable.records
567
729
  .filter((company) => !held.has(company.id))
@@ -583,7 +745,7 @@ function PersonPositions({ person }: { readonly person: Person }): React.JSX.Ele
583
745
  setTitle(event.target.value)
584
746
  }}
585
747
  placeholder="Position title (optional)"
586
- className="w-full rounded-md border border-border bg-surface-raised px-2 py-1.5 text-[12px] outline-none focus:border-accent"
748
+ className="w-full rounded-md border border-border bg-surface-raised px-2 py-1.5 text-[13px] outline-none focus:border-accent"
587
749
  />
588
750
  <div className="flex justify-end gap-2">
589
751
  <button
@@ -602,7 +764,45 @@ function PersonPositions({ person }: { readonly person: Person }): React.JSX.Ele
602
764
  </div>
603
765
  </form>
604
766
  )}
605
- </section>
767
+
768
+ {positions.isLoading && <p className="text-[13px] text-ink-faint">Loading positions…</p>}
769
+
770
+ {!positions.isLoading && positions.records.length === 0 && !adding ? (
771
+ <p className="text-[13px] text-ink-faint">No positions yet.</p>
772
+ ) : (
773
+ <ul className="divide-y divide-border rounded-md border border-border">
774
+ {positions.records.map((position) => (
775
+ <li key={position.id} className="space-y-1 px-3.5 py-3">
776
+ <div className="flex items-start justify-between gap-2">
777
+ <Link
778
+ to={`/companies/${position.companyId}`}
779
+ className="text-[13px] font-medium text-ink hover:text-accent"
780
+ >
781
+ {companyNameById.get(position.companyId) ?? 'Unknown'}
782
+ </Link>
783
+ <button
784
+ type="button"
785
+ onClick={() => {
786
+ deletePosition.run(position.id)
787
+ }}
788
+ className="text-[11px] font-medium text-danger hover:underline"
789
+ >
790
+ Remove
791
+ </button>
792
+ </div>
793
+ <InlineEdit
794
+ value={position.title}
795
+ onChange={(next) => {
796
+ updateTitle.run({ id: position.id, changes: { title: next } })
797
+ }}
798
+ displayClassName="not-italic text-[12px] text-ink-muted"
799
+ emptyLabel="Add position title…"
800
+ />
801
+ </li>
802
+ ))}
803
+ </ul>
804
+ )}
805
+ </div>
606
806
  )
607
807
  }
608
808
 
@@ -1,15 +1,16 @@
1
1
  import {
2
- PIPELINE_KIND_LABELS,
3
- PIPELINE_KINDS,
4
2
  PLAN_ITEM_STATUS_LABELS,
5
3
  PLAN_ITEM_STATUSES,
4
+ PLAN_ITEM_TARGET_TYPE_LABELS,
5
+ PLAN_ITEM_TARGET_TYPES,
6
6
  } from '@kelpie/schemas'
7
- import type { PipelineKind, PlanItem, PlanItemStatus } from '@kelpie/schemas'
7
+ import type { PlanItem, PlanItemStatus, PlanItemTargetType } from '@kelpie/schemas'
8
8
  import { useState } from 'react'
9
9
  import type { FormEvent } from 'react'
10
10
 
11
11
  import { useDeals } from '../api/resources/deals.ts'
12
12
  import { useEnquiries } from '../api/resources/enquiries.ts'
13
+ import { useEvents } from '../api/resources/events.ts'
13
14
  import { useMembers } from '../api/resources/members.ts'
14
15
  import { useOpportunities } from '../api/resources/opportunities.ts'
15
16
  import { usePartnerships } from '../api/resources/partnerships.ts'
@@ -41,7 +42,7 @@ import { monthBounds, planStatusTone, todayIso } from '../lib/plan.ts'
41
42
  */
42
43
 
43
44
  type ViewMode = 'list' | 'calendar'
44
- type TypeFilter = PipelineKind | 'all'
45
+ type TypeFilter = PlanItemTargetType | 'all'
45
46
 
46
47
  const WEEKDAYS = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] as const
47
48
 
@@ -110,9 +111,9 @@ export function PlanningPage(): React.JSX.Element {
110
111
  className="rounded-md border border-border bg-surface-raised px-2.5 py-1 text-[12px] outline-none focus:border-accent"
111
112
  >
112
113
  <option value="all">All types</option>
113
- {PIPELINE_KINDS.map((kind) => (
114
+ {PLAN_ITEM_TARGET_TYPES.map((kind) => (
114
115
  <option key={kind} value={kind}>
115
- {PIPELINE_KIND_LABELS[kind]}
116
+ {PLAN_ITEM_TARGET_TYPE_LABELS[kind]}
116
117
  </option>
117
118
  ))}
118
119
  </select>
@@ -207,7 +208,7 @@ export function PlanningPage(): React.JSX.Element {
207
208
  * for PlanTargetLink. One page per kind, same ceiling as the rest of Planning.
208
209
  */
209
210
  function usePipelineTargets(): {
210
- readonly byKind: Readonly<Record<PipelineKind, readonly PipelineTarget[]>>
211
+ readonly byKind: Readonly<Record<PlanItemTargetType, readonly PipelineTarget[]>>
211
212
  readonly nameById: ReadonlyMap<string, string>
212
213
  } {
213
214
  const deals = useDeals({ limit: MAX_PAGE_SIZE })
@@ -215,13 +216,15 @@ function usePipelineTargets(): {
215
216
  const raises = useRaises({ limit: MAX_PAGE_SIZE })
216
217
  const partnerships = usePartnerships({ limit: MAX_PAGE_SIZE })
217
218
  const enquiries = useEnquiries({ limit: MAX_PAGE_SIZE })
219
+ const events = useEvents({ limit: MAX_PAGE_SIZE })
218
220
 
219
- const byKind: Readonly<Record<PipelineKind, readonly PipelineTarget[]>> = {
221
+ const byKind: Readonly<Record<PlanItemTargetType, readonly PipelineTarget[]>> = {
220
222
  enquiry: enquiries.records.map((record) => ({ id: record.id, name: record.name })),
221
223
  deal: deals.records.map((record) => ({ id: record.id, name: record.name })),
222
224
  opportunity: opportunities.records.map((record) => ({ id: record.id, name: record.name })),
223
225
  raise: raises.records.map((record) => ({ id: record.id, name: record.name })),
224
226
  partnership: partnerships.records.map((record) => ({ id: record.id, name: record.name })),
227
+ event: events.records.map((record) => ({ id: record.id, name: record.name })),
225
228
  }
226
229
 
227
230
  return {
@@ -235,7 +238,7 @@ function usePipelineTargets(): {
235
238
  }
236
239
 
237
240
  interface AddPlanItemFields {
238
- readonly targetType: PipelineKind
241
+ readonly targetType: PlanItemTargetType
239
242
  readonly targetId: string
240
243
  readonly date: string
241
244
  readonly title: string
@@ -251,8 +254,8 @@ function AddPlanItemForm({
251
254
  onSubmit,
252
255
  onCancel,
253
256
  }: {
254
- readonly initialTargetType: PipelineKind
255
- readonly targetsByKind: Readonly<Record<PipelineKind, readonly PipelineTarget[]>>
257
+ readonly initialTargetType: PlanItemTargetType
258
+ readonly targetsByKind: Readonly<Record<PlanItemTargetType, readonly PipelineTarget[]>>
256
259
  readonly isPending: boolean
257
260
  readonly error: Error | null
258
261
  readonly onSubmit: (fields: AddPlanItemFields) => void
@@ -288,16 +291,16 @@ function AddPlanItemForm({
288
291
  <select
289
292
  value={draft.targetType}
290
293
  onChange={(event) => {
291
- const targetType = event.target.value as PipelineKind
294
+ const targetType = event.target.value as PlanItemTargetType
292
295
 
293
296
  setDraft((current) => ({ ...current, targetType, targetId: '' }))
294
297
  }}
295
298
  aria-label="Record type"
296
299
  className={inputClass}
297
300
  >
298
- {PIPELINE_KINDS.map((kind) => (
301
+ {PLAN_ITEM_TARGET_TYPES.map((kind) => (
299
302
  <option key={kind} value={kind}>
300
- {PIPELINE_KIND_LABELS[kind]}
303
+ {PLAN_ITEM_TARGET_TYPE_LABELS[kind]}
301
304
  </option>
302
305
  ))}
303
306
  </select>