Skip to content

Commit 5d4e632

Browse files
authored
feat(pro): UI updates (#7110)
* wip * rename * show 'Free' badge next to team names * fix font-family name * show 'Free' badge next to active team name * rename around personal teams * link to team settings * remove active icon * update dropdown arrow * replace tooltip with external link * fixup * fix extra padding around disabled items * fixup
1 parent b33a6aa commit 5d4e632

File tree

9 files changed

+86
-94
lines changed

9 files changed

+86
-94
lines changed

packages/app/src/app/pages/Pro/upgrade/utils.ts renamed to packages/app/src/app/hooks/useCreateCustomerPortal.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,6 @@ import { useState } from 'react';
22
import { useEffects } from 'app/overmind';
33
import { dashboard } from '@codesandbox/common/lib/utils/url-generator';
44

5-
export type WorkspaceType = 'pro' | 'teamPro';
6-
export type Interval = 'month' | 'year';
7-
85
export const useCreateCustomerPortal = (
96
activeTeam: string
107
): [boolean, () => void] => {

packages/app/src/app/pages/Dashboard/Content/routes/Settings/TeamSettings/ManageSubscription/stripe.tsx

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
import React from 'react';
2-
import { Stack, Text, Link, Button } from '@codesandbox/components';
3-
import { useAppState } from 'app/overmind';
42
import { format } from 'date-fns';
5-
63
import css from '@styled-system/css';
7-
import { useCreateCustomerPortal } from 'app/pages/Pro/upgrade/utils';
4+
import { Stack, Text, Link, Button } from '@codesandbox/components';
5+
import { useAppState } from 'app/overmind';
6+
import { useCreateCustomerPortal } from 'app/hooks/useCreateCustomerPortal';
87

98
export const Stripe = () => {
109
const { activeTeam, activeTeamInfo: team } = useAppState();

packages/app/src/app/pages/Dashboard/Content/routes/Settings/UserSettings/ManageSubscription/Stripe.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { useAppState } from 'app/overmind';
44
import { format } from 'date-fns';
55

66
import css from '@styled-system/css';
7-
import { useCreateCustomerPortal } from '../../../../../../Pro/upgrade/utils';
7+
import { useCreateCustomerPortal } from 'app/hooks/useCreateCustomerPortal';
88

99
export const Stripe = () => {
1010
const { activeTeam, activeTeamInfo: team } = useAppState();

packages/app/src/app/pages/Dashboard/Sidebar/BottomMessages/TrialExpiring.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import React from 'react';
22
import { Stack, Text, Button } from '@codesandbox/components';
3-
import { useCreateCustomerPortal } from 'app/pages/Pro/upgrade/utils';
3+
import { useCreateCustomerPortal } from 'app/hooks/useCreateCustomerPortal';
44

55
export const TrialExpiring: React.FC<{
66
activeTeam: string;

packages/app/src/app/pages/Pro/upgrade.tsx renamed to packages/app/src/app/pages/Pro/Upgrade.tsx

Lines changed: 47 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -4,34 +4,38 @@ import {
44
ThemeProvider,
55
Stack,
66
Element,
7+
Link as StyledLink,
78
Tooltip,
9+
Icon,
810
Text,
911
} from '@codesandbox/components';
1012
import { Helmet } from 'react-helmet';
1113
import { Navigation } from 'app/pages/common/Navigation';
14+
import { useCreateCustomerPortal } from 'app/hooks/useCreateCustomerPortal';
1215
import css from '@styled-system/css';
1316
import { sortBy } from 'lodash-es';
1417
import { AnimatePresence, motion } from 'framer-motion';
1518
import { dashboard as dashboardUrls } from '@codesandbox/common/lib/utils/url-generator';
16-
import { useLocation, useHistory } from 'react-router-dom';
19+
import { useLocation, useHistory, Link as RouterLink } from 'react-router-dom';
1720
import { formatCurrency } from 'app/utils/currency';
1821
import { useCreateCheckout } from 'app/hooks';
19-
import { useCreateCustomerPortal, Interval } from './upgrade/utils';
2022
import {
2123
UpgradeButton,
2224
Caption,
2325
Summary,
2426
BoxPlaceholder,
2527
SwitchPlan,
2628
PlanTitle,
27-
} from './upgrade/elements';
28-
import { Switcher } from './upgrade/Switcher';
29+
} from './components/elements';
30+
import { Switcher } from './components/Switcher';
2931
import {
3032
SubscriptionPaymentProvider,
3133
SubscriptionType,
3234
TeamMemberAuthorization,
3335
} from '../../graphql/types';
3436

37+
type Interval = 'month' | 'year';
38+
3539
export const ProUpgrade = () => {
3640
const {
3741
pro: { pageMounted },
@@ -329,32 +333,46 @@ export const ProUpgrade = () => {
329333
exit={{ opacity: 0, height: 0 }}
330334
style={{ overflow: 'hidden' }}
331335
>
332-
<Caption css={{ paddingTop: 24 }}>
333-
<Element
334-
css={{ display: 'flex', alignItems: 'center' }}
335-
>
336-
Paid seats
337-
<Tooltip label="The amount of paid seats is automatically calculated by the amount of admin and editors per team.">
338-
<Element
339-
css={{ display: 'block', marginLeft: '.5em' }}
340-
>
341-
<svg
342-
width="12"
343-
height="12"
344-
viewBox="0 0 12 12"
345-
fill="none"
346-
xmlns="http://www.w3.org/2000/svg"
347-
style={{ display: 'block' }}
336+
<Stack justify="space-between">
337+
<Caption css={{ paddingTop: 24 }}>
338+
<Element
339+
css={{ display: 'flex', alignItems: 'center' }}
340+
>
341+
Paid seats
342+
<Tooltip label="The amount of paid seats is automatically calculated by the amount of admin and editors per team.">
343+
<Element
344+
css={{ display: 'block', marginLeft: '.5em' }}
348345
>
349-
<path
350-
d="M6 10.625C3.44568 10.625 1.375 8.55432 1.375 6C1.375 3.44568 3.44568 1.375 6 1.375C8.55432 1.375 10.625 3.44568 10.625 6C10.625 8.55432 8.55432 10.625 6 10.625ZM0.625 6C0.625 8.96853 3.03147 11.375 6 11.375C8.96853 11.375 11.375 8.96853 11.375 6C11.375 3.03147 8.96853 0.625002 6 0.625002C3.03147 0.625002 0.625 3.03147 0.625 6ZM6 8.875C6.20711 8.875 6.375 8.70711 6.375 8.5V6C6.375 5.79289 6.20711 5.625 6 5.625C5.79289 5.625 5.625 5.79289 5.625 6V8.5C5.625 8.70711 5.79289 8.875 6 8.875ZM6 4.5C6.2071 4.5 6.375 4.33211 6.375 4.125L6.375 4.0625C6.375 3.8554 6.20711 3.6875 6 3.6875C5.7929 3.6875 5.625 3.85539 5.625 4.0625L5.625 4.125C5.625 4.3321 5.79289 4.5 6 4.5Z"
351-
fill="#C5C5C5"
352-
/>
353-
</svg>
354-
</Element>
355-
</Tooltip>
356-
</Element>
357-
</Caption>
346+
<svg
347+
width="12"
348+
height="12"
349+
viewBox="0 0 12 12"
350+
fill="none"
351+
xmlns="http://www.w3.org/2000/svg"
352+
style={{ display: 'block' }}
353+
>
354+
<path
355+
d="M6 10.625C3.44568 10.625 1.375 8.55432 1.375 6C1.375 3.44568 3.44568 1.375 6 1.375C8.55432 1.375 10.625 3.44568 10.625 6C10.625 8.55432 8.55432 10.625 6 10.625ZM0.625 6C0.625 8.96853 3.03147 11.375 6 11.375C8.96853 11.375 11.375 8.96853 11.375 6C11.375 3.03147 8.96853 0.625002 6 0.625002C3.03147 0.625002 0.625 3.03147 0.625 6ZM6 8.875C6.20711 8.875 6.375 8.70711 6.375 8.5V6C6.375 5.79289 6.20711 5.625 6 5.625C5.79289 5.625 5.625 5.79289 5.625 6V8.5C5.625 8.70711 5.79289 8.875 6 8.875ZM6 4.5C6.2071 4.5 6.375 4.33211 6.375 4.125L6.375 4.0625C6.375 3.8554 6.20711 3.6875 6 3.6875C5.7929 3.6875 5.625 3.85539 5.625 4.0625L5.625 4.125C5.625 4.3321 5.79289 4.5 6 4.5Z"
356+
fill="#C5C5C5"
357+
/>
358+
</svg>
359+
</Element>
360+
</Tooltip>
361+
</Element>
362+
</Caption>
363+
364+
<Caption css={{ paddingTop: 24 }}>
365+
<StyledLink
366+
as={RouterLink}
367+
to={dashboardUrls.settings(activeTeam)}
368+
>
369+
<Stack gap={2}>
370+
<span>Go to team settings</span>
371+
<Icon name="external" size={16} />
372+
</Stack>
373+
</StyledLink>
374+
</Caption>
375+
</Stack>
358376

359377
<BoxPlaceholder>
360378
<span>{amountPaidMember}</span>

packages/app/src/app/pages/Pro/upgrade/Switcher.tsx renamed to packages/app/src/app/pages/Pro/components/Switcher.tsx

Lines changed: 29 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import React from 'react';
33
import { TeamAvatar } from 'app/components/TeamAvatar';
44
import styled from 'styled-components';
55
import {
6+
Badge,
67
Stack,
78
Avatar,
89
Menu,
@@ -41,6 +42,10 @@ export const Switcher: React.FC<{
4142
const members = activeTeamInfo.users.length;
4243
const memberLabel = `${members} member${members > 1 ? 's' : ''}`;
4344
const isPersonalWorkspace = workspaceType === 'pro';
45+
const isFreeWorkspace = ![
46+
SubscriptionType.TeamPro,
47+
SubscriptionType.PersonalPro,
48+
].includes(activeTeamInfo.subscription?.type);
4449

4550
return (
4651
<Stack
@@ -56,12 +61,16 @@ export const Switcher: React.FC<{
5661
name={activeTeamInfo.name}
5762
/>
5863

59-
<Stack css={{ marginLeft: 24}} direction="vertical">
60-
<WorkspaceName>
61-
<span>{activeTeamInfo.name}</span>
62-
</WorkspaceName>
64+
<Stack css={{ marginLeft: 24 }} direction="vertical">
65+
<Stack align="center" gap={1}>
66+
<WorkspaceName>
67+
<span>{activeTeamInfo.name}</span>
68+
</WorkspaceName>
69+
{isFreeWorkspace && <Badge color="accent">Free</Badge>}
70+
<Icon css={{ color: '#fff' }} name="chevronDown" size={8} />
71+
</Stack>
6372
<WorkspaceType>
64-
{isPersonalWorkspace ? 'personal team' : memberLabel}
73+
{isPersonalWorkspace ? 'Personal' : memberLabel}
6574
</WorkspaceType>
6675
</Stack>
6776
</Stack>
@@ -102,7 +111,7 @@ export const Switcher: React.FC<{
102111
onSelect={() => setActiveTeam(workspace)}
103112
key={workspace.id}
104113
disabled={disabled}
105-
style={{ opacity: disabled ? 0.5 : 1 }}
114+
style={{ opacity: disabled ? 0.5 : 1, padding: 0 }}
106115
>
107116
<Stack css={{ padding: '12px 24px' }} align="center">
108117
<TeamAvatar
@@ -115,21 +124,22 @@ export const Switcher: React.FC<{
115124
direction="vertical"
116125
css={{ flex: 1, marginLeft: 19 }}
117126
>
118-
<Stack>
119-
<Text size={4}>{workspace.name}</Text>
120-
{isPro && <ProBadge>Pro</ProBadge>}
127+
<Stack gap={1}>
128+
<Text size={4}>
129+
{workspace.id === personalWorkspaceId
130+
? 'Personal'
131+
: workspace.name}
132+
</Text>
121133
</Stack>
122134

123135
<Text size={3}>
124-
{workspace.id === personalWorkspaceId
125-
? 'personal team'
126-
: seatsLabel}
136+
{workspace.id !== personalWorkspaceId
137+
? seatsLabel
138+
: null}
127139
</Text>
128140
</Stack>
129141

130-
{workspace.id === activeTeamInfo.id && (
131-
<Icon css={{ marginLeft: 16 }} name="simpleCheck" />
132-
)}
142+
{!isPro && <Badge color="accent">Free</Badge>}
133143
</Stack>
134144
</MenuItem>
135145
);
@@ -247,17 +257,17 @@ const Dialog = styled.div`
247257
`;
248258

249259
const WorkspaceName = styled.p`
250-
font-family: 'TWKEverett', sans-serif;
260+
font-family: 'Inter', sans-serif;
251261
font-style: normal;
262+
font-size: 28px;
252263
font-weight: 500;
264+
line-height: 36px;
265+
letter-spacing: -0.01em;
253266
254267
margin: 0;
255-
position: relative;
256268
text-align: left;
257269
color: #e5e5e5;
258270
259-
font-size: 24px;
260-
261271
& span::-moz-selection {
262272
-webkit-text-stroke: 1px #e5e5e5;
263273
color: transparent;
@@ -269,15 +279,6 @@ const WorkspaceName = styled.p`
269279
color: transparent;
270280
background: transparent;
271281
}
272-
273-
&:after {
274-
content: '';
275-
position: absolute;
276-
right: -20px;
277-
top: calc(50% - 4px);
278-
border: 5px solid transparent;
279-
border-top: 7px solid white;
280-
}
281282
`;
282283

283284
const WorkspaceType = styled.p`
@@ -331,18 +332,3 @@ const MenuItem = styled(Menu.Item)`
331332
}
332333
}
333334
`;
334-
335-
const ProBadge = styled.p`
336-
border-radius: 2px;
337-
background-color: rgba(229, 229, 229, 0.1);
338-
color: #c5c5c5;
339-
340-
width: 35px;
341-
height: 18px;
342-
343-
text-align: center;
344-
line-height: 18px;
345-
font-size: 13px;
346-
347-
margin: 0 0 0 8px;
348-
`;

packages/app/src/app/pages/Pro/upgrade/elements.ts renamed to packages/app/src/app/pages/Pro/components/elements.ts

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,8 @@
11
import { Button } from '@codesandbox/components';
2-
import styled, { createGlobalStyle, css } from 'styled-components';
3-
4-
export const GlobalFonts = createGlobalStyle`
5-
@font-face {
6-
font-family: "TWKEverett";
7-
src: url("/static/fonts/TWKEverett-Medium-web.woff") format("woff"),
8-
url("/static/fonts/TWKEverett-Medium-web.ttf") format("ttf");
9-
}
10-
`;
2+
import styled, { css } from 'styled-components';
113

124
export const PlanTitle = styled.h1`
13-
font-family: 'TWKEverett', sans-serif;
5+
font-family: 'Everett', sans-serif;
146
font-weight: 500;
157
letter-spacing: -0.018em;
168
transition: all 0.6s ease;
@@ -130,7 +122,7 @@ export const SwitchPlan = styled.button`
130122
line-height: 42px;
131123
margin-top: 18px;
132124
margin-bottom: 4px;
133-
font-family: 'TWKEverett', sans-serif;
125+
font-family: 'Everett', sans-serif;
134126
135127
span {
136128
color: #434343;

packages/app/src/app/pages/Pro/index.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ import {
77
import { useHistory } from 'react-router-dom';
88
import { signInPageUrl } from '@codesandbox/common/lib/utils/url-generator';
99

10-
import { ProLegacy } from './legacy';
11-
import { ProUpgrade } from './upgrade';
10+
import { ProLegacy } from './Legacy';
11+
import { ProUpgrade } from './Upgrade';
1212

1313
export const ProPage: React.FC = () => {
1414
const { pageMounted } = useActions().pro;

0 commit comments

Comments
 (0)