-
-
Notifications
You must be signed in to change notification settings - Fork 4.4k
feat(checkout v3): Full screen #98540
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 4 commits
507643d
1d331ba
22d4d30
5fd9193
61d5136
8cb3770
da01c2c
dc58b31
8de6ca3
003b8ed
0f9a09b
642a300
de59697
579ee01
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import type React from 'react'; | ||
|
||
import OrganizationContainer from 'sentry/views/organizationContainer'; | ||
|
||
import SubscriptionContext from 'getsentry/components/subscriptionContext'; | ||
|
||
type Props = { | ||
children: React.JSX.Element; | ||
}; | ||
|
||
function OrganizationSubscriptionContext({children}: Props) { | ||
return ( | ||
<OrganizationContainer> | ||
<SubscriptionContext>{children}</SubscriptionContext> | ||
</OrganizationContainer> | ||
); | ||
} | ||
|
||
export default OrganizationSubscriptionContext; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,27 @@ | ||
import type {SentryRouteObject} from 'sentry/components/route'; | ||
import {makeLazyloadComponent as make} from 'sentry/makeLazyloadComponent'; | ||
import errorHandler from 'sentry/utils/errorHandler'; | ||
|
||
const rootRoutes = (): SentryRouteObject => ({}); | ||
import OrganizationSubscriptionContext from 'getsentry/components/organizationSubscriptionContext'; | ||
|
||
const rootRoutes = (): SentryRouteObject => ({ | ||
children: [ | ||
{ | ||
// TODO(checkout v3): change this to the correct path (/settings/billing/checkout/) | ||
// when GA'd | ||
path: '/checkout-v3/', | ||
component: errorHandler(OrganizationSubscriptionContext), | ||
deprecatedRouteProps: true, | ||
customerDomainOnlyRoute: true, | ||
children: [ | ||
{ | ||
index: true, | ||
component: make(() => import('../views/decideCheckout')), | ||
deprecatedRouteProps: true, | ||
isabellaenriquez marked this conversation as resolved.
Show resolved
Hide resolved
|
||
}, | ||
], | ||
}, | ||
], | ||
}); | ||
|
||
export default rootRoutes; |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,18 +9,22 @@ import moment from 'moment-timezone'; | |
|
||
import type {Client} from 'sentry/api'; | ||
import {Alert} from 'sentry/components/core/alert'; | ||
import {Button} from 'sentry/components/core/button'; | ||
import {LinkButton} from 'sentry/components/core/button/linkButton'; | ||
import {ExternalLink} from 'sentry/components/core/link'; | ||
import LoadingError from 'sentry/components/loadingError'; | ||
import LoadingIndicator from 'sentry/components/loadingIndicator'; | ||
import LogoSentry from 'sentry/components/logoSentry'; | ||
import Panel from 'sentry/components/panels/panel'; | ||
import SentryDocumentTitle from 'sentry/components/sentryDocumentTitle'; | ||
import TextOverflow from 'sentry/components/textOverflow'; | ||
import {IconArrow} from 'sentry/icons'; | ||
import {t, tct} from 'sentry/locale'; | ||
import ConfigStore from 'sentry/stores/configStore'; | ||
import type {DataCategory} from 'sentry/types/core'; | ||
import type {RouteComponentProps} from 'sentry/types/legacyReactRouter'; | ||
import type {Organization} from 'sentry/types/organization'; | ||
import {browserHistory} from 'sentry/utils/browserHistory'; | ||
import type {QueryClient} from 'sentry/utils/queryClient'; | ||
import normalizeUrl from 'sentry/utils/url/normalizeUrl'; | ||
import withApi from 'sentry/utils/withApi'; | ||
|
@@ -122,6 +126,12 @@ class AMCheckout extends Component<Props, State> { | |
) { | ||
props.onToggleLegacy(props.subscription.planTier); | ||
} | ||
// TODO(checkout v3): remove these checks once checkout v3 is GA'd | ||
if (props.location?.pathname.includes('checkout-v3') && !props.isNewCheckout) { | ||
browserHistory.push(`/settings/${props.organization.slug}/billing/checkout/`); | ||
} else if (!props.location?.pathname.includes('checkout-v3') && props.isNewCheckout) { | ||
browserHistory.push(`/checkout-v3/`); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i have a backlog ticket to refactor this component to FC so we can use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yeah this is fine for now |
||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
let step = 1; | ||
if (props.location?.hash) { | ||
const stepMatch = /^#step(\d)$/.exec(props.location.hash); | ||
|
@@ -771,12 +781,21 @@ class AMCheckout extends Component<Props, State> { | |
const isOnSponsoredPartnerPlan = | ||
(subscription.partner?.isActive && subscription.isSponsored) || false; | ||
|
||
const ParentComponent = isNewCheckout ? FullScreenContainer : Fragment; | ||
|
||
return ( | ||
<Fragment> | ||
<ParentComponent> | ||
<SentryDocumentTitle | ||
title={t('Change Subscription')} | ||
orgSlug={organization.slug} | ||
/> | ||
{isNewCheckout && ( | ||
<FullScreenHeader> | ||
<HeaderContent> | ||
<LogoSentry /> | ||
</HeaderContent> | ||
</FullScreenHeader> | ||
)} | ||
{isOnSponsoredPartnerPlan && ( | ||
<Alert.Container> | ||
<Alert type="info"> | ||
|
@@ -800,9 +819,20 @@ class AMCheckout extends Component<Props, State> { | |
data-test-id="change-subscription" | ||
/> | ||
)} | ||
|
||
<CheckoutContainer isNewCheckout={!!isNewCheckout}> | ||
<div> | ||
{isNewCheckout && ( | ||
<BackButton | ||
borderless | ||
aria-label={t('Back to Subscription Overview')} | ||
onClick={() => { | ||
browserHistory.push(`/settings/${organization.slug}/billing/`); | ||
}} | ||
> | ||
<IconArrow direction="left" /> | ||
<span>{t('Back')}</span> | ||
</BackButton> | ||
)} | ||
{this.renderPartnerAlert()} | ||
<CheckoutStepsContainer | ||
data-test-id="checkout-steps" | ||
|
@@ -863,11 +893,42 @@ class AMCheckout extends Component<Props, State> { | |
)} | ||
</SidePanel> | ||
</CheckoutContainer> | ||
</Fragment> | ||
</ParentComponent> | ||
); | ||
} | ||
} | ||
|
||
const FullScreenContainer = styled('div')` | ||
isabellaenriquez marked this conversation as resolved.
Show resolved
Hide resolved
|
||
display: flex; | ||
flex-direction: column; | ||
align-items: center; | ||
background: ${p => p.theme.background}; | ||
`; | ||
isabellaenriquez marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
const FullScreenHeader = styled('header')` | ||
isabellaenriquez marked this conversation as resolved.
Show resolved
Hide resolved
|
||
width: 100%; | ||
border-bottom: 1px solid ${p => p.theme.border}; | ||
display: flex; | ||
justify-content: center; | ||
`; | ||
|
||
const HeaderContent = styled('div')` | ||
isabellaenriquez marked this conversation as resolved.
Show resolved
Hide resolved
|
||
width: 100%; | ||
display: flex; | ||
justify-content: flex-start; | ||
padding: ${p => p.theme.space['2xl']}; | ||
max-width: ${p => p.theme.breakpoints.xl}; | ||
`; | ||
|
||
const BackButton = styled(Button)` | ||
align-self: flex-start; | ||
padding: 0; | ||
|
||
& span { | ||
margin-left: ${p => p.theme.space.sm}; | ||
isabellaenriquez marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
`; | ||
|
||
const CheckoutContainer = styled('div')<{isNewCheckout: boolean}>` | ||
display: grid; | ||
gap: ${p => p.theme.space['2xl']}; | ||
|
@@ -877,6 +938,13 @@ const CheckoutContainer = styled('div')<{isNewCheckout: boolean}>` | |
p.isNewCheckout ? p.theme.breakpoints.md : p.theme.breakpoints.lg}) { | ||
grid-template-columns: auto; | ||
} | ||
|
||
${p => | ||
p.isNewCheckout && | ||
css` | ||
max-width: ${p.theme.breakpoints.xl}; | ||
padding: ${p.theme.space['2xl']}; | ||
`} | ||
`; | ||
|
||
const SidePanel = styled('div')` | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: use absolute path here