poc - cal.com integration in onboarding flow (#12530)
This commit is contained in:
@ -7,6 +7,7 @@
|
||||
"@aws-sdk/client-s3": "^3.700.0",
|
||||
"@aws-sdk/client-sts": "^3.700.0",
|
||||
"@aws-sdk/credential-providers": "^3.700.0",
|
||||
"@calcom/embed-react": "^1.5.3",
|
||||
"@codesandbox/sandpack-react": "^2.13.5",
|
||||
"@dagrejs/dagre": "^1.1.2",
|
||||
"@emotion/react": "^11.11.1",
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 627 KiB |
@ -318,6 +318,7 @@ export type ClientConfig = {
|
||||
api: ApiConfig;
|
||||
authProviders: AuthProviders;
|
||||
billing: Billing;
|
||||
calendarBookingPageId?: Maybe<Scalars['String']>;
|
||||
canManageFeatureFlags: Scalars['Boolean'];
|
||||
captcha: Captcha;
|
||||
chromeExtensionId?: Maybe<Scalars['String']>;
|
||||
@ -948,6 +949,7 @@ export type Mutation = {
|
||||
signUp: AvailableWorkspacesAndAccessTokensOutput;
|
||||
signUpInNewWorkspace: SignUpOutput;
|
||||
signUpInWorkspace: SignUpOutput;
|
||||
skipBookOnboardingStep: OnboardingStepSuccess;
|
||||
skipSyncEmailOnboardingStep: OnboardingStepSuccess;
|
||||
submitFormStep: Scalars['Boolean'];
|
||||
switchToEnterprisePlan: BillingUpdateOutput;
|
||||
@ -1477,6 +1479,7 @@ export type OnDbEventInput = {
|
||||
|
||||
/** Onboarding status */
|
||||
export enum OnboardingStatus {
|
||||
BOOK_ONBOARDING = 'BOOK_ONBOARDING',
|
||||
COMPLETED = 'COMPLETED',
|
||||
INVITE_TEAM = 'INVITE_TEAM',
|
||||
PLAN_REQUIRED = 'PLAN_REQUIRED',
|
||||
@ -2747,7 +2750,7 @@ export type GetMeteredProductsUsageQuery = { __typename?: 'Query', getMeteredPro
|
||||
export type GetClientConfigQueryVariables = Exact<{ [key: string]: never; }>;
|
||||
|
||||
|
||||
export type GetClientConfigQuery = { __typename?: 'Query', clientConfig: { __typename?: 'ClientConfig', signInPrefilled: boolean, isMultiWorkspaceEnabled: boolean, isEmailVerificationRequired: boolean, defaultSubdomain?: string | null, frontDomain: string, debugMode: boolean, analyticsEnabled: boolean, isAttachmentPreviewEnabled: boolean, chromeExtensionId?: string | null, canManageFeatureFlags: boolean, isMicrosoftMessagingEnabled: boolean, isMicrosoftCalendarEnabled: boolean, isGoogleMessagingEnabled: boolean, isGoogleCalendarEnabled: boolean, isConfigVariablesInDbEnabled: boolean, billing: { __typename?: 'Billing', isBillingEnabled: boolean, billingUrl?: string | null, trialPeriods: Array<{ __typename?: 'BillingTrialPeriodDTO', duration: number, isCreditCardRequired: boolean }> }, authProviders: { __typename?: 'AuthProviders', google: boolean, password: boolean, microsoft: boolean, sso: Array<{ __typename?: 'SSOIdentityProvider', id: string, name: string, type: IdentityProviderType, status: SsoIdentityProviderStatus, issuer: string }> }, support: { __typename?: 'Support', supportDriver: SupportDriver, supportFrontChatId?: string | null }, sentry: { __typename?: 'Sentry', dsn?: string | null, environment?: string | null, release?: string | null }, captcha: { __typename?: 'Captcha', provider?: CaptchaDriverType | null, siteKey?: string | null }, api: { __typename?: 'ApiConfig', mutationMaximumAffectedRecords: number }, publicFeatureFlags: Array<{ __typename?: 'PublicFeatureFlag', key: FeatureFlagKey, metadata: { __typename?: 'PublicFeatureFlagMetadata', label: string, description: string, imagePath: string } }> } };
|
||||
export type GetClientConfigQuery = { __typename?: 'Query', clientConfig: { __typename?: 'ClientConfig', signInPrefilled: boolean, isMultiWorkspaceEnabled: boolean, isEmailVerificationRequired: boolean, defaultSubdomain?: string | null, frontDomain: string, debugMode: boolean, analyticsEnabled: boolean, isAttachmentPreviewEnabled: boolean, chromeExtensionId?: string | null, canManageFeatureFlags: boolean, isMicrosoftMessagingEnabled: boolean, isMicrosoftCalendarEnabled: boolean, isGoogleMessagingEnabled: boolean, isGoogleCalendarEnabled: boolean, isConfigVariablesInDbEnabled: boolean, calendarBookingPageId?: string | null, billing: { __typename?: 'Billing', isBillingEnabled: boolean, billingUrl?: string | null, trialPeriods: Array<{ __typename?: 'BillingTrialPeriodDTO', duration: number, isCreditCardRequired: boolean }> }, authProviders: { __typename?: 'AuthProviders', google: boolean, password: boolean, microsoft: boolean, sso: Array<{ __typename?: 'SSOIdentityProvider', id: string, name: string, type: IdentityProviderType, status: SsoIdentityProviderStatus, issuer: string }> }, support: { __typename?: 'Support', supportDriver: SupportDriver, supportFrontChatId?: string | null }, sentry: { __typename?: 'Sentry', dsn?: string | null, environment?: string | null, release?: string | null }, captcha: { __typename?: 'Captcha', provider?: CaptchaDriverType | null, siteKey?: string | null }, api: { __typename?: 'ApiConfig', mutationMaximumAffectedRecords: number }, publicFeatureFlags: Array<{ __typename?: 'PublicFeatureFlag', key: FeatureFlagKey, metadata: { __typename?: 'PublicFeatureFlagMetadata', label: string, description: string, imagePath: string } }> } };
|
||||
|
||||
export type SearchQueryVariables = Exact<{
|
||||
searchInput: Scalars['String'];
|
||||
@ -2761,6 +2764,11 @@ export type SearchQueryVariables = Exact<{
|
||||
|
||||
export type SearchQuery = { __typename?: 'Query', search: { __typename?: 'SearchResultConnection', edges: Array<{ __typename?: 'SearchResultEdge', cursor: string, node: { __typename?: 'SearchRecord', recordId: string, objectNameSingular: string, label: string, imageUrl?: string | null, tsRankCD: number, tsRank: number } }>, pageInfo: { __typename?: 'SearchResultPageInfo', hasNextPage: boolean, endCursor?: string | null } } };
|
||||
|
||||
export type SkipBookOnboardingStepMutationVariables = Exact<{ [key: string]: never; }>;
|
||||
|
||||
|
||||
export type SkipBookOnboardingStepMutation = { __typename?: 'Mutation', skipBookOnboardingStep: { __typename?: 'OnboardingStepSuccess', success: boolean } };
|
||||
|
||||
export type SkipSyncEmailOnboardingStepMutationVariables = Exact<{ [key: string]: never; }>;
|
||||
|
||||
|
||||
@ -4758,6 +4766,7 @@ export const GetClientConfigDocument = gql`
|
||||
isGoogleMessagingEnabled
|
||||
isGoogleCalendarEnabled
|
||||
isConfigVariablesInDbEnabled
|
||||
calendarBookingPageId
|
||||
}
|
||||
}
|
||||
`;
|
||||
@ -4849,6 +4858,38 @@ export function useSearchLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<Sea
|
||||
export type SearchQueryHookResult = ReturnType<typeof useSearchQuery>;
|
||||
export type SearchLazyQueryHookResult = ReturnType<typeof useSearchLazyQuery>;
|
||||
export type SearchQueryResult = Apollo.QueryResult<SearchQuery, SearchQueryVariables>;
|
||||
export const SkipBookOnboardingStepDocument = gql`
|
||||
mutation SkipBookOnboardingStep {
|
||||
skipBookOnboardingStep {
|
||||
success
|
||||
}
|
||||
}
|
||||
`;
|
||||
export type SkipBookOnboardingStepMutationFn = Apollo.MutationFunction<SkipBookOnboardingStepMutation, SkipBookOnboardingStepMutationVariables>;
|
||||
|
||||
/**
|
||||
* __useSkipBookOnboardingStepMutation__
|
||||
*
|
||||
* To run a mutation, you first call `useSkipBookOnboardingStepMutation` within a React component and pass it any options that fit your needs.
|
||||
* When your component renders, `useSkipBookOnboardingStepMutation` returns a tuple that includes:
|
||||
* - A mutate function that you can call at any time to execute the mutation
|
||||
* - An object with fields that represent the current status of the mutation's execution
|
||||
*
|
||||
* @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2;
|
||||
*
|
||||
* @example
|
||||
* const [skipBookOnboardingStepMutation, { data, loading, error }] = useSkipBookOnboardingStepMutation({
|
||||
* variables: {
|
||||
* },
|
||||
* });
|
||||
*/
|
||||
export function useSkipBookOnboardingStepMutation(baseOptions?: Apollo.MutationHookOptions<SkipBookOnboardingStepMutation, SkipBookOnboardingStepMutationVariables>) {
|
||||
const options = {...defaultOptions, ...baseOptions}
|
||||
return Apollo.useMutation<SkipBookOnboardingStepMutation, SkipBookOnboardingStepMutationVariables>(SkipBookOnboardingStepDocument, options);
|
||||
}
|
||||
export type SkipBookOnboardingStepMutationHookResult = ReturnType<typeof useSkipBookOnboardingStepMutation>;
|
||||
export type SkipBookOnboardingStepMutationResult = Apollo.MutationResult<SkipBookOnboardingStepMutation>;
|
||||
export type SkipBookOnboardingStepMutationOptions = Apollo.BaseMutationOptions<SkipBookOnboardingStepMutation, SkipBookOnboardingStepMutationVariables>;
|
||||
export const SkipSyncEmailOnboardingStepDocument = gql`
|
||||
mutation SkipSyncEmailOnboardingStep {
|
||||
skipSyncEmailOnboardingStep {
|
||||
|
||||
@ -9,10 +9,10 @@ import { useRecoilValue } from 'recoil';
|
||||
|
||||
import { OnboardingStatus } from '~/generated/graphql';
|
||||
|
||||
import { useIsCurrentLocationOnAWorkspace } from '@/domain-manager/hooks/useIsCurrentLocationOnAWorkspace';
|
||||
import { usePageChangeEffectNavigateLocation } from '~/hooks/usePageChangeEffectNavigateLocation';
|
||||
import { UNTESTED_APP_PATHS } from '~/testing/constants/UntestedAppPaths';
|
||||
import { isMatchingLocation } from '~/utils/isMatchingLocation';
|
||||
import { useIsCurrentLocationOnAWorkspace } from '@/domain-manager/hooks/useIsCurrentLocationOnAWorkspace';
|
||||
|
||||
jest.mock('@/onboarding/hooks/useOnboardingStatus');
|
||||
const setupMockOnboardingStatus = (
|
||||
@ -92,6 +92,7 @@ const testCases: {
|
||||
{ loc: AppPath.Verify, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PROFILE_CREATION, res: AppPath.CreateProfile },
|
||||
{ loc: AppPath.Verify, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.SYNC_EMAIL, res: AppPath.SyncEmails },
|
||||
{ loc: AppPath.Verify, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.INVITE_TEAM, res: AppPath.InviteTeam },
|
||||
{ loc: AppPath.Verify, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.BOOK_ONBOARDING, res: AppPath.BookCallDecision },
|
||||
{ loc: AppPath.Verify, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, res: defaultHomePagePath },
|
||||
|
||||
{ loc: AppPath.SignInUp, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PLAN_REQUIRED, res: AppPath.PlanRequired },
|
||||
@ -101,6 +102,7 @@ const testCases: {
|
||||
{ loc: AppPath.SignInUp, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PROFILE_CREATION, res: AppPath.CreateProfile },
|
||||
{ loc: AppPath.SignInUp, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.SYNC_EMAIL, res: AppPath.SyncEmails },
|
||||
{ loc: AppPath.SignInUp, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.INVITE_TEAM, res: AppPath.InviteTeam },
|
||||
{ loc: AppPath.SignInUp, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.BOOK_ONBOARDING, res: AppPath.BookCallDecision },
|
||||
{ loc: AppPath.SignInUp, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, res: defaultHomePagePath },
|
||||
|
||||
{ loc: AppPath.Invite, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PLAN_REQUIRED, res: '/plan-required' },
|
||||
@ -110,6 +112,7 @@ const testCases: {
|
||||
{ loc: AppPath.Invite, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PROFILE_CREATION, res: '/create/profile' },
|
||||
{ loc: AppPath.Invite, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.SYNC_EMAIL, res: '/sync/emails' },
|
||||
{ loc: AppPath.Invite, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.INVITE_TEAM, res: '/invite-team' },
|
||||
{ loc: AppPath.Invite, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.BOOK_ONBOARDING, res: AppPath.BookCallDecision },
|
||||
{ loc: AppPath.Invite, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, res: defaultHomePagePath },
|
||||
|
||||
{ loc: AppPath.ResetPassword, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PLAN_REQUIRED, res: '/plan-required' },
|
||||
@ -119,6 +122,7 @@ const testCases: {
|
||||
{ loc: AppPath.ResetPassword, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PROFILE_CREATION, res: '/create/profile' },
|
||||
{ loc: AppPath.ResetPassword, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.SYNC_EMAIL, res: '/sync/emails' },
|
||||
{ loc: AppPath.ResetPassword, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.INVITE_TEAM, res: '/invite-team' },
|
||||
{ loc: AppPath.ResetPassword, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.BOOK_ONBOARDING, res: AppPath.BookCallDecision },
|
||||
{ loc: AppPath.ResetPassword, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, res: undefined },
|
||||
|
||||
{ loc: AppPath.VerifyEmail, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PLAN_REQUIRED, res: AppPath.PlanRequired },
|
||||
@ -130,6 +134,7 @@ const testCases: {
|
||||
{ loc: AppPath.VerifyEmail, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PROFILE_CREATION, res: AppPath.CreateProfile },
|
||||
{ loc: AppPath.VerifyEmail, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.SYNC_EMAIL, res: AppPath.SyncEmails },
|
||||
{ loc: AppPath.VerifyEmail, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.INVITE_TEAM, res: AppPath.InviteTeam },
|
||||
{ loc: AppPath.VerifyEmail, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.BOOK_ONBOARDING, res: AppPath.BookCallDecision },
|
||||
{ loc: AppPath.VerifyEmail, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, res: defaultHomePagePath },
|
||||
|
||||
{ loc: AppPath.CreateWorkspace, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PLAN_REQUIRED, res: AppPath.PlanRequired },
|
||||
@ -139,6 +144,7 @@ const testCases: {
|
||||
{ loc: AppPath.CreateWorkspace, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PROFILE_CREATION, res: AppPath.CreateProfile },
|
||||
{ loc: AppPath.CreateWorkspace, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.SYNC_EMAIL, res: AppPath.SyncEmails },
|
||||
{ loc: AppPath.CreateWorkspace, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.INVITE_TEAM, res: AppPath.InviteTeam },
|
||||
{ loc: AppPath.CreateWorkspace, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.BOOK_ONBOARDING, res: AppPath.BookCallDecision },
|
||||
{ loc: AppPath.CreateWorkspace, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, res: defaultHomePagePath },
|
||||
|
||||
{ loc: AppPath.CreateProfile, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PLAN_REQUIRED, res: AppPath.PlanRequired },
|
||||
@ -148,6 +154,7 @@ const testCases: {
|
||||
{ loc: AppPath.CreateProfile, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PROFILE_CREATION, res: undefined },
|
||||
{ loc: AppPath.CreateProfile, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.SYNC_EMAIL, res: AppPath.SyncEmails },
|
||||
{ loc: AppPath.CreateProfile, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.INVITE_TEAM, res: AppPath.InviteTeam },
|
||||
{ loc: AppPath.CreateProfile, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.BOOK_ONBOARDING, res: AppPath.BookCallDecision },
|
||||
{ loc: AppPath.CreateProfile, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, res: defaultHomePagePath },
|
||||
|
||||
{ loc: AppPath.SyncEmails, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PLAN_REQUIRED, res: AppPath.PlanRequired },
|
||||
@ -157,6 +164,7 @@ const testCases: {
|
||||
{ loc: AppPath.SyncEmails, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PROFILE_CREATION, res: AppPath.CreateProfile },
|
||||
{ loc: AppPath.SyncEmails, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.SYNC_EMAIL, res: undefined },
|
||||
{ loc: AppPath.SyncEmails, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.INVITE_TEAM, res: AppPath.InviteTeam },
|
||||
{ loc: AppPath.SyncEmails, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.BOOK_ONBOARDING, res: AppPath.BookCallDecision },
|
||||
{ loc: AppPath.SyncEmails, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, res: defaultHomePagePath },
|
||||
|
||||
{ loc: AppPath.InviteTeam, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PLAN_REQUIRED, res: AppPath.PlanRequired },
|
||||
@ -166,8 +174,29 @@ const testCases: {
|
||||
{ loc: AppPath.InviteTeam, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PROFILE_CREATION, res: AppPath.CreateProfile },
|
||||
{ loc: AppPath.InviteTeam, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.SYNC_EMAIL, res: AppPath.SyncEmails },
|
||||
{ loc: AppPath.InviteTeam, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.INVITE_TEAM, res: undefined },
|
||||
{ loc: AppPath.InviteTeam, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.BOOK_ONBOARDING, res: AppPath.BookCallDecision },
|
||||
{ loc: AppPath.InviteTeam, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, res: defaultHomePagePath },
|
||||
|
||||
{ loc: AppPath.BookCallDecision, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PLAN_REQUIRED, res: undefined },
|
||||
{ loc: AppPath.BookCallDecision, isLoggedIn: true, isWorkspaceSuspended: true, onboardingStatus: OnboardingStatus.COMPLETED, res: '/settings/billing' },
|
||||
{ loc: AppPath.BookCallDecision, isLoggedIn: false, isWorkspaceSuspended: false, onboardingStatus: undefined, res: AppPath.SignInUp },
|
||||
{ loc: AppPath.BookCallDecision, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.WORKSPACE_ACTIVATION, res: undefined },
|
||||
{ loc: AppPath.BookCallDecision, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PROFILE_CREATION, res: AppPath.CreateProfile },
|
||||
{ loc: AppPath.BookCallDecision, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.SYNC_EMAIL, res: AppPath.SyncEmails },
|
||||
{ loc: AppPath.BookCallDecision, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.INVITE_TEAM, res: AppPath.InviteTeam },
|
||||
{ loc: AppPath.BookCallDecision, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.BOOK_ONBOARDING, res: undefined },
|
||||
{ loc: AppPath.BookCallDecision, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, res: defaultHomePagePath },
|
||||
|
||||
{ loc: AppPath.BookCall, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PLAN_REQUIRED, res: undefined },
|
||||
{ loc: AppPath.BookCall, isLoggedIn: true, isWorkspaceSuspended: true, onboardingStatus: OnboardingStatus.COMPLETED, res: '/settings/billing' },
|
||||
{ loc: AppPath.BookCall, isLoggedIn: false, isWorkspaceSuspended: false, onboardingStatus: undefined, res: AppPath.SignInUp },
|
||||
{ loc: AppPath.BookCall, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.WORKSPACE_ACTIVATION, res: undefined },
|
||||
{ loc: AppPath.BookCall, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PROFILE_CREATION, res: AppPath.CreateProfile },
|
||||
{ loc: AppPath.BookCall, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.SYNC_EMAIL, res: AppPath.SyncEmails },
|
||||
{ loc: AppPath.BookCall, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.INVITE_TEAM, res: AppPath.InviteTeam },
|
||||
{ loc: AppPath.BookCall, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.BOOK_ONBOARDING, res: undefined },
|
||||
{ loc: AppPath.BookCall, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, res: defaultHomePagePath },
|
||||
|
||||
{ loc: AppPath.PlanRequired, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PLAN_REQUIRED, res: undefined },
|
||||
{ loc: AppPath.PlanRequired, isLoggedIn: true, isWorkspaceSuspended: true, onboardingStatus: OnboardingStatus.COMPLETED, res: '/settings/billing' },
|
||||
{ loc: AppPath.PlanRequired, isLoggedIn: false, isWorkspaceSuspended: false, onboardingStatus: undefined, res: AppPath.SignInUp },
|
||||
@ -175,6 +204,7 @@ const testCases: {
|
||||
{ loc: AppPath.PlanRequired, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PROFILE_CREATION, res: AppPath.CreateProfile },
|
||||
{ loc: AppPath.PlanRequired, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.SYNC_EMAIL, res: AppPath.SyncEmails },
|
||||
{ loc: AppPath.PlanRequired, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.INVITE_TEAM, res: AppPath.InviteTeam },
|
||||
{ loc: AppPath.PlanRequired, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.BOOK_ONBOARDING, res: AppPath.BookCallDecision },
|
||||
{ loc: AppPath.PlanRequired, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, res: defaultHomePagePath },
|
||||
|
||||
{ loc: AppPath.PlanRequiredSuccess, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PLAN_REQUIRED, res: undefined },
|
||||
@ -184,6 +214,7 @@ const testCases: {
|
||||
{ loc: AppPath.PlanRequiredSuccess, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PROFILE_CREATION, res: AppPath.CreateProfile },
|
||||
{ loc: AppPath.PlanRequiredSuccess, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.SYNC_EMAIL, res: AppPath.SyncEmails },
|
||||
{ loc: AppPath.PlanRequiredSuccess, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.INVITE_TEAM, res: AppPath.InviteTeam },
|
||||
{ loc: AppPath.PlanRequiredSuccess, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.BOOK_ONBOARDING, res: AppPath.BookCallDecision },
|
||||
{ loc: AppPath.PlanRequiredSuccess, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, res: defaultHomePagePath },
|
||||
|
||||
{ loc: AppPath.Index, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PLAN_REQUIRED, res: AppPath.PlanRequired },
|
||||
@ -193,6 +224,7 @@ const testCases: {
|
||||
{ loc: AppPath.Index, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PROFILE_CREATION, res: AppPath.CreateProfile },
|
||||
{ loc: AppPath.Index, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.SYNC_EMAIL, res: AppPath.SyncEmails },
|
||||
{ loc: AppPath.Index, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.INVITE_TEAM, res: AppPath.InviteTeam },
|
||||
{ loc: AppPath.Index, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.BOOK_ONBOARDING, res: AppPath.BookCallDecision },
|
||||
{ loc: AppPath.Index, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, res: defaultHomePagePath },
|
||||
|
||||
{ loc: AppPath.TasksPage, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PLAN_REQUIRED, res: AppPath.PlanRequired },
|
||||
@ -202,6 +234,7 @@ const testCases: {
|
||||
{ loc: AppPath.TasksPage, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PROFILE_CREATION, res: AppPath.CreateProfile },
|
||||
{ loc: AppPath.TasksPage, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.SYNC_EMAIL, res: AppPath.SyncEmails },
|
||||
{ loc: AppPath.TasksPage, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.INVITE_TEAM, res: AppPath.InviteTeam },
|
||||
{ loc: AppPath.TasksPage, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.BOOK_ONBOARDING, res: AppPath.BookCallDecision },
|
||||
{ loc: AppPath.TasksPage, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, res: undefined },
|
||||
|
||||
{ loc: AppPath.OpportunitiesPage, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PLAN_REQUIRED, res: AppPath.PlanRequired },
|
||||
@ -211,6 +244,7 @@ const testCases: {
|
||||
{ loc: AppPath.OpportunitiesPage, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PROFILE_CREATION, res: AppPath.CreateProfile },
|
||||
{ loc: AppPath.OpportunitiesPage, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.SYNC_EMAIL, res: AppPath.SyncEmails },
|
||||
{ loc: AppPath.OpportunitiesPage, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.INVITE_TEAM, res: AppPath.InviteTeam },
|
||||
{ loc: AppPath.OpportunitiesPage, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.BOOK_ONBOARDING, res: AppPath.BookCallDecision },
|
||||
{ loc: AppPath.OpportunitiesPage, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, res: undefined },
|
||||
|
||||
{ loc: AppPath.RecordIndexPage, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PLAN_REQUIRED, res: AppPath.PlanRequired },
|
||||
@ -220,6 +254,7 @@ const testCases: {
|
||||
{ loc: AppPath.RecordIndexPage, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PROFILE_CREATION, res: AppPath.CreateProfile },
|
||||
{ loc: AppPath.RecordIndexPage, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.SYNC_EMAIL, res: AppPath.SyncEmails },
|
||||
{ loc: AppPath.RecordIndexPage, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.INVITE_TEAM, res: AppPath.InviteTeam },
|
||||
{ loc: AppPath.RecordIndexPage, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.BOOK_ONBOARDING, res: AppPath.BookCallDecision },
|
||||
{ loc: AppPath.RecordIndexPage, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, res: undefined },
|
||||
{ loc: AppPath.RecordIndexPage, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, res: undefined, objectNamePluralFromParams: 'existing-object', objectNamePluralFromMetadata: 'existing-object' },
|
||||
{ loc: AppPath.RecordIndexPage, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, res: AppPath.NotFound, objectNamePluralFromParams: 'non-existing-object', objectNamePluralFromMetadata: 'existing-object' },
|
||||
@ -231,6 +266,7 @@ const testCases: {
|
||||
{ loc: AppPath.RecordShowPage, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PROFILE_CREATION, res: AppPath.CreateProfile },
|
||||
{ loc: AppPath.RecordShowPage, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.SYNC_EMAIL, res: AppPath.SyncEmails },
|
||||
{ loc: AppPath.RecordShowPage, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.INVITE_TEAM, res: AppPath.InviteTeam },
|
||||
{ loc: AppPath.RecordShowPage, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.BOOK_ONBOARDING, res: AppPath.BookCallDecision },
|
||||
{ loc: AppPath.RecordShowPage, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, res: undefined },
|
||||
|
||||
{ loc: AppPath.SettingsCatchAll, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PLAN_REQUIRED, res: AppPath.PlanRequired },
|
||||
@ -240,6 +276,7 @@ const testCases: {
|
||||
{ loc: AppPath.SettingsCatchAll, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PROFILE_CREATION, res: AppPath.CreateProfile },
|
||||
{ loc: AppPath.SettingsCatchAll, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.SYNC_EMAIL, res: AppPath.SyncEmails },
|
||||
{ loc: AppPath.SettingsCatchAll, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.INVITE_TEAM, res: AppPath.InviteTeam },
|
||||
{ loc: AppPath.SettingsCatchAll, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.BOOK_ONBOARDING, res: AppPath.BookCallDecision },
|
||||
{ loc: AppPath.SettingsCatchAll, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, res: undefined },
|
||||
|
||||
{ loc: AppPath.DevelopersCatchAll, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PLAN_REQUIRED, res: AppPath.PlanRequired },
|
||||
@ -249,6 +286,7 @@ const testCases: {
|
||||
{ loc: AppPath.DevelopersCatchAll, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PROFILE_CREATION, res: AppPath.CreateProfile },
|
||||
{ loc: AppPath.DevelopersCatchAll, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.SYNC_EMAIL, res: AppPath.SyncEmails },
|
||||
{ loc: AppPath.DevelopersCatchAll, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.INVITE_TEAM, res: AppPath.InviteTeam },
|
||||
{ loc: AppPath.DevelopersCatchAll, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.BOOK_ONBOARDING, res: AppPath.BookCallDecision },
|
||||
{ loc: AppPath.DevelopersCatchAll, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, res: undefined },
|
||||
|
||||
{ loc: AppPath.Authorize, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PLAN_REQUIRED, res: AppPath.PlanRequired },
|
||||
@ -258,6 +296,7 @@ const testCases: {
|
||||
{ loc: AppPath.Authorize, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PROFILE_CREATION, res: AppPath.CreateProfile },
|
||||
{ loc: AppPath.Authorize, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.SYNC_EMAIL, res: AppPath.SyncEmails },
|
||||
{ loc: AppPath.Authorize, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.INVITE_TEAM, res: AppPath.InviteTeam },
|
||||
{ loc: AppPath.Authorize, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.BOOK_ONBOARDING, res: AppPath.BookCallDecision },
|
||||
{ loc: AppPath.Authorize, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, res: undefined },
|
||||
|
||||
{ loc: AppPath.NotFoundWildcard, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PLAN_REQUIRED, res: AppPath.PlanRequired },
|
||||
@ -267,6 +306,7 @@ const testCases: {
|
||||
{ loc: AppPath.NotFoundWildcard, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PROFILE_CREATION, res: AppPath.CreateProfile },
|
||||
{ loc: AppPath.NotFoundWildcard, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.SYNC_EMAIL, res: AppPath.SyncEmails },
|
||||
{ loc: AppPath.NotFoundWildcard, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.INVITE_TEAM, res: AppPath.InviteTeam },
|
||||
{ loc: AppPath.NotFoundWildcard, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.BOOK_ONBOARDING, res: AppPath.BookCallDecision },
|
||||
{ loc: AppPath.NotFoundWildcard, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, res: undefined },
|
||||
|
||||
{ loc: AppPath.NotFound, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PLAN_REQUIRED, res: AppPath.PlanRequired },
|
||||
@ -276,6 +316,7 @@ const testCases: {
|
||||
{ loc: AppPath.NotFound, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PROFILE_CREATION, res: AppPath.CreateProfile },
|
||||
{ loc: AppPath.NotFound, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.SYNC_EMAIL, res: AppPath.SyncEmails },
|
||||
{ loc: AppPath.NotFound, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.INVITE_TEAM, res: AppPath.InviteTeam },
|
||||
{ loc: AppPath.NotFound, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.BOOK_ONBOARDING, res: AppPath.BookCallDecision },
|
||||
{ loc: AppPath.NotFound, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, res: undefined },
|
||||
];
|
||||
|
||||
|
||||
@ -39,6 +39,8 @@ export const usePageChangeEffectNavigateLocation = () => {
|
||||
AppPath.InviteTeam,
|
||||
AppPath.PlanRequired,
|
||||
AppPath.PlanRequiredSuccess,
|
||||
AppPath.BookCallDecision,
|
||||
AppPath.BookCall,
|
||||
];
|
||||
|
||||
const objectNamePlural = useParams().objectNamePlural ?? '';
|
||||
@ -60,7 +62,12 @@ export const usePageChangeEffectNavigateLocation = () => {
|
||||
|
||||
if (
|
||||
onboardingStatus === OnboardingStatus.PLAN_REQUIRED &&
|
||||
!someMatchingLocationOf([AppPath.PlanRequired, AppPath.PlanRequiredSuccess])
|
||||
!someMatchingLocationOf([
|
||||
AppPath.PlanRequired,
|
||||
AppPath.PlanRequiredSuccess,
|
||||
AppPath.BookCall,
|
||||
AppPath.BookCallDecision,
|
||||
])
|
||||
) {
|
||||
if (
|
||||
isMatchingLocation(location, AppPath.VerifyEmail) &&
|
||||
@ -86,6 +93,8 @@ export const usePageChangeEffectNavigateLocation = () => {
|
||||
!someMatchingLocationOf([
|
||||
AppPath.CreateWorkspace,
|
||||
AppPath.PlanRequiredSuccess,
|
||||
AppPath.BookCallDecision,
|
||||
AppPath.BookCall,
|
||||
])
|
||||
) {
|
||||
return AppPath.CreateWorkspace;
|
||||
@ -112,6 +121,13 @@ export const usePageChangeEffectNavigateLocation = () => {
|
||||
return AppPath.InviteTeam;
|
||||
}
|
||||
|
||||
if (
|
||||
onboardingStatus === OnboardingStatus.BOOK_ONBOARDING &&
|
||||
!someMatchingLocationOf([AppPath.BookCallDecision, AppPath.BookCall])
|
||||
) {
|
||||
return AppPath.BookCallDecision;
|
||||
}
|
||||
|
||||
if (
|
||||
onboardingStatus === OnboardingStatus.COMPLETED &&
|
||||
someMatchingLocationOf([...onboardingPaths, ...onGoingUserCreationPaths]) &&
|
||||
|
||||
@ -19,6 +19,8 @@ import { SignInUp } from '~/pages/auth/SignInUp';
|
||||
import { NotFound } from '~/pages/not-found/NotFound';
|
||||
import { RecordIndexPage } from '~/pages/object-record/RecordIndexPage';
|
||||
import { RecordShowPage } from '~/pages/object-record/RecordShowPage';
|
||||
import { BookCall } from '~/pages/onboarding/BookCall';
|
||||
import { BookCallDecision } from '~/pages/onboarding/BookCallDecision';
|
||||
import { ChooseYourPlan } from '~/pages/onboarding/ChooseYourPlan';
|
||||
import { CreateProfile } from '~/pages/onboarding/CreateProfile';
|
||||
import { CreateWorkspace } from '~/pages/onboarding/CreateWorkspace';
|
||||
@ -53,6 +55,11 @@ export const useCreateAppRouter = (
|
||||
path={AppPath.PlanRequiredSuccess}
|
||||
element={<PaymentSuccess />}
|
||||
/>
|
||||
<Route
|
||||
path={AppPath.BookCallDecision}
|
||||
element={<BookCallDecision />}
|
||||
/>
|
||||
<Route path={AppPath.BookCall} element={<BookCall />} />
|
||||
<Route path={indexAppPath.getIndexAppPath()} element={<></>} />
|
||||
<Route path={AppPath.RecordIndexPage} element={<RecordIndexPage />} />
|
||||
<Route path={AppPath.RecordShowPage} element={<RecordShowPage />} />
|
||||
|
||||
@ -1,9 +1,11 @@
|
||||
import { AuthModalMountEffect } from '@/auth/components/AuthModalMountEffect';
|
||||
import { AUTH_MODAL_ID } from '@/auth/constants/AuthModalId';
|
||||
import { getAuthModalConfig } from '@/auth/utils/getAuthModalConfig';
|
||||
import { Modal } from '@/ui/layout/modal/components/Modal';
|
||||
import { ScrollWrapper } from '@/ui/utilities/scroll/components/ScrollWrapper';
|
||||
import styled from '@emotion/styled';
|
||||
import React from 'react';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
|
||||
const StyledContent = styled.div`
|
||||
align-items: center;
|
||||
@ -14,13 +16,27 @@ type AuthModalProps = {
|
||||
children: React.ReactNode;
|
||||
};
|
||||
|
||||
export const AuthModal = ({ children }: AuthModalProps) => (
|
||||
<>
|
||||
<AuthModalMountEffect />
|
||||
<Modal modalId={AUTH_MODAL_ID} padding={'none'} modalVariant="primary">
|
||||
<ScrollWrapper componentInstanceId="scroll-wrapper-modal-content">
|
||||
<StyledContent>{children}</StyledContent>
|
||||
</ScrollWrapper>
|
||||
</Modal>
|
||||
</>
|
||||
);
|
||||
export const AuthModal = ({ children }: AuthModalProps) => {
|
||||
const location = useLocation();
|
||||
const config = getAuthModalConfig(location);
|
||||
|
||||
return (
|
||||
<>
|
||||
<AuthModalMountEffect />
|
||||
<Modal
|
||||
modalId={AUTH_MODAL_ID}
|
||||
padding={'none'}
|
||||
size={config.size}
|
||||
modalVariant={config.variant}
|
||||
>
|
||||
{config.showScrollWrapper ? (
|
||||
<ScrollWrapper componentInstanceId="scroll-wrapper-modal-content">
|
||||
<StyledContent>{children}</StyledContent>
|
||||
</ScrollWrapper>
|
||||
) : (
|
||||
<>{children}</>
|
||||
)}
|
||||
</Modal>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@ -0,0 +1,24 @@
|
||||
import { AppPath } from '@/types/AppPath';
|
||||
import { ModalSize, ModalVariants } from '@/ui/layout/modal/components/Modal';
|
||||
|
||||
type AuthModalConfigType = {
|
||||
size: ModalSize;
|
||||
variant: ModalVariants;
|
||||
showScrollWrapper: boolean;
|
||||
};
|
||||
|
||||
export const AUTH_MODAL_CONFIG: {
|
||||
default: AuthModalConfigType;
|
||||
[key: string]: AuthModalConfigType;
|
||||
} = {
|
||||
default: {
|
||||
size: 'medium',
|
||||
variant: 'primary',
|
||||
showScrollWrapper: true,
|
||||
},
|
||||
[AppPath.BookCall]: {
|
||||
size: 'extraLarge',
|
||||
variant: 'transparent',
|
||||
showScrollWrapper: false,
|
||||
},
|
||||
};
|
||||
@ -0,0 +1,18 @@
|
||||
import { AUTH_MODAL_CONFIG } from '@/auth/constants/AuthModalConfig';
|
||||
import { AppPath } from '@/types/AppPath';
|
||||
import { Location } from 'react-router-dom';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { isMatchingLocation } from '~/utils/isMatchingLocation';
|
||||
|
||||
export const getAuthModalConfig = (location: Location) => {
|
||||
for (const path of Object.values(AppPath)) {
|
||||
if (
|
||||
isMatchingLocation(location, path) &&
|
||||
isDefined(AUTH_MODAL_CONFIG[path])
|
||||
) {
|
||||
return AUTH_MODAL_CONFIG[path];
|
||||
}
|
||||
}
|
||||
|
||||
return AUTH_MODAL_CONFIG.default;
|
||||
};
|
||||
@ -2,6 +2,7 @@ import { useClientConfig } from '@/client-config/hooks/useClientConfig';
|
||||
import { apiConfigState } from '@/client-config/states/apiConfigState';
|
||||
import { authProvidersState } from '@/client-config/states/authProvidersState';
|
||||
import { billingState } from '@/client-config/states/billingState';
|
||||
import { calendarBookingPageIdState } from '@/client-config/states/calendarBookingPageIdState';
|
||||
import { canManageFeatureFlagsState } from '@/client-config/states/canManageFeatureFlagsState';
|
||||
import { captchaState } from '@/client-config/states/captchaState';
|
||||
import { chromeExtensionIdState } from '@/client-config/states/chromeExtensionIdState';
|
||||
@ -85,6 +86,10 @@ export const ClientConfigProviderEffect = () => {
|
||||
isConfigVariablesInDbEnabledState,
|
||||
);
|
||||
|
||||
const setCalendarBookingPageId = useSetRecoilState(
|
||||
calendarBookingPageIdState,
|
||||
);
|
||||
|
||||
const { data, loading, error, fetchClientConfig } = useClientConfig();
|
||||
|
||||
useEffect(() => {
|
||||
@ -173,6 +178,8 @@ export const ClientConfigProviderEffect = () => {
|
||||
...currentStatus,
|
||||
isSaved: true,
|
||||
}));
|
||||
|
||||
setCalendarBookingPageId(data?.clientConfig?.calendarBookingPageId ?? null);
|
||||
}, [
|
||||
data,
|
||||
loading,
|
||||
@ -198,6 +205,7 @@ export const ClientConfigProviderEffect = () => {
|
||||
setGoogleCalendarEnabled,
|
||||
setIsAttachmentPreviewEnabled,
|
||||
setIsConfigVariablesInDbEnabled,
|
||||
setCalendarBookingPageId,
|
||||
]);
|
||||
|
||||
return <></>;
|
||||
|
||||
@ -62,6 +62,7 @@ export const GET_CLIENT_CONFIG = gql`
|
||||
isGoogleMessagingEnabled
|
||||
isGoogleCalendarEnabled
|
||||
isConfigVariablesInDbEnabled
|
||||
calendarBookingPageId
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
@ -0,0 +1,6 @@
|
||||
import { createState } from 'twenty-ui/utilities';
|
||||
|
||||
export const calendarBookingPageIdState = createState<string | null>({
|
||||
key: 'calendarBookingPageIdState',
|
||||
defaultValue: null,
|
||||
});
|
||||
@ -0,0 +1 @@
|
||||
export const BOOK_CALL_MODAL_ID = 'book-call-modal';
|
||||
@ -0,0 +1,9 @@
|
||||
import { gql } from '@apollo/client';
|
||||
|
||||
export const SKIP_BOOK_ONBOARDING_STEP = gql`
|
||||
mutation SkipBookOnboardingStep {
|
||||
skipBookOnboardingStep {
|
||||
success
|
||||
}
|
||||
}
|
||||
`;
|
||||
@ -5,12 +5,14 @@ import {
|
||||
CurrentWorkspace,
|
||||
currentWorkspaceState,
|
||||
} from '@/auth/states/currentWorkspaceState';
|
||||
import { calendarBookingPageIdState } from '@/client-config/states/calendarBookingPageIdState';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { OnboardingStatus } from '~/generated/graphql';
|
||||
|
||||
const getNextOnboardingStatus = (
|
||||
currentUser: CurrentUser | null,
|
||||
currentWorkspace: CurrentWorkspace | null,
|
||||
calendarBookingPageId: string | null,
|
||||
) => {
|
||||
if (currentUser?.onboardingStatus === OnboardingStatus.WORKSPACE_ACTIVATION) {
|
||||
return OnboardingStatus.PROFILE_CREATION;
|
||||
@ -25,12 +27,21 @@ const getNextOnboardingStatus = (
|
||||
) {
|
||||
return OnboardingStatus.INVITE_TEAM;
|
||||
}
|
||||
if (currentUser?.onboardingStatus === OnboardingStatus.INVITE_TEAM) {
|
||||
return isDefined(calendarBookingPageId)
|
||||
? OnboardingStatus.BOOK_ONBOARDING
|
||||
: OnboardingStatus.COMPLETED;
|
||||
}
|
||||
if (currentUser?.onboardingStatus === OnboardingStatus.BOOK_ONBOARDING) {
|
||||
return OnboardingStatus.COMPLETED;
|
||||
}
|
||||
return OnboardingStatus.COMPLETED;
|
||||
};
|
||||
|
||||
export const useSetNextOnboardingStatus = () => {
|
||||
const currentUser = useRecoilValue(currentUserState);
|
||||
const currentWorkspace = useRecoilValue(currentWorkspaceState);
|
||||
const calendarBookingPageId = useRecoilValue(calendarBookingPageIdState);
|
||||
|
||||
return useRecoilCallback(
|
||||
({ set }) =>
|
||||
@ -38,6 +49,7 @@ export const useSetNextOnboardingStatus = () => {
|
||||
const nextOnboardingStatus = getNextOnboardingStatus(
|
||||
currentUser,
|
||||
currentWorkspace,
|
||||
calendarBookingPageId,
|
||||
);
|
||||
set(currentUserState, (current) => {
|
||||
if (isDefined(current)) {
|
||||
@ -49,6 +61,6 @@ export const useSetNextOnboardingStatus = () => {
|
||||
return current;
|
||||
});
|
||||
},
|
||||
[currentWorkspace, currentUser],
|
||||
[currentWorkspace, currentUser, calendarBookingPageId],
|
||||
);
|
||||
};
|
||||
|
||||
@ -13,6 +13,8 @@ export enum AppPath {
|
||||
InviteTeam = '/invite-team',
|
||||
PlanRequired = '/plan-required',
|
||||
PlanRequiredSuccess = '/plan-required/payment-success',
|
||||
BookCallDecision = '/book-call-decision',
|
||||
BookCall = '/book-call',
|
||||
|
||||
// Onboarded
|
||||
Index = '/',
|
||||
|
||||
@ -43,6 +43,8 @@ const testCases = [
|
||||
{ loc: AppPath.InviteTeam, res: true },
|
||||
{ loc: AppPath.PlanRequired, res: true },
|
||||
{ loc: AppPath.PlanRequiredSuccess, res: true },
|
||||
{ loc: AppPath.BookCallDecision, res: true },
|
||||
{ loc: AppPath.BookCall, res: true },
|
||||
|
||||
{ loc: AppPath.Index, res: false },
|
||||
{ loc: AppPath.RecordIndexPage, res: false },
|
||||
|
||||
@ -19,7 +19,9 @@ export const useShowAuthModal = () => {
|
||||
isMatchingLocation(location, AppPath.SignInUp) ||
|
||||
isMatchingLocation(location, AppPath.CreateWorkspace) ||
|
||||
isMatchingLocation(location, AppPath.PlanRequired) ||
|
||||
isMatchingLocation(location, AppPath.PlanRequiredSuccess)
|
||||
isMatchingLocation(location, AppPath.PlanRequiredSuccess) ||
|
||||
isMatchingLocation(location, AppPath.BookCallDecision) ||
|
||||
isMatchingLocation(location, AppPath.BookCall)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -25,11 +25,14 @@ const StyledModalDiv = styled(motion.div)<{
|
||||
box-shadow: ${({ theme, modalVariant }) =>
|
||||
modalVariant === 'primary'
|
||||
? theme.boxShadow.superHeavy
|
||||
: theme.boxShadow.strong};
|
||||
background: ${({ theme }) => theme.background.primary};
|
||||
: modalVariant === 'transparent'
|
||||
? 'none'
|
||||
: theme.boxShadow.strong};
|
||||
background: ${({ theme, modalVariant }) =>
|
||||
modalVariant === 'transparent' ? 'transparent' : theme.background.primary};
|
||||
color: ${({ theme }) => theme.font.color.primary};
|
||||
border-radius: ${({ theme, isMobile }) => {
|
||||
if (isMobile) return `0`;
|
||||
border-radius: ${({ theme, isMobile, modalVariant }) => {
|
||||
if (isMobile || modalVariant === 'transparent') return `0`;
|
||||
return theme.border.radius.md;
|
||||
}};
|
||||
overflow-x: hidden;
|
||||
@ -123,7 +126,7 @@ const StyledBackDrop = styled(motion.div)<{
|
||||
}>`
|
||||
align-items: center;
|
||||
background: ${({ theme, modalVariant }) =>
|
||||
modalVariant === 'primary'
|
||||
modalVariant === 'primary' || modalVariant === 'transparent'
|
||||
? theme.background.overlayPrimary
|
||||
: modalVariant === 'secondary'
|
||||
? theme.background.overlaySecondary
|
||||
@ -177,7 +180,11 @@ const ModalFooter = ({ children, className }: ModalFooterProps) => (
|
||||
|
||||
export type ModalSize = 'small' | 'medium' | 'large' | 'extraLarge';
|
||||
export type ModalPadding = 'none' | 'small' | 'medium' | 'large';
|
||||
export type ModalVariants = 'primary' | 'secondary' | 'tertiary';
|
||||
export type ModalVariants =
|
||||
| 'primary'
|
||||
| 'secondary'
|
||||
| 'tertiary'
|
||||
| 'transparent';
|
||||
|
||||
export type ModalProps = React.PropsWithChildren & {
|
||||
modalId: string;
|
||||
|
||||
86
packages/twenty-front/src/pages/onboarding/BookCall.tsx
Normal file
86
packages/twenty-front/src/pages/onboarding/BookCall.tsx
Normal file
@ -0,0 +1,86 @@
|
||||
import Cal from '@calcom/embed-react';
|
||||
import styled from '@emotion/styled';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
import { currentUserState } from '@/auth/states/currentUserState';
|
||||
import { calendarBookingPageIdState } from '@/client-config/states/calendarBookingPageIdState';
|
||||
import { useSetNextOnboardingStatus } from '@/onboarding/hooks/useSetNextOnboardingStatus';
|
||||
import { AppPath } from '@/types/AppPath';
|
||||
import { Modal } from '@/ui/layout/modal/components/Modal';
|
||||
import { ScrollWrapper } from '@/ui/utilities/scroll/components/ScrollWrapper';
|
||||
import { useTheme } from '@emotion/react';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { IconChevronLeft, IconChevronRightPipe } from 'twenty-ui/display';
|
||||
import { LightButton } from 'twenty-ui/input';
|
||||
import { useIsMobile } from 'twenty-ui/utilities';
|
||||
import {
|
||||
OnboardingStatus,
|
||||
useSkipBookOnboardingStepMutation,
|
||||
} from '~/generated/graphql';
|
||||
|
||||
const StyledModalFooter = styled(Modal.Footer)`
|
||||
height: auto;
|
||||
justify-content: center;
|
||||
padding: ${({ theme }) => theme.spacing(3)};
|
||||
`;
|
||||
|
||||
const StyledModalContent = styled(Modal.Content)`
|
||||
overflow: hidden;
|
||||
padding: 0;
|
||||
`;
|
||||
|
||||
const StyledScrollWrapper = styled(ScrollWrapper)<{ isMobile: boolean }>`
|
||||
${({ isMobile }) => !isMobile && 'height: auto;'}
|
||||
`;
|
||||
|
||||
export const BookCall = () => {
|
||||
const { t } = useLingui();
|
||||
const theme = useTheme();
|
||||
const calendarBookingPageId = useRecoilValue(calendarBookingPageIdState);
|
||||
const setNextOnboardingStatus = useSetNextOnboardingStatus();
|
||||
const currentUser = useRecoilValue(currentUserState);
|
||||
const [skipBookOnboardingStepMutation] = useSkipBookOnboardingStepMutation();
|
||||
|
||||
const isMobile = useIsMobile();
|
||||
const isPlanRequired =
|
||||
currentUser?.onboardingStatus === OnboardingStatus.PLAN_REQUIRED;
|
||||
|
||||
const handleCompleteOnboarding = async () => {
|
||||
await skipBookOnboardingStepMutation();
|
||||
setNextOnboardingStatus();
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<StyledModalContent isHorizontalCentered isVerticalCentered>
|
||||
<StyledScrollWrapper
|
||||
componentInstanceId="scroll-wrapper-modal-content"
|
||||
isMobile={isMobile}
|
||||
>
|
||||
<Cal
|
||||
calLink={calendarBookingPageId ?? ''}
|
||||
config={{
|
||||
layout: 'month_view',
|
||||
theme: theme.name === 'light' ? 'light' : 'dark',
|
||||
email: currentUser?.email ?? '',
|
||||
}}
|
||||
/>
|
||||
</StyledScrollWrapper>
|
||||
</StyledModalContent>
|
||||
<StyledModalFooter>
|
||||
{isPlanRequired ? (
|
||||
<Link to={AppPath.PlanRequired}>
|
||||
<LightButton Icon={IconChevronLeft} title={t`Back`} />
|
||||
</Link>
|
||||
) : (
|
||||
<LightButton
|
||||
Icon={IconChevronRightPipe}
|
||||
title={t`Skip`}
|
||||
onClick={handleCompleteOnboarding}
|
||||
/>
|
||||
)}
|
||||
</StyledModalFooter>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@ -0,0 +1,74 @@
|
||||
import { SubTitle } from '@/auth/components/SubTitle';
|
||||
import { Title } from '@/auth/components/Title';
|
||||
import { useSetNextOnboardingStatus } from '@/onboarding/hooks/useSetNextOnboardingStatus';
|
||||
import { AppPath } from '@/types/AppPath';
|
||||
import { Modal } from '@/ui/layout/modal/components/Modal';
|
||||
import styled from '@emotion/styled';
|
||||
import { Trans, useLingui } from '@lingui/react/macro';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { LightButton, MainButton } from 'twenty-ui/input';
|
||||
import { useSkipBookOnboardingStepMutation } from '~/generated/graphql';
|
||||
|
||||
const StyledCoverImage = styled.img`
|
||||
border-radius: ${({ theme }) => theme.border.radius.sm};
|
||||
height: 204px;
|
||||
object-fit: cover;
|
||||
width: 320px;
|
||||
`;
|
||||
|
||||
const StyledModalContent = styled(Modal.Content)`
|
||||
gap: ${({ theme }) => theme.spacing(8)};
|
||||
`;
|
||||
|
||||
const StyledTitleContainer = styled.div`
|
||||
align-items: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
`;
|
||||
|
||||
const StyledButtonContainer = styled.div`
|
||||
align-items: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: ${({ theme }) => theme.spacing(4)};
|
||||
width: 100%;
|
||||
`;
|
||||
|
||||
const StyledLink = styled(Link)`
|
||||
text-decoration: none;
|
||||
`;
|
||||
|
||||
export const BookCallDecision = () => {
|
||||
const { t } = useLingui();
|
||||
const setNextOnboardingStatus = useSetNextOnboardingStatus();
|
||||
const [skipBookOnboardingStepMutation] = useSkipBookOnboardingStepMutation();
|
||||
|
||||
const handleFinish = async () => {
|
||||
await skipBookOnboardingStepMutation();
|
||||
setNextOnboardingStatus();
|
||||
};
|
||||
|
||||
return (
|
||||
<StyledModalContent isVerticalCentered isHorizontalCentered>
|
||||
<StyledTitleContainer>
|
||||
<Title noMarginTop>
|
||||
<Trans>Book your onboarding</Trans>
|
||||
</Title>
|
||||
<SubTitle>
|
||||
<Trans>
|
||||
Our team can help you set up your workspace to match your specific
|
||||
needs and workflows.
|
||||
</Trans>
|
||||
</SubTitle>
|
||||
</StyledTitleContainer>
|
||||
<StyledCoverImage src="/images/placeholders/onboarding-covers/onboarding-book-call-decision-cover.png" />
|
||||
<StyledButtonContainer>
|
||||
<StyledLink to={AppPath.BookCall}>
|
||||
<MainButton title={t`Book onboarding`} width={198} />
|
||||
</StyledLink>
|
||||
<LightButton title={t`Finish`} onClick={handleFinish} />
|
||||
</StyledButtonContainer>
|
||||
</StyledModalContent>
|
||||
);
|
||||
};
|
||||
@ -9,6 +9,8 @@ import { TrialCard } from '@/billing/components/TrialCard';
|
||||
import { useHandleCheckoutSession } from '@/billing/hooks/useHandleCheckoutSession';
|
||||
import { isBillingPriceLicensed } from '@/billing/utils/isBillingPriceLicensed';
|
||||
import { billingState } from '@/client-config/states/billingState';
|
||||
import { calendarBookingPageIdState } from '@/client-config/states/calendarBookingPageIdState';
|
||||
import { AppPath } from '@/types/AppPath';
|
||||
import { Modal } from '@/ui/layout/modal/components/Modal';
|
||||
import styled from '@emotion/styled';
|
||||
import { Trans, useLingui } from '@lingui/react/macro';
|
||||
@ -97,6 +99,8 @@ export const ChooseYourPlan = () => {
|
||||
billingCheckoutSessionState,
|
||||
);
|
||||
|
||||
const calendarBookingPageId = useRecoilValue(calendarBookingPageIdState);
|
||||
|
||||
const [verifyEmailNextPath, setVerifyEmailNextPath] = useRecoilState(
|
||||
verifyEmailNextPathState,
|
||||
);
|
||||
@ -250,7 +254,11 @@ export const ChooseYourPlan = () => {
|
||||
<Trans>Change Plan</Trans>
|
||||
</ClickToActionLink>
|
||||
<span />
|
||||
<ClickToActionLink href={CAL_LINK} target="_blank" rel="noreferrer">
|
||||
<ClickToActionLink
|
||||
href={calendarBookingPageId ? AppPath.BookCall : CAL_LINK}
|
||||
target={calendarBookingPageId ? '_self' : '_blank'}
|
||||
rel={calendarBookingPageId ? '' : 'noreferrer'}
|
||||
>
|
||||
<Trans>Book a Call</Trans>
|
||||
</ClickToActionLink>
|
||||
</StyledLinkGroup>
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import { SubTitle } from '@/auth/components/SubTitle';
|
||||
import { Title } from '@/auth/components/Title';
|
||||
import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState';
|
||||
import { calendarBookingPageIdState } from '@/client-config/states/calendarBookingPageIdState';
|
||||
import { useSetNextOnboardingStatus } from '@/onboarding/hooks/useSetNextOnboardingStatus';
|
||||
import { PageHotkeyScope } from '@/types/PageHotkeyScope';
|
||||
import { SnackBarVariant } from '@/ui/feedback/snack-bar-manager/components/SnackBar';
|
||||
@ -66,9 +67,11 @@ export const InviteTeam = () => {
|
||||
const theme = useTheme();
|
||||
const { enqueueSnackBar } = useSnackBar();
|
||||
const { sendInvitation } = useCreateWorkspaceInvitation();
|
||||
|
||||
const setNextOnboardingStatus = useSetNextOnboardingStatus();
|
||||
const currentWorkspace = useRecoilValue(currentWorkspaceState);
|
||||
const calendarBookingPageId = useRecoilValue(calendarBookingPageIdState);
|
||||
const hasCalendarBooking = isDefined(calendarBookingPageId);
|
||||
|
||||
const {
|
||||
control,
|
||||
handleSubmit,
|
||||
@ -136,8 +139,6 @@ export const InviteTeam = () => {
|
||||
);
|
||||
const result = await sendInvitation({ emails });
|
||||
|
||||
setNextOnboardingStatus();
|
||||
|
||||
if (isDefined(result.errors)) {
|
||||
throw result.errors;
|
||||
}
|
||||
@ -147,6 +148,8 @@ export const InviteTeam = () => {
|
||||
duration: 2000,
|
||||
});
|
||||
}
|
||||
|
||||
setNextOnboardingStatus();
|
||||
},
|
||||
[enqueueSnackBar, sendInvitation, setNextOnboardingStatus, t],
|
||||
);
|
||||
@ -214,7 +217,7 @@ export const InviteTeam = () => {
|
||||
</StyledAnimatedContainer>
|
||||
<StyledButtonContainer>
|
||||
<MainButton
|
||||
title={t`Continue`}
|
||||
title={hasCalendarBooking ? t`Continue` : t`Finish`}
|
||||
disabled={!isValid || isSubmitting}
|
||||
onClick={handleSubmit(onSubmit)}
|
||||
fullWidth
|
||||
|
||||
@ -83,6 +83,7 @@ describe('ClientConfigController', () => {
|
||||
isGoogleMessagingEnabled: false,
|
||||
isGoogleCalendarEnabled: false,
|
||||
isConfigVariablesInDbEnabled: false,
|
||||
calendarBookingPageId: undefined,
|
||||
};
|
||||
|
||||
jest
|
||||
|
||||
@ -147,4 +147,7 @@ export class ClientConfig {
|
||||
|
||||
@Field(() => Boolean)
|
||||
isConfigVariablesInDbEnabled: boolean;
|
||||
|
||||
@Field(() => String, { nullable: true })
|
||||
calendarBookingPageId?: string;
|
||||
}
|
||||
|
||||
@ -78,6 +78,7 @@ describe('ClientConfigService', () => {
|
||||
MESSAGING_PROVIDER_GMAIL_ENABLED: true,
|
||||
CALENDAR_PROVIDER_GOOGLE_ENABLED: true,
|
||||
IS_CONFIG_VARIABLES_IN_DB_ENABLED: false,
|
||||
CALENDAR_BOOKING_PAGE_ID: 'team/twenty/talk-to-us',
|
||||
};
|
||||
|
||||
return mockValues[key];
|
||||
@ -145,6 +146,7 @@ describe('ClientConfigService', () => {
|
||||
isGoogleMessagingEnabled: true,
|
||||
isGoogleCalendarEnabled: true,
|
||||
isConfigVariablesInDbEnabled: false,
|
||||
calendarBookingPageId: 'team/twenty/talk-to-us',
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@ -102,6 +102,9 @@ export class ClientConfigService {
|
||||
isConfigVariablesInDbEnabled: this.twentyConfigService.get(
|
||||
'IS_CONFIG_VARIABLES_IN_DB_ENABLED',
|
||||
),
|
||||
calendarBookingPageId: this.twentyConfigService.get(
|
||||
'CALENDAR_BOOKING_PAGE_ID',
|
||||
),
|
||||
};
|
||||
|
||||
return clientConfig;
|
||||
|
||||
@ -4,5 +4,6 @@ export enum OnboardingStatus {
|
||||
PROFILE_CREATION = 'PROFILE_CREATION',
|
||||
SYNC_EMAIL = 'SYNC_EMAIL',
|
||||
INVITE_TEAM = 'INVITE_TEAM',
|
||||
BOOK_ONBOARDING = 'BOOK_ONBOARDING',
|
||||
COMPLETED = 'COMPLETED',
|
||||
}
|
||||
|
||||
@ -28,4 +28,16 @@ export class OnboardingResolver {
|
||||
|
||||
return { success: true };
|
||||
}
|
||||
|
||||
@Mutation(() => OnboardingStepSuccess)
|
||||
async skipBookOnboardingStep(
|
||||
@AuthWorkspace() workspace: Workspace,
|
||||
): Promise<OnboardingStepSuccess> {
|
||||
await this.onboardingService.setOnboardingBookOnboardingPending({
|
||||
workspaceId: workspace.id,
|
||||
value: false,
|
||||
});
|
||||
|
||||
return { success: true };
|
||||
}
|
||||
}
|
||||
|
||||
@ -12,12 +12,14 @@ export enum OnboardingStepKeys {
|
||||
ONBOARDING_CONNECT_ACCOUNT_PENDING = 'ONBOARDING_CONNECT_ACCOUNT_PENDING',
|
||||
ONBOARDING_INVITE_TEAM_PENDING = 'ONBOARDING_INVITE_TEAM_PENDING',
|
||||
ONBOARDING_CREATE_PROFILE_PENDING = 'ONBOARDING_CREATE_PROFILE_PENDING',
|
||||
ONBOARDING_BOOK_ONBOARDING_PENDING = 'ONBOARDING_BOOK_ONBOARDING_PENDING',
|
||||
}
|
||||
|
||||
export type OnboardingKeyValueTypeMap = {
|
||||
[OnboardingStepKeys.ONBOARDING_CONNECT_ACCOUNT_PENDING]: boolean;
|
||||
[OnboardingStepKeys.ONBOARDING_INVITE_TEAM_PENDING]: boolean;
|
||||
[OnboardingStepKeys.ONBOARDING_CREATE_PROFILE_PENDING]: boolean;
|
||||
[OnboardingStepKeys.ONBOARDING_BOOK_ONBOARDING_PENDING]: boolean;
|
||||
};
|
||||
|
||||
@Injectable()
|
||||
@ -62,6 +64,10 @@ export class OnboardingService {
|
||||
const isInviteTeamPending =
|
||||
userVars.get(OnboardingStepKeys.ONBOARDING_INVITE_TEAM_PENDING) === true;
|
||||
|
||||
const isBookOnboardingPending =
|
||||
userVars.get(OnboardingStepKeys.ONBOARDING_BOOK_ONBOARDING_PENDING) ===
|
||||
true;
|
||||
|
||||
if (isProfileCreationPending) {
|
||||
return OnboardingStatus.PROFILE_CREATION;
|
||||
}
|
||||
@ -74,6 +80,10 @@ export class OnboardingService {
|
||||
return OnboardingStatus.INVITE_TEAM;
|
||||
}
|
||||
|
||||
if (isBookOnboardingPending) {
|
||||
return OnboardingStatus.BOOK_ONBOARDING;
|
||||
}
|
||||
|
||||
return OnboardingStatus.COMPLETED;
|
||||
}
|
||||
|
||||
@ -153,4 +163,27 @@ export class OnboardingService {
|
||||
value: true,
|
||||
});
|
||||
}
|
||||
|
||||
async setOnboardingBookOnboardingPending({
|
||||
workspaceId,
|
||||
value,
|
||||
}: {
|
||||
workspaceId: string;
|
||||
value: boolean;
|
||||
}) {
|
||||
if (!value) {
|
||||
await this.userVarsService.delete({
|
||||
workspaceId,
|
||||
key: OnboardingStepKeys.ONBOARDING_BOOK_ONBOARDING_PENDING,
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
await this.userVarsService.set({
|
||||
workspaceId,
|
||||
key: OnboardingStepKeys.ONBOARDING_BOOK_ONBOARDING_PENDING,
|
||||
value: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -630,6 +630,14 @@ export class ConfigVariables {
|
||||
@IsOptional()
|
||||
CHROME_EXTENSION_ID: string;
|
||||
|
||||
@ConfigVariablesMetadata({
|
||||
group: ConfigVariablesGroup.Other,
|
||||
description: 'Page ID for Cal.com booking integration',
|
||||
type: ConfigVariableType.STRING,
|
||||
})
|
||||
@IsOptional()
|
||||
CALENDAR_BOOKING_PAGE_ID?: string;
|
||||
|
||||
@ConfigVariablesMetadata({
|
||||
group: ConfigVariablesGroup.Logging,
|
||||
description: 'Enable or disable buffering for logs before sending',
|
||||
|
||||
@ -70,6 +70,7 @@ describe('WorkspaceInvitationService', () => {
|
||||
provide: OnboardingService,
|
||||
useValue: {
|
||||
setOnboardingInviteTeamPending: jest.fn(),
|
||||
setOnboardingBookOnboardingPending: jest.fn(),
|
||||
},
|
||||
},
|
||||
{
|
||||
@ -181,6 +182,12 @@ describe('WorkspaceInvitationService', () => {
|
||||
workspaceId: workspace.id,
|
||||
value: false,
|
||||
});
|
||||
expect(
|
||||
onboardingService.setOnboardingBookOnboardingPending,
|
||||
).toHaveBeenCalledWith({
|
||||
workspaceId: workspace.id,
|
||||
value: true,
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -324,6 +324,11 @@ export class WorkspaceInvitationService {
|
||||
value: false,
|
||||
});
|
||||
|
||||
await this.onboardingService.setOnboardingBookOnboardingPending({
|
||||
workspaceId: workspace.id,
|
||||
value: true,
|
||||
});
|
||||
|
||||
const result = invitationsPr.reduce<{
|
||||
errors: string[];
|
||||
result: ReturnType<
|
||||
|
||||
@ -4,18 +4,18 @@ export {
|
||||
IconAlertCircle,
|
||||
IconAlertTriangle,
|
||||
IconApi,
|
||||
IconAppWindow,
|
||||
IconApps,
|
||||
IconAppWindow,
|
||||
IconArchive,
|
||||
IconArchiveOff,
|
||||
IconArrowBackUp,
|
||||
IconArrowDown,
|
||||
IconArrowLeft,
|
||||
IconArrowRight,
|
||||
IconArrowUp,
|
||||
IconArrowUpRight,
|
||||
IconArrowsDiagonal,
|
||||
IconArrowsVertical,
|
||||
IconArrowUp,
|
||||
IconArrowUpRight,
|
||||
IconAt,
|
||||
IconBaselineDensitySmall,
|
||||
IconBell,
|
||||
@ -47,8 +47,9 @@ export {
|
||||
IconChevronDown,
|
||||
IconChevronLeft,
|
||||
IconChevronRight,
|
||||
IconChevronUp,
|
||||
IconChevronRightPipe,
|
||||
IconChevronsRight,
|
||||
IconChevronUp,
|
||||
IconCircleDot,
|
||||
IconCircleOff,
|
||||
IconCirclePlus,
|
||||
|
||||
@ -66,18 +66,18 @@ export {
|
||||
IconAlertCircle,
|
||||
IconAlertTriangle,
|
||||
IconApi,
|
||||
IconAppWindow,
|
||||
IconApps,
|
||||
IconAppWindow,
|
||||
IconArchive,
|
||||
IconArchiveOff,
|
||||
IconArrowBackUp,
|
||||
IconArrowDown,
|
||||
IconArrowLeft,
|
||||
IconArrowRight,
|
||||
IconArrowUp,
|
||||
IconArrowUpRight,
|
||||
IconArrowsDiagonal,
|
||||
IconArrowsVertical,
|
||||
IconArrowUp,
|
||||
IconArrowUpRight,
|
||||
IconAt,
|
||||
IconBaselineDensitySmall,
|
||||
IconBell,
|
||||
@ -109,8 +109,9 @@ export {
|
||||
IconChevronDown,
|
||||
IconChevronLeft,
|
||||
IconChevronRight,
|
||||
IconChevronUp,
|
||||
IconChevronRightPipe,
|
||||
IconChevronsRight,
|
||||
IconChevronUp,
|
||||
IconCircleDot,
|
||||
IconCircleOff,
|
||||
IconCirclePlus,
|
||||
|
||||
30
yarn.lock
30
yarn.lock
@ -4814,6 +4814,35 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@calcom/embed-core@npm:1.5.3":
|
||||
version: 1.5.3
|
||||
resolution: "@calcom/embed-core@npm:1.5.3"
|
||||
checksum: 10c0/85d2a17800dc685c75670a24ddc650eabac571001067640f2715aa7e9ffdad5fb36fc4c5f33c6d00bf6937ae6997a3beb45cd0d3cc96754fc1b3171ea888d796
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@calcom/embed-react@npm:^1.5.3":
|
||||
version: 1.5.3
|
||||
resolution: "@calcom/embed-react@npm:1.5.3"
|
||||
dependencies:
|
||||
"@calcom/embed-core": "npm:1.5.3"
|
||||
"@calcom/embed-snippet": "npm:1.3.3"
|
||||
peerDependencies:
|
||||
react: ^18.2.0 || ^19.0.0
|
||||
react-dom: ^18.2.0 || ^19.0.0
|
||||
checksum: 10c0/aa42bbd96b2d7b16dc2b582cdc6e13ea5015b91fa8e6f680f554e56d562f64e783df74eac50b028543827b3a8d62307fde37cad19f574b7ff7bc3bab8cf52dfe
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@calcom/embed-snippet@npm:1.3.3":
|
||||
version: 1.3.3
|
||||
resolution: "@calcom/embed-snippet@npm:1.3.3"
|
||||
dependencies:
|
||||
"@calcom/embed-core": "npm:1.5.3"
|
||||
checksum: 10c0/2488d33f23aa1495004803b6f8f3bba7f3aad2bd2b951aaffb9891c27250aed48fa7deb251cf4cf65e4e8c1f12c07c70eb5e6ab6706455fa71b8208fe53dfd53
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@clickhouse/client-common@npm:1.11.0":
|
||||
version: 1.11.0
|
||||
resolution: "@clickhouse/client-common@npm:1.11.0"
|
||||
@ -56654,6 +56683,7 @@ __metadata:
|
||||
"@babel/core": "npm:^7.14.5"
|
||||
"@babel/preset-react": "npm:^7.14.5"
|
||||
"@babel/preset-typescript": "npm:^7.24.6"
|
||||
"@calcom/embed-react": "npm:^1.5.3"
|
||||
"@codesandbox/sandpack-react": "npm:^2.13.5"
|
||||
"@crxjs/vite-plugin": "npm:^1.0.14"
|
||||
"@dagrejs/dagre": "npm:^1.1.2"
|
||||
|
||||
Reference in New Issue
Block a user