@kelpie/ui 0.1.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 (704) hide show
  1. package/LICENSE +661 -0
  2. package/README.md +44 -0
  3. package/dist/ServiceStatus.d.ts +6 -0
  4. package/dist/ServiceStatus.d.ts.map +1 -0
  5. package/dist/ServiceStatus.js +35 -0
  6. package/dist/ServiceStatus.js.map +1 -0
  7. package/dist/api/ApiProvider.d.ts +19 -0
  8. package/dist/api/ApiProvider.d.ts.map +1 -0
  9. package/dist/api/ApiProvider.js +18 -0
  10. package/dist/api/ApiProvider.js.map +1 -0
  11. package/dist/api/client.d.ts +83 -0
  12. package/dist/api/client.d.ts.map +1 -0
  13. package/dist/api/client.js +162 -0
  14. package/dist/api/client.js.map +1 -0
  15. package/dist/api/context.d.ts +14 -0
  16. package/dist/api/context.d.ts.map +1 -0
  17. package/dist/api/context.js +20 -0
  18. package/dist/api/context.js.map +1 -0
  19. package/dist/api/errors.d.ts +9 -0
  20. package/dist/api/errors.d.ts.map +1 -0
  21. package/dist/api/errors.js +14 -0
  22. package/dist/api/errors.js.map +1 -0
  23. package/dist/api/health.d.ts +15 -0
  24. package/dist/api/health.d.ts.map +1 -0
  25. package/dist/api/health.js +22 -0
  26. package/dist/api/health.js.map +1 -0
  27. package/dist/api/json.d.ts +3 -0
  28. package/dist/api/json.d.ts.map +1 -0
  29. package/dist/api/json.js +5 -0
  30. package/dist/api/json.js.map +1 -0
  31. package/dist/api/queryClient.d.ts +17 -0
  32. package/dist/api/queryClient.d.ts.map +1 -0
  33. package/dist/api/queryClient.js +33 -0
  34. package/dist/api/queryClient.js.map +1 -0
  35. package/dist/api/resource.d.ts +110 -0
  36. package/dist/api/resource.d.ts.map +1 -0
  37. package/dist/api/resource.js +238 -0
  38. package/dist/api/resource.js.map +1 -0
  39. package/dist/api/resources/account.d.ts +49 -0
  40. package/dist/api/resources/account.d.ts.map +1 -0
  41. package/dist/api/resources/account.js +146 -0
  42. package/dist/api/resources/account.js.map +1 -0
  43. package/dist/api/resources/activities.d.ts +8 -0
  44. package/dist/api/resources/activities.d.ts.map +1 -0
  45. package/dist/api/resources/activities.js +21 -0
  46. package/dist/api/resources/activities.js.map +1 -0
  47. package/dist/api/resources/agentTasks.d.ts +31 -0
  48. package/dist/api/resources/agentTasks.d.ts.map +1 -0
  49. package/dist/api/resources/agentTasks.js +103 -0
  50. package/dist/api/resources/agentTasks.js.map +1 -0
  51. package/dist/api/resources/candidates.d.ts +17 -0
  52. package/dist/api/resources/candidates.d.ts.map +1 -0
  53. package/dist/api/resources/candidates.js +40 -0
  54. package/dist/api/resources/candidates.js.map +1 -0
  55. package/dist/api/resources/companies.d.ts +22 -0
  56. package/dist/api/resources/companies.d.ts.map +1 -0
  57. package/dist/api/resources/companies.js +36 -0
  58. package/dist/api/resources/companies.js.map +1 -0
  59. package/dist/api/resources/dashboard.d.ts +8 -0
  60. package/dist/api/resources/dashboard.d.ts.map +1 -0
  61. package/dist/api/resources/dashboard.js +27 -0
  62. package/dist/api/resources/dashboard.js.map +1 -0
  63. package/dist/api/resources/deals.d.ts +30 -0
  64. package/dist/api/resources/deals.d.ts.map +1 -0
  65. package/dist/api/resources/deals.js +38 -0
  66. package/dist/api/resources/deals.js.map +1 -0
  67. package/dist/api/resources/decisions.d.ts +13 -0
  68. package/dist/api/resources/decisions.d.ts.map +1 -0
  69. package/dist/api/resources/decisions.js +38 -0
  70. package/dist/api/resources/decisions.js.map +1 -0
  71. package/dist/api/resources/forms.d.ts +82 -0
  72. package/dist/api/resources/forms.d.ts.map +1 -0
  73. package/dist/api/resources/forms.js +129 -0
  74. package/dist/api/resources/forms.js.map +1 -0
  75. package/dist/api/resources/handbookPages.d.ts +33 -0
  76. package/dist/api/resources/handbookPages.d.ts.map +1 -0
  77. package/dist/api/resources/handbookPages.js +49 -0
  78. package/dist/api/resources/handbookPages.js.map +1 -0
  79. package/dist/api/resources/importJobs.d.ts +72 -0
  80. package/dist/api/resources/importJobs.d.ts.map +1 -0
  81. package/dist/api/resources/importJobs.js +145 -0
  82. package/dist/api/resources/importJobs.js.map +1 -0
  83. package/dist/api/resources/invites.d.ts +19 -0
  84. package/dist/api/resources/invites.d.ts.map +1 -0
  85. package/dist/api/resources/invites.js +78 -0
  86. package/dist/api/resources/invites.js.map +1 -0
  87. package/dist/api/resources/mcpTools.d.ts +8 -0
  88. package/dist/api/resources/mcpTools.d.ts.map +1 -0
  89. package/dist/api/resources/mcpTools.js +23 -0
  90. package/dist/api/resources/mcpTools.js.map +1 -0
  91. package/dist/api/resources/members.d.ts +40 -0
  92. package/dist/api/resources/members.d.ts.map +1 -0
  93. package/dist/api/resources/members.js +67 -0
  94. package/dist/api/resources/members.js.map +1 -0
  95. package/dist/api/resources/moduleSettings.d.ts +14 -0
  96. package/dist/api/resources/moduleSettings.d.ts.map +1 -0
  97. package/dist/api/resources/moduleSettings.js +43 -0
  98. package/dist/api/resources/moduleSettings.js.map +1 -0
  99. package/dist/api/resources/mutation.d.ts +18 -0
  100. package/dist/api/resources/mutation.d.ts.map +1 -0
  101. package/dist/api/resources/mutation.js +12 -0
  102. package/dist/api/resources/mutation.js.map +1 -0
  103. package/dist/api/resources/notes.d.ts +14 -0
  104. package/dist/api/resources/notes.d.ts.map +1 -0
  105. package/dist/api/resources/notes.js +39 -0
  106. package/dist/api/resources/notes.js.map +1 -0
  107. package/dist/api/resources/opportunities.d.ts +29 -0
  108. package/dist/api/resources/opportunities.d.ts.map +1 -0
  109. package/dist/api/resources/opportunities.js +38 -0
  110. package/dist/api/resources/opportunities.js.map +1 -0
  111. package/dist/api/resources/partnerships.d.ts +33 -0
  112. package/dist/api/resources/partnerships.d.ts.map +1 -0
  113. package/dist/api/resources/partnerships.js +39 -0
  114. package/dist/api/resources/partnerships.js.map +1 -0
  115. package/dist/api/resources/people.d.ts +22 -0
  116. package/dist/api/resources/people.d.ts.map +1 -0
  117. package/dist/api/resources/people.js +36 -0
  118. package/dist/api/resources/people.js.map +1 -0
  119. package/dist/api/resources/pipelineStages.d.ts +22 -0
  120. package/dist/api/resources/pipelineStages.d.ts.map +1 -0
  121. package/dist/api/resources/pipelineStages.js +61 -0
  122. package/dist/api/resources/pipelineStages.js.map +1 -0
  123. package/dist/api/resources/planItems.d.ts +31 -0
  124. package/dist/api/resources/planItems.d.ts.map +1 -0
  125. package/dist/api/resources/planItems.js +60 -0
  126. package/dist/api/resources/planItems.js.map +1 -0
  127. package/dist/api/resources/positions.d.ts +23 -0
  128. package/dist/api/resources/positions.d.ts.map +1 -0
  129. package/dist/api/resources/positions.js +31 -0
  130. package/dist/api/resources/positions.js.map +1 -0
  131. package/dist/api/resources/raises.d.ts +30 -0
  132. package/dist/api/resources/raises.d.ts.map +1 -0
  133. package/dist/api/resources/raises.js +38 -0
  134. package/dist/api/resources/raises.js.map +1 -0
  135. package/dist/api/resources/roles.d.ts +20 -0
  136. package/dist/api/resources/roles.d.ts.map +1 -0
  137. package/dist/api/resources/roles.js +31 -0
  138. package/dist/api/resources/roles.js.map +1 -0
  139. package/dist/api/resources/search.d.ts +12 -0
  140. package/dist/api/resources/search.d.ts.map +1 -0
  141. package/dist/api/resources/search.js +37 -0
  142. package/dist/api/resources/search.js.map +1 -0
  143. package/dist/api/resources/session.d.ts +58 -0
  144. package/dist/api/resources/session.d.ts.map +1 -0
  145. package/dist/api/resources/session.js +157 -0
  146. package/dist/api/resources/session.js.map +1 -0
  147. package/dist/api/resources/webhooks.d.ts +45 -0
  148. package/dist/api/resources/webhooks.d.ts.map +1 -0
  149. package/dist/api/resources/webhooks.js +106 -0
  150. package/dist/api/resources/webhooks.js.map +1 -0
  151. package/dist/api/resources/workspace.d.ts +20 -0
  152. package/dist/api/resources/workspace.d.ts.map +1 -0
  153. package/dist/api/resources/workspace.js +63 -0
  154. package/dist/api/resources/workspace.js.map +1 -0
  155. package/dist/app/KelpieApp.d.ts +18 -0
  156. package/dist/app/KelpieApp.d.ts.map +1 -0
  157. package/dist/app/KelpieApp.js +59 -0
  158. package/dist/app/KelpieApp.js.map +1 -0
  159. package/dist/app/SessionGate.d.ts +14 -0
  160. package/dist/app/SessionGate.d.ts.map +1 -0
  161. package/dist/app/SessionGate.js +33 -0
  162. package/dist/app/SessionGate.js.map +1 -0
  163. package/dist/components/ActivitiesPanel.d.ts +28 -0
  164. package/dist/components/ActivitiesPanel.d.ts.map +1 -0
  165. package/dist/components/ActivitiesPanel.js +75 -0
  166. package/dist/components/ActivitiesPanel.js.map +1 -0
  167. package/dist/components/AgentTasks.d.ts +16 -0
  168. package/dist/components/AgentTasks.d.ts.map +1 -0
  169. package/dist/components/AgentTasks.js +166 -0
  170. package/dist/components/AgentTasks.js.map +1 -0
  171. package/dist/components/Chip.d.ts +10 -0
  172. package/dist/components/Chip.d.ts.map +1 -0
  173. package/dist/components/Chip.js +21 -0
  174. package/dist/components/Chip.js.map +1 -0
  175. package/dist/components/CopyButton.d.ts +7 -0
  176. package/dist/components/CopyButton.d.ts.map +1 -0
  177. package/dist/components/CopyButton.js +30 -0
  178. package/dist/components/CopyButton.js.map +1 -0
  179. package/dist/components/DataTable.d.ts +36 -0
  180. package/dist/components/DataTable.d.ts.map +1 -0
  181. package/dist/components/DataTable.js +43 -0
  182. package/dist/components/DataTable.js.map +1 -0
  183. package/dist/components/DecisionsPanel.d.ts +14 -0
  184. package/dist/components/DecisionsPanel.d.ts.map +1 -0
  185. package/dist/components/DecisionsPanel.js +73 -0
  186. package/dist/components/DecisionsPanel.js.map +1 -0
  187. package/dist/components/DeleteRecord.d.ts +19 -0
  188. package/dist/components/DeleteRecord.d.ts.map +1 -0
  189. package/dist/components/DeleteRecord.js +22 -0
  190. package/dist/components/DeleteRecord.js.map +1 -0
  191. package/dist/components/EntitySearch.d.ts +33 -0
  192. package/dist/components/EntitySearch.d.ts.map +1 -0
  193. package/dist/components/EntitySearch.js +111 -0
  194. package/dist/components/EntitySearch.js.map +1 -0
  195. package/dist/components/ErrorBoundary.d.ts +21 -0
  196. package/dist/components/ErrorBoundary.d.ts.map +1 -0
  197. package/dist/components/ErrorBoundary.js +26 -0
  198. package/dist/components/ErrorBoundary.js.map +1 -0
  199. package/dist/components/InlineEdit.d.ts +37 -0
  200. package/dist/components/InlineEdit.d.ts.map +1 -0
  201. package/dist/components/InlineEdit.js +77 -0
  202. package/dist/components/InlineEdit.js.map +1 -0
  203. package/dist/components/KanbanBoard.d.ts +24 -0
  204. package/dist/components/KanbanBoard.d.ts.map +1 -0
  205. package/dist/components/KanbanBoard.js +92 -0
  206. package/dist/components/KanbanBoard.js.map +1 -0
  207. package/dist/components/MarkdownView.d.ts +4 -0
  208. package/dist/components/MarkdownView.d.ts.map +1 -0
  209. package/dist/components/MarkdownView.js +45 -0
  210. package/dist/components/MarkdownView.js.map +1 -0
  211. package/dist/components/NotesPanel.d.ts +17 -0
  212. package/dist/components/NotesPanel.d.ts.map +1 -0
  213. package/dist/components/NotesPanel.js +53 -0
  214. package/dist/components/NotesPanel.js.map +1 -0
  215. package/dist/components/PageHeader.d.ts +20 -0
  216. package/dist/components/PageHeader.d.ts.map +1 -0
  217. package/dist/components/PageHeader.js +15 -0
  218. package/dist/components/PageHeader.js.map +1 -0
  219. package/dist/components/PhonesField.d.ts +7 -0
  220. package/dist/components/PhonesField.d.ts.map +1 -0
  221. package/dist/components/PhonesField.js +92 -0
  222. package/dist/components/PhonesField.js.map +1 -0
  223. package/dist/components/PlanAttention.d.ts +40 -0
  224. package/dist/components/PlanAttention.d.ts.map +1 -0
  225. package/dist/components/PlanAttention.js +86 -0
  226. package/dist/components/PlanAttention.js.map +1 -0
  227. package/dist/components/PlanPanel.d.ts +18 -0
  228. package/dist/components/PlanPanel.d.ts.map +1 -0
  229. package/dist/components/PlanPanel.js +102 -0
  230. package/dist/components/PlanPanel.js.map +1 -0
  231. package/dist/components/QueryState.d.ts +24 -0
  232. package/dist/components/QueryState.d.ts.map +1 -0
  233. package/dist/components/QueryState.js +34 -0
  234. package/dist/components/QueryState.js.map +1 -0
  235. package/dist/components/RecordTabs.d.ts +16 -0
  236. package/dist/components/RecordTabs.d.ts.map +1 -0
  237. package/dist/components/RecordTabs.js +15 -0
  238. package/dist/components/RecordTabs.js.map +1 -0
  239. package/dist/components/SectionHeader.d.ts +15 -0
  240. package/dist/components/SectionHeader.d.ts.map +1 -0
  241. package/dist/components/SectionHeader.js +14 -0
  242. package/dist/components/SectionHeader.js.map +1 -0
  243. package/dist/components/SegmentedControl.d.ts +13 -0
  244. package/dist/components/SegmentedControl.d.ts.map +1 -0
  245. package/dist/components/SegmentedControl.js +14 -0
  246. package/dist/components/SegmentedControl.js.map +1 -0
  247. package/dist/components/Shell.d.ts +2 -0
  248. package/dist/components/Shell.d.ts.map +1 -0
  249. package/dist/components/Shell.js +143 -0
  250. package/dist/components/Shell.js.map +1 -0
  251. package/dist/components/SidebarField.d.ts +8 -0
  252. package/dist/components/SidebarField.d.ts.map +1 -0
  253. package/dist/components/SidebarField.js +6 -0
  254. package/dist/components/SidebarField.js.map +1 -0
  255. package/dist/components/SocialProfilesField.d.ts +8 -0
  256. package/dist/components/SocialProfilesField.d.ts.map +1 -0
  257. package/dist/components/SocialProfilesField.js +176 -0
  258. package/dist/components/SocialProfilesField.js.map +1 -0
  259. package/dist/components/StageSettings.d.ts +16 -0
  260. package/dist/components/StageSettings.d.ts.map +1 -0
  261. package/dist/components/StageSettings.js +107 -0
  262. package/dist/components/StageSettings.js.map +1 -0
  263. package/dist/components/SummaryBlock.d.ts +12 -0
  264. package/dist/components/SummaryBlock.d.ts.map +1 -0
  265. package/dist/components/SummaryBlock.js +12 -0
  266. package/dist/components/SummaryBlock.js.map +1 -0
  267. package/dist/index.d.ts +90 -0
  268. package/dist/index.d.ts.map +1 -0
  269. package/dist/index.js +55 -0
  270. package/dist/index.js.map +1 -0
  271. package/dist/lib/dates.d.ts +26 -0
  272. package/dist/lib/dates.d.ts.map +1 -0
  273. package/dist/lib/dates.js +71 -0
  274. package/dist/lib/dates.js.map +1 -0
  275. package/dist/lib/money.d.ts +7 -0
  276. package/dist/lib/money.d.ts.map +1 -0
  277. package/dist/lib/money.js +13 -0
  278. package/dist/lib/money.js.map +1 -0
  279. package/dist/lib/names.d.ts +9 -0
  280. package/dist/lib/names.d.ts.map +1 -0
  281. package/dist/lib/names.js +13 -0
  282. package/dist/lib/names.js.map +1 -0
  283. package/dist/lib/plan.d.ts +67 -0
  284. package/dist/lib/plan.d.ts.map +1 -0
  285. package/dist/lib/plan.js +96 -0
  286. package/dist/lib/plan.js.map +1 -0
  287. package/dist/lib/theme.d.ts +19 -0
  288. package/dist/lib/theme.d.ts.map +1 -0
  289. package/dist/lib/theme.js +30 -0
  290. package/dist/lib/theme.js.map +1 -0
  291. package/dist/pages/CompaniesPage.d.ts +2 -0
  292. package/dist/pages/CompaniesPage.d.ts.map +1 -0
  293. package/dist/pages/CompaniesPage.js +77 -0
  294. package/dist/pages/CompaniesPage.js.map +1 -0
  295. package/dist/pages/CompanyDetail.d.ts +2 -0
  296. package/dist/pages/CompanyDetail.d.ts.map +1 -0
  297. package/dist/pages/CompanyDetail.js +177 -0
  298. package/dist/pages/CompanyDetail.js.map +1 -0
  299. package/dist/pages/DealDetail.d.ts +2 -0
  300. package/dist/pages/DealDetail.d.ts.map +1 -0
  301. package/dist/pages/DealDetail.js +192 -0
  302. package/dist/pages/DealDetail.js.map +1 -0
  303. package/dist/pages/DealStageSettingsPage.d.ts +7 -0
  304. package/dist/pages/DealStageSettingsPage.d.ts.map +1 -0
  305. package/dist/pages/DealStageSettingsPage.js +38 -0
  306. package/dist/pages/DealStageSettingsPage.js.map +1 -0
  307. package/dist/pages/DealsPage.d.ts +2 -0
  308. package/dist/pages/DealsPage.d.ts.map +1 -0
  309. package/dist/pages/DealsPage.js +177 -0
  310. package/dist/pages/DealsPage.js.map +1 -0
  311. package/dist/pages/DecisionsPage.d.ts +2 -0
  312. package/dist/pages/DecisionsPage.d.ts.map +1 -0
  313. package/dist/pages/DecisionsPage.js +121 -0
  314. package/dist/pages/DecisionsPage.js.map +1 -0
  315. package/dist/pages/FormDetail.d.ts +2 -0
  316. package/dist/pages/FormDetail.d.ts.map +1 -0
  317. package/dist/pages/FormDetail.js +56 -0
  318. package/dist/pages/FormDetail.js.map +1 -0
  319. package/dist/pages/FormsPage.d.ts +2 -0
  320. package/dist/pages/FormsPage.d.ts.map +1 -0
  321. package/dist/pages/FormsPage.js +67 -0
  322. package/dist/pages/FormsPage.js.map +1 -0
  323. package/dist/pages/FundraisingPage.d.ts +2 -0
  324. package/dist/pages/FundraisingPage.d.ts.map +1 -0
  325. package/dist/pages/FundraisingPage.js +187 -0
  326. package/dist/pages/FundraisingPage.js.map +1 -0
  327. package/dist/pages/HiringPage.d.ts +9 -0
  328. package/dist/pages/HiringPage.d.ts.map +1 -0
  329. package/dist/pages/HiringPage.js +73 -0
  330. package/dist/pages/HiringPage.js.map +1 -0
  331. package/dist/pages/NotFoundPage.d.ts +10 -0
  332. package/dist/pages/NotFoundPage.d.ts.map +1 -0
  333. package/dist/pages/NotFoundPage.js +14 -0
  334. package/dist/pages/NotFoundPage.js.map +1 -0
  335. package/dist/pages/OpportunitiesPage.d.ts +2 -0
  336. package/dist/pages/OpportunitiesPage.d.ts.map +1 -0
  337. package/dist/pages/OpportunitiesPage.js +184 -0
  338. package/dist/pages/OpportunitiesPage.js.map +1 -0
  339. package/dist/pages/OpportunityDetail.d.ts +2 -0
  340. package/dist/pages/OpportunityDetail.d.ts.map +1 -0
  341. package/dist/pages/OpportunityDetail.js +132 -0
  342. package/dist/pages/OpportunityDetail.js.map +1 -0
  343. package/dist/pages/OpportunityStageSettingsPage.d.ts +3 -0
  344. package/dist/pages/OpportunityStageSettingsPage.d.ts.map +1 -0
  345. package/dist/pages/OpportunityStageSettingsPage.js +34 -0
  346. package/dist/pages/OpportunityStageSettingsPage.js.map +1 -0
  347. package/dist/pages/PartnershipDetail.d.ts +2 -0
  348. package/dist/pages/PartnershipDetail.d.ts.map +1 -0
  349. package/dist/pages/PartnershipDetail.js +179 -0
  350. package/dist/pages/PartnershipDetail.js.map +1 -0
  351. package/dist/pages/PartnershipStageSettingsPage.d.ts +3 -0
  352. package/dist/pages/PartnershipStageSettingsPage.d.ts.map +1 -0
  353. package/dist/pages/PartnershipStageSettingsPage.js +34 -0
  354. package/dist/pages/PartnershipStageSettingsPage.js.map +1 -0
  355. package/dist/pages/PartnershipsPage.d.ts +2 -0
  356. package/dist/pages/PartnershipsPage.d.ts.map +1 -0
  357. package/dist/pages/PartnershipsPage.js +182 -0
  358. package/dist/pages/PartnershipsPage.js.map +1 -0
  359. package/dist/pages/PeoplePage.d.ts +10 -0
  360. package/dist/pages/PeoplePage.d.ts.map +1 -0
  361. package/dist/pages/PeoplePage.js +71 -0
  362. package/dist/pages/PeoplePage.js.map +1 -0
  363. package/dist/pages/PersonDetail.d.ts +2 -0
  364. package/dist/pages/PersonDetail.d.ts.map +1 -0
  365. package/dist/pages/PersonDetail.js +193 -0
  366. package/dist/pages/PersonDetail.js.map +1 -0
  367. package/dist/pages/PlanningPage.d.ts +2 -0
  368. package/dist/pages/PlanningPage.d.ts.map +1 -0
  369. package/dist/pages/PlanningPage.js +112 -0
  370. package/dist/pages/PlanningPage.js.map +1 -0
  371. package/dist/pages/RaiseDetail.d.ts +2 -0
  372. package/dist/pages/RaiseDetail.d.ts.map +1 -0
  373. package/dist/pages/RaiseDetail.js +198 -0
  374. package/dist/pages/RaiseDetail.js.map +1 -0
  375. package/dist/pages/RaiseStageSettingsPage.d.ts +3 -0
  376. package/dist/pages/RaiseStageSettingsPage.d.ts.map +1 -0
  377. package/dist/pages/RaiseStageSettingsPage.js +34 -0
  378. package/dist/pages/RaiseStageSettingsPage.js.map +1 -0
  379. package/dist/pages/RoleDetail.d.ts +2 -0
  380. package/dist/pages/RoleDetail.d.ts.map +1 -0
  381. package/dist/pages/RoleDetail.js +177 -0
  382. package/dist/pages/RoleDetail.js.map +1 -0
  383. package/dist/pages/SearchPage.d.ts +2 -0
  384. package/dist/pages/SearchPage.d.ts.map +1 -0
  385. package/dist/pages/SearchPage.js +51 -0
  386. package/dist/pages/SearchPage.js.map +1 -0
  387. package/dist/pages/account/AccountLayout.d.ts +2 -0
  388. package/dist/pages/account/AccountLayout.d.ts.map +1 -0
  389. package/dist/pages/account/AccountLayout.js +25 -0
  390. package/dist/pages/account/AccountLayout.js.map +1 -0
  391. package/dist/pages/account/Field.d.ts +8 -0
  392. package/dist/pages/account/Field.d.ts.map +1 -0
  393. package/dist/pages/account/Field.js +6 -0
  394. package/dist/pages/account/Field.js.map +1 -0
  395. package/dist/pages/account/PreferencesPage.d.ts +2 -0
  396. package/dist/pages/account/PreferencesPage.d.ts.map +1 -0
  397. package/dist/pages/account/PreferencesPage.js +92 -0
  398. package/dist/pages/account/PreferencesPage.js.map +1 -0
  399. package/dist/pages/account/ProfilePage.d.ts +14 -0
  400. package/dist/pages/account/ProfilePage.d.ts.map +1 -0
  401. package/dist/pages/account/ProfilePage.js +71 -0
  402. package/dist/pages/account/ProfilePage.js.map +1 -0
  403. package/dist/pages/account/SecurityPage.d.ts +11 -0
  404. package/dist/pages/account/SecurityPage.d.ts.map +1 -0
  405. package/dist/pages/account/SecurityPage.js +78 -0
  406. package/dist/pages/account/SecurityPage.js.map +1 -0
  407. package/dist/pages/admin/DataPage.d.ts +3 -0
  408. package/dist/pages/admin/DataPage.d.ts.map +1 -0
  409. package/dist/pages/admin/DataPage.js +210 -0
  410. package/dist/pages/admin/DataPage.js.map +1 -0
  411. package/dist/pages/admin/McpPage.d.ts +2 -0
  412. package/dist/pages/admin/McpPage.d.ts.map +1 -0
  413. package/dist/pages/admin/McpPage.js +128 -0
  414. package/dist/pages/admin/McpPage.js.map +1 -0
  415. package/dist/pages/admin/ModulesPage.d.ts +2 -0
  416. package/dist/pages/admin/ModulesPage.d.ts.map +1 -0
  417. package/dist/pages/admin/ModulesPage.js +53 -0
  418. package/dist/pages/admin/ModulesPage.js.map +1 -0
  419. package/dist/pages/admin/TeamPage.d.ts +2 -0
  420. package/dist/pages/admin/TeamPage.d.ts.map +1 -0
  421. package/dist/pages/admin/TeamPage.js +99 -0
  422. package/dist/pages/admin/TeamPage.js.map +1 -0
  423. package/dist/pages/admin/WebhookDeliveries.d.ts +4 -0
  424. package/dist/pages/admin/WebhookDeliveries.d.ts.map +1 -0
  425. package/dist/pages/admin/WebhookDeliveries.js +88 -0
  426. package/dist/pages/admin/WebhookDeliveries.js.map +1 -0
  427. package/dist/pages/admin/WebhooksPage.d.ts +2 -0
  428. package/dist/pages/admin/WebhooksPage.d.ts.map +1 -0
  429. package/dist/pages/admin/WebhooksPage.js +152 -0
  430. package/dist/pages/admin/WebhooksPage.js.map +1 -0
  431. package/dist/pages/admin/WorkspaceSettingsPage.d.ts +2 -0
  432. package/dist/pages/admin/WorkspaceSettingsPage.d.ts.map +1 -0
  433. package/dist/pages/admin/WorkspaceSettingsPage.js +117 -0
  434. package/dist/pages/admin/WorkspaceSettingsPage.js.map +1 -0
  435. package/dist/pages/auth/AuthForm.d.ts +46 -0
  436. package/dist/pages/auth/AuthForm.d.ts.map +1 -0
  437. package/dist/pages/auth/AuthForm.js +32 -0
  438. package/dist/pages/auth/AuthForm.js.map +1 -0
  439. package/dist/pages/auth/AuthLayout.d.ts +24 -0
  440. package/dist/pages/auth/AuthLayout.d.ts.map +1 -0
  441. package/dist/pages/auth/AuthLayout.js +19 -0
  442. package/dist/pages/auth/AuthLayout.js.map +1 -0
  443. package/dist/pages/auth/ForgotPasswordPage.d.ts +13 -0
  444. package/dist/pages/auth/ForgotPasswordPage.d.ts.map +1 -0
  445. package/dist/pages/auth/ForgotPasswordPage.js +39 -0
  446. package/dist/pages/auth/ForgotPasswordPage.js.map +1 -0
  447. package/dist/pages/auth/JoinPage.d.ts +12 -0
  448. package/dist/pages/auth/JoinPage.d.ts.map +1 -0
  449. package/dist/pages/auth/JoinPage.js +43 -0
  450. package/dist/pages/auth/JoinPage.js.map +1 -0
  451. package/dist/pages/auth/ResetPasswordPage.d.ts +13 -0
  452. package/dist/pages/auth/ResetPasswordPage.d.ts.map +1 -0
  453. package/dist/pages/auth/ResetPasswordPage.js +58 -0
  454. package/dist/pages/auth/ResetPasswordPage.js.map +1 -0
  455. package/dist/pages/auth/SignInPage.d.ts +2 -0
  456. package/dist/pages/auth/SignInPage.d.ts.map +1 -0
  457. package/dist/pages/auth/SignInPage.js +38 -0
  458. package/dist/pages/auth/SignInPage.js.map +1 -0
  459. package/dist/pages/auth/SignUpPage.d.ts +13 -0
  460. package/dist/pages/auth/SignUpPage.d.ts.map +1 -0
  461. package/dist/pages/auth/SignUpPage.js +43 -0
  462. package/dist/pages/auth/SignUpPage.js.map +1 -0
  463. package/dist/pages/candidateFields.d.ts +22 -0
  464. package/dist/pages/candidateFields.d.ts.map +1 -0
  465. package/dist/pages/candidateFields.js +82 -0
  466. package/dist/pages/candidateFields.js.map +1 -0
  467. package/dist/pages/dashboard/DashboardPage.d.ts +2 -0
  468. package/dist/pages/dashboard/DashboardPage.d.ts.map +1 -0
  469. package/dist/pages/dashboard/DashboardPage.js +40 -0
  470. package/dist/pages/dashboard/DashboardPage.js.map +1 -0
  471. package/dist/pages/dashboard/attention.d.ts +41 -0
  472. package/dist/pages/dashboard/attention.d.ts.map +1 -0
  473. package/dist/pages/dashboard/attention.js +146 -0
  474. package/dist/pages/dashboard/attention.js.map +1 -0
  475. package/dist/pages/dashboard/sections.d.ts +20 -0
  476. package/dist/pages/dashboard/sections.d.ts.map +1 -0
  477. package/dist/pages/dashboard/sections.js +60 -0
  478. package/dist/pages/dashboard/sections.js.map +1 -0
  479. package/dist/pages/fields.d.ts +11 -0
  480. package/dist/pages/fields.d.ts.map +1 -0
  481. package/dist/pages/fields.js +17 -0
  482. package/dist/pages/fields.js.map +1 -0
  483. package/dist/pages/forms/EmbedPanel.d.ts +14 -0
  484. package/dist/pages/forms/EmbedPanel.d.ts.map +1 -0
  485. package/dist/pages/forms/EmbedPanel.js +19 -0
  486. package/dist/pages/forms/EmbedPanel.js.map +1 -0
  487. package/dist/pages/forms/FieldsEditor.d.ts +6 -0
  488. package/dist/pages/forms/FieldsEditor.d.ts.map +1 -0
  489. package/dist/pages/forms/FieldsEditor.js +115 -0
  490. package/dist/pages/forms/FieldsEditor.js.map +1 -0
  491. package/dist/pages/forms/FormSettings.d.ts +6 -0
  492. package/dist/pages/forms/FormSettings.d.ts.map +1 -0
  493. package/dist/pages/forms/FormSettings.js +47 -0
  494. package/dist/pages/forms/FormSettings.js.map +1 -0
  495. package/dist/pages/forms/SubmissionsTable.d.ts +8 -0
  496. package/dist/pages/forms/SubmissionsTable.d.ts.map +1 -0
  497. package/dist/pages/forms/SubmissionsTable.js +91 -0
  498. package/dist/pages/forms/SubmissionsTable.js.map +1 -0
  499. package/dist/pages/forms/fieldList.d.ts +70 -0
  500. package/dist/pages/forms/fieldList.d.ts.map +1 -0
  501. package/dist/pages/forms/fieldList.js +126 -0
  502. package/dist/pages/forms/fieldList.js.map +1 -0
  503. package/dist/pages/forms/template.d.ts +18 -0
  504. package/dist/pages/forms/template.d.ts.map +1 -0
  505. package/dist/pages/forms/template.js +34 -0
  506. package/dist/pages/forms/template.js.map +1 -0
  507. package/dist/pages/handbook/HandbookPage.d.ts +2 -0
  508. package/dist/pages/handbook/HandbookPage.d.ts.map +1 -0
  509. package/dist/pages/handbook/HandbookPage.js +197 -0
  510. package/dist/pages/handbook/HandbookPage.js.map +1 -0
  511. package/dist/pages/handbook/tree.d.ts +62 -0
  512. package/dist/pages/handbook/tree.d.ts.map +1 -0
  513. package/dist/pages/handbook/tree.js +222 -0
  514. package/dist/pages/handbook/tree.js.map +1 -0
  515. package/dist/pages/hiringDirectory.d.ts +60 -0
  516. package/dist/pages/hiringDirectory.d.ts.map +1 -0
  517. package/dist/pages/hiringDirectory.js +81 -0
  518. package/dist/pages/hiringDirectory.js.map +1 -0
  519. package/dist/pages/onboarding/HandbookStepPage.d.ts +14 -0
  520. package/dist/pages/onboarding/HandbookStepPage.d.ts.map +1 -0
  521. package/dist/pages/onboarding/HandbookStepPage.js +29 -0
  522. package/dist/pages/onboarding/HandbookStepPage.js.map +1 -0
  523. package/dist/pages/onboarding/InvitesStepPage.d.ts +2 -0
  524. package/dist/pages/onboarding/InvitesStepPage.d.ts.map +1 -0
  525. package/dist/pages/onboarding/InvitesStepPage.js +77 -0
  526. package/dist/pages/onboarding/InvitesStepPage.js.map +1 -0
  527. package/dist/pages/onboarding/WorkspaceStepPage.d.ts +2 -0
  528. package/dist/pages/onboarding/WorkspaceStepPage.d.ts.map +1 -0
  529. package/dist/pages/onboarding/WorkspaceStepPage.js +72 -0
  530. package/dist/pages/onboarding/WorkspaceStepPage.js.map +1 -0
  531. package/dist/pages/positionDirectory.d.ts +20 -0
  532. package/dist/pages/positionDirectory.d.ts.map +1 -0
  533. package/dist/pages/positionDirectory.js +58 -0
  534. package/dist/pages/positionDirectory.js.map +1 -0
  535. package/dist/registry/UiExtensionProvider.d.ts +12 -0
  536. package/dist/registry/UiExtensionProvider.d.ts.map +1 -0
  537. package/dist/registry/UiExtensionProvider.js +10 -0
  538. package/dist/registry/UiExtensionProvider.js.map +1 -0
  539. package/dist/registry/context.d.ts +31 -0
  540. package/dist/registry/context.d.ts.map +1 -0
  541. package/dist/registry/context.js +45 -0
  542. package/dist/registry/context.js.map +1 -0
  543. package/dist/registry/contributions.d.ts +71 -0
  544. package/dist/registry/contributions.d.ts.map +1 -0
  545. package/dist/registry/contributions.js +25 -0
  546. package/dist/registry/contributions.js.map +1 -0
  547. package/dist/registry/overridable.d.ts +27 -0
  548. package/dist/registry/overridable.d.ts.map +1 -0
  549. package/dist/registry/overridable.js +29 -0
  550. package/dist/registry/overridable.js.map +1 -0
  551. package/dist/registry/registry.d.ts +68 -0
  552. package/dist/registry/registry.d.ts.map +1 -0
  553. package/dist/registry/registry.js +112 -0
  554. package/dist/registry/registry.js.map +1 -0
  555. package/dist/testing/inputs.d.ts +13 -0
  556. package/dist/testing/inputs.d.ts.map +1 -0
  557. package/dist/testing/inputs.js +16 -0
  558. package/dist/testing/inputs.js.map +1 -0
  559. package/dist/testing/stubClient.d.ts +42 -0
  560. package/dist/testing/stubClient.d.ts.map +1 -0
  561. package/dist/testing/stubClient.js +29 -0
  562. package/dist/testing/stubClient.js.map +1 -0
  563. package/package.json +73 -0
  564. package/src/ServiceStatus.tsx +61 -0
  565. package/src/api/ApiProvider.tsx +40 -0
  566. package/src/api/client.ts +267 -0
  567. package/src/api/context.ts +25 -0
  568. package/src/api/errors.ts +14 -0
  569. package/src/api/health.ts +38 -0
  570. package/src/api/json.ts +4 -0
  571. package/src/api/queryClient.ts +35 -0
  572. package/src/api/resource.ts +412 -0
  573. package/src/api/resources/account.ts +220 -0
  574. package/src/api/resources/activities.ts +31 -0
  575. package/src/api/resources/agentTasks.ts +172 -0
  576. package/src/api/resources/candidates.ts +69 -0
  577. package/src/api/resources/companies.ts +72 -0
  578. package/src/api/resources/dashboard.ts +39 -0
  579. package/src/api/resources/deals.ts +82 -0
  580. package/src/api/resources/decisions.ts +60 -0
  581. package/src/api/resources/forms.ts +218 -0
  582. package/src/api/resources/handbookPages.ts +77 -0
  583. package/src/api/resources/importJobs.ts +229 -0
  584. package/src/api/resources/invites.ts +112 -0
  585. package/src/api/resources/mcpTools.ts +28 -0
  586. package/src/api/resources/members.ts +105 -0
  587. package/src/api/resources/moduleSettings.ts +67 -0
  588. package/src/api/resources/mutation.ts +31 -0
  589. package/src/api/resources/notes.ts +62 -0
  590. package/src/api/resources/opportunities.ts +84 -0
  591. package/src/api/resources/partnerships.ts +89 -0
  592. package/src/api/resources/people.ts +72 -0
  593. package/src/api/resources/pipelineStages.ts +93 -0
  594. package/src/api/resources/planItems.ts +103 -0
  595. package/src/api/resources/positions.ts +70 -0
  596. package/src/api/resources/raises.ts +82 -0
  597. package/src/api/resources/roles.ts +65 -0
  598. package/src/api/resources/search.ts +49 -0
  599. package/src/api/resources/session.ts +220 -0
  600. package/src/api/resources/webhooks.ts +157 -0
  601. package/src/api/resources/workspace.ts +81 -0
  602. package/src/app/KelpieApp.tsx +162 -0
  603. package/src/app/SessionGate.tsx +42 -0
  604. package/src/components/ActivitiesPanel.tsx +235 -0
  605. package/src/components/AgentTasks.tsx +473 -0
  606. package/src/components/Chip.tsx +36 -0
  607. package/src/components/CopyButton.tsx +48 -0
  608. package/src/components/DataTable.tsx +209 -0
  609. package/src/components/DecisionsPanel.tsx +233 -0
  610. package/src/components/DeleteRecord.tsx +73 -0
  611. package/src/components/EntitySearch.tsx +268 -0
  612. package/src/components/ErrorBoundary.tsx +58 -0
  613. package/src/components/InlineEdit.tsx +179 -0
  614. package/src/components/KanbanBoard.tsx +234 -0
  615. package/src/components/MarkdownView.tsx +73 -0
  616. package/src/components/NotesPanel.tsx +169 -0
  617. package/src/components/PageHeader.tsx +61 -0
  618. package/src/components/PhonesField.tsx +204 -0
  619. package/src/components/PlanAttention.tsx +249 -0
  620. package/src/components/PlanPanel.tsx +317 -0
  621. package/src/components/QueryState.tsx +83 -0
  622. package/src/components/RecordTabs.tsx +69 -0
  623. package/src/components/SectionHeader.tsx +63 -0
  624. package/src/components/SegmentedControl.tsx +48 -0
  625. package/src/components/Shell.tsx +300 -0
  626. package/src/components/SidebarField.tsx +18 -0
  627. package/src/components/SocialProfilesField.tsx +356 -0
  628. package/src/components/StageSettings.tsx +319 -0
  629. package/src/components/SummaryBlock.tsx +27 -0
  630. package/src/index.ts +190 -0
  631. package/src/lib/dates.ts +90 -0
  632. package/src/lib/money.ts +12 -0
  633. package/src/lib/names.ts +13 -0
  634. package/src/lib/plan.ts +147 -0
  635. package/src/lib/theme.ts +53 -0
  636. package/src/pages/CompaniesPage.tsx +143 -0
  637. package/src/pages/CompanyDetail.tsx +502 -0
  638. package/src/pages/DealDetail.tsx +512 -0
  639. package/src/pages/DealStageSettingsPage.tsx +67 -0
  640. package/src/pages/DealsPage.tsx +342 -0
  641. package/src/pages/DecisionsPage.tsx +211 -0
  642. package/src/pages/FormDetail.tsx +130 -0
  643. package/src/pages/FormsPage.tsx +151 -0
  644. package/src/pages/FundraisingPage.tsx +354 -0
  645. package/src/pages/HiringPage.tsx +169 -0
  646. package/src/pages/NotFoundPage.tsx +27 -0
  647. package/src/pages/OpportunitiesPage.tsx +349 -0
  648. package/src/pages/OpportunityDetail.tsx +337 -0
  649. package/src/pages/OpportunityStageSettingsPage.tsx +63 -0
  650. package/src/pages/PartnershipDetail.tsx +490 -0
  651. package/src/pages/PartnershipStageSettingsPage.tsx +63 -0
  652. package/src/pages/PartnershipsPage.tsx +353 -0
  653. package/src/pages/PeoplePage.tsx +145 -0
  654. package/src/pages/PersonDetail.tsx +526 -0
  655. package/src/pages/PlanningPage.tsx +318 -0
  656. package/src/pages/RaiseDetail.tsx +498 -0
  657. package/src/pages/RaiseStageSettingsPage.tsx +63 -0
  658. package/src/pages/RoleDetail.tsx +455 -0
  659. package/src/pages/SearchPage.tsx +135 -0
  660. package/src/pages/account/AccountLayout.tsx +38 -0
  661. package/src/pages/account/Field.tsx +20 -0
  662. package/src/pages/account/PreferencesPage.tsx +224 -0
  663. package/src/pages/account/ProfilePage.tsx +147 -0
  664. package/src/pages/account/SecurityPage.tsx +237 -0
  665. package/src/pages/admin/DataPage.tsx +772 -0
  666. package/src/pages/admin/McpPage.tsx +404 -0
  667. package/src/pages/admin/ModulesPage.tsx +113 -0
  668. package/src/pages/admin/TeamPage.tsx +386 -0
  669. package/src/pages/admin/WebhookDeliveries.tsx +184 -0
  670. package/src/pages/admin/WebhooksPage.tsx +443 -0
  671. package/src/pages/admin/WorkspaceSettingsPage.tsx +274 -0
  672. package/src/pages/auth/AuthForm.tsx +118 -0
  673. package/src/pages/auth/AuthLayout.tsx +74 -0
  674. package/src/pages/auth/ForgotPasswordPage.tsx +80 -0
  675. package/src/pages/auth/JoinPage.tsx +85 -0
  676. package/src/pages/auth/ResetPasswordPage.tsx +124 -0
  677. package/src/pages/auth/SignInPage.tsx +83 -0
  678. package/src/pages/auth/SignUpPage.tsx +93 -0
  679. package/src/pages/candidateFields.tsx +175 -0
  680. package/src/pages/dashboard/DashboardPage.tsx +108 -0
  681. package/src/pages/dashboard/attention.ts +206 -0
  682. package/src/pages/dashboard/sections.tsx +269 -0
  683. package/src/pages/fields.ts +21 -0
  684. package/src/pages/forms/EmbedPanel.tsx +95 -0
  685. package/src/pages/forms/FieldsEditor.tsx +412 -0
  686. package/src/pages/forms/FormSettings.tsx +159 -0
  687. package/src/pages/forms/SubmissionsTable.tsx +171 -0
  688. package/src/pages/forms/fieldList.ts +209 -0
  689. package/src/pages/forms/template.ts +37 -0
  690. package/src/pages/handbook/HandbookPage.tsx +500 -0
  691. package/src/pages/handbook/tree.ts +327 -0
  692. package/src/pages/hiringDirectory.ts +146 -0
  693. package/src/pages/onboarding/HandbookStepPage.tsx +75 -0
  694. package/src/pages/onboarding/InvitesStepPage.tsx +180 -0
  695. package/src/pages/onboarding/WorkspaceStepPage.tsx +122 -0
  696. package/src/pages/positionDirectory.ts +98 -0
  697. package/src/registry/UiExtensionProvider.tsx +20 -0
  698. package/src/registry/context.ts +67 -0
  699. package/src/registry/contributions.ts +89 -0
  700. package/src/registry/overridable.ts +62 -0
  701. package/src/registry/registry.ts +204 -0
  702. package/src/styles.css +175 -0
  703. package/src/testing/inputs.ts +18 -0
  704. package/src/testing/stubClient.ts +78 -0
@@ -0,0 +1,224 @@
1
+ import { THEME_PREFERENCES } from '@kelpie/schemas'
2
+ import type { AccountPreferences, ThemePreference } from '@kelpie/schemas'
3
+ import { useState } from 'react'
4
+ import type { FormEvent, ReactNode } from 'react'
5
+
6
+ import {
7
+ useAccountPreferences,
8
+ useTheme,
9
+ useUpdateAccountPreferences,
10
+ } from '../../api/resources/account.ts'
11
+ import { EntitySearch } from '../../components/EntitySearch.tsx'
12
+ import { PageHeader } from '../../components/PageHeader.tsx'
13
+ import { ErrorPanel, LoadingPanel } from '../../components/QueryState.tsx'
14
+ import { Field } from './Field.tsx'
15
+
16
+ /**
17
+ * Appearance, timezone, and what to email.
18
+ *
19
+ * Ported from the mockup's Preferences page. Appearance is applied the moment it
20
+ * is clicked, because it is visible in the click; everything else waits for the
21
+ * save button, as the mockup does.
22
+ */
23
+
24
+ const THEME_LABELS: Readonly<Record<ThemePreference, string>> = {
25
+ system: 'System',
26
+ light: 'Light',
27
+ dark: 'Dark',
28
+ }
29
+
30
+ /**
31
+ * Every zone this runtime's ICU knows, matching what the server's
32
+ * `timezoneSchema` will accept. Falls back to the zones the mockup offered if
33
+ * `Intl.supportedValuesOf` is missing, for a browser old enough to lack it.
34
+ *
35
+ * `UTC` is prepended because `supportedValuesOf` omits it in some engines even
36
+ * though ECMA-402 guarantees `Intl.DateTimeFormat` accepts it as a zone name.
37
+ * Without this, a very common choice would be searchable only by accident of
38
+ * already being the stored value.
39
+ */
40
+ const ALL_TIMEZONES: readonly string[] = (() => {
41
+ try {
42
+ return ['UTC', ...Intl.supportedValuesOf('timeZone')]
43
+ } catch {
44
+ return [
45
+ 'UTC',
46
+ 'Australia/Sydney',
47
+ 'Australia/Melbourne',
48
+ 'America/Los_Angeles',
49
+ 'America/New_York',
50
+ 'Europe/London',
51
+ ]
52
+ }
53
+ })()
54
+
55
+ export function PreferencesPage(): React.JSX.Element {
56
+ const { preferences, isLoading, error } = useAccountPreferences()
57
+
58
+ if (error !== null) {
59
+ return <ErrorPanel error={error} />
60
+ }
61
+
62
+ if (isLoading || preferences === undefined) {
63
+ return <LoadingPanel />
64
+ }
65
+
66
+ return <PreferencesForm preferences={preferences} />
67
+ }
68
+
69
+ function PreferencesForm({
70
+ preferences,
71
+ }: {
72
+ readonly preferences: AccountPreferences
73
+ }): React.JSX.Element {
74
+ const { theme, setTheme } = useTheme()
75
+ const update = useUpdateAccountPreferences()
76
+ const [timezone, setTimezone] = useState(preferences.timezone)
77
+ const [emailDigest, setEmailDigest] = useState(preferences.emailDigest)
78
+ const [mentionEmails, setMentionEmails] = useState(preferences.mentionEmails)
79
+ const [productUpdates, setProductUpdates] = useState(preferences.productUpdates)
80
+ const [saved, setSaved] = useState(false)
81
+
82
+ const zones = ALL_TIMEZONES.includes(timezone) ? ALL_TIMEZONES : [timezone, ...ALL_TIMEZONES]
83
+
84
+ function save(event: FormEvent): void {
85
+ event.preventDefault()
86
+ setSaved(false)
87
+
88
+ update
89
+ // Theme is left out deliberately: it is already saved, by the control that
90
+ // changed it. Sending the current one back would undo a click made while
91
+ // this form sat open.
92
+ .runAsync({ timezone, emailDigest, mentionEmails, productUpdates })
93
+ .then(() => {
94
+ setSaved(true)
95
+ })
96
+ .catch(() => undefined)
97
+ }
98
+
99
+ return (
100
+ <div className="animate-slide-in space-y-6">
101
+ <PageHeader
102
+ title="Preferences"
103
+ description="Appearance, timezone, and email notifications."
104
+ />
105
+
106
+ <form onSubmit={save} className="space-y-5">
107
+ <fieldset>
108
+ <legend className="mb-1.5 text-[12px] font-medium text-ink">Appearance</legend>
109
+ <div className="inline-flex rounded-md border border-border p-0.5">
110
+ {THEME_PREFERENCES.map((value) => (
111
+ <button
112
+ key={value}
113
+ type="button"
114
+ onClick={() => {
115
+ setTheme(value)
116
+ }}
117
+ className={[
118
+ 'rounded px-2.5 py-1 text-[12px] transition',
119
+ theme === value
120
+ ? 'bg-surface-sunken font-medium text-ink'
121
+ : 'text-ink-muted hover:text-ink',
122
+ ].join(' ')}
123
+ >
124
+ {THEME_LABELS[value]}
125
+ </button>
126
+ ))}
127
+ </div>
128
+ <p className="mt-1 text-[11px] text-ink-faint">
129
+ Saved to your account as you click, and applied in every browser you sign in to.
130
+ </p>
131
+ </fieldset>
132
+
133
+ <div className="max-w-md">
134
+ <Field
135
+ label="Timezone"
136
+ hint="Stored on your account. Kelpie does not format dates by it yet."
137
+ >
138
+ <EntitySearch
139
+ options={zones.map((zone) => ({ id: zone, label: zone }))}
140
+ value={timezone}
141
+ onChange={setTimezone}
142
+ placeholder="Search time zones…"
143
+ limit={20}
144
+ required
145
+ size="md"
146
+ />
147
+ </Field>
148
+ </div>
149
+
150
+ <fieldset className="space-y-2">
151
+ <legend className="text-[12px] font-medium text-ink">Email notifications</legend>
152
+ {/* Said plainly rather than left to be inferred from a toggle that
153
+ looks live. Kelpie sends no notification email yet; these record
154
+ the answer for when it does. */}
155
+ <p className="max-w-lg text-[11px] text-ink-faint">
156
+ Kelpie does not send these emails yet. Your choices are saved and will apply when it
157
+ does.
158
+ </p>
159
+ <Toggle
160
+ checked={emailDigest}
161
+ onChange={setEmailDigest}
162
+ label="Weekly digest"
163
+ description="Summary of deals, decisions, and activity."
164
+ />
165
+ <Toggle
166
+ checked={mentionEmails}
167
+ onChange={setMentionEmails}
168
+ label="Mentions and assignments"
169
+ description="When someone mentions you or assigns a Plan item."
170
+ />
171
+ <Toggle
172
+ checked={productUpdates}
173
+ onChange={setProductUpdates}
174
+ label="Product updates"
175
+ description="Occasional notes about Kelpie releases."
176
+ />
177
+ </fieldset>
178
+
179
+ {update.error !== null && (
180
+ <div className="max-w-lg">
181
+ <ErrorPanel error={update.error} />
182
+ </div>
183
+ )}
184
+
185
+ <button
186
+ type="submit"
187
+ disabled={update.isPending}
188
+ className="rounded-md bg-accent px-3 py-1.5 text-[12px] font-medium text-accent-fg transition hover:bg-accent-hover disabled:opacity-50"
189
+ >
190
+ {update.isPending ? 'Saving…' : saved ? 'Saved' : 'Save preferences'}
191
+ </button>
192
+ </form>
193
+ </div>
194
+ )
195
+ }
196
+
197
+ function Toggle({
198
+ checked,
199
+ onChange,
200
+ label,
201
+ description,
202
+ }: {
203
+ readonly checked: boolean
204
+ readonly onChange: (value: boolean) => void
205
+ readonly label: string
206
+ readonly description: string
207
+ }): ReactNode {
208
+ return (
209
+ <label className="flex max-w-lg cursor-pointer items-start gap-3 rounded-md border border-border px-3 py-2.5">
210
+ <input
211
+ type="checkbox"
212
+ checked={checked}
213
+ onChange={(event) => {
214
+ onChange(event.target.checked)
215
+ }}
216
+ className="mt-0.5 h-4 w-4 rounded border-border text-accent focus:ring-accent/20"
217
+ />
218
+ <span>
219
+ <span className="block text-[13px] font-medium text-ink">{label}</span>
220
+ <span className="mt-0.5 block text-[12px] text-ink-muted">{description}</span>
221
+ </span>
222
+ </label>
223
+ )
224
+ }
@@ -0,0 +1,147 @@
1
+ import type { Account } from '@kelpie/schemas'
2
+ import { useState } from 'react'
3
+ import type { FormEvent } from 'react'
4
+
5
+ import { useAccount, useUpdateAccount } from '../../api/resources/account.ts'
6
+ import { PageHeader } from '../../components/PageHeader.tsx'
7
+ import { ErrorPanel, LoadingPanel } from '../../components/QueryState.tsx'
8
+ import { initialsOf } from '../../lib/names.ts'
9
+ import { Field } from './Field.tsx'
10
+
11
+ /**
12
+ * The account's name and address.
13
+ *
14
+ * Ported from the mockup's Profile page. Two differences now that there is an
15
+ * API behind it: the address is unique across Kelpie, so a save can be refused,
16
+ * and changing it changes what this person signs in with, so the service (and
17
+ * this form) asks for the current password before it takes effect.
18
+ *
19
+ * The form saves explicitly rather than per keystroke, like workspace settings:
20
+ * a half-typed address is a different account, and committing one on every
21
+ * character would be a stream of them.
22
+ */
23
+
24
+ export function ProfilePage(): React.JSX.Element {
25
+ const { account, isLoading, error } = useAccount()
26
+
27
+ if (error !== null) {
28
+ return <ErrorPanel error={error} />
29
+ }
30
+
31
+ if (isLoading || account === undefined) {
32
+ return <LoadingPanel />
33
+ }
34
+
35
+ return <ProfileForm key={account.id} account={account} />
36
+ }
37
+
38
+ function ProfileForm({ account }: { readonly account: Account }): React.JSX.Element {
39
+ const update = useUpdateAccount()
40
+ const [name, setName] = useState(account.name)
41
+ const [email, setEmail] = useState(account.email)
42
+ const [currentPassword, setCurrentPassword] = useState('')
43
+ const [saved, setSaved] = useState(false)
44
+ const [localError, setLocalError] = useState<string | null>(null)
45
+
46
+ const trimmedEmail = email.trim()
47
+ const emailChanged = trimmedEmail !== account.email
48
+
49
+ function save(event: FormEvent): void {
50
+ event.preventDefault()
51
+ setSaved(false)
52
+
53
+ if (emailChanged && currentPassword.length === 0) {
54
+ setLocalError('Enter your current password to change your email.')
55
+ return
56
+ }
57
+
58
+ setLocalError(null)
59
+
60
+ const trimmedName = name.trim()
61
+
62
+ update
63
+ .runAsync({
64
+ ...(trimmedName === account.name ? {} : { name: trimmedName }),
65
+ ...(emailChanged ? { email: trimmedEmail, currentPassword } : {}),
66
+ })
67
+ .then((updated) => {
68
+ // The service lowercases the address it stored. Showing what was typed
69
+ // instead would leave the field disagreeing with the account.
70
+ setEmail(updated.email)
71
+ setName(updated.name)
72
+ setCurrentPassword('')
73
+ setSaved(true)
74
+ })
75
+ .catch(() => undefined)
76
+ }
77
+
78
+ return (
79
+ <div className="animate-slide-in space-y-6">
80
+ <PageHeader title="Profile" description="Your name and email across every workspace." />
81
+
82
+ <form onSubmit={save} className="space-y-4">
83
+ <div className="flex items-center gap-3">
84
+ <div className="flex h-12 w-12 items-center justify-center rounded-full bg-accent text-[13px] font-medium text-accent-fg">
85
+ {initialsOf(name)}
86
+ </div>
87
+ <p className="text-[12px] text-ink-muted">Initials are derived from your name.</p>
88
+ </div>
89
+
90
+ <Field label="Name">
91
+ <input
92
+ value={name}
93
+ onChange={(event) => {
94
+ setName(event.target.value)
95
+ }}
96
+ required
97
+ className="w-full max-w-md rounded-md border border-border bg-surface-raised px-3 py-2 text-[13px] outline-none focus:border-accent focus:ring-2 focus:ring-accent/20"
98
+ />
99
+ </Field>
100
+
101
+ <Field label="Email" hint="This is the address you sign in with.">
102
+ <input
103
+ type="email"
104
+ value={email}
105
+ onChange={(event) => {
106
+ setEmail(event.target.value)
107
+ }}
108
+ required
109
+ autoComplete="email"
110
+ className="w-full max-w-md rounded-md border border-border bg-surface-raised px-3 py-2 text-[13px] outline-none focus:border-accent focus:ring-2 focus:ring-accent/20"
111
+ />
112
+ </Field>
113
+
114
+ {emailChanged && (
115
+ <Field label="Current password" hint="Required to change the address you sign in with.">
116
+ <input
117
+ type="password"
118
+ value={currentPassword}
119
+ onChange={(event) => {
120
+ setCurrentPassword(event.target.value)
121
+ }}
122
+ autoComplete="current-password"
123
+ required
124
+ className="w-full max-w-md rounded-md border border-border bg-surface-raised px-3 py-2 text-[13px] outline-none focus:border-accent focus:ring-2 focus:ring-accent/20"
125
+ />
126
+ </Field>
127
+ )}
128
+
129
+ {localError !== null && <p className="text-[12px] text-danger">{localError}</p>}
130
+
131
+ {update.error !== null && (
132
+ <div className="max-w-xl">
133
+ <ErrorPanel error={update.error} />
134
+ </div>
135
+ )}
136
+
137
+ <button
138
+ type="submit"
139
+ disabled={update.isPending}
140
+ className="rounded-md bg-accent px-3.5 py-2 text-[12px] font-semibold text-accent-fg transition hover:bg-accent-hover disabled:opacity-50"
141
+ >
142
+ {update.isPending ? 'Saving…' : saved ? 'Saved' : 'Save changes'}
143
+ </button>
144
+ </form>
145
+ </div>
146
+ )
147
+ }
@@ -0,0 +1,237 @@
1
+ import { MINIMUM_PASSWORD_LENGTH } from '@kelpie/schemas'
2
+ import type { AccountSession } from '@kelpie/schemas'
3
+ import { useState } from 'react'
4
+ import type { FormEvent } from 'react'
5
+
6
+ import {
7
+ useAccountSessions,
8
+ useChangePassword,
9
+ useRevokeAccountSession,
10
+ } from '../../api/resources/account.ts'
11
+ import { PageHeader } from '../../components/PageHeader.tsx'
12
+ import { ErrorPanel, LoadingPanel } from '../../components/QueryState.tsx'
13
+ import { formatDateTime } from '../../lib/dates.ts'
14
+
15
+ /**
16
+ * Password and signed-in devices.
17
+ *
18
+ * Ported from the mockup's Security page against the endpoints that already
19
+ * existed. Two things the mockup could not show: changing the password really
20
+ * does end every other session, so the list below refetches, and the caller's
21
+ * own row cannot be revoked because signing yourself out from here is what the
22
+ * account menu is for.
23
+ */
24
+
25
+ export function SecurityPage(): React.JSX.Element {
26
+ return (
27
+ <div className="animate-slide-in space-y-8">
28
+ <PageHeader title="Security" description="Your password and where you are signed in." />
29
+ <ChangePasswordForm />
30
+ <SessionList />
31
+ </div>
32
+ )
33
+ }
34
+
35
+ const inputClass =
36
+ 'w-full rounded-md border border-border bg-surface-raised px-3 py-2 text-[13px] outline-none focus:border-accent focus:ring-2 focus:ring-accent/20'
37
+
38
+ function ChangePasswordForm(): React.JSX.Element {
39
+ const change = useChangePassword()
40
+ const [currentPassword, setCurrentPassword] = useState('')
41
+ const [newPassword, setNewPassword] = useState('')
42
+ const [confirmation, setConfirmation] = useState('')
43
+ const [localError, setLocalError] = useState<string | null>(null)
44
+ const [changed, setChanged] = useState(false)
45
+
46
+ /**
47
+ * The two rules the browser can decide on its own. Length is checked here as
48
+ * well as by the service so the reader learns it before submitting; the
49
+ * confirmation never reaches the API, which has nothing to compare it to.
50
+ */
51
+ function localProblem(): string | null {
52
+ if (currentPassword.length === 0 || newPassword.length === 0) {
53
+ return 'Enter your current and new password.'
54
+ }
55
+
56
+ if (newPassword.length < MINIMUM_PASSWORD_LENGTH) {
57
+ return `New password must be at least ${String(MINIMUM_PASSWORD_LENGTH)} characters.`
58
+ }
59
+
60
+ return newPassword === confirmation ? null : 'New password and confirmation do not match.'
61
+ }
62
+
63
+ function submit(event: FormEvent): void {
64
+ event.preventDefault()
65
+ setChanged(false)
66
+
67
+ const problem = localProblem()
68
+
69
+ setLocalError(problem)
70
+
71
+ if (problem !== null) {
72
+ return
73
+ }
74
+
75
+ change
76
+ .runAsync({ currentPassword, newPassword })
77
+ .then(() => {
78
+ setCurrentPassword('')
79
+ setNewPassword('')
80
+ setConfirmation('')
81
+ setChanged(true)
82
+ })
83
+ .catch(() => undefined)
84
+ }
85
+
86
+ return (
87
+ <form onSubmit={submit} className="space-y-3">
88
+ <h2 className="text-[14px] font-semibold text-ink">Change password</h2>
89
+ <p className="max-w-md text-[12px] text-ink-muted">
90
+ Changing your password signs you out everywhere except this browser.
91
+ </p>
92
+
93
+ <label className="block max-w-md">
94
+ <span className="mb-1.5 block text-[12px] font-medium text-ink">Current password</span>
95
+ <input
96
+ type="password"
97
+ value={currentPassword}
98
+ onChange={(event) => {
99
+ setCurrentPassword(event.target.value)
100
+ }}
101
+ autoComplete="current-password"
102
+ className={inputClass}
103
+ />
104
+ </label>
105
+
106
+ <label className="block max-w-md">
107
+ <span className="mb-1.5 block text-[12px] font-medium text-ink">New password</span>
108
+ <input
109
+ type="password"
110
+ value={newPassword}
111
+ onChange={(event) => {
112
+ setNewPassword(event.target.value)
113
+ }}
114
+ autoComplete="new-password"
115
+ className={inputClass}
116
+ />
117
+ <span className="mt-1 block text-[11px] text-ink-faint">
118
+ At least {MINIMUM_PASSWORD_LENGTH} characters.
119
+ </span>
120
+ </label>
121
+
122
+ <label className="block max-w-md">
123
+ <span className="mb-1.5 block text-[12px] font-medium text-ink">Confirm new password</span>
124
+ <input
125
+ type="password"
126
+ value={confirmation}
127
+ onChange={(event) => {
128
+ setConfirmation(event.target.value)
129
+ }}
130
+ autoComplete="new-password"
131
+ className={inputClass}
132
+ />
133
+ </label>
134
+
135
+ {localError !== null && <p className="text-[12px] text-danger">{localError}</p>}
136
+ {change.error !== null && (
137
+ <div className="max-w-md">
138
+ <ErrorPanel error={change.error} />
139
+ </div>
140
+ )}
141
+
142
+ <button
143
+ type="submit"
144
+ disabled={change.isPending}
145
+ className="rounded-md bg-accent px-3.5 py-2 text-[12px] font-semibold text-accent-fg transition hover:bg-accent-hover disabled:opacity-50"
146
+ >
147
+ {change.isPending ? 'Updating…' : changed ? 'Password updated' : 'Update password'}
148
+ </button>
149
+ </form>
150
+ )
151
+ }
152
+
153
+ function SessionList(): React.JSX.Element {
154
+ const { sessions, isLoading, error } = useAccountSessions()
155
+ const revoke = useRevokeAccountSession()
156
+
157
+ return (
158
+ <section>
159
+ <h2 className="mb-3 text-[14px] font-semibold text-ink">Sessions</h2>
160
+
161
+ {error !== null && <ErrorPanel error={error} />}
162
+ {error === null && isLoading && <LoadingPanel label="Loading sessions…" />}
163
+
164
+ {/* The wrapper scrolls rather than clips, like the team tables: a narrow
165
+ window must not hide the column with the Revoke button in it. */}
166
+ {error === null && !isLoading && (
167
+ <div className="overflow-x-auto rounded-md border border-border">
168
+ <table className="w-full text-left text-[13px]">
169
+ <thead>
170
+ <tr className="border-b border-border bg-surface text-[11px] font-semibold tracking-wide text-ink-muted uppercase">
171
+ <th className="px-4 py-2.5">Device</th>
172
+ <th className="px-4 py-2.5">Location</th>
173
+ <th className="px-4 py-2.5">Last active</th>
174
+ <th className="px-4 py-2.5 text-right">Actions</th>
175
+ </tr>
176
+ </thead>
177
+ <tbody>
178
+ {sessions.map((session) => (
179
+ <SessionRow
180
+ key={session.id}
181
+ session={session}
182
+ onRevoke={() => {
183
+ revoke.run(session.id)
184
+ }}
185
+ isRevoking={revoke.isPending}
186
+ />
187
+ ))}
188
+ </tbody>
189
+ </table>
190
+ </div>
191
+ )}
192
+
193
+ {revoke.error !== null && (
194
+ <div className="mt-3 max-w-xl">
195
+ <ErrorPanel error={revoke.error} />
196
+ </div>
197
+ )}
198
+ </section>
199
+ )
200
+ }
201
+
202
+ function SessionRow({
203
+ session,
204
+ onRevoke,
205
+ isRevoking,
206
+ }: {
207
+ readonly session: AccountSession
208
+ readonly onRevoke: () => void
209
+ readonly isRevoking: boolean
210
+ }): React.JSX.Element {
211
+ return (
212
+ <tr className="border-b border-border last:border-0">
213
+ <td className="px-4 py-3">
214
+ <div className="font-medium break-all text-ink">{session.device ?? 'Unknown device'}</div>
215
+ {session.current && <span className="text-[11px] font-medium text-success">This device</span>}
216
+ </td>
217
+ {/* Always unknown today: the service records the User-Agent and nothing
218
+ derives a location from the request. The column stays because the field
219
+ is on the wire and a session says where it is from once something can
220
+ tell. */}
221
+ <td className="px-4 py-3 text-ink-muted">{session.location ?? 'Unknown'}</td>
222
+ <td className="px-4 py-3 text-ink-muted">{formatDateTime(session.lastActiveAt)}</td>
223
+ <td className="px-4 py-3 text-right">
224
+ {!session.current && (
225
+ <button
226
+ type="button"
227
+ onClick={onRevoke}
228
+ disabled={isRevoking}
229
+ className="text-[12px] font-medium text-danger hover:underline disabled:opacity-50"
230
+ >
231
+ Revoke
232
+ </button>
233
+ )}
234
+ </td>
235
+ </tr>
236
+ )
237
+ }