Skip to content

Commit

Permalink
feat: new pricing plans design (#2374)
Browse files Browse the repository at this point in the history
  • Loading branch information
stepan662 committed Jun 26, 2024
1 parent 7412852 commit 6f5762b
Show file tree
Hide file tree
Showing 92 changed files with 2,827 additions and 1,972 deletions.
9 changes: 3 additions & 6 deletions e2e/cypress/support/dataCyType.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,6 @@ declare namespace DataCy {
"billing-actual-used-strings" |
"billing-estimated-costs" |
"billing-estimated-costs-open-button" |
"billing-extra-credits-buy" |
"billing-invoice-item-number" |
"billing-invoice-usage-button" |
"billing-invoices-list" |
Expand All @@ -106,13 +105,11 @@ declare namespace DataCy {
"billing-plan" |
"billing-plan-action-button" |
"billing-plan-monthly-price" |
"billing-plan-price-per-seat-extra" |
"billing-plan-price-per-thousand-mt-credits-extra" |
"billing-plan-price-per-thousand-strings-extra" |
"billing-plan-price-extra-seat" |
"billing-plan-price-extra-thousand-mt-credits" |
"billing-plan-price-extra-thousand-strings" |
"billing-plan-subtitle" |
"billing-plan-title" |
"billing-progress-label-item" |
"billing-self-hosted-ee-plan" |
"billing-self-hosted-ee-plan-subscribe-button" |
"billing-subscriptions-cloud-button" |
"billing-subscriptions-self-hosted-ee-button" |
Expand Down
20 changes: 12 additions & 8 deletions webapp/src/ThemeProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import RighteousLatinWoff2 from './fonts/Righteous/righteous-latin.woff2';
// @ts-ignore
import RubikWoff2 from './fonts/Rubik/Rubik-Regular.woff2';
import { colors } from './colors';
import { tolgeeColors, tolgeePalette } from 'figmaTheme';

const LOCALSTORAGE_THEME_MODE = 'themeMode';

Expand Down Expand Up @@ -61,11 +62,13 @@ const righteousLatinExt = {

const getTheme = (mode: PaletteMode) => {
const c = mode === 'light' ? colors.light : colors.dark;
const tPalette = mode === 'light' ? tolgeePalette.Light : tolgeePalette.Dark;

return createTheme({
typography: {
fontFamily:
'-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"',
htmlFontSize: 15,
h1: {
fontSize: 42,
fontWeight: 300,
Expand Down Expand Up @@ -121,17 +124,19 @@ const getTheme = (mode: PaletteMode) => {
},
palette: {
mode,
primary: createColor(c.primary),
primary: tPalette.primary,
primaryText: c.primaryText,
secondary: createColor(c.secondary),
secondary: tPalette.secondary,
default: createColor(c.default),
info: createColor(c.info),
info: tPalette.info,
warning: tPalette.warning,
error: tPalette.error,
common: {
white: c.white,
},
text: {
primary: c.text,
secondary: c.textSecondary,
primary: tPalette.text.primary,
secondary: tPalette.text.secondary,
},
divider1: c.divider1,
tile: c.tile,
Expand All @@ -145,16 +150,15 @@ const getTheme = (mode: PaletteMode) => {
activity: c.activity,
emphasis: c.emphasis,
editor: c.editor,
billingProgress: c.billingProgress,
billingPlan: createColor(c.billingPlan),
globalLoading: createColor(c.globalLoading),
marker: c.marker,
topBanner: c.topBanner,
quickStart: c.quickStart,
import: c.import,
exampleBanner: c.exampleBanner,
tipsBanner: c.tipsBanner,
tokens: c.tokens,
tokens: tPalette,
colors: tolgeeColors,
placeholders: c.placeholders,
languageChips: c.languageChips,
login: c.login,
Expand Down
42 changes: 0 additions & 42 deletions webapp/src/colors.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { grey } from '@mui/material/colors';
import { ALL_TOKENS } from './tokens';

const customGrey: Emphasis = {
50: '#f0f2f4',
Expand Down Expand Up @@ -52,15 +51,6 @@ export type Activity = {
addedHighlight: string;
};

export type BillingProgress = {
background: string;
low: string;
over: string;
sufficient: string;
overForbidden: string;
separator: string;
};

export type Marker = {
primary: string;
secondary: string;
Expand Down Expand Up @@ -140,18 +130,6 @@ export type LanguageChips = {
background: string;
};

const getTokensByMode = (mode: 'light' | 'dark') => {
const result = {} as Record<keyof typeof ALL_TOKENS, string>;
Object.entries(ALL_TOKENS).map(([tokenName, value]) => {
if (typeof value === 'string') {
result[tokenName] = value;
} else {
result[tokenName] = value[mode];
}
});
return result;
};

export const colors = {
light: {
white: '#fff',
Expand Down Expand Up @@ -188,15 +166,6 @@ export const colors = {
other: '#002bff',
main: '#2C3C52',
} satisfies Editor,
billingProgress: {
background: '#C4C4C4',
low: '#E80000',
over: '#ffce00',
overForbidden: '#970000',
sufficient: '#17AD18',
separator: '#656565',
} satisfies BillingProgress,
billingPlan: '#F8F8F8',
globalLoading: '#c9a2b5',
marker: {
primary: '#ff0000',
Expand Down Expand Up @@ -243,7 +212,6 @@ export const colors = {
languageChips: {
background: '#F6F6F8',
} satisfies LanguageChips,
tokens: getTokensByMode('light'),
placeholders: {
variable: {
border: '#7AD3C1',
Expand Down Expand Up @@ -323,15 +291,6 @@ export const colors = {
other: '#99aaff',
main: '#eeeeee',
} satisfies Editor,
billingProgress: {
background: '#565656',
low: '#ca0000',
over: '#ffce00',
overForbidden: '#980000',
sufficient: '#1e991e',
separator: '#656565',
} satisfies BillingProgress,
billingPlan: '#233043',
globalLoading: '#ff6995',
marker: {
primary: '#ff0000',
Expand Down Expand Up @@ -377,7 +336,6 @@ export const colors = {
languageChips: {
background: '#243245',
} satisfies LanguageChips,
tokens: getTokensByMode('dark'),
placeholders: {
variable: {
border: '#008371',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { T } from '@tolgee/react';
import { Box, Typography } from '@mui/material';

import { components } from 'tg.service/billingApiSchema.generated';
import { useDateFormatter } from 'tg.hooks/useLocale';
import { PlanTitleText } from '../Plan/PlanTitle';

type Status = components['schemas']['SelfHostedEeSubscriptionModel']['status'];

type Props = {
name: string;
status: Status;
createdAt?: number;
periodStart?: number;
periodEnd?: number;
highlightColor: string;
};

export const ActivePlanTitle = ({
name,
createdAt,
periodStart,
periodEnd,
highlightColor,
}: Props) => {
const formatDate = useDateFormatter();

return (
<Box sx={{ mb: 1 }}>
<PlanTitleText sx={{ color: highlightColor, mb: 1 }}>
{name}
</PlanTitleText>
<Box display="grid">
{createdAt && (
<Typography variant="caption">
{createdAt && (
<Typography variant="caption">
<T keyName="active-plan-subscribed-at-tooltip" />:{' '}
{formatDate(createdAt)}
</Typography>
)}
</Typography>
)}
{Boolean(periodStart && periodEnd) && (
<Typography variant="caption">
<T
keyName="active-plan-current-period"
params={{ start: periodStart, end: periodEnd }}
/>
</Typography>
)}
</Box>
</Box>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { useTranslate } from '@tolgee/react';
import { styled, useTheme } from '@mui/material';
import { PlanSubtitle } from '../Plan/PlanStyles';
import { components } from 'tg.service/apiSchema.generated';

type EeSubscriptionModelStatus =
components['schemas']['EeSubscriptionModel']['status'];

const StyledCustomLabel = styled('span')`
font-size: 14px;
font-weight: 400;
text-transform: lowercase;
`;

type Props = {
status: EeSubscriptionModelStatus;
custom?: boolean;
};

export const ActiveSubscriptionBanner = ({ status, custom }: Props) => {
const { t } = useTranslate();
const theme = useTheme();

const statusMap: Record<
EeSubscriptionModelStatus,
{ label: string; color: 'secondary' | 'error' }
> = {
ACTIVE: { label: t('ee_license_status_label_active'), color: 'secondary' },
CANCELED: {
label: t('ee_license_status_label_canceled'),
color: 'error',
},
PAST_DUE: {
label: t('ee_license_status_label_past_due'),
color: 'error',
},
ERROR: { label: t('ee_license_status_label_error'), color: 'error' },
UNPAID: { label: t('ee_license_status_label_unpaid'), color: 'error' },
KEY_USED_BY_ANOTHER_INSTANCE: {
label: t('ee_license_status_label_key_used_by_another_instance'),
color: 'error',
},
};

const { label, color } = statusMap[status];
const clrObject = theme.palette.tokens[color];

return (
<PlanSubtitle
data-cy="billing-plan-subtitle"
sx={{ background: clrObject._states.hover, color: clrObject.main }}
>
<span>{label}</span>
{custom && (
<>
{' '}
<StyledCustomLabel className="noBackground">
{t('billing_subscription_custom')}
</StyledCustomLabel>
</>
)}
</PlanSubtitle>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { styled } from '@mui/material';
import { IncludedFeatures } from '../Plan/IncludedFeatures';
import { components } from 'tg.service/apiSchema.generated';
import { useState } from 'react';
import {
ShowAllFeaturesButton,
ShowAllFeaturesLink,
} from '../Plan/ShowAllFeatures';
import { PlanFeaturesBox } from '../Plan/PlanStyles';

type Features = components['schemas']['EeSubscriptionModel']['enabledFeatures'];

const StyledFeatures = styled(IncludedFeatures)`
display: grid;
grid-template-columns: repeat(auto-fit, minmax(min(200px, 100%), 1fr));
margin: 0px;
`;

type Props = {
custom: boolean;
features: Features;
};

export const CollapsedFeatures = ({ custom, features }: Props) => {
const [expanded, setExpanded] = useState(false);
return (
<>
{custom && expanded && (
<PlanFeaturesBox sx={{ gap: '18px', mb: 1 }}>
<StyledFeatures features={features} />
</PlanFeaturesBox>
)}
{custom && !expanded && (
<ShowAllFeaturesButton onClick={() => setExpanded(true)} />
)}
{!custom && <ShowAllFeaturesLink />}
</>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,10 @@ import { ClipboardCopyInput } from 'tg.component/common/ClipboardCopyInput';
type Props = {
licenseKey?: string;
defaultOpen: boolean;
custom?: boolean;
};

export const PlanLicenseKey = ({ licenseKey, defaultOpen }: Props) => {
export const PlanLicenseKey = ({ licenseKey, defaultOpen, custom }: Props) => {
useEffect(() => {
if (defaultOpen) {
setOpen(true);
Expand All @@ -32,7 +33,7 @@ export const PlanLicenseKey = ({ licenseKey, defaultOpen }: Props) => {
<Button
onClick={() => setOpen(true)}
size="small"
color="primary"
color={custom ? 'info' : 'primary'}
variant="contained"
>
<T keyName="active-plan-license-key-button" />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { FC } from 'react';
import { components } from 'tg.service/billingApiSchema.generated';
import { useBillingApiQuery } from 'tg.service/http/useQueryApi';
import { useOrganization } from '../../../useOrganization';
import { PlanUsageEstimatedCosts } from '../../common/usage/PlanUsageEstimatedCosts';
import { PlanUsageEstimatedCosts } from 'tg.views/organizations/billing/common/usage/PlanUsageEstimatedCosts';
import { useOrganization } from 'tg.views/organizations/useOrganization';

export const SelfHostedEeEstimatedCosts: FC<{
subscription: components['schemas']['SelfHostedEeSubscriptionModel'];
Expand Down
Loading

0 comments on commit 6f5762b

Please sign in to comment.