@bcrumbs.net/inbox 0.0.59 → 0.0.62

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 (88) hide show
  1. package/assets/ar/inbox.json +16 -3
  2. package/assets/en/inbox.json +16 -3
  3. package/index.cjs.js +49121 -49385
  4. package/index.esm.js +49125 -49389
  5. package/package.json +4 -4
  6. package/playwright.config.d.ts +9 -0
  7. package/src/app/ai/components/Crumby/ChatView.d.ts +12 -0
  8. package/src/app/ai/components/Crumby/CrumbyComposer.d.ts +3 -0
  9. package/src/app/ai/components/Crumby/CrumbySendAction.d.ts +4 -0
  10. package/src/app/ai/components/Crumby/CrumbyWidget.d.ts +2 -0
  11. package/src/app/ai/components/Crumby/index.d.ts +1 -2
  12. package/src/app/ai/components/playground/Button.d.ts +1 -1
  13. package/src/app/ai/components/playground/ThreadMessages.d.ts +5 -1
  14. package/src/app/ai/components/playground/TooltipIconButton.d.ts +2 -2
  15. package/src/app/auth/components/UserAvatar/AccountSettingsDropdown.d.ts +3 -5
  16. package/src/app/auth/components/password-page/AuthPasswordPageLayout.d.ts +7 -0
  17. package/src/app/auth/components/password-page/ForgetPasswordFormView.d.ts +20 -0
  18. package/src/app/auth/components/password-page/PasswordFormView.d.ts +22 -0
  19. package/src/app/auth/components/password-page/PasswordSuccessView.d.ts +8 -0
  20. package/src/app/auth/hooks/useRoles.d.ts +1 -0
  21. package/src/app/auth/pages/Auth.style.d.ts +68 -0
  22. package/src/app/auth/pages/Forget.d.ts +0 -3
  23. package/src/app/auth/pages/Login.style.d.ts +1 -0
  24. package/src/app/auth/pages/Register.style.d.ts +5 -0
  25. package/src/app/auth/utils/avatar.d.ts +1 -0
  26. package/src/app/auth/utils/resetWorkspaceRoleState.d.ts +4 -0
  27. package/src/app/broadcast/components/BroadcastAnalysisContent.d.ts +3 -1
  28. package/src/app/broadcast/components/BroadcastAnalysisReciepients.d.ts +6 -1
  29. package/src/app/broadcast/components/BroadcastAnalysisReciepientsHeader.d.ts +7 -1
  30. package/src/app/contact/components/ContactFilterOptions.d.ts +4 -1
  31. package/src/app/contact/components/ContactFormFields.d.ts +4 -1
  32. package/src/app/dashboard/components/AgentPerformanceCard.d.ts +2 -1
  33. package/src/app/dashboard/components/BroadcastCampaignProgressCard.d.ts +3 -1
  34. package/src/app/dashboard/components/DashboardExportButton.d.ts +8 -0
  35. package/src/app/dashboard/components/DashboardSections.d.ts +2 -1
  36. package/src/app/dashboard/components/OpenedChatsCard.d.ts +5 -1
  37. package/src/app/dashboard/components/TagPerformanceCard.d.ts +2 -1
  38. package/src/app/dashboard/utils/dashboardReportExports.d.ts +100 -0
  39. package/src/app/generic/components/PhoneDigitsInput.d.ts +7 -0
  40. package/src/app/generic/hooks/useResourceColumns.d.ts +3 -1
  41. package/src/app/inbox/components/Chat/ChatHeader.d.ts +2 -0
  42. package/src/app/inbox/components/Chat/NoConvSelected.d.ts +5 -0
  43. package/src/app/inbox/components/Chat/index.d.ts +4 -1
  44. package/src/app/inbox/components/NewDetails/ClientSection.d.ts +2 -1
  45. package/src/app/inbox/components/NewDetails/UserHeader.d.ts +2 -1
  46. package/src/app/inbox/components/NewDetails/index.d.ts +2 -1
  47. package/src/app/inbox/components/Shared/Inbox.d.ts +4 -1
  48. package/src/app/inbox/components/Shared/MobileChatDetailsSlider.d.ts +14 -0
  49. package/src/app/inbox/components/Shared/MobileDetailsSwipeHint.d.ts +9 -0
  50. package/src/app/inbox/components/Shared/MobileMenu.d.ts +2 -1
  51. package/src/app/inbox/hooks/useConvActions.d.ts +1 -0
  52. package/src/app/inbox/hooks/useConversationsPerodicFetch.d.ts +3 -0
  53. package/src/app/inbox/hooks/useStartedTimeAgo.d.ts +5 -0
  54. package/src/app/inbox/utils/convs.d.ts +8 -1
  55. package/src/app/inbox/utils/inboxAssignableAis.d.ts +11 -1
  56. package/src/app/layout/constants/index.d.ts +11 -10
  57. package/src/app/layout/hooks/useCrumbyEnabled.d.ts +18 -0
  58. package/src/app/layout/hooks/useCrumbyUpgradeAction.d.ts +10 -0
  59. package/src/app/managemnet/config/types.d.ts +2 -0
  60. package/src/app/onboarding/components/OnboardingStepDetail.d.ts +10 -0
  61. package/src/app/onboarding/components/OnboardingView.d.ts +19 -0
  62. package/src/app/onboarding/components/onboardingStepGuide.d.ts +11 -0
  63. package/src/app/onboarding/components/useOnboardingChecklist.d.ts +30 -0
  64. package/src/app/onboarding/utils/onboardingChecklistPersistence.d.ts +18 -0
  65. package/src/app/onboarding/utils/onboardingChecklistStorage.d.ts +24 -2
  66. package/src/app/resources/components/Integrations/Facebook/PagePickerPopup.d.ts +3 -1
  67. package/src/app/resources/components/ListResources/Utils.d.ts +1 -0
  68. package/src/app/subscriptions/components/NewSubscription/OnboardingStepper.d.ts +8 -0
  69. package/src/app/subscriptions/components/NewSubscription/SubscriptionFailed.d.ts +6 -0
  70. package/src/app/subscriptions/components/NewSubscription/SubscriptionName.d.ts +1 -1
  71. package/src/app/subscriptions/components/NewSubscription/SubscriptionSuccess.d.ts +5 -2
  72. package/src/app/subscriptions/components/NewSubscription/WorkspaceStepLayout.d.ts +11 -0
  73. package/src/app/subscriptions/components/Plans/ShowcasePlans.d.ts +3 -1
  74. package/src/app/subscriptions/components/SubscriptionSwitcher/Switcher.d.ts +1 -1
  75. package/src/app/subscriptions/pages/NewSubscription.d.ts +1 -1
  76. package/src/app/subscriptions/utils/newWorkspaceCheckout.d.ts +16 -0
  77. package/src/assets/locales/translations.d.ts +122 -1
  78. package/src/graphql.autogenerated.d.ts +557 -4
  79. package/src/graphql.billing.autogenerated.d.ts +2 -0
  80. package/src/lib/EmbeddedMobileMenu.d.ts +2 -1
  81. package/src/routes/PrivateRoutes.d.ts +1 -5
  82. package/src/utils/exportCsv.d.ts +8 -0
  83. package/src/utils/localStorage.d.ts +1 -0
  84. package/src/utils/textUtils.d.ts +2 -0
  85. package/src/app/broadcast/components/BroadcastTargetingComplianceNotice.d.ts +0 -2
  86. package/src/app/generic/hooks/WithMenuConfig.d.ts +0 -1
  87. package/src/app/layout/components/language/LanguageDropdown.d.ts +0 -9
  88. package/src/app/onboarding/components/OnboardingChecklistWidget.d.ts +0 -3
@@ -11,6 +11,7 @@ interface Props {
11
11
  convStages: Tag[];
12
12
  onUpdate?: () => void;
13
13
  clientSectionPlaceholder?: React.ReactNode;
14
+ onBackToList?: () => void;
14
15
  }
15
- declare const NewDetails: ({ conv, clientTags, conversationTags, tagsLoading, refetchTags, agents, aiAgents, convStages, onUpdate, clientSectionPlaceholder, }: Props) => import("@emotion/react/jsx-runtime").JSX.Element;
16
+ declare const NewDetails: ({ conv, clientTags, conversationTags, tagsLoading, refetchTags, agents, aiAgents, convStages, onUpdate, clientSectionPlaceholder, onBackToList, }: Props) => import("@emotion/react/jsx-runtime").JSX.Element;
16
17
  export default NewDetails;
@@ -13,8 +13,11 @@ export declare const MobileContent: import("@emotion/styled").StyledComponent<{
13
13
  } & {
14
14
  $reserveBottomNavSpace?: boolean | undefined;
15
15
  }, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
16
- export declare const InboxNoSelectionContainer: ({ convsLength, loadingConvs, handleStartConversation, }: {
16
+ export declare const InboxNoSelectionContainer: ({ convsLength, loadingConvs, handleStartConversation, hasInboxAccess, forceNoChannels, resolvingChannels, }: {
17
17
  convsLength?: number;
18
18
  loadingConvs?: boolean;
19
19
  handleStartConversation?: () => void;
20
+ hasInboxAccess?: boolean;
21
+ forceNoChannels?: boolean;
22
+ resolvingChannels?: boolean;
20
23
  }) => import("@emotion/react/jsx-runtime").JSX.Element;
@@ -0,0 +1,14 @@
1
+ import { ReactNode } from 'react';
2
+ type MobileChatDetailsSliderProps = {
3
+ showDetails: boolean;
4
+ onShowDetailsChange: (showDetails: boolean) => void;
5
+ rtl?: boolean;
6
+ chat: ReactNode;
7
+ details: ReactNode;
8
+ };
9
+ /**
10
+ * Side-by-side chat/details pager with follow-the-finger drag.
11
+ * Edge chevron buttons remain for one-tap navigation.
12
+ */
13
+ export declare const MobileChatDetailsSlider: ({ showDetails, onShowDetailsChange, rtl, chat, details, }: MobileChatDetailsSliderProps) => import("@emotion/react/jsx-runtime").JSX.Element;
14
+ export {};
@@ -0,0 +1,9 @@
1
+ type MobileDetailsSwipeHintProps = {
2
+ rtl?: boolean;
3
+ onClick: () => void;
4
+ /** `toDetails` sits on the trailing edge; `toChat` on the leading edge. */
5
+ direction?: 'toDetails' | 'toChat';
6
+ };
7
+ /** Edge affordance for mobile chat ↔ details swipe navigation. */
8
+ export declare const MobileDetailsSwipeHint: ({ rtl, onClick, direction, }: MobileDetailsSwipeHintProps) => import("@emotion/react/jsx-runtime").JSX.Element;
9
+ export {};
@@ -3,6 +3,7 @@ export type { MobileViews };
3
3
  type MobileMenuProps = {
4
4
  activePage: MobileViews;
5
5
  setActivePage: (page: MobileViews) => void;
6
+ /** @deprecated Details is opened via swipe; kept for call-site compatibility. */
6
7
  hideDetails?: boolean;
7
8
  };
8
- export declare const MobileMenu: ({ activePage, setActivePage, hideDetails }: MobileMenuProps) => import("@emotion/react/jsx-runtime").JSX.Element;
9
+ export declare const MobileMenu: ({ activePage, setActivePage }: MobileMenuProps) => import("@emotion/react/jsx-runtime").JSX.Element;
@@ -12,5 +12,6 @@ interface ConvActionsProps {
12
12
  }
13
13
  declare const useConvActions: ({ conv, handleChangeStage, handleAssignAgent, agents, convStages, myAgent, onConvEnd, aiAgents, }: ConvActionsProps) => {
14
14
  DropdownActions: ActionItem[];
15
+ CrumbyUpgradeDialog: import("@emotion/react/jsx-runtime").JSX.Element;
15
16
  };
16
17
  export default useConvActions;
@@ -22,6 +22,8 @@ declare function useConversationsPeriodicFetch(selectedConvId?: string, onSelect
22
22
  ratingFlowInProgress?: boolean | null | undefined;
23
23
  broadcastId?: string | null | undefined;
24
24
  broadcastName?: string | null | undefined;
25
+ sourceType?: string | null | undefined;
26
+ sourceUrl?: string | null | undefined;
25
27
  integrationSwitches?: {
26
28
  __typename?: "ConvIntegrationSwitch" | undefined;
27
29
  fromIntegrationId: string;
@@ -57,6 +59,7 @@ declare function useConversationsPeriodicFetch(selectedConvId?: string, onSelect
57
59
  surname?: string | null | undefined;
58
60
  code?: string | null | undefined;
59
61
  phone?: string | null | undefined;
62
+ avatarUrl?: string | null | undefined;
60
63
  isDeleted: boolean;
61
64
  } | null | undefined;
62
65
  assignees?: ({
@@ -0,0 +1,5 @@
1
+ type StartedTimeAgoTranslation = (key: string, options?: {
2
+ count?: number;
3
+ }) => string;
4
+ export declare function useStartedTimeAgo(createdAt: string, t: StartedTimeAgoTranslation): string;
5
+ export {};
@@ -26,6 +26,9 @@ interface BuildAgentsMenuOptions {
26
26
  assignableAis?: Ai[];
27
27
  onAssignableAiSelect?: (aiId: string) => void;
28
28
  onUnassigneeSelect?: () => void;
29
+ /** When false, Crumby is shown locked with an Upgrade CTA */
30
+ isCrumbyEnabled?: boolean;
31
+ onCrumbyUpgrade?: () => void;
29
32
  t: any;
30
33
  includeAllOption?: boolean;
31
34
  onAllSelect?: () => void;
@@ -45,9 +48,13 @@ export declare function getLastMessage(messages: Maybe<Message[]> | undefined, f
45
48
  export declare function hashStatuses(messages?: Maybe<Message[]> | null): string;
46
49
  export declare function isOutside24HourWindow(message: Message | null | undefined): boolean;
47
50
  export declare function formatSeconds(value: number): string;
51
+ type StartedTimeAgoTranslation = (key: string, options?: {
52
+ count?: number;
53
+ }) => string;
54
+ export declare function formatStartedTimeAgo(createdAt: string, t: StartedTimeAgoTranslation): string;
48
55
  export declare const getMessageStatusIcon: (message: Message | null | undefined) => import("@emotion/react/jsx-runtime").JSX.Element | null;
49
56
  export declare const getDisplayName: (clientData: ClientQuery['client'] | undefined) => string;
50
- export declare const buildAgentsMenu: ({ agents, myAgent, selectedAgentId, selectedAiId, onAgentSelect, assignableAis, onAssignableAiSelect, onUnassigneeSelect, t, includeAllOption, onAllSelect, addSeparatorAtLast, counts, showAllAgents, }: BuildAgentsMenuOptions) => ActionItem[];
57
+ export declare const buildAgentsMenu: ({ agents, myAgent, selectedAgentId, selectedAiId, onAgentSelect, assignableAis, onAssignableAiSelect, onUnassigneeSelect, isCrumbyEnabled, onCrumbyUpgrade, t, includeAllOption, onAllSelect, addSeparatorAtLast, counts, showAllAgents, }: BuildAgentsMenuOptions) => ActionItem[];
51
58
  export declare const buildLifeCycleMenu: ({ convStages, selectedStageId, onStageSelect, t, addSeparatorAtLast, }: BuildLifeCycleMenuOptions) => ActionItem[];
52
59
  interface BuildTagsMenuOptions {
53
60
  conversationTags: Tag[];
@@ -1,10 +1,20 @@
1
1
  import { Ai } from '../../../graphql.autogenerated';
2
2
  /** Stored name for the primary Crumby assistant record */
3
3
  export declare const CRUMBY_AI_RECORD_NAME = "Crumby AI";
4
+ /** Placeholder id used when Crumby is shown as a locked upgrade option */
5
+ export declare const CRUMBY_UPGRADE_PLACEHOLDER_ID = "__crumby_upgrade__";
6
+ export declare const isCrumbyAi: (ai: Pick<Ai, 'name' | 'type'> | undefined | null) => boolean;
7
+ export declare const createCrumbyUpgradePlaceholder: () => Ai;
4
8
  /** Primary Crumby assistant rows first, then remaining AIs by name */
5
9
  export declare function sortInboxAssignableAis(ais: Ai[]): Ai[];
6
10
  /**
7
11
  * Workspace AIs users may assign or filter by in the inbox.
8
- * Excludes internal assistants and hides Crumby when the feature flag is off.
12
+ * Excludes internal assistants. When Crumby is not plan-enabled, it is omitted
13
+ * from filters; assign menus inject a locked upgrade entry separately.
9
14
  */
10
15
  export declare function getInboxAssignableAis(aiAgents: Ai[] | undefined, isCrumbyEnabled: boolean): Ai[];
16
+ /**
17
+ * Assign-menu list: always includes Crumby. When the feature is locked, uses an
18
+ * existing Crumby record if present, otherwise a non-assignable placeholder.
19
+ */
20
+ export declare function getInboxAssignableAisForMenu(aiAgents: Ai[] | undefined, isCrumbyEnabled: boolean, existingCrumby?: Ai | null): Ai[];
@@ -8,8 +8,18 @@ export declare const BCMainNavigation: {
8
8
  action: string;
9
9
  description: string;
10
10
  tags: string[];
11
+ requiredPermissions: Permission[];
11
12
  subMenu?: undefined;
13
+ } | {
14
+ label: string;
15
+ title: string;
16
+ icon: import("@emotion/react/jsx-runtime").JSX.Element;
17
+ link: string;
18
+ action: string;
19
+ description: string;
20
+ tags: string[];
12
21
  requiredPermissions?: undefined;
22
+ subMenu?: undefined;
13
23
  } | {
14
24
  label: string;
15
25
  title: string;
@@ -37,17 +47,7 @@ export declare const BCMainNavigation: {
37
47
  })[];
38
48
  }[];
39
49
  tags: string[];
40
- requiredPermissions?: undefined;
41
- } | {
42
- label: string;
43
- title: string;
44
- icon: import("@emotion/react/jsx-runtime").JSX.Element;
45
- link: string;
46
- action: string;
47
- description: string;
48
- tags: string[];
49
50
  requiredPermissions: Permission[];
50
- subMenu?: undefined;
51
51
  })[];
52
52
  leftBottomLinks: {
53
53
  label: string;
@@ -56,6 +56,7 @@ export declare const BCMainNavigation: {
56
56
  link: string;
57
57
  action: string;
58
58
  tags: string[];
59
+ requiredPermissions: Permission[];
59
60
  }[];
60
61
  };
61
62
  export declare const MOBILE_DIMENSION = 767;
@@ -1 +1,19 @@
1
+ /**
2
+ * Whether the workspace has the paid AI features enabled: the AI tab (Playground,
3
+ * Sources), conversation assignment to Crumby, and the AI-specific onboarding steps.
4
+ * Gated by the plan's `aiEnabled` flag (or a feature-flag override).
5
+ *
6
+ * NOTE: This does NOT gate the Crumby assistant chat widget — that is available on
7
+ * all plans (including free) via `useCrumbyAssistantEnabled`.
8
+ */
1
9
  export declare const useCrumbyEnabled: () => boolean;
10
+ /**
11
+ * Whether the Crumby assistant chat widget should be shown. The assistant is available
12
+ * on every plan, including free — unlike the paid AI features gated by `useCrumbyEnabled`.
13
+ *
14
+ * Returns a constant `true` for now (no rule). It is kept as a hook to act as the single
15
+ * seam for future gating — e.g. a kill switch (feature flag / PostHog), a whitelabel with
16
+ * no AI, or a backend "assistant enabled" flag — so only this hook changes, not every call
17
+ * site. It also keeps the call site readable and symmetric with `useCrumbyEnabled`.
18
+ */
19
+ export declare const useCrumbyAssistantEnabled: () => boolean;
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Shared upgrade CTA for Crumby when the plan/feature flag does not enable AI.
3
+ * Owners/admins go to the workspace upgrade page; others see a contact-admin dialog.
4
+ */
5
+ export declare const useCrumbyUpgradeAction: () => {
6
+ isCrumbyEnabled: boolean;
7
+ canManageUpgrade: boolean;
8
+ requestCrumbyUpgrade: any;
9
+ CrumbyUpgradeDialog: import("@emotion/react/jsx-runtime").JSX.Element;
10
+ };
@@ -62,5 +62,7 @@ export interface ResourceDefinition<T> {
62
62
  unDeleteMutation?: Omit<BackendMutationDefinition<T>, 'fields'>;
63
63
  archiveMutation?: Omit<BackendMutationDefinition<T>, 'fields'>;
64
64
  unArchiveMutation?: Omit<BackendMutationDefinition<T>, 'fields'>;
65
+ blockMutation?: Omit<BackendMutationDefinition<T>, 'fields'>;
66
+ unBlockMutation?: Omit<BackendMutationDefinition<T>, 'fields'>;
65
67
  client?: Apollo.ApolloClient<Apollo.NormalizedCacheObject>;
66
68
  }
@@ -0,0 +1,10 @@
1
+ import { type OnboardingChecklistStepId } from '../utils/onboardingChecklistStorage';
2
+ export type OnboardingStepDetailProps = {
3
+ stepId: OnboardingChecklistStepId;
4
+ /** Right-to-left layout (flips the back arrow direction). */
5
+ rtl: boolean;
6
+ onBack: () => void;
7
+ onClose: () => void;
8
+ };
9
+ /** Single-step guide: instructions (Step 1/Step 2…) plus optional screenshots. */
10
+ export declare function OnboardingStepDetail({ stepId, rtl, onBack, onClose }: OnboardingStepDetailProps): import("@emotion/react/jsx-runtime").JSX.Element;
@@ -0,0 +1,19 @@
1
+ import { type OnboardingChecklistState, type OnboardingChecklistStepId } from '../utils/onboardingChecklistStorage';
2
+ export type OnboardingViewProps = {
3
+ applicableStepIds: OnboardingChecklistStepId[];
4
+ checklistState: OnboardingChecklistState | null;
5
+ completedCount: number;
6
+ celebrateStepId: OnboardingChecklistStepId | null;
7
+ /** Show the "Ask crumby…" input (hidden when Crumby chat is unavailable). */
8
+ showInput: boolean;
9
+ rtl: boolean;
10
+ toggleStep: (stepId: OnboardingChecklistStepId) => void;
11
+ onOpenStep: (stepId: OnboardingChecklistStepId) => void;
12
+ onClose: () => void;
13
+ /** Submit text from the input — switches the panel to chat and sends it. */
14
+ onSendToChat: (text: string) => void;
15
+ /** Finish onboarding (all steps done) and open the chat. */
16
+ onFinish: () => void;
17
+ };
18
+ /** Onboarding mode of the unified widget: welcome header, setup checklist, AI input. */
19
+ export declare function OnboardingView({ applicableStepIds, checklistState, completedCount, celebrateStepId, showInput, rtl, toggleStep, onOpenStep, onClose, onSendToChat, onFinish, }: OnboardingViewProps): import("@emotion/react/jsx-runtime").JSX.Element;
@@ -0,0 +1,11 @@
1
+ import { type OnboardingChecklistStepId } from '../utils/onboardingChecklistStorage';
2
+ export type OnboardingStepGuide = {
3
+ /** Optional illustrative screenshots shown under the step instructions. */
4
+ images?: string[];
5
+ };
6
+ /**
7
+ * Per-step visual guide config. Instruction copy lives in i18n
8
+ * (`onboardingChecklist.guide.steps.*`); this only adds optional screenshots.
9
+ * Steps without images render text-only — add entries here as designs ship.
10
+ */
11
+ export declare const ONBOARDING_STEP_GUIDE: Partial<Record<OnboardingChecklistStepId, OnboardingStepGuide>>;
@@ -0,0 +1,30 @@
1
+ import { type OnboardingChecklistState, type OnboardingChecklistStepId } from '../utils/onboardingChecklistStorage';
2
+ export type UseOnboardingChecklist = {
3
+ /** Steps relevant for the current plan (drops Crumby steps when AI is disabled). */
4
+ applicableStepIds: OnboardingChecklistStepId[];
5
+ /** Parsed checklist, or null when there is no active checklist for this user. */
6
+ checklistState: OnboardingChecklistState | null;
7
+ /** Number of applicable steps the user has completed. */
8
+ completedCount: number;
9
+ /** True while there is a non-expired checklist with at least one applicable step still open. */
10
+ isActive: boolean;
11
+ /** Step currently playing the completion sweep, or null. */
12
+ celebrateStepId: OnboardingChecklistStepId | null;
13
+ /** One-shot request to auto-open the widget on onboarding (set right after sign-in). */
14
+ shouldAutoOpen: boolean;
15
+ /** Toggle a step's completed flag (manual checkbox). */
16
+ toggleStep: (stepId: OnboardingChecklistStepId) => void;
17
+ /** Clears the one-shot auto-open request once the widget has acted on it. */
18
+ consumeAutoOpen: () => void;
19
+ /** Run when the widget panel closes: clears the completed checklist from storage. */
20
+ onPanelClosed: () => void;
21
+ /** Finish onboarding now (Get started button): clears the checklist for this workspace. */
22
+ dismissChecklist: () => void;
23
+ };
24
+ /**
25
+ * Owns the onboarding-checklist state previously held inside OnboardingChecklistWidget:
26
+ * load/parse/TTL, applicable steps for the current plan, completion celebration, the
27
+ * cross-tab updated event, and the post-sign-in auto-open signal. The presentation is
28
+ * delegated to the unified Crumby widget.
29
+ */
30
+ export declare function useOnboardingChecklist(): UseOnboardingChecklist;
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Durable persistence for onboarding checklist data (state + dismissed flag).
3
+ *
4
+ * Backed by cookies on purpose: logout runs `auth.clearAllAppStorage()` which wipes
5
+ * localStorage/sessionStorage but NOT cookies, so progress and the "finished" flag
6
+ * survive a logout → login cycle (same browser).
7
+ *
8
+ * This is a temporary stand-in for a backend-owned onboarding record. When the backend
9
+ * returns the flag + progress, swap the implementation of `onboardingChecklistStore`
10
+ * (or its call sites) for the server-backed read/writes — the get/set/remove shape
11
+ * matches the localStorage util so the change stays local.
12
+ */
13
+ /** Cookie-backed store mirroring the localStorage util's get/set/remove shape. */
14
+ export declare const onboardingChecklistStore: {
15
+ get(key: string): unknown;
16
+ set(key: string, value: unknown): void;
17
+ remove(key: string): void;
18
+ };
@@ -11,8 +11,29 @@ export declare const ONBOARDING_CHECKLIST_STEP_IDS: OnboardingChecklistStepId[];
11
11
  export declare const ONBOARDING_CHECKLIST_CRUMBY_STEP_IDS: OnboardingChecklistStepId[];
12
12
  export declare function getApplicableOnboardingChecklistStepIds(isCrumbyEnabled: boolean): OnboardingChecklistStepId[];
13
13
  export declare function isOnboardingChecklistCompleteForCrumbySetting(state: OnboardingChecklistState, isCrumbyEnabled: boolean): boolean;
14
- export declare function getOnboardingChecklistStorageKey(userId: string | number): string;
14
+ export declare function getOnboardingChecklistStorageKey(userId: string | number, workspaceId?: string | number | null): string;
15
+ /** Pre-workspace-scoping key: showcase_onboarding_checklist_{userId} */
16
+ export declare function getLegacyOnboardingChecklistStorageKey(userId: string | number): string;
17
+ /**
18
+ * Load checklist for user + workspace from the durable (cookie) store. Migrates the older
19
+ * localStorage keys (scoped, legacy user-only, empty-workspace) into the cookie store once.
20
+ * Returns null when workspace context is not available.
21
+ */
22
+ export declare function loadOnboardingChecklistState(userId: string | number, workspaceId?: string | number | null): OnboardingChecklistState | null;
23
+ /**
24
+ * Pending key is keyed by user only (NOT workspace): it is a one-shot "user just signed in"
25
+ * signal set at login, before the workspace context is available. The widget consumes it on
26
+ * first load and creates the checklist scoped to whichever workspace the user landed in.
27
+ */
15
28
  export declare function getOnboardingChecklistPendingKey(userId: string | number): string;
29
+ /**
30
+ * Persisted "user finished / dismissed onboarding for this workspace" marker.
31
+ * Unlike the checklist key (which is removed on finish), this survives so that a later
32
+ * logout → login does not recreate a fresh checklist for a workspace already onboarded.
33
+ */
34
+ export declare function getOnboardingChecklistDismissedKey(userId: string | number, workspaceId?: string | number | null): string;
35
+ export declare function isOnboardingChecklistDismissed(userId: string | number, workspaceId?: string | number | null): boolean;
36
+ export declare function markOnboardingChecklistDismissed(userId: string | number, workspaceId?: string | number | null): void;
16
37
  /** One-shot: open checklist popover after sign-in (session tab only). */
17
38
  export declare const ONBOARDING_CHECKLIST_SESSION_AUTOPEN_KEY = "showcase_onboarding_checklist_session_autopen";
18
39
  export declare function clearOnboardingChecklistSessionAutopen(): void;
@@ -30,10 +51,11 @@ export declare function notifyOnboardingChecklistAfterSignIn(userId: string | nu
30
51
  * Use this to cheaply skip heavy work (e.g. scanning all inbox messages) when the step is already done
31
52
  * or there is no active checklist.
32
53
  */
33
- export declare function getActiveOnboardingChecklistState(userId: string | number | null | undefined): OnboardingChecklistState | null;
54
+ export declare function getActiveOnboardingChecklistState(userId: string | number | null | undefined, workspaceId?: string | number | null): OnboardingChecklistState | null;
34
55
  export type MarkOnboardingChecklistStepOptions = {
35
56
  /** When already loaded (e.g. after a gate check), avoids a second localStorage read. */
36
57
  knownActiveState?: OnboardingChecklistState;
58
+ workspaceId?: string | number | null;
37
59
  };
38
60
  /**
39
61
  * Marks a checklist step done when the user performs the real action (persists + notifies widget).
@@ -1,8 +1,10 @@
1
1
  import { IntegrationWithSecrets } from '../../../../../graphql.autogenerated';
2
2
  import { FBPage } from '../../../hooks/useFBPagesHook';
3
- export declare function PagePickerPopup({ onClose, setInitialValues, pages, rtl, }: {
3
+ export declare function PagePickerPopup({ onClose, setInitialValues, pages, userAccessToken, rtl, }: {
4
4
  onClose: () => void;
5
5
  setInitialValues: (initialResource: Partial<IntegrationWithSecrets>) => void;
6
6
  pages: FBPage[];
7
+ /** Short-lived Facebook user token; exchanged server-side for a long-lived page token. */
8
+ userAccessToken: string;
7
9
  rtl?: boolean;
8
10
  }): import("@emotion/react/jsx-runtime").JSX.Element;
@@ -1,3 +1,4 @@
1
+ /// <reference types="react" />
1
2
  import { TFunction } from "i18next";
2
3
  import { Row, Action } from "@bcrumbs.net/bc-ui";
3
4
  import { ResourceDefinition } from "../../config";
@@ -0,0 +1,8 @@
1
+ export type OnboardingStepStatus = 'complete' | 'active' | 'upcoming';
2
+ export type OnboardingStepKey = 'registration' | 'workspace' | 'checkout';
3
+ type OnboardingStepperProps = {
4
+ /** Status per step; defaults to registration complete, workspace active, checkout upcoming. */
5
+ statuses?: Partial<Record<OnboardingStepKey, OnboardingStepStatus>>;
6
+ };
7
+ export declare const OnboardingStepper: ({ statuses }: OnboardingStepperProps) => import("@emotion/react/jsx-runtime").JSX.Element;
8
+ export default OnboardingStepper;
@@ -0,0 +1,6 @@
1
+ type SubscriptionFailedProps = {
2
+ loading?: boolean;
3
+ onRetry: () => void;
4
+ };
5
+ export declare const SubscriptionFailed: ({ loading, onRetry }: SubscriptionFailedProps) => import("@emotion/react/jsx-runtime").JSX.Element;
6
+ export default SubscriptionFailed;
@@ -1,5 +1,5 @@
1
1
  type SubscriptionNameProps = {
2
- onSubmit: (companyName: any) => void;
2
+ onSubmit: (companyName: string) => void;
3
3
  };
4
4
  export declare const SubscriptionName: (props: SubscriptionNameProps) => import("@emotion/react/jsx-runtime").JSX.Element;
5
5
  export default SubscriptionName;
@@ -1,5 +1,8 @@
1
1
  type SubscriptionSuccessProps = {
2
- sessionId?: string;
2
+ /** Workspace that was created/paid for; activated before navigating to the inbox. */
3
+ workspaceId?: number;
4
+ /** When false, copy reflects activation without a payment (free plan). */
5
+ paid?: boolean;
3
6
  };
4
- export declare const SubscriptionSuccess: ({ sessionId, }: SubscriptionSuccessProps) => import("@emotion/react/jsx-runtime").JSX.Element;
7
+ export declare const SubscriptionSuccess: ({ workspaceId, paid }: SubscriptionSuccessProps) => import("@emotion/react/jsx-runtime").JSX.Element;
5
8
  export default SubscriptionSuccess;
@@ -0,0 +1,11 @@
1
+ import { ReactNode } from 'react';
2
+ import { OnboardingStepKey, OnboardingStepStatus } from './OnboardingStepper';
3
+ type WorkspaceStepLayoutProps = {
4
+ statuses?: Partial<Record<OnboardingStepKey, OnboardingStepStatus>>;
5
+ illustration: string;
6
+ title: string;
7
+ subtitle?: string;
8
+ children?: ReactNode;
9
+ };
10
+ export declare const WorkspaceStepLayout: ({ statuses, illustration, title, subtitle, children, }: WorkspaceStepLayoutProps) => import("@emotion/react/jsx-runtime").JSX.Element;
11
+ export default WorkspaceStepLayout;
@@ -10,6 +10,8 @@ type ShowcasePlansProps = {
10
10
  selectingPlan?: boolean;
11
11
  processing?: boolean;
12
12
  loadingPlanType?: PlanType | null;
13
+ /** Force the Crumby AI plan toggle on (e.g. deep-link from upgrade CTA). */
14
+ defaultIncludeAi?: boolean;
13
15
  };
14
- export declare const ShowcasePlans: ({ onPlanPicked, disableFreePlan, currentPlanType, currentTerm, selectingPlan, processing, loadingPlanType, }: ShowcasePlansProps) => import("@emotion/react/jsx-runtime").JSX.Element;
16
+ export declare const ShowcasePlans: ({ onPlanPicked, disableFreePlan, currentPlanType, currentTerm, selectingPlan, processing, loadingPlanType, defaultIncludeAi, }: ShowcasePlansProps) => import("@emotion/react/jsx-runtime").JSX.Element;
15
17
  export default ShowcasePlans;
@@ -17,4 +17,4 @@ export type SwitcherProps = {
17
17
  compact?: boolean;
18
18
  workspaceLogo?: React.ReactNode;
19
19
  };
20
- export declare function Switcher({ items, title, headerItems, footerItems, width, name, maxVisibleItems, addPlanWord, isLoading, plan, onDropdownStateChange, compact, workspaceLogo, }: SwitcherProps): import("@emotion/react/jsx-runtime").JSX.Element;
20
+ export declare function Switcher({ items, title, footerItems, width, name, addPlanWord, isLoading, plan, onDropdownStateChange, compact, workspaceLogo, }: SwitcherProps): import("@emotion/react/jsx-runtime").JSX.Element;
@@ -3,6 +3,6 @@ export type Props = {
3
3
  history: any;
4
4
  router: any;
5
5
  };
6
- export declare const NewSubscription: ({ router, }: Props) => import("@emotion/react/jsx-runtime").JSX.Element;
6
+ export declare const NewSubscription: ({ router }: Props) => import("@emotion/react/jsx-runtime").JSX.Element;
7
7
  declare const _default: any;
8
8
  export default _default;
@@ -0,0 +1,16 @@
1
+ import { PlanType } from '../../../graphql.billing.autogenerated';
2
+ /**
3
+ * Marker written right before redirecting to a hosted checkout (Polar/Stripe) from the
4
+ * new-workspace onboarding flow. Because the backend always returns hosted checkouts to
5
+ * `/billing/done`, the done page reads this per-tab marker to tell a new-workspace checkout
6
+ * apart from a normal upgrade, then routes the user back into the workspace stepper flow.
7
+ * It also remembers the plan so the failed screen can retry the same checkout.
8
+ */
9
+ export declare const NEW_WORKSPACE_PENDING_CHECKOUT_KEY = "bc_new_workspace_pending_checkout";
10
+ export type PendingCheckout = {
11
+ workspaceId: number;
12
+ planType: PlanType;
13
+ };
14
+ export declare function storePendingCheckout(value: PendingCheckout): void;
15
+ export declare function readPendingCheckout(): PendingCheckout | null;
16
+ export declare function clearPendingCheckout(): void;