Polish onboarding v2 verify animation and step screens (#22585)
https://github.com/user-attachments/assets/1d9b8dc2-ef01-4202-a97e-b41cab048f87 A few polish tweaks to onboarding v2: - **Verify/workspace-creation animation:** emphasize the key phrase of each message in medium weight, the rest regular (e.g. "Creating your **workspace**…"). - **Wider content column:** 340px → 440px. Collapses to full width on mobile via the existing `max-width: 100%` on every consumer. - **Sticky disabled buttons:** step submit buttons now stay disabled from submit through navigation instead of briefly re-enabling once the mutation resolves. - **Fewer pulse loaders:** stop the pulsing logo from flashing when navigating between onboarding steps (removed the step-page Suspense fallback loader). The verify animation, cold-boot gates, and sign-in fallbacks are unchanged. Note: the reworded activation messages get new Lingui catalog IDs, so non-English locales fall back to English until catalogs are re-extracted. <!-- This is an auto-generated description by cubic. --> <a href="https://cubic.dev/pr/twentyhq/twenty/pull/22585?utm_source=github" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><picture><source media="(prefers-color-scheme: dark)" srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img alt="Review in cubic" src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a> <!-- End of auto-generated description by cubic. -->
This commit is contained in:
@@ -57,23 +57,23 @@
|
||||
</script>
|
||||
<style>
|
||||
:root {
|
||||
/* THEME_DARK.background.tertiary */
|
||||
--theme-dark-background-tertiary: #1d1d1d;
|
||||
/* THEME_LIGHT.background.tertiary */
|
||||
--theme-light-background-tertiary: #f1f1f1;
|
||||
/* THEME_DARK.background.secondary */
|
||||
--theme-dark-background-secondary: #1b1b1b;
|
||||
/* THEME_LIGHT.background.secondary */
|
||||
--theme-light-background-secondary: #fcfcfc;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
html,
|
||||
body {
|
||||
background-color: var(--theme-dark-background-tertiary);
|
||||
background-color: var(--theme-dark-background-secondary);
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: light) {
|
||||
html,
|
||||
body {
|
||||
background-color: var(--theme-light-background-tertiary);
|
||||
background-color: var(--theme-light-background-secondary);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
import { AppPath } from 'twenty-shared/types';
|
||||
|
||||
export const ONBOARDING_VERIFY_PATHS = [
|
||||
AppPath.Verify,
|
||||
AppPath.WorkspaceActivation,
|
||||
];
|
||||
-8
@@ -1,8 +0,0 @@
|
||||
import { msg } from '@lingui/core/macro';
|
||||
|
||||
export const WORKSPACE_ACTIVATION_MESSAGES = [
|
||||
msg`Creating your workspace...`,
|
||||
msg`Setting up your database...`,
|
||||
msg`Creating your data model...`,
|
||||
msg`Prefilling your workspace data...`,
|
||||
];
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
import { StyledOnboardingActivationMessageEmphasis } from '@/onboarding/components/StyledOnboardingActivationMessageEmphasis';
|
||||
import { type OnboardingActivationMessage } from '@/onboarding/types/OnboardingActivationMessage';
|
||||
import { Trans } from '@lingui/react/macro';
|
||||
|
||||
export const WORKSPACE_ACTIVATION_MESSAGES: OnboardingActivationMessage[] = [
|
||||
{
|
||||
id: 'creating-workspace',
|
||||
content: (
|
||||
<Trans>
|
||||
Creating your{' '}
|
||||
<StyledOnboardingActivationMessageEmphasis>
|
||||
workspace
|
||||
</StyledOnboardingActivationMessageEmphasis>
|
||||
...
|
||||
</Trans>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: 'setting-up-database',
|
||||
content: (
|
||||
<Trans>
|
||||
Setting up your{' '}
|
||||
<StyledOnboardingActivationMessageEmphasis>
|
||||
database
|
||||
</StyledOnboardingActivationMessageEmphasis>
|
||||
...
|
||||
</Trans>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: 'creating-data-model',
|
||||
content: (
|
||||
<Trans>
|
||||
Creating your{' '}
|
||||
<StyledOnboardingActivationMessageEmphasis>
|
||||
data model
|
||||
</StyledOnboardingActivationMessageEmphasis>
|
||||
...
|
||||
</Trans>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: 'prefilling-workspace-data',
|
||||
content: (
|
||||
<Trans>
|
||||
Prefilling your{' '}
|
||||
<StyledOnboardingActivationMessageEmphasis>
|
||||
workspace data
|
||||
</StyledOnboardingActivationMessageEmphasis>
|
||||
...
|
||||
</Trans>
|
||||
),
|
||||
},
|
||||
];
|
||||
@@ -0,0 +1,9 @@
|
||||
import { matchPath } from 'react-router-dom';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { ONBOARDING_VERIFY_PATHS } from '@/auth/constants/OnboardingVerifyPaths';
|
||||
|
||||
export const isOnOnboardingVerifyPath = (pathname: string) =>
|
||||
ONBOARDING_VERIFY_PATHS.some((verifyPath) =>
|
||||
isDefined(matchPath(verifyPath, pathname)),
|
||||
);
|
||||
+3
-5
@@ -1,8 +1,7 @@
|
||||
import { SubTitle } from '@/auth/components/SubTitle';
|
||||
import { useOnboardingMotionTransition } from '@/onboarding/hooks/useOnboardingMotionTransition';
|
||||
import { type OnboardingActivationMessage } from '@/onboarding/types/OnboardingActivationMessage';
|
||||
import { styled } from '@linaria/react';
|
||||
import { type MessageDescriptor } from '@lingui/core';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { motion } from 'framer-motion';
|
||||
|
||||
const STEP_OPACITIES = [1, 0.4, 0.12];
|
||||
@@ -26,7 +25,7 @@ const StyledStepBase = styled.div`
|
||||
const StyledStep = motion.create(StyledStepBase);
|
||||
|
||||
type OnboardingActivationStepsProps = {
|
||||
messages: MessageDescriptor[];
|
||||
messages: OnboardingActivationMessage[];
|
||||
messageIndex: number;
|
||||
};
|
||||
|
||||
@@ -34,7 +33,6 @@ export const OnboardingActivationSteps = ({
|
||||
messages,
|
||||
messageIndex,
|
||||
}: OnboardingActivationStepsProps) => {
|
||||
const { i18n } = useLingui();
|
||||
const transition = useOnboardingMotionTransition();
|
||||
|
||||
return (
|
||||
@@ -53,7 +51,7 @@ export const OnboardingActivationSteps = ({
|
||||
}}
|
||||
transition={transition}
|
||||
>
|
||||
<SubTitle>{i18n._(message)}</SubTitle>
|
||||
<SubTitle>{message.content}</SubTitle>
|
||||
</StyledStep>
|
||||
);
|
||||
})}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
import { useOnboardingContentWidth } from '@/onboarding/hooks/useOnboardingContentWidth';
|
||||
import { useOnboardingMotionTransition } from '@/onboarding/hooks/useOnboardingMotionTransition';
|
||||
import { ONBOARDING_CONTENT_BLOCK_WIDTH } from '@/onboarding/constants/OnboardingContentBlockWidth';
|
||||
import { styled } from '@linaria/react';
|
||||
import { motion } from 'framer-motion';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { IconChevronLeft, IconCoins, IconInfoCircle } from 'twenty-ui/icon';
|
||||
@@ -30,10 +28,10 @@ const StyledLeftSide = styled(StyledSide)`
|
||||
padding-right: ${themeCssVariables.spacing[1]};
|
||||
`;
|
||||
|
||||
const StyledCenter = styled.div<{ contentWidth: number }>`
|
||||
const StyledCenter = styled.div`
|
||||
align-items: center;
|
||||
display: flex;
|
||||
flex: 0 1 ${({ contentWidth }) => `${contentWidth}px`};
|
||||
flex: 0 1 ${ONBOARDING_CONTENT_BLOCK_WIDTH}px;
|
||||
justify-content: flex-start;
|
||||
min-width: 0;
|
||||
`;
|
||||
@@ -43,7 +41,7 @@ const StyledRightSide = styled(StyledSide)`
|
||||
padding-left: ${themeCssVariables.spacing[1]};
|
||||
`;
|
||||
|
||||
const StyledLogoBase = styled.div`
|
||||
const StyledLogo = styled.div`
|
||||
background-image: url('/images/integrations/twenty-logo.svg');
|
||||
background-size: cover;
|
||||
height: ${themeCssVariables.spacing[6]};
|
||||
@@ -51,8 +49,6 @@ const StyledLogoBase = styled.div`
|
||||
width: ${themeCssVariables.spacing[6]};
|
||||
`;
|
||||
|
||||
const StyledLogo = motion.create(StyledLogoBase);
|
||||
|
||||
const StyledFreeCredits = styled.div`
|
||||
align-items: center;
|
||||
color: ${themeCssVariables.font.color.tertiary};
|
||||
@@ -109,8 +105,6 @@ export const OnboardingHeader = ({
|
||||
}: OnboardingHeaderProps) => {
|
||||
const { t } = useLingui();
|
||||
const theme = useTheme();
|
||||
const contentWidth = useOnboardingContentWidth();
|
||||
const transition = useOnboardingMotionTransition();
|
||||
|
||||
return (
|
||||
<StyledHeader>
|
||||
@@ -125,8 +119,8 @@ export const OnboardingHeader = ({
|
||||
/>
|
||||
)}
|
||||
</StyledLeftSide>
|
||||
<StyledCenter contentWidth={contentWidth}>
|
||||
<StyledLogo layout transition={transition} />
|
||||
<StyledCenter>
|
||||
<StyledLogo />
|
||||
</StyledCenter>
|
||||
<StyledRightSide>
|
||||
{isDefined(freeCredits) && (
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { isOnOnboardingVerifyPath } from '@/auth/utils/isOnOnboardingVerifyPath';
|
||||
import { OnboardingPulsingLogo } from '@/onboarding/components/OnboardingPulsingLogo';
|
||||
import { styled } from '@linaria/react';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
@@ -12,8 +13,12 @@ const StyledContainer = styled.div`
|
||||
width: 100%;
|
||||
`;
|
||||
|
||||
// The verify screen renders its own pulsing logo, so the loader shown before it
|
||||
// omits the logo to avoid a double-logo flash on cold boot into the verify step.
|
||||
export const OnboardingPageLoader = () => (
|
||||
<StyledContainer>
|
||||
<OnboardingPulsingLogo />
|
||||
{!isOnOnboardingVerifyPath(window.location.pathname) && (
|
||||
<OnboardingPulsingLogo />
|
||||
)}
|
||||
</StyledContainer>
|
||||
);
|
||||
|
||||
+3
-9
@@ -1,17 +1,11 @@
|
||||
import { OnboardingPulsingLogo } from '@/onboarding/components/OnboardingPulsingLogo';
|
||||
import { styled } from '@linaria/react';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
|
||||
const StyledContainer = styled.div`
|
||||
align-items: center;
|
||||
display: flex;
|
||||
background: ${themeCssVariables.background.secondary};
|
||||
flex: 1;
|
||||
justify-content: center;
|
||||
min-height: 0;
|
||||
width: 100%;
|
||||
`;
|
||||
|
||||
export const OnboardingStepPageLoader = () => (
|
||||
<StyledContainer>
|
||||
<OnboardingPulsingLogo />
|
||||
</StyledContainer>
|
||||
);
|
||||
export const OnboardingStepPageLoader = () => <StyledContainer />;
|
||||
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
import { styled } from '@linaria/react';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
|
||||
export const StyledOnboardingActivationMessageEmphasis = styled.span`
|
||||
color: ${themeCssVariables.font.color.primary};
|
||||
font-weight: ${themeCssVariables.font.weight.medium};
|
||||
`;
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
import { ONBOARDING_CONTENT_BLOCK_WIDTH } from '@/onboarding/constants/OnboardingContentBlockWidth';
|
||||
import { styled } from '@linaria/react';
|
||||
|
||||
export const StyledOnboardingContentBlock = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
max-width: 100%;
|
||||
width: ${ONBOARDING_CONTENT_BLOCK_WIDTH}px;
|
||||
`;
|
||||
+2
-6
@@ -1,11 +1,7 @@
|
||||
import { ONBOARDING_CONTENT_BLOCK_WIDTH } from '@/onboarding/constants/OnboardingContentBlockWidth';
|
||||
import { StyledOnboardingContentBlock } from '@/onboarding/components/StyledOnboardingContentBlock';
|
||||
import { styled } from '@linaria/react';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
|
||||
export const StyledOnboardingStepHeading = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
export const StyledOnboardingStepHeading = styled(StyledOnboardingContentBlock)`
|
||||
gap: ${themeCssVariables.spacing[4]};
|
||||
max-width: 100%;
|
||||
width: ${ONBOARDING_CONTENT_BLOCK_WIDTH}px;
|
||||
`;
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
import { WORKSPACE_ACTIVATION_MESSAGES } from '@/auth/sign-in-up/constants/WorkspaceActivationMessages';
|
||||
import { msg } from '@lingui/core/macro';
|
||||
|
||||
export const ONBOARDING_ACTIVATION_MESSAGES = [
|
||||
msg`Verifying your login token`,
|
||||
...WORKSPACE_ACTIVATION_MESSAGES,
|
||||
];
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
import { WORKSPACE_ACTIVATION_MESSAGES } from '@/auth/sign-in-up/constants/WorkspaceActivationMessages';
|
||||
import { StyledOnboardingActivationMessageEmphasis } from '@/onboarding/components/StyledOnboardingActivationMessageEmphasis';
|
||||
import { type OnboardingActivationMessage } from '@/onboarding/types/OnboardingActivationMessage';
|
||||
import { Trans } from '@lingui/react/macro';
|
||||
|
||||
export const ONBOARDING_ACTIVATION_MESSAGES: OnboardingActivationMessage[] = [
|
||||
{
|
||||
id: 'verifying-login-token',
|
||||
content: (
|
||||
<Trans>
|
||||
Verifying your{' '}
|
||||
<StyledOnboardingActivationMessageEmphasis>
|
||||
login token
|
||||
</StyledOnboardingActivationMessageEmphasis>
|
||||
</Trans>
|
||||
),
|
||||
},
|
||||
...WORKSPACE_ACTIVATION_MESSAGES,
|
||||
];
|
||||
+1
-1
@@ -1 +1 @@
|
||||
export const ONBOARDING_CONTENT_BLOCK_WIDTH = 340;
|
||||
export const ONBOARDING_CONTENT_BLOCK_WIDTH = 440;
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
export const UPGRADE_STEP_CONTENT_WIDTH = 440;
|
||||
@@ -31,6 +31,8 @@ export const useInviteTeam = () => {
|
||||
const setOnboardingFreeCredits = useSetAtomState(onboardingFreeCreditsState);
|
||||
const onboardingConfig = useAtomStateValue(onboardingConfigState);
|
||||
|
||||
const [isNavigating, setIsNavigating] = useState(false);
|
||||
|
||||
const {
|
||||
control,
|
||||
handleSubmit,
|
||||
@@ -152,6 +154,7 @@ export const useInviteTeam = () => {
|
||||
}
|
||||
|
||||
setNextOnboardingStatus();
|
||||
setIsNavigating(true);
|
||||
},
|
||||
[
|
||||
enqueueSuccessSnackBar,
|
||||
@@ -186,5 +189,6 @@ export const useInviteTeam = () => {
|
||||
getPlaceholder,
|
||||
isValid,
|
||||
isSubmitting,
|
||||
isNavigating,
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
import { ONBOARDING_CONTENT_BLOCK_WIDTH } from '@/onboarding/constants/OnboardingContentBlockWidth';
|
||||
import { UPGRADE_STEP_CONTENT_WIDTH } from '@/onboarding/constants/UpgradeStepContentWidth';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
import { AppPath } from 'twenty-shared/types';
|
||||
import { isMatchingLocation } from '~/utils/isMatchingLocation';
|
||||
|
||||
export const useOnboardingContentWidth = () => {
|
||||
const location = useLocation();
|
||||
|
||||
return isMatchingLocation(location, AppPath.PlanRequired)
|
||||
? UPGRADE_STEP_CONTENT_WIDTH
|
||||
: ONBOARDING_CONTENT_BLOCK_WIDTH;
|
||||
};
|
||||
@@ -0,0 +1,6 @@
|
||||
import { type ReactNode } from 'react';
|
||||
|
||||
export type OnboardingActivationMessage = {
|
||||
id: string;
|
||||
content: ReactNode;
|
||||
};
|
||||
@@ -3,7 +3,7 @@ import { Outlet } from 'react-router-dom';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
|
||||
const StyledLayout = styled.div`
|
||||
background: ${themeCssVariables.background.noisy};
|
||||
background: ${themeCssVariables.background.secondary};
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100dvh;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { billingState } from '@/client-config/states/billingState';
|
||||
import { onboardingConfigState } from '@/client-config/states/onboardingConfigState';
|
||||
import { OnboardingPageLoader } from '@/onboarding/components/OnboardingPageLoader';
|
||||
import { usePlans } from '@/settings/billing/hooks/usePlans';
|
||||
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
@@ -16,7 +15,5 @@ export const ChooseYourPlan = () => {
|
||||
billing={billing}
|
||||
creditsReward={onboardingConfig?.upgradeCreditsReward}
|
||||
/>
|
||||
) : (
|
||||
<OnboardingPageLoader />
|
||||
);
|
||||
) : null;
|
||||
};
|
||||
|
||||
@@ -87,6 +87,8 @@ export const CreateProfile = () => {
|
||||
);
|
||||
const { updateWorkspaceMemberSettings } = useUpdateWorkspaceMemberSettings();
|
||||
|
||||
const [isNavigating, setIsNavigating] = useState(false);
|
||||
|
||||
const {
|
||||
control,
|
||||
handleSubmit,
|
||||
@@ -151,7 +153,9 @@ export const CreateProfile = () => {
|
||||
});
|
||||
|
||||
setNextOnboardingStatus();
|
||||
setIsNavigating(true);
|
||||
} catch (error: any) {
|
||||
setIsNavigating(false);
|
||||
enqueueErrorSnackBar({
|
||||
apolloError: CombinedGraphQLErrors.is(error) ? error : undefined,
|
||||
});
|
||||
@@ -279,7 +283,7 @@ export const CreateProfile = () => {
|
||||
<MainButton
|
||||
title={t`Continue`}
|
||||
onClick={handleSubmit(onSubmit)}
|
||||
disabled={!isValid || isSubmitting}
|
||||
disabled={!isValid || isSubmitting || isNavigating}
|
||||
fullWidth
|
||||
/>
|
||||
</StyledButtonContainer>
|
||||
|
||||
@@ -51,6 +51,7 @@ export const InviteTeam = () => {
|
||||
getPlaceholder,
|
||||
isValid,
|
||||
isSubmitting,
|
||||
isNavigating,
|
||||
} = useInviteTeam();
|
||||
const onboardingConfig = useAtomStateValue(onboardingConfigState);
|
||||
const creditsRewardPerUser = onboardingConfig?.inviteTeamCreditsRewardPerUser;
|
||||
@@ -123,11 +124,14 @@ export const InviteTeam = () => {
|
||||
<StyledFooter>
|
||||
<MainButton
|
||||
title={t`Invite`}
|
||||
disabled={!isValid || isSubmitting}
|
||||
disabled={!isValid || isSubmitting || isNavigating}
|
||||
onClick={handleSubmit(onSubmit)}
|
||||
fullWidth
|
||||
/>
|
||||
<OnboardingSkipButton onClick={handleSkip} />
|
||||
<OnboardingSkipButton
|
||||
onClick={handleSkip}
|
||||
disabled={isSubmitting || isNavigating}
|
||||
/>
|
||||
</StyledFooter>
|
||||
</OnboardingStepAnimatedItem>
|
||||
</StyledOnboardingStepPage>
|
||||
|
||||
@@ -4,7 +4,6 @@ import { isGoogleMessagingEnabledState } from '@/client-config/states/isGoogleMe
|
||||
import { isMicrosoftCalendarEnabledState } from '@/client-config/states/isMicrosoftCalendarEnabledState';
|
||||
import { isMicrosoftMessagingEnabledState } from '@/client-config/states/isMicrosoftMessagingEnabledState';
|
||||
import { onboardingConfigState } from '@/client-config/states/onboardingConfigState';
|
||||
import { OnboardingPageLoader } from '@/onboarding/components/OnboardingPageLoader';
|
||||
import { SyncEmailsAutoSkipEffect } from '@/onboarding/effect-components/SyncEmailsAutoSkipEffect';
|
||||
import { useSkipSyncEmailOnboardingStep } from '@/onboarding/hooks/useSkipSyncEmailOnboardingStep';
|
||||
import { onboardingFreeCreditsState } from '@/onboarding/states/onboardingFreeCreditsState';
|
||||
@@ -86,16 +85,11 @@ export const SyncEmails = () => {
|
||||
}, []);
|
||||
|
||||
if (!isClientConfigLoaded) {
|
||||
return <OnboardingPageLoader />;
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!hasProviderEnabled && !hasAutoSkipFailed) {
|
||||
return (
|
||||
<>
|
||||
<SyncEmailsAutoSkipEffect onError={handleAutoSkipError} />
|
||||
<OnboardingPageLoader />
|
||||
</>
|
||||
);
|
||||
return <SyncEmailsAutoSkipEffect onError={handleAutoSkipError} />;
|
||||
}
|
||||
|
||||
return (
|
||||
|
||||
@@ -3,6 +3,8 @@ import { useAuth } from '@/auth/hooks/useAuth';
|
||||
import { billingCheckoutSessionState } from '@/auth/states/billingCheckoutSessionState';
|
||||
import { currentUserState } from '@/auth/states/currentUserState';
|
||||
import { calendarBookingPageIdState } from '@/client-config/states/calendarBookingPageIdState';
|
||||
import { StyledOnboardingContentBlock } from '@/onboarding/components/StyledOnboardingContentBlock';
|
||||
import { StyledOnboardingStepHeading } from '@/onboarding/components/StyledOnboardingStepHeading';
|
||||
import { StyledOnboardingStepPage } from '@/onboarding/components/StyledOnboardingStepPage';
|
||||
import { StyledOnboardingStepSubtitle } from '@/onboarding/components/StyledOnboardingStepSubtitle';
|
||||
import { StyledOnboardingStepTagsRow } from '@/onboarding/components/StyledOnboardingStepTagsRow';
|
||||
@@ -11,7 +13,6 @@ import { OnboardingStepAnimatedItem } from '@/onboarding/components/OnboardingSt
|
||||
import { OnboardingCreditsRewardTag } from '@/onboarding/components/import-contacts/OnboardingCreditsRewardTag';
|
||||
import { OnboardingPlanCard } from '@/onboarding/components/upgrade-free-trial/OnboardingPlanCard';
|
||||
import { OnboardingTrialExtensionTag } from '@/onboarding/components/upgrade-free-trial/OnboardingTrialExtensionTag';
|
||||
import { UPGRADE_STEP_CONTENT_WIDTH } from '@/onboarding/constants/UpgradeStepContentWidth';
|
||||
import { useBaseLicensedPriceByPlanKeyAndInterval } from '@/settings/billing/hooks/useBaseLicensedPriceByPlanKeyAndInterval';
|
||||
import { useHandleCheckoutSession } from '@/settings/billing/hooks/useHandleCheckoutSession';
|
||||
import { useStripeAppearance } from '@/settings/billing/hooks/useStripeAppearance';
|
||||
@@ -39,29 +40,13 @@ const StyledPage = styled(StyledOnboardingStepPage)`
|
||||
padding: ${themeCssVariables.spacing[6]} ${themeCssVariables.spacing[8]};
|
||||
`;
|
||||
|
||||
const StyledHeading = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: ${themeCssVariables.spacing[4]};
|
||||
max-width: 100%;
|
||||
width: ${UPGRADE_STEP_CONTENT_WIDTH}px;
|
||||
`;
|
||||
|
||||
const StyledCards = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
const StyledCards = styled(StyledOnboardingContentBlock)`
|
||||
gap: ${themeCssVariables.spacing['1.5']};
|
||||
max-width: 100%;
|
||||
width: ${UPGRADE_STEP_CONTENT_WIDTH}px;
|
||||
`;
|
||||
|
||||
const StyledFooter = styled.div`
|
||||
const StyledFooter = styled(StyledOnboardingContentBlock)`
|
||||
align-items: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: ${themeCssVariables.spacing['1.5']};
|
||||
max-width: 100%;
|
||||
width: ${UPGRADE_STEP_CONTENT_WIDTH}px;
|
||||
`;
|
||||
|
||||
const StyledLinkGroup = styled.div`
|
||||
@@ -282,7 +267,7 @@ export const UpgradeFreeTrial = ({
|
||||
|
||||
return (
|
||||
<StyledPage>
|
||||
<StyledHeading>
|
||||
<StyledOnboardingStepHeading>
|
||||
<OnboardingStepAnimatedItem index={0}>
|
||||
<StyledOnboardingStepTitle>{t`Upgrade your free trial`}</StyledOnboardingStepTitle>
|
||||
</OnboardingStepAnimatedItem>
|
||||
@@ -303,7 +288,7 @@ export const UpgradeFreeTrial = ({
|
||||
)}
|
||||
</StyledOnboardingStepTagsRow>
|
||||
</OnboardingStepAnimatedItem>
|
||||
</StyledHeading>
|
||||
</StyledOnboardingStepHeading>
|
||||
|
||||
{isDefined(stripePromise) && isDefined(baseProductPrice) ? (
|
||||
<Elements
|
||||
|
||||
Reference in New Issue
Block a user