Skip to content

Commit 9e3626a

Browse files
authored
feat: update pricing (#8676)
* pricing page updates * convert actions * update moment * updated plans * fix content * plans * fix: typecheck * fix: typecheck * fix: lint
1 parent 0dd52a7 commit 9e3626a

File tree

27 files changed

+637
-364
lines changed

27 files changed

+637
-364
lines changed
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import React from 'react';
2+
import { MessageStripe, Text } from '@codesandbox/components';
3+
4+
export const AcquisitionAnnouncement: React.FC<{ onDismiss: () => void }> = ({
5+
onDismiss,
6+
}) => (
7+
<MessageStripe
8+
justify="space-between"
9+
variant="primary"
10+
corners="straight"
11+
onDismiss={onDismiss}
12+
>
13+
<Text>
14+
CodeSandbox is now part of{' '}
15+
<a
16+
style={{ color: 'inherit' }}
17+
href="https://together.ai"
18+
rel="noreferrer"
19+
target="_blank"
20+
>
21+
Together AI!
22+
</a>{' '}
23+
We have joined forces to launch{' '}
24+
<a
25+
style={{ color: 'inherit' }}
26+
href="https://codesandbox.io/sdk"
27+
rel="noreferrer"
28+
target="_blank"
29+
>
30+
CodeSandbox SDK
31+
</a>{' '}
32+
and bring code interpretation to generative AI.
33+
</Text>
34+
<MessageStripe.Action
35+
as="a"
36+
target="_blank"
37+
rel="noreferrer"
38+
href="https://codesandbox.io/blog/joining-forces-with-together-ai-introducing-codesandbox-sdk"
39+
>
40+
See full announcement
41+
</MessageStripe.Action>
42+
</MessageStripe>
43+
);

packages/app/src/app/components/WorkspaceSetup/Layout.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,10 @@ export const WorkspaceFlowLayout: React.FC<{
3535
css={{
3636
width: '100%',
3737
height: '100%',
38-
padding: '64px',
38+
padding: '64px 0px',
3939
flex: 1,
4040
'@media (max-width: 1330px)': {
41-
padding: '64px 24px',
41+
padding: '64px 16px',
4242
},
4343
'@media (max-width: 768px)': {
4444
height: 'auto',

packages/app/src/app/components/WorkspaceSetup/StepHeader.tsx

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
import React from 'react';
22
import { Icon, Stack, Text, Button } from '@codesandbox/components';
3-
import { useAppState } from 'app/overmind';
43

54
interface StepHeaderProps {
65
numberOfSteps: number;
76
currentStep: number;
87
title: string;
9-
workspaceId?: string;
8+
headerNote?: React.ReactNode;
109
onPrevStep: () => void;
1110
onDismiss: () => void;
1211
}
@@ -15,13 +14,10 @@ export const StepHeader = ({
1514
currentStep,
1615
numberOfSteps,
1716
title,
17+
headerNote,
1818
onDismiss,
1919
onPrevStep,
20-
workspaceId,
2120
}: StepHeaderProps) => {
22-
const { dashboard } = useAppState();
23-
const workspaceName = dashboard.teams.find(t => t.id === workspaceId)?.name;
24-
2521
return (
2622
<Stack direction="vertical" gap={8}>
2723
{currentStep === 0 ? (
@@ -65,7 +61,7 @@ export const StepHeader = ({
6561
{title}
6662
</Text>
6763

68-
{workspaceName && <Text>Upgrade {workspaceName}&apos;s workspace</Text>}
64+
{headerNote && <Text>{headerNote}</Text>}
6965
</Stack>
7066
</Stack>
7167
);

packages/app/src/app/components/WorkspaceSetup/WorkspaceSetup.tsx

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import { SpendingLimit } from './steps/SpendingLimit';
77
import { SelectWorkspace } from './steps/SelectWorkspace';
88
import { Addons } from './steps/Addons';
99
import { Finalize } from './steps/Finalize';
10-
import { ChangeAddons } from './steps/ChangeAddons';
1110
import { SelectUsecases } from './steps/SelectUsecases';
1211

1312
export type WorkspaceSetupProps = {
@@ -63,13 +62,8 @@ const STEP_COMPONENTS: Record<WorkspaceSetupStep, React.FC<StepProps>> = {
6362
usecases: SelectUsecases,
6463
plans: Plans,
6564
'spending-limit': SpendingLimit,
66-
addons: Addons,
65+
addons: Addons, // Deprecated
6766
finalize: Finalize,
68-
'change-addons-confirmation': ChangeAddons,
6967
};
7068

71-
const STEPS_WITH_CHECKOUT: WorkspaceSetupStep[] = [
72-
'spending-limit',
73-
'addons',
74-
'change-addons-confirmation',
75-
];
69+
const STEPS_WITH_CHECKOUT: WorkspaceSetupStep[] = ['spending-limit', 'addons'];

packages/app/src/app/components/WorkspaceSetup/steps/Addons.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,9 @@ export const Addons: React.FC<StepProps> = ({
2828

2929
const handleSubmit = () => {
3030
if (isPro) {
31-
checkout.calculateConversionCharge({ workspaceId: urlWorkspaceId });
31+
checkout.calculateLegacyToUBBConversionCharge({
32+
workspaceId: urlWorkspaceId,
33+
});
3234
}
3335

3436
track('Checkout - Next from addons', {
@@ -53,7 +55,6 @@ export const Addons: React.FC<StepProps> = ({
5355
? 'Update plan'
5456
: 'Choose your add-ons (optional)'
5557
}
56-
workspaceId={urlWorkspaceId}
5758
/>
5859

5960
<Stack direction="vertical" gap={8}>

packages/app/src/app/components/WorkspaceSetup/steps/ChangeAddons.tsx

Lines changed: 0 additions & 128 deletions
This file was deleted.
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
import React from 'react';
2+
import track from '@codesandbox/common/lib/utils/analytics';
3+
import { Stack, Button, Text, Icon } from '@codesandbox/components';
4+
import * as dashboardUrls from '@codesandbox/common/lib/utils/url-generator/dashboard';
5+
6+
import { SubscriptionInterval } from 'app/graphql/types';
7+
import { useURLSearchParams } from 'app/hooks/useURLSearchParams';
8+
import { useActions, useAppState } from 'app/overmind';
9+
import { StepProps } from '../types';
10+
import { StepHeader } from '../StepHeader';
11+
import { AnimatedStep } from '../elements';
12+
13+
export const ChangeLegacyPlan: React.FC<StepProps> = ({
14+
onPrevStep,
15+
onDismiss,
16+
currentStep,
17+
numberOfSteps,
18+
}) => {
19+
const actions = useActions();
20+
const { checkout } = useAppState();
21+
const { getQueryParam } = useURLSearchParams();
22+
const urlWorkspaceId = getQueryParam('workspace');
23+
24+
const handleSubmit = async e => {
25+
e.preventDefault();
26+
const result = await actions.checkout.convertToUsageBilling({
27+
workspaceId: urlWorkspaceId,
28+
});
29+
if (result.success) {
30+
track('Checkout - Change Pro Plan');
31+
window.location.href = dashboardUrls.portalOverview(urlWorkspaceId);
32+
} else {
33+
actions.addNotification({
34+
message: result.error,
35+
type: 'error',
36+
timeAlive: 10,
37+
});
38+
}
39+
};
40+
41+
return (
42+
<AnimatedStep>
43+
<Stack direction="vertical" gap={12} as="form" onSubmit={handleSubmit}>
44+
<StepHeader
45+
onPrevStep={onPrevStep}
46+
onDismiss={onDismiss}
47+
currentStep={currentStep}
48+
numberOfSteps={numberOfSteps}
49+
title="Review plan"
50+
/>
51+
52+
<Text color="#e5e5e5">You are switching to the following plan:</Text>
53+
54+
<Stack justify="space-between" gap={4}>
55+
<Stack direction="vertical">
56+
<Text size={6} color="#e5e5e5">
57+
Pro plan
58+
</Text>
59+
<Text>{checkout.newSubscription.totalCredits} VM credits</Text>
60+
</Stack>
61+
<Text size={6} color="#e5e5e5">
62+
${checkout.newSubscription.totalPrice} /{' '}
63+
{checkout.newSubscription.billingInterval ===
64+
SubscriptionInterval.Monthly
65+
? 'month'
66+
: 'year'}
67+
</Text>
68+
</Stack>
69+
70+
<Text>
71+
Additional VM credits are available on-demand for $0.018/credit.
72+
<br />
73+
Spending limit: ${checkout.spendingLimit} / month
74+
</Text>
75+
76+
{checkout.convertLegacyPlanToUBBCharge && (
77+
<Stack direction="vertical" gap={2}>
78+
<Stack justify="space-between" gap={4}>
79+
<Stack direction="vertical">
80+
<Text size={6} color="#e5e5e5">
81+
Current charge
82+
</Text>
83+
{checkout.convertLegacyPlanToUBBCharge.total > 0 && (
84+
/** If amount charged is 0 show a single line */
85+
<Text>Charge (excl. taxes)</Text>
86+
)}
87+
</Stack>
88+
<Stack direction="vertical" align="flex-end">
89+
<Text size={6} color="#e5e5e5">
90+
${checkout.convertLegacyPlanToUBBCharge.total}
91+
</Text>
92+
{checkout.convertLegacyPlanToUBBCharge.total > 0 && (
93+
/** If amount charged is 0 show a single line */
94+
<Text>
95+
${checkout.convertLegacyPlanToUBBCharge.totalExcludingTax}
96+
</Text>
97+
)}
98+
</Stack>
99+
</Stack>
100+
<Stack css={{ color: '#A8BFFA' }} gap={1}>
101+
<Icon name="circleBang" size={20} />
102+
<Text>
103+
The charge has been prorated based on your existing plan.
104+
<br />
105+
Your new billing cycle will start now.
106+
</Text>
107+
</Stack>
108+
</Stack>
109+
)}
110+
111+
<Button autoWidth size="large" type="submit">
112+
Accept changes
113+
</Button>
114+
</Stack>
115+
</AnimatedStep>
116+
);
117+
};

0 commit comments

Comments
 (0)