@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.
- package/LICENSE +661 -0
- package/README.md +44 -0
- package/dist/ServiceStatus.d.ts +6 -0
- package/dist/ServiceStatus.d.ts.map +1 -0
- package/dist/ServiceStatus.js +35 -0
- package/dist/ServiceStatus.js.map +1 -0
- package/dist/api/ApiProvider.d.ts +19 -0
- package/dist/api/ApiProvider.d.ts.map +1 -0
- package/dist/api/ApiProvider.js +18 -0
- package/dist/api/ApiProvider.js.map +1 -0
- package/dist/api/client.d.ts +83 -0
- package/dist/api/client.d.ts.map +1 -0
- package/dist/api/client.js +162 -0
- package/dist/api/client.js.map +1 -0
- package/dist/api/context.d.ts +14 -0
- package/dist/api/context.d.ts.map +1 -0
- package/dist/api/context.js +20 -0
- package/dist/api/context.js.map +1 -0
- package/dist/api/errors.d.ts +9 -0
- package/dist/api/errors.d.ts.map +1 -0
- package/dist/api/errors.js +14 -0
- package/dist/api/errors.js.map +1 -0
- package/dist/api/health.d.ts +15 -0
- package/dist/api/health.d.ts.map +1 -0
- package/dist/api/health.js +22 -0
- package/dist/api/health.js.map +1 -0
- package/dist/api/json.d.ts +3 -0
- package/dist/api/json.d.ts.map +1 -0
- package/dist/api/json.js +5 -0
- package/dist/api/json.js.map +1 -0
- package/dist/api/queryClient.d.ts +17 -0
- package/dist/api/queryClient.d.ts.map +1 -0
- package/dist/api/queryClient.js +33 -0
- package/dist/api/queryClient.js.map +1 -0
- package/dist/api/resource.d.ts +110 -0
- package/dist/api/resource.d.ts.map +1 -0
- package/dist/api/resource.js +238 -0
- package/dist/api/resource.js.map +1 -0
- package/dist/api/resources/account.d.ts +49 -0
- package/dist/api/resources/account.d.ts.map +1 -0
- package/dist/api/resources/account.js +146 -0
- package/dist/api/resources/account.js.map +1 -0
- package/dist/api/resources/activities.d.ts +8 -0
- package/dist/api/resources/activities.d.ts.map +1 -0
- package/dist/api/resources/activities.js +21 -0
- package/dist/api/resources/activities.js.map +1 -0
- package/dist/api/resources/agentTasks.d.ts +31 -0
- package/dist/api/resources/agentTasks.d.ts.map +1 -0
- package/dist/api/resources/agentTasks.js +103 -0
- package/dist/api/resources/agentTasks.js.map +1 -0
- package/dist/api/resources/candidates.d.ts +17 -0
- package/dist/api/resources/candidates.d.ts.map +1 -0
- package/dist/api/resources/candidates.js +40 -0
- package/dist/api/resources/candidates.js.map +1 -0
- package/dist/api/resources/companies.d.ts +22 -0
- package/dist/api/resources/companies.d.ts.map +1 -0
- package/dist/api/resources/companies.js +36 -0
- package/dist/api/resources/companies.js.map +1 -0
- package/dist/api/resources/dashboard.d.ts +8 -0
- package/dist/api/resources/dashboard.d.ts.map +1 -0
- package/dist/api/resources/dashboard.js +27 -0
- package/dist/api/resources/dashboard.js.map +1 -0
- package/dist/api/resources/deals.d.ts +30 -0
- package/dist/api/resources/deals.d.ts.map +1 -0
- package/dist/api/resources/deals.js +38 -0
- package/dist/api/resources/deals.js.map +1 -0
- package/dist/api/resources/decisions.d.ts +13 -0
- package/dist/api/resources/decisions.d.ts.map +1 -0
- package/dist/api/resources/decisions.js +38 -0
- package/dist/api/resources/decisions.js.map +1 -0
- package/dist/api/resources/forms.d.ts +82 -0
- package/dist/api/resources/forms.d.ts.map +1 -0
- package/dist/api/resources/forms.js +129 -0
- package/dist/api/resources/forms.js.map +1 -0
- package/dist/api/resources/handbookPages.d.ts +33 -0
- package/dist/api/resources/handbookPages.d.ts.map +1 -0
- package/dist/api/resources/handbookPages.js +49 -0
- package/dist/api/resources/handbookPages.js.map +1 -0
- package/dist/api/resources/importJobs.d.ts +72 -0
- package/dist/api/resources/importJobs.d.ts.map +1 -0
- package/dist/api/resources/importJobs.js +145 -0
- package/dist/api/resources/importJobs.js.map +1 -0
- package/dist/api/resources/invites.d.ts +19 -0
- package/dist/api/resources/invites.d.ts.map +1 -0
- package/dist/api/resources/invites.js +78 -0
- package/dist/api/resources/invites.js.map +1 -0
- package/dist/api/resources/mcpTools.d.ts +8 -0
- package/dist/api/resources/mcpTools.d.ts.map +1 -0
- package/dist/api/resources/mcpTools.js +23 -0
- package/dist/api/resources/mcpTools.js.map +1 -0
- package/dist/api/resources/members.d.ts +40 -0
- package/dist/api/resources/members.d.ts.map +1 -0
- package/dist/api/resources/members.js +67 -0
- package/dist/api/resources/members.js.map +1 -0
- package/dist/api/resources/moduleSettings.d.ts +14 -0
- package/dist/api/resources/moduleSettings.d.ts.map +1 -0
- package/dist/api/resources/moduleSettings.js +43 -0
- package/dist/api/resources/moduleSettings.js.map +1 -0
- package/dist/api/resources/mutation.d.ts +18 -0
- package/dist/api/resources/mutation.d.ts.map +1 -0
- package/dist/api/resources/mutation.js +12 -0
- package/dist/api/resources/mutation.js.map +1 -0
- package/dist/api/resources/notes.d.ts +14 -0
- package/dist/api/resources/notes.d.ts.map +1 -0
- package/dist/api/resources/notes.js +39 -0
- package/dist/api/resources/notes.js.map +1 -0
- package/dist/api/resources/opportunities.d.ts +29 -0
- package/dist/api/resources/opportunities.d.ts.map +1 -0
- package/dist/api/resources/opportunities.js +38 -0
- package/dist/api/resources/opportunities.js.map +1 -0
- package/dist/api/resources/partnerships.d.ts +33 -0
- package/dist/api/resources/partnerships.d.ts.map +1 -0
- package/dist/api/resources/partnerships.js +39 -0
- package/dist/api/resources/partnerships.js.map +1 -0
- package/dist/api/resources/people.d.ts +22 -0
- package/dist/api/resources/people.d.ts.map +1 -0
- package/dist/api/resources/people.js +36 -0
- package/dist/api/resources/people.js.map +1 -0
- package/dist/api/resources/pipelineStages.d.ts +22 -0
- package/dist/api/resources/pipelineStages.d.ts.map +1 -0
- package/dist/api/resources/pipelineStages.js +61 -0
- package/dist/api/resources/pipelineStages.js.map +1 -0
- package/dist/api/resources/planItems.d.ts +31 -0
- package/dist/api/resources/planItems.d.ts.map +1 -0
- package/dist/api/resources/planItems.js +60 -0
- package/dist/api/resources/planItems.js.map +1 -0
- package/dist/api/resources/positions.d.ts +23 -0
- package/dist/api/resources/positions.d.ts.map +1 -0
- package/dist/api/resources/positions.js +31 -0
- package/dist/api/resources/positions.js.map +1 -0
- package/dist/api/resources/raises.d.ts +30 -0
- package/dist/api/resources/raises.d.ts.map +1 -0
- package/dist/api/resources/raises.js +38 -0
- package/dist/api/resources/raises.js.map +1 -0
- package/dist/api/resources/roles.d.ts +20 -0
- package/dist/api/resources/roles.d.ts.map +1 -0
- package/dist/api/resources/roles.js +31 -0
- package/dist/api/resources/roles.js.map +1 -0
- package/dist/api/resources/search.d.ts +12 -0
- package/dist/api/resources/search.d.ts.map +1 -0
- package/dist/api/resources/search.js +37 -0
- package/dist/api/resources/search.js.map +1 -0
- package/dist/api/resources/session.d.ts +58 -0
- package/dist/api/resources/session.d.ts.map +1 -0
- package/dist/api/resources/session.js +157 -0
- package/dist/api/resources/session.js.map +1 -0
- package/dist/api/resources/webhooks.d.ts +45 -0
- package/dist/api/resources/webhooks.d.ts.map +1 -0
- package/dist/api/resources/webhooks.js +106 -0
- package/dist/api/resources/webhooks.js.map +1 -0
- package/dist/api/resources/workspace.d.ts +20 -0
- package/dist/api/resources/workspace.d.ts.map +1 -0
- package/dist/api/resources/workspace.js +63 -0
- package/dist/api/resources/workspace.js.map +1 -0
- package/dist/app/KelpieApp.d.ts +18 -0
- package/dist/app/KelpieApp.d.ts.map +1 -0
- package/dist/app/KelpieApp.js +59 -0
- package/dist/app/KelpieApp.js.map +1 -0
- package/dist/app/SessionGate.d.ts +14 -0
- package/dist/app/SessionGate.d.ts.map +1 -0
- package/dist/app/SessionGate.js +33 -0
- package/dist/app/SessionGate.js.map +1 -0
- package/dist/components/ActivitiesPanel.d.ts +28 -0
- package/dist/components/ActivitiesPanel.d.ts.map +1 -0
- package/dist/components/ActivitiesPanel.js +75 -0
- package/dist/components/ActivitiesPanel.js.map +1 -0
- package/dist/components/AgentTasks.d.ts +16 -0
- package/dist/components/AgentTasks.d.ts.map +1 -0
- package/dist/components/AgentTasks.js +166 -0
- package/dist/components/AgentTasks.js.map +1 -0
- package/dist/components/Chip.d.ts +10 -0
- package/dist/components/Chip.d.ts.map +1 -0
- package/dist/components/Chip.js +21 -0
- package/dist/components/Chip.js.map +1 -0
- package/dist/components/CopyButton.d.ts +7 -0
- package/dist/components/CopyButton.d.ts.map +1 -0
- package/dist/components/CopyButton.js +30 -0
- package/dist/components/CopyButton.js.map +1 -0
- package/dist/components/DataTable.d.ts +36 -0
- package/dist/components/DataTable.d.ts.map +1 -0
- package/dist/components/DataTable.js +43 -0
- package/dist/components/DataTable.js.map +1 -0
- package/dist/components/DecisionsPanel.d.ts +14 -0
- package/dist/components/DecisionsPanel.d.ts.map +1 -0
- package/dist/components/DecisionsPanel.js +73 -0
- package/dist/components/DecisionsPanel.js.map +1 -0
- package/dist/components/DeleteRecord.d.ts +19 -0
- package/dist/components/DeleteRecord.d.ts.map +1 -0
- package/dist/components/DeleteRecord.js +22 -0
- package/dist/components/DeleteRecord.js.map +1 -0
- package/dist/components/EntitySearch.d.ts +33 -0
- package/dist/components/EntitySearch.d.ts.map +1 -0
- package/dist/components/EntitySearch.js +111 -0
- package/dist/components/EntitySearch.js.map +1 -0
- package/dist/components/ErrorBoundary.d.ts +21 -0
- package/dist/components/ErrorBoundary.d.ts.map +1 -0
- package/dist/components/ErrorBoundary.js +26 -0
- package/dist/components/ErrorBoundary.js.map +1 -0
- package/dist/components/InlineEdit.d.ts +37 -0
- package/dist/components/InlineEdit.d.ts.map +1 -0
- package/dist/components/InlineEdit.js +77 -0
- package/dist/components/InlineEdit.js.map +1 -0
- package/dist/components/KanbanBoard.d.ts +24 -0
- package/dist/components/KanbanBoard.d.ts.map +1 -0
- package/dist/components/KanbanBoard.js +92 -0
- package/dist/components/KanbanBoard.js.map +1 -0
- package/dist/components/MarkdownView.d.ts +4 -0
- package/dist/components/MarkdownView.d.ts.map +1 -0
- package/dist/components/MarkdownView.js +45 -0
- package/dist/components/MarkdownView.js.map +1 -0
- package/dist/components/NotesPanel.d.ts +17 -0
- package/dist/components/NotesPanel.d.ts.map +1 -0
- package/dist/components/NotesPanel.js +53 -0
- package/dist/components/NotesPanel.js.map +1 -0
- package/dist/components/PageHeader.d.ts +20 -0
- package/dist/components/PageHeader.d.ts.map +1 -0
- package/dist/components/PageHeader.js +15 -0
- package/dist/components/PageHeader.js.map +1 -0
- package/dist/components/PhonesField.d.ts +7 -0
- package/dist/components/PhonesField.d.ts.map +1 -0
- package/dist/components/PhonesField.js +92 -0
- package/dist/components/PhonesField.js.map +1 -0
- package/dist/components/PlanAttention.d.ts +40 -0
- package/dist/components/PlanAttention.d.ts.map +1 -0
- package/dist/components/PlanAttention.js +86 -0
- package/dist/components/PlanAttention.js.map +1 -0
- package/dist/components/PlanPanel.d.ts +18 -0
- package/dist/components/PlanPanel.d.ts.map +1 -0
- package/dist/components/PlanPanel.js +102 -0
- package/dist/components/PlanPanel.js.map +1 -0
- package/dist/components/QueryState.d.ts +24 -0
- package/dist/components/QueryState.d.ts.map +1 -0
- package/dist/components/QueryState.js +34 -0
- package/dist/components/QueryState.js.map +1 -0
- package/dist/components/RecordTabs.d.ts +16 -0
- package/dist/components/RecordTabs.d.ts.map +1 -0
- package/dist/components/RecordTabs.js +15 -0
- package/dist/components/RecordTabs.js.map +1 -0
- package/dist/components/SectionHeader.d.ts +15 -0
- package/dist/components/SectionHeader.d.ts.map +1 -0
- package/dist/components/SectionHeader.js +14 -0
- package/dist/components/SectionHeader.js.map +1 -0
- package/dist/components/SegmentedControl.d.ts +13 -0
- package/dist/components/SegmentedControl.d.ts.map +1 -0
- package/dist/components/SegmentedControl.js +14 -0
- package/dist/components/SegmentedControl.js.map +1 -0
- package/dist/components/Shell.d.ts +2 -0
- package/dist/components/Shell.d.ts.map +1 -0
- package/dist/components/Shell.js +143 -0
- package/dist/components/Shell.js.map +1 -0
- package/dist/components/SidebarField.d.ts +8 -0
- package/dist/components/SidebarField.d.ts.map +1 -0
- package/dist/components/SidebarField.js +6 -0
- package/dist/components/SidebarField.js.map +1 -0
- package/dist/components/SocialProfilesField.d.ts +8 -0
- package/dist/components/SocialProfilesField.d.ts.map +1 -0
- package/dist/components/SocialProfilesField.js +176 -0
- package/dist/components/SocialProfilesField.js.map +1 -0
- package/dist/components/StageSettings.d.ts +16 -0
- package/dist/components/StageSettings.d.ts.map +1 -0
- package/dist/components/StageSettings.js +107 -0
- package/dist/components/StageSettings.js.map +1 -0
- package/dist/components/SummaryBlock.d.ts +12 -0
- package/dist/components/SummaryBlock.d.ts.map +1 -0
- package/dist/components/SummaryBlock.js +12 -0
- package/dist/components/SummaryBlock.js.map +1 -0
- package/dist/index.d.ts +90 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +55 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/dates.d.ts +26 -0
- package/dist/lib/dates.d.ts.map +1 -0
- package/dist/lib/dates.js +71 -0
- package/dist/lib/dates.js.map +1 -0
- package/dist/lib/money.d.ts +7 -0
- package/dist/lib/money.d.ts.map +1 -0
- package/dist/lib/money.js +13 -0
- package/dist/lib/money.js.map +1 -0
- package/dist/lib/names.d.ts +9 -0
- package/dist/lib/names.d.ts.map +1 -0
- package/dist/lib/names.js +13 -0
- package/dist/lib/names.js.map +1 -0
- package/dist/lib/plan.d.ts +67 -0
- package/dist/lib/plan.d.ts.map +1 -0
- package/dist/lib/plan.js +96 -0
- package/dist/lib/plan.js.map +1 -0
- package/dist/lib/theme.d.ts +19 -0
- package/dist/lib/theme.d.ts.map +1 -0
- package/dist/lib/theme.js +30 -0
- package/dist/lib/theme.js.map +1 -0
- package/dist/pages/CompaniesPage.d.ts +2 -0
- package/dist/pages/CompaniesPage.d.ts.map +1 -0
- package/dist/pages/CompaniesPage.js +77 -0
- package/dist/pages/CompaniesPage.js.map +1 -0
- package/dist/pages/CompanyDetail.d.ts +2 -0
- package/dist/pages/CompanyDetail.d.ts.map +1 -0
- package/dist/pages/CompanyDetail.js +177 -0
- package/dist/pages/CompanyDetail.js.map +1 -0
- package/dist/pages/DealDetail.d.ts +2 -0
- package/dist/pages/DealDetail.d.ts.map +1 -0
- package/dist/pages/DealDetail.js +192 -0
- package/dist/pages/DealDetail.js.map +1 -0
- package/dist/pages/DealStageSettingsPage.d.ts +7 -0
- package/dist/pages/DealStageSettingsPage.d.ts.map +1 -0
- package/dist/pages/DealStageSettingsPage.js +38 -0
- package/dist/pages/DealStageSettingsPage.js.map +1 -0
- package/dist/pages/DealsPage.d.ts +2 -0
- package/dist/pages/DealsPage.d.ts.map +1 -0
- package/dist/pages/DealsPage.js +177 -0
- package/dist/pages/DealsPage.js.map +1 -0
- package/dist/pages/DecisionsPage.d.ts +2 -0
- package/dist/pages/DecisionsPage.d.ts.map +1 -0
- package/dist/pages/DecisionsPage.js +121 -0
- package/dist/pages/DecisionsPage.js.map +1 -0
- package/dist/pages/FormDetail.d.ts +2 -0
- package/dist/pages/FormDetail.d.ts.map +1 -0
- package/dist/pages/FormDetail.js +56 -0
- package/dist/pages/FormDetail.js.map +1 -0
- package/dist/pages/FormsPage.d.ts +2 -0
- package/dist/pages/FormsPage.d.ts.map +1 -0
- package/dist/pages/FormsPage.js +67 -0
- package/dist/pages/FormsPage.js.map +1 -0
- package/dist/pages/FundraisingPage.d.ts +2 -0
- package/dist/pages/FundraisingPage.d.ts.map +1 -0
- package/dist/pages/FundraisingPage.js +187 -0
- package/dist/pages/FundraisingPage.js.map +1 -0
- package/dist/pages/HiringPage.d.ts +9 -0
- package/dist/pages/HiringPage.d.ts.map +1 -0
- package/dist/pages/HiringPage.js +73 -0
- package/dist/pages/HiringPage.js.map +1 -0
- package/dist/pages/NotFoundPage.d.ts +10 -0
- package/dist/pages/NotFoundPage.d.ts.map +1 -0
- package/dist/pages/NotFoundPage.js +14 -0
- package/dist/pages/NotFoundPage.js.map +1 -0
- package/dist/pages/OpportunitiesPage.d.ts +2 -0
- package/dist/pages/OpportunitiesPage.d.ts.map +1 -0
- package/dist/pages/OpportunitiesPage.js +184 -0
- package/dist/pages/OpportunitiesPage.js.map +1 -0
- package/dist/pages/OpportunityDetail.d.ts +2 -0
- package/dist/pages/OpportunityDetail.d.ts.map +1 -0
- package/dist/pages/OpportunityDetail.js +132 -0
- package/dist/pages/OpportunityDetail.js.map +1 -0
- package/dist/pages/OpportunityStageSettingsPage.d.ts +3 -0
- package/dist/pages/OpportunityStageSettingsPage.d.ts.map +1 -0
- package/dist/pages/OpportunityStageSettingsPage.js +34 -0
- package/dist/pages/OpportunityStageSettingsPage.js.map +1 -0
- package/dist/pages/PartnershipDetail.d.ts +2 -0
- package/dist/pages/PartnershipDetail.d.ts.map +1 -0
- package/dist/pages/PartnershipDetail.js +179 -0
- package/dist/pages/PartnershipDetail.js.map +1 -0
- package/dist/pages/PartnershipStageSettingsPage.d.ts +3 -0
- package/dist/pages/PartnershipStageSettingsPage.d.ts.map +1 -0
- package/dist/pages/PartnershipStageSettingsPage.js +34 -0
- package/dist/pages/PartnershipStageSettingsPage.js.map +1 -0
- package/dist/pages/PartnershipsPage.d.ts +2 -0
- package/dist/pages/PartnershipsPage.d.ts.map +1 -0
- package/dist/pages/PartnershipsPage.js +182 -0
- package/dist/pages/PartnershipsPage.js.map +1 -0
- package/dist/pages/PeoplePage.d.ts +10 -0
- package/dist/pages/PeoplePage.d.ts.map +1 -0
- package/dist/pages/PeoplePage.js +71 -0
- package/dist/pages/PeoplePage.js.map +1 -0
- package/dist/pages/PersonDetail.d.ts +2 -0
- package/dist/pages/PersonDetail.d.ts.map +1 -0
- package/dist/pages/PersonDetail.js +193 -0
- package/dist/pages/PersonDetail.js.map +1 -0
- package/dist/pages/PlanningPage.d.ts +2 -0
- package/dist/pages/PlanningPage.d.ts.map +1 -0
- package/dist/pages/PlanningPage.js +112 -0
- package/dist/pages/PlanningPage.js.map +1 -0
- package/dist/pages/RaiseDetail.d.ts +2 -0
- package/dist/pages/RaiseDetail.d.ts.map +1 -0
- package/dist/pages/RaiseDetail.js +198 -0
- package/dist/pages/RaiseDetail.js.map +1 -0
- package/dist/pages/RaiseStageSettingsPage.d.ts +3 -0
- package/dist/pages/RaiseStageSettingsPage.d.ts.map +1 -0
- package/dist/pages/RaiseStageSettingsPage.js +34 -0
- package/dist/pages/RaiseStageSettingsPage.js.map +1 -0
- package/dist/pages/RoleDetail.d.ts +2 -0
- package/dist/pages/RoleDetail.d.ts.map +1 -0
- package/dist/pages/RoleDetail.js +177 -0
- package/dist/pages/RoleDetail.js.map +1 -0
- package/dist/pages/SearchPage.d.ts +2 -0
- package/dist/pages/SearchPage.d.ts.map +1 -0
- package/dist/pages/SearchPage.js +51 -0
- package/dist/pages/SearchPage.js.map +1 -0
- package/dist/pages/account/AccountLayout.d.ts +2 -0
- package/dist/pages/account/AccountLayout.d.ts.map +1 -0
- package/dist/pages/account/AccountLayout.js +25 -0
- package/dist/pages/account/AccountLayout.js.map +1 -0
- package/dist/pages/account/Field.d.ts +8 -0
- package/dist/pages/account/Field.d.ts.map +1 -0
- package/dist/pages/account/Field.js +6 -0
- package/dist/pages/account/Field.js.map +1 -0
- package/dist/pages/account/PreferencesPage.d.ts +2 -0
- package/dist/pages/account/PreferencesPage.d.ts.map +1 -0
- package/dist/pages/account/PreferencesPage.js +92 -0
- package/dist/pages/account/PreferencesPage.js.map +1 -0
- package/dist/pages/account/ProfilePage.d.ts +14 -0
- package/dist/pages/account/ProfilePage.d.ts.map +1 -0
- package/dist/pages/account/ProfilePage.js +71 -0
- package/dist/pages/account/ProfilePage.js.map +1 -0
- package/dist/pages/account/SecurityPage.d.ts +11 -0
- package/dist/pages/account/SecurityPage.d.ts.map +1 -0
- package/dist/pages/account/SecurityPage.js +78 -0
- package/dist/pages/account/SecurityPage.js.map +1 -0
- package/dist/pages/admin/DataPage.d.ts +3 -0
- package/dist/pages/admin/DataPage.d.ts.map +1 -0
- package/dist/pages/admin/DataPage.js +210 -0
- package/dist/pages/admin/DataPage.js.map +1 -0
- package/dist/pages/admin/McpPage.d.ts +2 -0
- package/dist/pages/admin/McpPage.d.ts.map +1 -0
- package/dist/pages/admin/McpPage.js +128 -0
- package/dist/pages/admin/McpPage.js.map +1 -0
- package/dist/pages/admin/ModulesPage.d.ts +2 -0
- package/dist/pages/admin/ModulesPage.d.ts.map +1 -0
- package/dist/pages/admin/ModulesPage.js +53 -0
- package/dist/pages/admin/ModulesPage.js.map +1 -0
- package/dist/pages/admin/TeamPage.d.ts +2 -0
- package/dist/pages/admin/TeamPage.d.ts.map +1 -0
- package/dist/pages/admin/TeamPage.js +99 -0
- package/dist/pages/admin/TeamPage.js.map +1 -0
- package/dist/pages/admin/WebhookDeliveries.d.ts +4 -0
- package/dist/pages/admin/WebhookDeliveries.d.ts.map +1 -0
- package/dist/pages/admin/WebhookDeliveries.js +88 -0
- package/dist/pages/admin/WebhookDeliveries.js.map +1 -0
- package/dist/pages/admin/WebhooksPage.d.ts +2 -0
- package/dist/pages/admin/WebhooksPage.d.ts.map +1 -0
- package/dist/pages/admin/WebhooksPage.js +152 -0
- package/dist/pages/admin/WebhooksPage.js.map +1 -0
- package/dist/pages/admin/WorkspaceSettingsPage.d.ts +2 -0
- package/dist/pages/admin/WorkspaceSettingsPage.d.ts.map +1 -0
- package/dist/pages/admin/WorkspaceSettingsPage.js +117 -0
- package/dist/pages/admin/WorkspaceSettingsPage.js.map +1 -0
- package/dist/pages/auth/AuthForm.d.ts +46 -0
- package/dist/pages/auth/AuthForm.d.ts.map +1 -0
- package/dist/pages/auth/AuthForm.js +32 -0
- package/dist/pages/auth/AuthForm.js.map +1 -0
- package/dist/pages/auth/AuthLayout.d.ts +24 -0
- package/dist/pages/auth/AuthLayout.d.ts.map +1 -0
- package/dist/pages/auth/AuthLayout.js +19 -0
- package/dist/pages/auth/AuthLayout.js.map +1 -0
- package/dist/pages/auth/ForgotPasswordPage.d.ts +13 -0
- package/dist/pages/auth/ForgotPasswordPage.d.ts.map +1 -0
- package/dist/pages/auth/ForgotPasswordPage.js +39 -0
- package/dist/pages/auth/ForgotPasswordPage.js.map +1 -0
- package/dist/pages/auth/JoinPage.d.ts +12 -0
- package/dist/pages/auth/JoinPage.d.ts.map +1 -0
- package/dist/pages/auth/JoinPage.js +43 -0
- package/dist/pages/auth/JoinPage.js.map +1 -0
- package/dist/pages/auth/ResetPasswordPage.d.ts +13 -0
- package/dist/pages/auth/ResetPasswordPage.d.ts.map +1 -0
- package/dist/pages/auth/ResetPasswordPage.js +58 -0
- package/dist/pages/auth/ResetPasswordPage.js.map +1 -0
- package/dist/pages/auth/SignInPage.d.ts +2 -0
- package/dist/pages/auth/SignInPage.d.ts.map +1 -0
- package/dist/pages/auth/SignInPage.js +38 -0
- package/dist/pages/auth/SignInPage.js.map +1 -0
- package/dist/pages/auth/SignUpPage.d.ts +13 -0
- package/dist/pages/auth/SignUpPage.d.ts.map +1 -0
- package/dist/pages/auth/SignUpPage.js +43 -0
- package/dist/pages/auth/SignUpPage.js.map +1 -0
- package/dist/pages/candidateFields.d.ts +22 -0
- package/dist/pages/candidateFields.d.ts.map +1 -0
- package/dist/pages/candidateFields.js +82 -0
- package/dist/pages/candidateFields.js.map +1 -0
- package/dist/pages/dashboard/DashboardPage.d.ts +2 -0
- package/dist/pages/dashboard/DashboardPage.d.ts.map +1 -0
- package/dist/pages/dashboard/DashboardPage.js +40 -0
- package/dist/pages/dashboard/DashboardPage.js.map +1 -0
- package/dist/pages/dashboard/attention.d.ts +41 -0
- package/dist/pages/dashboard/attention.d.ts.map +1 -0
- package/dist/pages/dashboard/attention.js +146 -0
- package/dist/pages/dashboard/attention.js.map +1 -0
- package/dist/pages/dashboard/sections.d.ts +20 -0
- package/dist/pages/dashboard/sections.d.ts.map +1 -0
- package/dist/pages/dashboard/sections.js +60 -0
- package/dist/pages/dashboard/sections.js.map +1 -0
- package/dist/pages/fields.d.ts +11 -0
- package/dist/pages/fields.d.ts.map +1 -0
- package/dist/pages/fields.js +17 -0
- package/dist/pages/fields.js.map +1 -0
- package/dist/pages/forms/EmbedPanel.d.ts +14 -0
- package/dist/pages/forms/EmbedPanel.d.ts.map +1 -0
- package/dist/pages/forms/EmbedPanel.js +19 -0
- package/dist/pages/forms/EmbedPanel.js.map +1 -0
- package/dist/pages/forms/FieldsEditor.d.ts +6 -0
- package/dist/pages/forms/FieldsEditor.d.ts.map +1 -0
- package/dist/pages/forms/FieldsEditor.js +115 -0
- package/dist/pages/forms/FieldsEditor.js.map +1 -0
- package/dist/pages/forms/FormSettings.d.ts +6 -0
- package/dist/pages/forms/FormSettings.d.ts.map +1 -0
- package/dist/pages/forms/FormSettings.js +47 -0
- package/dist/pages/forms/FormSettings.js.map +1 -0
- package/dist/pages/forms/SubmissionsTable.d.ts +8 -0
- package/dist/pages/forms/SubmissionsTable.d.ts.map +1 -0
- package/dist/pages/forms/SubmissionsTable.js +91 -0
- package/dist/pages/forms/SubmissionsTable.js.map +1 -0
- package/dist/pages/forms/fieldList.d.ts +70 -0
- package/dist/pages/forms/fieldList.d.ts.map +1 -0
- package/dist/pages/forms/fieldList.js +126 -0
- package/dist/pages/forms/fieldList.js.map +1 -0
- package/dist/pages/forms/template.d.ts +18 -0
- package/dist/pages/forms/template.d.ts.map +1 -0
- package/dist/pages/forms/template.js +34 -0
- package/dist/pages/forms/template.js.map +1 -0
- package/dist/pages/handbook/HandbookPage.d.ts +2 -0
- package/dist/pages/handbook/HandbookPage.d.ts.map +1 -0
- package/dist/pages/handbook/HandbookPage.js +197 -0
- package/dist/pages/handbook/HandbookPage.js.map +1 -0
- package/dist/pages/handbook/tree.d.ts +62 -0
- package/dist/pages/handbook/tree.d.ts.map +1 -0
- package/dist/pages/handbook/tree.js +222 -0
- package/dist/pages/handbook/tree.js.map +1 -0
- package/dist/pages/hiringDirectory.d.ts +60 -0
- package/dist/pages/hiringDirectory.d.ts.map +1 -0
- package/dist/pages/hiringDirectory.js +81 -0
- package/dist/pages/hiringDirectory.js.map +1 -0
- package/dist/pages/onboarding/HandbookStepPage.d.ts +14 -0
- package/dist/pages/onboarding/HandbookStepPage.d.ts.map +1 -0
- package/dist/pages/onboarding/HandbookStepPage.js +29 -0
- package/dist/pages/onboarding/HandbookStepPage.js.map +1 -0
- package/dist/pages/onboarding/InvitesStepPage.d.ts +2 -0
- package/dist/pages/onboarding/InvitesStepPage.d.ts.map +1 -0
- package/dist/pages/onboarding/InvitesStepPage.js +77 -0
- package/dist/pages/onboarding/InvitesStepPage.js.map +1 -0
- package/dist/pages/onboarding/WorkspaceStepPage.d.ts +2 -0
- package/dist/pages/onboarding/WorkspaceStepPage.d.ts.map +1 -0
- package/dist/pages/onboarding/WorkspaceStepPage.js +72 -0
- package/dist/pages/onboarding/WorkspaceStepPage.js.map +1 -0
- package/dist/pages/positionDirectory.d.ts +20 -0
- package/dist/pages/positionDirectory.d.ts.map +1 -0
- package/dist/pages/positionDirectory.js +58 -0
- package/dist/pages/positionDirectory.js.map +1 -0
- package/dist/registry/UiExtensionProvider.d.ts +12 -0
- package/dist/registry/UiExtensionProvider.d.ts.map +1 -0
- package/dist/registry/UiExtensionProvider.js +10 -0
- package/dist/registry/UiExtensionProvider.js.map +1 -0
- package/dist/registry/context.d.ts +31 -0
- package/dist/registry/context.d.ts.map +1 -0
- package/dist/registry/context.js +45 -0
- package/dist/registry/context.js.map +1 -0
- package/dist/registry/contributions.d.ts +71 -0
- package/dist/registry/contributions.d.ts.map +1 -0
- package/dist/registry/contributions.js +25 -0
- package/dist/registry/contributions.js.map +1 -0
- package/dist/registry/overridable.d.ts +27 -0
- package/dist/registry/overridable.d.ts.map +1 -0
- package/dist/registry/overridable.js +29 -0
- package/dist/registry/overridable.js.map +1 -0
- package/dist/registry/registry.d.ts +68 -0
- package/dist/registry/registry.d.ts.map +1 -0
- package/dist/registry/registry.js +112 -0
- package/dist/registry/registry.js.map +1 -0
- package/dist/testing/inputs.d.ts +13 -0
- package/dist/testing/inputs.d.ts.map +1 -0
- package/dist/testing/inputs.js +16 -0
- package/dist/testing/inputs.js.map +1 -0
- package/dist/testing/stubClient.d.ts +42 -0
- package/dist/testing/stubClient.d.ts.map +1 -0
- package/dist/testing/stubClient.js +29 -0
- package/dist/testing/stubClient.js.map +1 -0
- package/package.json +73 -0
- package/src/ServiceStatus.tsx +61 -0
- package/src/api/ApiProvider.tsx +40 -0
- package/src/api/client.ts +267 -0
- package/src/api/context.ts +25 -0
- package/src/api/errors.ts +14 -0
- package/src/api/health.ts +38 -0
- package/src/api/json.ts +4 -0
- package/src/api/queryClient.ts +35 -0
- package/src/api/resource.ts +412 -0
- package/src/api/resources/account.ts +220 -0
- package/src/api/resources/activities.ts +31 -0
- package/src/api/resources/agentTasks.ts +172 -0
- package/src/api/resources/candidates.ts +69 -0
- package/src/api/resources/companies.ts +72 -0
- package/src/api/resources/dashboard.ts +39 -0
- package/src/api/resources/deals.ts +82 -0
- package/src/api/resources/decisions.ts +60 -0
- package/src/api/resources/forms.ts +218 -0
- package/src/api/resources/handbookPages.ts +77 -0
- package/src/api/resources/importJobs.ts +229 -0
- package/src/api/resources/invites.ts +112 -0
- package/src/api/resources/mcpTools.ts +28 -0
- package/src/api/resources/members.ts +105 -0
- package/src/api/resources/moduleSettings.ts +67 -0
- package/src/api/resources/mutation.ts +31 -0
- package/src/api/resources/notes.ts +62 -0
- package/src/api/resources/opportunities.ts +84 -0
- package/src/api/resources/partnerships.ts +89 -0
- package/src/api/resources/people.ts +72 -0
- package/src/api/resources/pipelineStages.ts +93 -0
- package/src/api/resources/planItems.ts +103 -0
- package/src/api/resources/positions.ts +70 -0
- package/src/api/resources/raises.ts +82 -0
- package/src/api/resources/roles.ts +65 -0
- package/src/api/resources/search.ts +49 -0
- package/src/api/resources/session.ts +220 -0
- package/src/api/resources/webhooks.ts +157 -0
- package/src/api/resources/workspace.ts +81 -0
- package/src/app/KelpieApp.tsx +162 -0
- package/src/app/SessionGate.tsx +42 -0
- package/src/components/ActivitiesPanel.tsx +235 -0
- package/src/components/AgentTasks.tsx +473 -0
- package/src/components/Chip.tsx +36 -0
- package/src/components/CopyButton.tsx +48 -0
- package/src/components/DataTable.tsx +209 -0
- package/src/components/DecisionsPanel.tsx +233 -0
- package/src/components/DeleteRecord.tsx +73 -0
- package/src/components/EntitySearch.tsx +268 -0
- package/src/components/ErrorBoundary.tsx +58 -0
- package/src/components/InlineEdit.tsx +179 -0
- package/src/components/KanbanBoard.tsx +234 -0
- package/src/components/MarkdownView.tsx +73 -0
- package/src/components/NotesPanel.tsx +169 -0
- package/src/components/PageHeader.tsx +61 -0
- package/src/components/PhonesField.tsx +204 -0
- package/src/components/PlanAttention.tsx +249 -0
- package/src/components/PlanPanel.tsx +317 -0
- package/src/components/QueryState.tsx +83 -0
- package/src/components/RecordTabs.tsx +69 -0
- package/src/components/SectionHeader.tsx +63 -0
- package/src/components/SegmentedControl.tsx +48 -0
- package/src/components/Shell.tsx +300 -0
- package/src/components/SidebarField.tsx +18 -0
- package/src/components/SocialProfilesField.tsx +356 -0
- package/src/components/StageSettings.tsx +319 -0
- package/src/components/SummaryBlock.tsx +27 -0
- package/src/index.ts +190 -0
- package/src/lib/dates.ts +90 -0
- package/src/lib/money.ts +12 -0
- package/src/lib/names.ts +13 -0
- package/src/lib/plan.ts +147 -0
- package/src/lib/theme.ts +53 -0
- package/src/pages/CompaniesPage.tsx +143 -0
- package/src/pages/CompanyDetail.tsx +502 -0
- package/src/pages/DealDetail.tsx +512 -0
- package/src/pages/DealStageSettingsPage.tsx +67 -0
- package/src/pages/DealsPage.tsx +342 -0
- package/src/pages/DecisionsPage.tsx +211 -0
- package/src/pages/FormDetail.tsx +130 -0
- package/src/pages/FormsPage.tsx +151 -0
- package/src/pages/FundraisingPage.tsx +354 -0
- package/src/pages/HiringPage.tsx +169 -0
- package/src/pages/NotFoundPage.tsx +27 -0
- package/src/pages/OpportunitiesPage.tsx +349 -0
- package/src/pages/OpportunityDetail.tsx +337 -0
- package/src/pages/OpportunityStageSettingsPage.tsx +63 -0
- package/src/pages/PartnershipDetail.tsx +490 -0
- package/src/pages/PartnershipStageSettingsPage.tsx +63 -0
- package/src/pages/PartnershipsPage.tsx +353 -0
- package/src/pages/PeoplePage.tsx +145 -0
- package/src/pages/PersonDetail.tsx +526 -0
- package/src/pages/PlanningPage.tsx +318 -0
- package/src/pages/RaiseDetail.tsx +498 -0
- package/src/pages/RaiseStageSettingsPage.tsx +63 -0
- package/src/pages/RoleDetail.tsx +455 -0
- package/src/pages/SearchPage.tsx +135 -0
- package/src/pages/account/AccountLayout.tsx +38 -0
- package/src/pages/account/Field.tsx +20 -0
- package/src/pages/account/PreferencesPage.tsx +224 -0
- package/src/pages/account/ProfilePage.tsx +147 -0
- package/src/pages/account/SecurityPage.tsx +237 -0
- package/src/pages/admin/DataPage.tsx +772 -0
- package/src/pages/admin/McpPage.tsx +404 -0
- package/src/pages/admin/ModulesPage.tsx +113 -0
- package/src/pages/admin/TeamPage.tsx +386 -0
- package/src/pages/admin/WebhookDeliveries.tsx +184 -0
- package/src/pages/admin/WebhooksPage.tsx +443 -0
- package/src/pages/admin/WorkspaceSettingsPage.tsx +274 -0
- package/src/pages/auth/AuthForm.tsx +118 -0
- package/src/pages/auth/AuthLayout.tsx +74 -0
- package/src/pages/auth/ForgotPasswordPage.tsx +80 -0
- package/src/pages/auth/JoinPage.tsx +85 -0
- package/src/pages/auth/ResetPasswordPage.tsx +124 -0
- package/src/pages/auth/SignInPage.tsx +83 -0
- package/src/pages/auth/SignUpPage.tsx +93 -0
- package/src/pages/candidateFields.tsx +175 -0
- package/src/pages/dashboard/DashboardPage.tsx +108 -0
- package/src/pages/dashboard/attention.ts +206 -0
- package/src/pages/dashboard/sections.tsx +269 -0
- package/src/pages/fields.ts +21 -0
- package/src/pages/forms/EmbedPanel.tsx +95 -0
- package/src/pages/forms/FieldsEditor.tsx +412 -0
- package/src/pages/forms/FormSettings.tsx +159 -0
- package/src/pages/forms/SubmissionsTable.tsx +171 -0
- package/src/pages/forms/fieldList.ts +209 -0
- package/src/pages/forms/template.ts +37 -0
- package/src/pages/handbook/HandbookPage.tsx +500 -0
- package/src/pages/handbook/tree.ts +327 -0
- package/src/pages/hiringDirectory.ts +146 -0
- package/src/pages/onboarding/HandbookStepPage.tsx +75 -0
- package/src/pages/onboarding/InvitesStepPage.tsx +180 -0
- package/src/pages/onboarding/WorkspaceStepPage.tsx +122 -0
- package/src/pages/positionDirectory.ts +98 -0
- package/src/registry/UiExtensionProvider.tsx +20 -0
- package/src/registry/context.ts +67 -0
- package/src/registry/contributions.ts +89 -0
- package/src/registry/overridable.ts +62 -0
- package/src/registry/registry.ts +204 -0
- package/src/styles.css +175 -0
- package/src/testing/inputs.ts +18 -0
- package/src/testing/stubClient.ts +78 -0
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
import type { Workspace } from '@kelpie/schemas'
|
|
2
|
+
import { useState } from 'react'
|
|
3
|
+
import type { FormEvent, ReactNode } from 'react'
|
|
4
|
+
import { useNavigate } from 'react-router'
|
|
5
|
+
|
|
6
|
+
import { useSession } from '../../api/resources/session.ts'
|
|
7
|
+
import {
|
|
8
|
+
useDeleteWorkspace,
|
|
9
|
+
useUpdateWorkspace,
|
|
10
|
+
useWorkspace,
|
|
11
|
+
} from '../../api/resources/workspace.ts'
|
|
12
|
+
import { PageHeader } from '../../components/PageHeader.tsx'
|
|
13
|
+
import { ErrorPanel, LoadingPanel } from '../../components/QueryState.tsx'
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Workspace settings, and the one screen that can end a workspace.
|
|
17
|
+
*
|
|
18
|
+
* Ported from the mockup's Workspace page. Two differences, both because there
|
|
19
|
+
* is an API behind it now: the slug is editable and can collide, and the danger
|
|
20
|
+
* zone deletes for real, so it asks the reader to type the slug rather than
|
|
21
|
+
* clicking one button.
|
|
22
|
+
*
|
|
23
|
+
* The form saves explicitly instead of per keystroke. Every field here is
|
|
24
|
+
* workspace-wide, and the slug appears in URLs, so committing on each character
|
|
25
|
+
* would be a stream of half-typed addresses.
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* The timezones the mockup offered, plus whatever this workspace already holds.
|
|
30
|
+
*
|
|
31
|
+
* A full IANA list belongs in a combo box, which is its own piece of work. An
|
|
32
|
+
* unlisted value must still survive a save, so it joins the list rather than
|
|
33
|
+
* being silently rewritten to the first option.
|
|
34
|
+
*/
|
|
35
|
+
const COMMON_TIMEZONES = [
|
|
36
|
+
'Australia/Sydney',
|
|
37
|
+
'Australia/Melbourne',
|
|
38
|
+
'America/Los_Angeles',
|
|
39
|
+
'America/New_York',
|
|
40
|
+
'Europe/London',
|
|
41
|
+
'UTC',
|
|
42
|
+
] as const
|
|
43
|
+
|
|
44
|
+
export function WorkspaceSettingsPage(): React.JSX.Element {
|
|
45
|
+
const { workspace, isLoading, error } = useWorkspace()
|
|
46
|
+
|
|
47
|
+
if (error !== null) {
|
|
48
|
+
return <ErrorPanel error={error} />
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (isLoading || workspace === undefined) {
|
|
52
|
+
return <LoadingPanel />
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Keyed on the id so the form state is rebuilt if the session moves to another
|
|
56
|
+
// workspace while this page is mounted.
|
|
57
|
+
return <WorkspaceSettingsForm key={workspace.id} workspace={workspace} />
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function WorkspaceSettingsForm({
|
|
61
|
+
workspace,
|
|
62
|
+
}: {
|
|
63
|
+
readonly workspace: Workspace
|
|
64
|
+
}): React.JSX.Element {
|
|
65
|
+
const { session } = useSession()
|
|
66
|
+
const update = useUpdateWorkspace()
|
|
67
|
+
const [name, setName] = useState(workspace.name)
|
|
68
|
+
const [slug, setSlug] = useState(workspace.slug)
|
|
69
|
+
const [timezone, setTimezone] = useState(workspace.timezone)
|
|
70
|
+
const [tagline, setTagline] = useState(workspace.tagline ?? '')
|
|
71
|
+
const [oneLiner, setOneLiner] = useState(workspace.oneLiner ?? '')
|
|
72
|
+
const [saved, setSaved] = useState(false)
|
|
73
|
+
|
|
74
|
+
const canEdit = session?.role === 'owner' || session?.role === 'admin'
|
|
75
|
+
const timezones = COMMON_TIMEZONES.includes(timezone as (typeof COMMON_TIMEZONES)[number])
|
|
76
|
+
? [...COMMON_TIMEZONES]
|
|
77
|
+
: [timezone, ...COMMON_TIMEZONES]
|
|
78
|
+
|
|
79
|
+
function save(event: FormEvent): void {
|
|
80
|
+
event.preventDefault()
|
|
81
|
+
setSaved(false)
|
|
82
|
+
|
|
83
|
+
update
|
|
84
|
+
.runAsync({
|
|
85
|
+
name: name.trim(),
|
|
86
|
+
slug: slug.trim(),
|
|
87
|
+
timezone,
|
|
88
|
+
// Empty is not blank text, it is no tagline. `null` clears the column;
|
|
89
|
+
// an empty string would store one and hand agents an empty identity.
|
|
90
|
+
tagline: tagline.trim().length === 0 ? null : tagline.trim(),
|
|
91
|
+
oneLiner: oneLiner.trim().length === 0 ? null : oneLiner.trim(),
|
|
92
|
+
})
|
|
93
|
+
.then(() => {
|
|
94
|
+
setSaved(true)
|
|
95
|
+
})
|
|
96
|
+
.catch(() => undefined)
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return (
|
|
100
|
+
<div className="animate-slide-in mx-auto max-w-4xl space-y-8">
|
|
101
|
+
<PageHeader
|
|
102
|
+
title="Workspace"
|
|
103
|
+
description="Name, address, timezone, and how the company introduces itself to an agent."
|
|
104
|
+
/>
|
|
105
|
+
|
|
106
|
+
<form onSubmit={save} className="space-y-4">
|
|
107
|
+
<Field label="Workspace name">
|
|
108
|
+
<input
|
|
109
|
+
value={name}
|
|
110
|
+
onChange={(event) => {
|
|
111
|
+
setName(event.target.value)
|
|
112
|
+
}}
|
|
113
|
+
required
|
|
114
|
+
disabled={!canEdit}
|
|
115
|
+
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 disabled:opacity-60"
|
|
116
|
+
/>
|
|
117
|
+
</Field>
|
|
118
|
+
|
|
119
|
+
<Field label="Slug" hint="Lowercase letters, digits, and hyphens. It appears in URLs.">
|
|
120
|
+
<input
|
|
121
|
+
value={slug}
|
|
122
|
+
onChange={(event) => {
|
|
123
|
+
setSlug(event.target.value)
|
|
124
|
+
}}
|
|
125
|
+
required
|
|
126
|
+
disabled={!canEdit}
|
|
127
|
+
className="w-full max-w-md rounded-md border border-border bg-surface-raised px-3 py-2 font-mono text-[13px] outline-none focus:border-accent focus:ring-2 focus:ring-accent/20 disabled:opacity-60"
|
|
128
|
+
/>
|
|
129
|
+
</Field>
|
|
130
|
+
|
|
131
|
+
<Field label="Tagline" hint="The short identity an agent loads first.">
|
|
132
|
+
<input
|
|
133
|
+
value={tagline}
|
|
134
|
+
onChange={(event) => {
|
|
135
|
+
setTagline(event.target.value)
|
|
136
|
+
}}
|
|
137
|
+
placeholder="CRM and company brain for agent-native startups"
|
|
138
|
+
disabled={!canEdit}
|
|
139
|
+
className="w-full max-w-xl 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 disabled:opacity-60"
|
|
140
|
+
/>
|
|
141
|
+
</Field>
|
|
142
|
+
|
|
143
|
+
<Field label="One-liner" hint="What the company does, in a sentence.">
|
|
144
|
+
<textarea
|
|
145
|
+
value={oneLiner}
|
|
146
|
+
onChange={(event) => {
|
|
147
|
+
setOneLiner(event.target.value)
|
|
148
|
+
}}
|
|
149
|
+
rows={2}
|
|
150
|
+
disabled={!canEdit}
|
|
151
|
+
className="w-full max-w-xl 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 disabled:opacity-60"
|
|
152
|
+
/>
|
|
153
|
+
</Field>
|
|
154
|
+
|
|
155
|
+
<Field label="Timezone">
|
|
156
|
+
<select
|
|
157
|
+
value={timezone}
|
|
158
|
+
onChange={(event) => {
|
|
159
|
+
setTimezone(event.target.value)
|
|
160
|
+
}}
|
|
161
|
+
disabled={!canEdit}
|
|
162
|
+
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 disabled:opacity-60"
|
|
163
|
+
>
|
|
164
|
+
{timezones.map((zone) => (
|
|
165
|
+
<option key={zone} value={zone}>
|
|
166
|
+
{zone}
|
|
167
|
+
</option>
|
|
168
|
+
))}
|
|
169
|
+
</select>
|
|
170
|
+
</Field>
|
|
171
|
+
|
|
172
|
+
{update.error !== null && (
|
|
173
|
+
<div className="max-w-xl">
|
|
174
|
+
<ErrorPanel error={update.error} />
|
|
175
|
+
</div>
|
|
176
|
+
)}
|
|
177
|
+
|
|
178
|
+
{canEdit ? (
|
|
179
|
+
<button
|
|
180
|
+
type="submit"
|
|
181
|
+
disabled={update.isPending}
|
|
182
|
+
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"
|
|
183
|
+
>
|
|
184
|
+
{update.isPending ? 'Saving…' : saved ? 'Saved' : 'Save changes'}
|
|
185
|
+
</button>
|
|
186
|
+
) : (
|
|
187
|
+
<p className="text-[12px] text-ink-muted">
|
|
188
|
+
Workspace settings are changed by an admin or the owner.
|
|
189
|
+
</p>
|
|
190
|
+
)}
|
|
191
|
+
</form>
|
|
192
|
+
|
|
193
|
+
{session?.role === 'owner' && <DangerZone slug={workspace.slug} />}
|
|
194
|
+
</div>
|
|
195
|
+
)
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Deleting the workspace, behind the workspace's own name.
|
|
200
|
+
*
|
|
201
|
+
* Owner only, both here and in the API. The typed slug is what the request
|
|
202
|
+
* carries, so this is the same guard on both sides rather than a browser-side
|
|
203
|
+
* flourish over an endpoint that would have deleted anyway.
|
|
204
|
+
*/
|
|
205
|
+
function DangerZone({ slug }: { readonly slug: string }): React.JSX.Element {
|
|
206
|
+
const navigate = useNavigate()
|
|
207
|
+
const remove = useDeleteWorkspace()
|
|
208
|
+
const [confirmation, setConfirmation] = useState('')
|
|
209
|
+
|
|
210
|
+
function submit(event: FormEvent): void {
|
|
211
|
+
event.preventDefault()
|
|
212
|
+
|
|
213
|
+
remove
|
|
214
|
+
.runAsync({ slug: confirmation.trim() })
|
|
215
|
+
// Nothing left to render here: the workspace this page describes is gone,
|
|
216
|
+
// and the account is back to having none.
|
|
217
|
+
.then(() => navigate('/onboarding/workspace', { replace: true }))
|
|
218
|
+
.catch(() => undefined)
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
return (
|
|
222
|
+
<section className="rounded-lg border border-danger/30 bg-danger-soft p-4">
|
|
223
|
+
<h2 className="text-[13px] font-semibold text-danger">Danger zone</h2>
|
|
224
|
+
<p className="mt-1 max-w-xl text-[12px] text-ink-muted">
|
|
225
|
+
Deleting this workspace removes every CRM record, the handbook, forms, invitations, and API
|
|
226
|
+
keys it owns. Everyone loses access. This cannot be undone.
|
|
227
|
+
</p>
|
|
228
|
+
<form onSubmit={submit} className="mt-3 flex flex-wrap items-end gap-2">
|
|
229
|
+
<label className="block">
|
|
230
|
+
<span className="mb-1.5 block text-[12px] font-medium text-ink">
|
|
231
|
+
Type <span className="font-mono">{slug}</span> to confirm
|
|
232
|
+
</span>
|
|
233
|
+
<input
|
|
234
|
+
value={confirmation}
|
|
235
|
+
onChange={(event) => {
|
|
236
|
+
setConfirmation(event.target.value)
|
|
237
|
+
}}
|
|
238
|
+
className="w-56 rounded-md border border-border bg-surface-raised px-3 py-1.5 font-mono text-[12px] outline-none focus:border-danger"
|
|
239
|
+
/>
|
|
240
|
+
</label>
|
|
241
|
+
<button
|
|
242
|
+
type="submit"
|
|
243
|
+
disabled={confirmation.trim() !== slug || remove.isPending}
|
|
244
|
+
className="rounded-md border border-danger bg-surface-raised px-3 py-1.5 text-[12px] font-medium text-danger transition hover:bg-danger hover:text-danger-fg disabled:opacity-40 disabled:hover:bg-surface-raised disabled:hover:text-danger"
|
|
245
|
+
>
|
|
246
|
+
{remove.isPending ? 'Deleting…' : 'Delete workspace'}
|
|
247
|
+
</button>
|
|
248
|
+
</form>
|
|
249
|
+
{remove.error !== null && (
|
|
250
|
+
<div className="mt-3 max-w-xl">
|
|
251
|
+
<ErrorPanel error={remove.error} />
|
|
252
|
+
</div>
|
|
253
|
+
)}
|
|
254
|
+
</section>
|
|
255
|
+
)
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
function Field({
|
|
259
|
+
label,
|
|
260
|
+
hint,
|
|
261
|
+
children,
|
|
262
|
+
}: {
|
|
263
|
+
readonly label: string
|
|
264
|
+
readonly hint?: string
|
|
265
|
+
readonly children: ReactNode
|
|
266
|
+
}): React.JSX.Element {
|
|
267
|
+
return (
|
|
268
|
+
<label className="block">
|
|
269
|
+
<span className="mb-1.5 block text-[12px] font-medium text-ink">{label}</span>
|
|
270
|
+
{children}
|
|
271
|
+
{hint !== undefined && <span className="mt-1 block text-[11px] text-ink-faint">{hint}</span>}
|
|
272
|
+
</label>
|
|
273
|
+
)
|
|
274
|
+
}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The controls the signed-out pages share.
|
|
3
|
+
*
|
|
4
|
+
* Seven forms across sign-in, signup, the two reset pages, and onboarding wrote
|
|
5
|
+
* the same label, input, and button markup. One copy of it here means a change
|
|
6
|
+
* to how a field looks is one edit rather than seven, and a page reads as what
|
|
7
|
+
* it asks for rather than as a wall of class names.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Exported for the one control `TextField` cannot express: the invite row pairs
|
|
12
|
+
* an address with a role on a single line, so neither gets its own label.
|
|
13
|
+
*/
|
|
14
|
+
export const AUTH_INPUT_CLASS =
|
|
15
|
+
'w-full rounded-md border border-border bg-surface px-3 py-2 text-[13px] outline-none focus:border-accent focus:ring-2 focus:ring-accent/20'
|
|
16
|
+
|
|
17
|
+
export interface TextFieldProps {
|
|
18
|
+
readonly label: string
|
|
19
|
+
readonly type?: 'text' | 'email' | 'password'
|
|
20
|
+
readonly value: string
|
|
21
|
+
readonly onChange: (value: string) => void
|
|
22
|
+
/** What a password manager should offer here. Always worth setting on a credential. */
|
|
23
|
+
readonly autoComplete?: string
|
|
24
|
+
readonly placeholder?: string
|
|
25
|
+
readonly hint?: string
|
|
26
|
+
readonly required?: boolean
|
|
27
|
+
/** A slug or a token: characters the reader has to be able to tell apart. */
|
|
28
|
+
readonly mono?: boolean
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function TextField({
|
|
32
|
+
label,
|
|
33
|
+
type = 'text',
|
|
34
|
+
value,
|
|
35
|
+
onChange,
|
|
36
|
+
autoComplete,
|
|
37
|
+
placeholder,
|
|
38
|
+
hint,
|
|
39
|
+
required = false,
|
|
40
|
+
mono = false,
|
|
41
|
+
}: TextFieldProps): React.JSX.Element {
|
|
42
|
+
return (
|
|
43
|
+
<label className="block">
|
|
44
|
+
<span className="mb-1.5 block text-[12px] font-medium text-ink">{label}</span>
|
|
45
|
+
<input
|
|
46
|
+
type={type}
|
|
47
|
+
value={value}
|
|
48
|
+
onChange={(event) => {
|
|
49
|
+
onChange(event.target.value)
|
|
50
|
+
}}
|
|
51
|
+
autoComplete={autoComplete}
|
|
52
|
+
placeholder={placeholder}
|
|
53
|
+
required={required}
|
|
54
|
+
className={mono ? `${AUTH_INPUT_CLASS} font-mono` : AUTH_INPUT_CLASS}
|
|
55
|
+
/>
|
|
56
|
+
{hint !== undefined && <span className="mt-1 block text-[11px] text-ink-faint">{hint}</span>}
|
|
57
|
+
</label>
|
|
58
|
+
)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export interface SubmitButtonProps {
|
|
62
|
+
readonly label: string
|
|
63
|
+
/** Shown while the request is in flight, so the button says what is happening. */
|
|
64
|
+
readonly pendingLabel: string
|
|
65
|
+
readonly isPending: boolean
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const PRIMARY_CLASS =
|
|
69
|
+
'w-full rounded-md bg-accent px-3.5 py-2 text-[12px] font-semibold text-accent-fg transition hover:bg-accent-hover disabled:opacity-50'
|
|
70
|
+
|
|
71
|
+
export function SubmitButton({
|
|
72
|
+
label,
|
|
73
|
+
pendingLabel,
|
|
74
|
+
isPending,
|
|
75
|
+
}: SubmitButtonProps): React.JSX.Element {
|
|
76
|
+
return (
|
|
77
|
+
<button type="submit" disabled={isPending} className={PRIMARY_CLASS}>
|
|
78
|
+
{isPending ? pendingLabel : label}
|
|
79
|
+
</button>
|
|
80
|
+
)
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/** The same button where there is no form to submit, only somewhere to go next. */
|
|
84
|
+
export function PrimaryButton({
|
|
85
|
+
label,
|
|
86
|
+
onClick,
|
|
87
|
+
}: {
|
|
88
|
+
readonly label: string
|
|
89
|
+
readonly onClick: () => void
|
|
90
|
+
}): React.JSX.Element {
|
|
91
|
+
return (
|
|
92
|
+
<button type="button" onClick={onClick} className={PRIMARY_CLASS}>
|
|
93
|
+
{label}
|
|
94
|
+
</button>
|
|
95
|
+
)
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/** The same button as a plain action: skipping a step, or finishing one. */
|
|
99
|
+
export function SecondaryButton({
|
|
100
|
+
label,
|
|
101
|
+
onClick,
|
|
102
|
+
disabled = false,
|
|
103
|
+
}: {
|
|
104
|
+
readonly label: string
|
|
105
|
+
readonly onClick: () => void
|
|
106
|
+
readonly disabled?: boolean
|
|
107
|
+
}): React.JSX.Element {
|
|
108
|
+
return (
|
|
109
|
+
<button
|
|
110
|
+
type="button"
|
|
111
|
+
onClick={onClick}
|
|
112
|
+
disabled={disabled}
|
|
113
|
+
className="w-full rounded-md border border-border bg-surface px-3.5 py-2 text-[12px] font-medium text-ink-muted transition hover:bg-surface-raised disabled:opacity-50"
|
|
114
|
+
>
|
|
115
|
+
{label}
|
|
116
|
+
</button>
|
|
117
|
+
)
|
|
118
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import type { ReactNode } from 'react'
|
|
2
|
+
import { Link } from 'react-router'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* The centred card every signed-out page sits in: sign in, signup, the two
|
|
6
|
+
* password-reset pages, and the three onboarding steps.
|
|
7
|
+
*
|
|
8
|
+
* `step` is what makes it an onboarding page. Onboarding is a sequence somebody
|
|
9
|
+
* is part-way through, and a card that does not say where they are in it turns
|
|
10
|
+
* three screens into three unrelated forms.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/** Onboarding, per `onboarding.md`: workspace, invites, handbook. */
|
|
14
|
+
const ONBOARDING_STEPS = [1, 2, 3] as const
|
|
15
|
+
|
|
16
|
+
export type OnboardingStep = (typeof ONBOARDING_STEPS)[number]
|
|
17
|
+
|
|
18
|
+
export interface AuthLayoutProps {
|
|
19
|
+
readonly title: string
|
|
20
|
+
readonly description?: string
|
|
21
|
+
/** Which onboarding step this is. Draws the progress bar and widens the card. */
|
|
22
|
+
readonly step?: OnboardingStep
|
|
23
|
+
readonly children: ReactNode
|
|
24
|
+
/** Links below the form: the way back, or the other way in. */
|
|
25
|
+
readonly footer?: ReactNode
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function AuthLayout({
|
|
29
|
+
title,
|
|
30
|
+
description,
|
|
31
|
+
step,
|
|
32
|
+
children,
|
|
33
|
+
footer,
|
|
34
|
+
}: AuthLayoutProps): React.JSX.Element {
|
|
35
|
+
return (
|
|
36
|
+
<div className="flex min-h-screen flex-col items-center justify-center bg-surface px-4 py-12">
|
|
37
|
+
<Link to="/login" className="mb-8 text-[20px] font-semibold tracking-tight text-ink">
|
|
38
|
+
Kelpie
|
|
39
|
+
</Link>
|
|
40
|
+
<div
|
|
41
|
+
className={`w-full animate-fade-in rounded-md border border-border p-6 ${
|
|
42
|
+
step === undefined ? 'max-w-sm' : 'max-w-md'
|
|
43
|
+
}`}
|
|
44
|
+
>
|
|
45
|
+
{step !== undefined && <StepProgress step={step} />}
|
|
46
|
+
<h1 className="text-[18px] font-semibold tracking-tight text-ink">{title}</h1>
|
|
47
|
+
{description !== undefined && (
|
|
48
|
+
<p className="mt-1 text-[13px] text-ink-muted">{description}</p>
|
|
49
|
+
)}
|
|
50
|
+
{children}
|
|
51
|
+
{footer !== undefined && <div className="mt-4 text-center text-[12px]">{footer}</div>}
|
|
52
|
+
</div>
|
|
53
|
+
</div>
|
|
54
|
+
)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function StepProgress({ step }: { readonly step: OnboardingStep }): React.JSX.Element {
|
|
58
|
+
return (
|
|
59
|
+
<>
|
|
60
|
+
<div className="mb-4 flex items-center gap-2">
|
|
61
|
+
{ONBOARDING_STEPS.map((each) => (
|
|
62
|
+
<div
|
|
63
|
+
key={each}
|
|
64
|
+
aria-hidden
|
|
65
|
+
className={`h-1.5 flex-1 rounded-full ${each <= step ? 'bg-accent' : 'bg-border'}`}
|
|
66
|
+
/>
|
|
67
|
+
))}
|
|
68
|
+
</div>
|
|
69
|
+
<p className="mb-1 text-[11px] font-medium tracking-wide text-ink-faint uppercase">
|
|
70
|
+
Step {step} of {ONBOARDING_STEPS.length}
|
|
71
|
+
</p>
|
|
72
|
+
</>
|
|
73
|
+
)
|
|
74
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { useState } from 'react'
|
|
2
|
+
import type { FormEvent } from 'react'
|
|
3
|
+
import { Link } from 'react-router'
|
|
4
|
+
|
|
5
|
+
import { resetUrlTemplate, useRequestPasswordReset } from '../../api/resources/session.ts'
|
|
6
|
+
import { ErrorPanel } from '../../components/QueryState.tsx'
|
|
7
|
+
import { SubmitButton, TextField } from './AuthForm.tsx'
|
|
8
|
+
import { AuthLayout } from './AuthLayout.tsx'
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Asking for a reset link, against `POST /v1/auth/password-reset`.
|
|
12
|
+
*
|
|
13
|
+
* The endpoint answers `202` whether or not the address is registered, and this
|
|
14
|
+
* page has to answer the same way. Saying "no account with that address" would
|
|
15
|
+
* make the form an account-existence oracle, which is the whole reason the
|
|
16
|
+
* service refuses to tell.
|
|
17
|
+
*
|
|
18
|
+
* So the confirmation is conditional: *if* an account exists. It is not a
|
|
19
|
+
* hedge, it is the only thing the browser actually knows.
|
|
20
|
+
*/
|
|
21
|
+
export function ForgotPasswordPage(): React.JSX.Element {
|
|
22
|
+
const request = useRequestPasswordReset()
|
|
23
|
+
const [email, setEmail] = useState('')
|
|
24
|
+
const [sentTo, setSentTo] = useState<string | null>(null)
|
|
25
|
+
|
|
26
|
+
function submit(event: FormEvent): void {
|
|
27
|
+
event.preventDefault()
|
|
28
|
+
|
|
29
|
+
const address = email.trim()
|
|
30
|
+
|
|
31
|
+
request
|
|
32
|
+
.runAsync({ email: address, resetUrlTemplate: resetUrlTemplate(window.location.origin) })
|
|
33
|
+
.then(() => {
|
|
34
|
+
setSentTo(address)
|
|
35
|
+
})
|
|
36
|
+
.catch(() => undefined)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const backToSignIn = (
|
|
40
|
+
<Link to="/login" className="font-medium text-accent hover:underline">
|
|
41
|
+
Back to sign in
|
|
42
|
+
</Link>
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
if (sentTo !== null) {
|
|
46
|
+
return (
|
|
47
|
+
<AuthLayout title="Check your email" footer={backToSignIn}>
|
|
48
|
+
<p className="mt-4 text-[13px] text-ink-muted">
|
|
49
|
+
If an account exists for <span className="font-medium text-ink">{sentTo}</span>, a reset
|
|
50
|
+
link is on its way. The link expires, so use it soon.
|
|
51
|
+
</p>
|
|
52
|
+
</AuthLayout>
|
|
53
|
+
)
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return (
|
|
57
|
+
<AuthLayout
|
|
58
|
+
title="Reset password"
|
|
59
|
+
description="Enter your email and we will send you a link."
|
|
60
|
+
footer={backToSignIn}
|
|
61
|
+
>
|
|
62
|
+
<form onSubmit={submit} className="mt-5 space-y-3">
|
|
63
|
+
<TextField
|
|
64
|
+
label="Email"
|
|
65
|
+
type="email"
|
|
66
|
+
value={email}
|
|
67
|
+
onChange={setEmail}
|
|
68
|
+
autoComplete="email"
|
|
69
|
+
required
|
|
70
|
+
/>
|
|
71
|
+
{request.error !== null && <ErrorPanel error={request.error} />}
|
|
72
|
+
<SubmitButton
|
|
73
|
+
label="Send reset link"
|
|
74
|
+
pendingLabel="Sending…"
|
|
75
|
+
isPending={request.isPending}
|
|
76
|
+
/>
|
|
77
|
+
</form>
|
|
78
|
+
</AuthLayout>
|
|
79
|
+
)
|
|
80
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { Link, Navigate, useNavigate, useSearchParams } from 'react-router'
|
|
2
|
+
|
|
3
|
+
import { useAcceptInvite, useSession } from '../../api/resources/session.ts'
|
|
4
|
+
import { ErrorPanel, LoadingPanel } from '../../components/QueryState.tsx'
|
|
5
|
+
import { AuthLayout } from './AuthLayout.tsx'
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Where an invitation email lands: `/join?token=…`.
|
|
9
|
+
*
|
|
10
|
+
* Accepting needs a signed-in account, because the invitation adds *somebody* to
|
|
11
|
+
* the workspace and the token does not say who. An invitee who is signed out is
|
|
12
|
+
* sent to sign in with the token kept in the URL they come back to.
|
|
13
|
+
*
|
|
14
|
+
* Accepting is not automatic on load. It is a write that changes which workspace
|
|
15
|
+
* the session is in, so it waits for the person to press the button.
|
|
16
|
+
*/
|
|
17
|
+
export function JoinPage(): React.JSX.Element {
|
|
18
|
+
const navigate = useNavigate()
|
|
19
|
+
const [searchParameters] = useSearchParams()
|
|
20
|
+
const token = searchParameters.get('token') ?? ''
|
|
21
|
+
const { isLoading, isSignedOut, error } = useSession()
|
|
22
|
+
const accept = useAcceptInvite()
|
|
23
|
+
|
|
24
|
+
if (token.length === 0) {
|
|
25
|
+
return (
|
|
26
|
+
<AuthLayout title="This link is incomplete" description="It carries no invitation token.">
|
|
27
|
+
<p className="mt-4 text-[13px] text-ink-muted">
|
|
28
|
+
Ask whoever invited you to send it again from the workspace's Team page.
|
|
29
|
+
</p>
|
|
30
|
+
</AuthLayout>
|
|
31
|
+
)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// The token rides along so signing in comes back here rather than to the CRM.
|
|
35
|
+
const signInHere = `/login?next=${encodeURIComponent(`/join?token=${token}`)}`
|
|
36
|
+
|
|
37
|
+
if (isSignedOut) {
|
|
38
|
+
return <Navigate to={signInHere} replace />
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (error !== null) {
|
|
42
|
+
return (
|
|
43
|
+
<AuthLayout title="Join a workspace">
|
|
44
|
+
<div className="mt-4">
|
|
45
|
+
<ErrorPanel error={error} />
|
|
46
|
+
</div>
|
|
47
|
+
</AuthLayout>
|
|
48
|
+
)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (isLoading) {
|
|
52
|
+
return <LoadingPanel />
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return (
|
|
56
|
+
<AuthLayout
|
|
57
|
+
title="Join a workspace"
|
|
58
|
+
description="You have been invited. Accepting adds this account to it."
|
|
59
|
+
>
|
|
60
|
+
<div className="mt-5 space-y-3">
|
|
61
|
+
{accept.error !== null && <ErrorPanel error={accept.error} />}
|
|
62
|
+
<button
|
|
63
|
+
type="button"
|
|
64
|
+
disabled={accept.isPending}
|
|
65
|
+
onClick={() => {
|
|
66
|
+
accept
|
|
67
|
+
.runAsync({ token })
|
|
68
|
+
.then(() => navigate('/dashboard', { replace: true }))
|
|
69
|
+
.catch(() => undefined)
|
|
70
|
+
}}
|
|
71
|
+
className="w-full rounded-md bg-accent px-3.5 py-2 text-[12px] font-semibold text-accent-fg transition hover:bg-accent-hover disabled:opacity-50"
|
|
72
|
+
>
|
|
73
|
+
{accept.isPending ? 'Joining…' : 'Accept invitation'}
|
|
74
|
+
</button>
|
|
75
|
+
<p className="text-[11px] text-ink-faint">
|
|
76
|
+
Signed in as the wrong account?{' '}
|
|
77
|
+
<Link to={signInHere} className="text-accent">
|
|
78
|
+
Sign in as somebody else
|
|
79
|
+
</Link>
|
|
80
|
+
.
|
|
81
|
+
</p>
|
|
82
|
+
</div>
|
|
83
|
+
</AuthLayout>
|
|
84
|
+
)
|
|
85
|
+
}
|