Skip to content

feat(pro): UI updates #7110

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

Merged
merged 13 commits into from
Nov 8, 2022
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@ import { useState } from 'react';
import { useEffects } from 'app/overmind';
import { dashboard } from '@codesandbox/common/lib/utils/url-generator';

export type WorkspaceType = 'pro' | 'teamPro';
export type Interval = 'month' | 'year';

export const useCreateCustomerPortal = (
activeTeam: string
): [boolean, () => void] => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import React from 'react';
import { Stack, Text, Link, Button } from '@codesandbox/components';
import { useAppState } from 'app/overmind';
import { format } from 'date-fns';

import css from '@styled-system/css';
import { useCreateCustomerPortal } from 'app/pages/Pro/upgrade/utils';
import { Stack, Text, Link, Button } from '@codesandbox/components';
import { useAppState } from 'app/overmind';
import { useCreateCustomerPortal } from 'app/hooks/useCreateCustomerPortal';

export const Stripe = () => {
const { activeTeam, activeTeamInfo: team } = useAppState();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { useAppState } from 'app/overmind';
import { format } from 'date-fns';

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

export const Stripe = () => {
const { activeTeam, activeTeamInfo: team } = useAppState();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';
import { Stack, Text, Button } from '@codesandbox/components';
import { useCreateCustomerPortal } from 'app/pages/Pro/upgrade/utils';
import { useCreateCustomerPortal } from 'app/hooks/useCreateCustomerPortal';

export const TrialExpiring: React.FC<{
activeTeam: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,34 +4,38 @@ import {
ThemeProvider,
Stack,
Element,
Link as StyledLink,
Tooltip,
Icon,
Text,
} from '@codesandbox/components';
import { Helmet } from 'react-helmet';
import { Navigation } from 'app/pages/common/Navigation';
import { useCreateCustomerPortal } from 'app/hooks/useCreateCustomerPortal';
import css from '@styled-system/css';
import { sortBy } from 'lodash-es';
import { AnimatePresence, motion } from 'framer-motion';
import { dashboard as dashboardUrls } from '@codesandbox/common/lib/utils/url-generator';
import { useLocation, useHistory } from 'react-router-dom';
import { useLocation, useHistory, Link as RouterLink } from 'react-router-dom';
import { formatCurrency } from 'app/utils/currency';
import { useCreateCheckout } from 'app/hooks';
import { useCreateCustomerPortal, Interval } from './upgrade/utils';
import {
UpgradeButton,
Caption,
Summary,
BoxPlaceholder,
SwitchPlan,
PlanTitle,
} from './upgrade/elements';
import { Switcher } from './upgrade/Switcher';
} from './components/elements';
import { Switcher } from './components/Switcher';
import {
SubscriptionPaymentProvider,
SubscriptionType,
TeamMemberAuthorization,
} from '../../graphql/types';

type Interval = 'month' | 'year';

export const ProUpgrade = () => {
const {
pro: { pageMounted },
Expand Down Expand Up @@ -329,32 +333,46 @@ export const ProUpgrade = () => {
exit={{ opacity: 0, height: 0 }}
style={{ overflow: 'hidden' }}
>
<Caption css={{ paddingTop: 24 }}>
<Element
css={{ display: 'flex', alignItems: 'center' }}
>
Paid seats
<Tooltip label="The amount of paid seats is automatically calculated by the amount of admin and editors per team.">
<Element
css={{ display: 'block', marginLeft: '.5em' }}
>
<svg
width="12"
height="12"
viewBox="0 0 12 12"
fill="none"
xmlns="http://www.w3.org/2000/svg"
style={{ display: 'block' }}
<Stack justify="space-between">
<Caption css={{ paddingTop: 24 }}>
<Element
css={{ display: 'flex', alignItems: 'center' }}
>
Paid seats
<Tooltip label="The amount of paid seats is automatically calculated by the amount of admin and editors per team.">
<Element
css={{ display: 'block', marginLeft: '.5em' }}
>
<path
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"
fill="#C5C5C5"
/>
</svg>
</Element>
</Tooltip>
</Element>
</Caption>
<svg
width="12"
height="12"
viewBox="0 0 12 12"
fill="none"
xmlns="http://www.w3.org/2000/svg"
style={{ display: 'block' }}
>
<path
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"
fill="#C5C5C5"
/>
</svg>
</Element>
</Tooltip>
</Element>
</Caption>

<Caption css={{ paddingTop: 24 }}>
<StyledLink
as={RouterLink}
to={dashboardUrls.settings(activeTeam)}
>
<Stack gap={2}>
<span>Go to team settings</span>
<Icon name="external" size={16} />
</Stack>
</StyledLink>
</Caption>
</Stack>

<BoxPlaceholder>
<span>{amountPaidMember}</span>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import React from 'react';
import { TeamAvatar } from 'app/components/TeamAvatar';
import styled from 'styled-components';
import {
Badge,
Stack,
Avatar,
Menu,
Expand Down Expand Up @@ -41,6 +42,10 @@ export const Switcher: React.FC<{
const members = activeTeamInfo.users.length;
const memberLabel = `${members} member${members > 1 ? 's' : ''}`;
const isPersonalWorkspace = workspaceType === 'pro';
const isFreeWorkspace = ![
SubscriptionType.TeamPro,
SubscriptionType.PersonalPro,
].includes(activeTeamInfo.subscription?.type);

return (
<Stack
Expand All @@ -56,12 +61,16 @@ export const Switcher: React.FC<{
name={activeTeamInfo.name}
/>

<Stack css={{ marginLeft: 24}} direction="vertical">
<WorkspaceName>
<span>{activeTeamInfo.name}</span>
</WorkspaceName>
<Stack css={{ marginLeft: 24 }} direction="vertical">
<Stack align="center" gap={1}>
<WorkspaceName>
<span>{activeTeamInfo.name}</span>
</WorkspaceName>
{isFreeWorkspace && <Badge color="accent">Free</Badge>}
<Icon css={{ color: '#fff' }} name="chevronDown" size={8} />
</Stack>
<WorkspaceType>
{isPersonalWorkspace ? 'personal team' : memberLabel}
{isPersonalWorkspace ? 'Personal' : memberLabel}
</WorkspaceType>
</Stack>
</Stack>
Expand Down Expand Up @@ -102,7 +111,7 @@ export const Switcher: React.FC<{
onSelect={() => setActiveTeam(workspace)}
key={workspace.id}
disabled={disabled}
style={{ opacity: disabled ? 0.5 : 1 }}
style={{ opacity: disabled ? 0.5 : 1, padding: 0 }}
>
<Stack css={{ padding: '12px 24px' }} align="center">
<TeamAvatar
Expand All @@ -115,21 +124,22 @@ export const Switcher: React.FC<{
direction="vertical"
css={{ flex: 1, marginLeft: 19 }}
>
<Stack>
<Text size={4}>{workspace.name}</Text>
{isPro && <ProBadge>Pro</ProBadge>}
<Stack gap={1}>
<Text size={4}>
{workspace.id === personalWorkspaceId
? 'Personal'
: workspace.name}
</Text>
</Stack>

<Text size={3}>
{workspace.id === personalWorkspaceId
? 'personal team'
: seatsLabel}
{workspace.id !== personalWorkspaceId
? seatsLabel
: null}
</Text>
</Stack>

{workspace.id === activeTeamInfo.id && (
<Icon css={{ marginLeft: 16 }} name="simpleCheck" />
)}
{!isPro && <Badge color="accent">Free</Badge>}
</Stack>
</MenuItem>
);
Expand Down Expand Up @@ -247,17 +257,17 @@ const Dialog = styled.div`
`;

const WorkspaceName = styled.p`
font-family: 'TWKEverett', sans-serif;
font-family: 'Inter', sans-serif;
font-style: normal;
font-size: 28px;
font-weight: 500;
line-height: 36px;
letter-spacing: -0.01em;

margin: 0;
position: relative;
text-align: left;
color: #e5e5e5;

font-size: 24px;

& span::-moz-selection {
-webkit-text-stroke: 1px #e5e5e5;
color: transparent;
Expand All @@ -269,15 +279,6 @@ const WorkspaceName = styled.p`
color: transparent;
background: transparent;
}

&:after {
content: '';
position: absolute;
right: -20px;
top: calc(50% - 4px);
border: 5px solid transparent;
border-top: 7px solid white;
}
`;

const WorkspaceType = styled.p`
Expand Down Expand Up @@ -331,18 +332,3 @@ const MenuItem = styled(Menu.Item)`
}
}
`;

const ProBadge = styled.p`
border-radius: 2px;
background-color: rgba(229, 229, 229, 0.1);
color: #c5c5c5;

width: 35px;
height: 18px;

text-align: center;
line-height: 18px;
font-size: 13px;

margin: 0 0 0 8px;
`;
Original file line number Diff line number Diff line change
@@ -1,16 +1,8 @@
import { Button } from '@codesandbox/components';
import styled, { createGlobalStyle, css } from 'styled-components';

export const GlobalFonts = createGlobalStyle`
@font-face {
font-family: "TWKEverett";
src: url("/static/fonts/TWKEverett-Medium-web.woff") format("woff"),
url("/static/fonts/TWKEverett-Medium-web.ttf") format("ttf");
}
`;
import styled, { css } from 'styled-components';

export const PlanTitle = styled.h1`
font-family: 'TWKEverett', sans-serif;
font-family: 'Everett', sans-serif;
font-weight: 500;
letter-spacing: -0.018em;
transition: all 0.6s ease;
Expand Down Expand Up @@ -130,7 +122,7 @@ export const SwitchPlan = styled.button`
line-height: 42px;
margin-top: 18px;
margin-bottom: 4px;
font-family: 'TWKEverett', sans-serif;
font-family: 'Everett', sans-serif;

span {
color: #434343;
Expand Down
4 changes: 2 additions & 2 deletions packages/app/src/app/pages/Pro/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import {
import { useHistory } from 'react-router-dom';
import { signInPageUrl } from '@codesandbox/common/lib/utils/url-generator';

import { ProLegacy } from './legacy';
import { ProUpgrade } from './upgrade';
import { ProLegacy } from './Legacy';
import { ProUpgrade } from './Upgrade';

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