Skip to content

Commit

Permalink
Wip make premium more visible
Browse files Browse the repository at this point in the history
  • Loading branch information
ClementPasteau committed Dec 18, 2024
1 parent e2281df commit d651606
Show file tree
Hide file tree
Showing 8 changed files with 238 additions and 75 deletions.
101 changes: 52 additions & 49 deletions newIDE/app/src/Profile/Subscription/SubscriptionDialog.js
Original file line number Diff line number Diff line change
Expand Up @@ -406,9 +406,13 @@ export default function SubscriptionDialog({
.filter(Boolean)
.filter(plan => {
if (filter === 'individual') {
return ['free', 'gdevelop_silver', 'gdevelop_gold'].includes(
plan.id
);
if (isPlanValid) {
return ['free', 'gdevelop_silver', 'gdevelop_gold'].includes(
plan.id
);
} else {
return ['gdevelop_silver', 'gdevelop_gold'].includes(plan.id);
}
}
if (filter === 'team') {
return ['gdevelop_startup', 'gdevelop_enterprise'].includes(
Expand All @@ -419,13 +423,15 @@ export default function SubscriptionDialog({
return ['gdevelop_education'].includes(plan.id);
}

return plan.id !== 'gdevelop_education';
return !['gdevelop_education', 'free'].includes(plan.id);
})
: null;

const dialogMaxWidth =
!displayedSubscriptionPlanWithPricingSystems ||
displayedSubscriptionPlanWithPricingSystems.length === 1
? 'sm'
: displayedSubscriptionPlanWithPricingSystems.length < 3
? 'md'
: displayedSubscriptionPlanWithPricingSystems.length < 4
? 'lg'
Expand Down Expand Up @@ -465,54 +471,51 @@ export default function SubscriptionDialog({
open={open}
fixedContent={
<>
{hasValidSubscriptionPlan(authenticatedUser.subscription) &&
userSubscriptionPlanWithPricingSystems && (
<Column noMargin>
<Text>
<Trans>Your plan:</Trans>
</Text>
<Paper
background="medium"
variant="outlined"
style={styles.currentPlanPaper}
{isPlanValid && userSubscriptionPlanWithPricingSystems && (
<Column noMargin>
<Text>
<Trans>Your plan:</Trans>
</Text>
<Paper
background="medium"
variant="outlined"
style={styles.currentPlanPaper}
>
<Line
justifyContent="space-between"
alignItems="center"
noMargin
>
<Line
justifyContent="space-between"
alignItems="center"
noMargin
>
<Line alignItems="center" noMargin>
{getPlanIcon({
subscriptionPlan: userSubscriptionPlanWithPricingSystems,
logoSize: 20,
})}
<Text size="block-title">
{selectMessageByLocale(
i18n,
userSubscriptionPlanWithPricingSystems.nameByLocale
)}
</Text>
</Line>
{!hasSubscriptionBeenManuallyAdded(
authenticatedUser.subscription
) &&
!isSubscriptionComingFromTeam(
authenticatedUser.subscription
) &&
!willCancelAtPeriodEnd &&
userPricingSystemId !== 'REDEMPTION_CODE' && (
<FlatButton
primary
label={<Trans>Cancel subscription</Trans>}
onClick={() =>
buyUpdateOrCancelPlan(i18n, null)
}
/>
<Line alignItems="center" noMargin>
{getPlanIcon({
subscriptionPlan: userSubscriptionPlanWithPricingSystems,
logoSize: 20,
})}
<Text size="block-title">
{selectMessageByLocale(
i18n,
userSubscriptionPlanWithPricingSystems.nameByLocale
)}
</Text>
</Line>
</Paper>
</Column>
)}
{!hasSubscriptionBeenManuallyAdded(
authenticatedUser.subscription
) &&
!isSubscriptionComingFromTeam(
authenticatedUser.subscription
) &&
!willCancelAtPeriodEnd &&
userPricingSystemId !== 'REDEMPTION_CODE' && (
<FlatButton
primary
label={<Trans>Cancel subscription</Trans>}
onClick={() => buyUpdateOrCancelPlan(i18n, null)}
/>
)}
</Line>
</Paper>
</Column>
)}
<Line justifyContent="space-between" alignItems="center">
<Text size="block-title">
<Trans>Subscription plans</Trans>
Expand Down
52 changes: 52 additions & 0 deletions newIDE/app/src/UI/CustomSvgIcons/CrownShining.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import React from 'react';
import SvgIcon from '@material-ui/core/SvgIcon';

export default React.memo(props => (
<SvgIcon
{...props}
width="16"
height="16"
viewBox="0 0 16 16"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M7.99999 0.166656C8.27613 0.166656 8.49999 0.390514 8.49999 0.666656V1.33332C8.49999 1.60947 8.27613 1.83332 7.99999 1.83332C7.72385 1.83332 7.49999 1.60947 7.49999 1.33332V0.666656C7.49999 0.390514 7.72385 0.166656 7.99999 0.166656Z"
fill="currentColor"
/>
<path
d="M14.1667 7.99999C14.1667 7.72385 14.3905 7.49999 14.6667 7.49999H15.3333C15.6095 7.49999 15.8333 7.72385 15.8333 7.99999C15.8333 8.27613 15.6095 8.49999 15.3333 8.49999H14.6667C14.3905 8.49999 14.1667 8.27613 14.1667 7.99999Z"
fill="currentColor"
/>
<path
d="M8.49999 14.6667C8.49999 14.3905 8.27613 14.1667 7.99999 14.1667C7.72385 14.1667 7.49999 14.3905 7.49999 14.6667V15.3333C7.49999 15.6095 7.72385 15.8333 7.99999 15.8333C8.27613 15.8333 8.49999 15.6095 8.49999 15.3333V14.6667Z"
fill="currentColor"
/>
<path
d="M12.3131 12.3131C12.5084 12.1178 12.8249 12.1178 13.0202 12.3131L13.6869 12.9798C13.8821 13.175 13.8821 13.4916 13.6869 13.6869C13.4916 13.8821 13.175 13.8821 12.9798 13.6869L12.3131 13.0202C12.1178 12.8249 12.1178 12.5084 12.3131 12.3131Z"
fill="currentColor"
/>
<path
d="M13.6869 3.02021C13.8821 2.82495 13.8821 2.50837 13.6869 2.3131C13.4916 2.11784 13.175 2.11784 12.9798 2.3131L12.3131 2.97977C12.1178 3.17503 12.1178 3.49161 12.3131 3.68688C12.5084 3.88214 12.8249 3.88214 13.0202 3.68688L13.6869 3.02021Z"
fill="currentColor"
/>
<path
d="M3.68688 12.3131C3.88214 12.5084 3.88214 12.8249 3.68688 13.0202L3.02021 13.6869C2.82495 13.8821 2.50837 13.8821 2.3131 13.6869C2.11784 13.4916 2.11784 13.175 2.3131 12.9798L2.97977 12.3131C3.17503 12.1178 3.49161 12.1178 3.68688 12.3131Z"
fill="currentColor"
/>
<path
d="M3.02021 2.3131C2.82495 2.11784 2.50837 2.11784 2.3131 2.3131C2.11784 2.50837 2.11784 2.82495 2.3131 3.02021L2.97977 3.68688C3.17503 3.88214 3.49161 3.88214 3.68688 3.68688C3.88214 3.49161 3.88214 3.17503 3.68688 2.97977L3.02021 2.3131Z"
fill="currentColor"
/>
<path
d="M0.166656 7.99999C0.166656 7.72385 0.390514 7.49999 0.666656 7.49999H1.33332C1.60947 7.49999 1.83332 7.72385 1.83332 7.99999C1.83332 8.27613 1.60947 8.49999 1.33332 8.49999H0.666656C0.390514 8.49999 0.166656 8.27613 0.166656 7.99999Z"
fill="currentColor"
/>
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M4.22361 5.21944C4.05503 5.13515 3.85337 5.15282 3.70202 5.26515C3.55067 5.37748 3.47535 5.56537 3.50719 5.75114L4.30719 10.4178C4.34834 10.6578 4.55646 10.8333 4.8 10.8333H11.2C11.4435 10.8333 11.6517 10.6578 11.6928 10.4178L12.4928 5.75114C12.5247 5.56537 12.4493 5.37748 12.298 5.26515C12.1466 5.15282 11.945 5.13515 11.7764 5.21944L9.32557 6.44486L8.37963 5.34126C8.28464 5.23044 8.14597 5.16666 8 5.16666C7.85404 5.16666 7.71537 5.23044 7.62037 5.34126L6.67444 6.44486L4.22361 5.21944ZM5.22158 9.83332L4.65967 6.55551L6.5764 7.51387C6.78161 7.61648 7.03032 7.56625 7.17963 7.39205L8 6.43495L8.82038 7.39205C8.96969 7.56625 9.2184 7.61648 9.42361 7.51387L11.3403 6.55551L10.7784 9.83332H5.22158Z"
fill="currentColor"
/>
</SvgIcon>
));
3 changes: 2 additions & 1 deletion newIDE/app/src/UI/RaisedButton.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import classNames from 'classnames';
export type RaisedButtonPropsWithoutOnClick = {|
label?: React.Node,
primary?: boolean,
color?: 'primary' | 'success' | 'danger',
color?: 'primary' | 'success' | 'danger' | 'premium',
size?: 'medium',
disabled?: boolean,
keyboardFocused?: boolean,
Expand Down Expand Up @@ -69,6 +69,7 @@ const RaisedButton = React.forwardRef<RaisedButtonProps, ButtonInterface>(
className={classNames({
[classes.buttonSuccess]: color === 'success',
[classes.buttonDanger]: color === 'danger',
[classes.buttonPremium]: color === 'premium',
})}
style={
style || !label
Expand Down
9 changes: 9 additions & 0 deletions newIDE/app/src/UI/RaisedButton.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,13 @@ button.buttonDanger {
button.buttonDanger:hover {
background-color: var(--theme-error-dark);
color: var(--theme-error-text-contrast-color);
}

button.buttonPremium {
background: linear-gradient(90deg, #3BF7F4 0%, #FFBC57 100%);
color: var(--theme-secondary-text-contrast-color);
}

button.buttonPremium:hover {
background: linear-gradient(90deg, #FFBC57 0%, #3BF7F4 100%);
}
48 changes: 48 additions & 0 deletions newIDE/app/src/UI/User/UserAvatar.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// @flow
import * as React from 'react';
import { Avatar, makeStyles } from '@material-ui/core';
import { getGravatarUrl } from '../GravatarUrl';

const styles = {
avatar: {
width: 20,
height: 20,
},
premiumAvatar: {
width: 16,
height: 16,
},
};

type Props = {| iconUrl: string, isPremium: boolean |};

export default function UserAvatar({ iconUrl, isPremium }: Props) {
const classes = makeStyles(theme => ({
premiumContainer: {
position: 'relative',
overflow: 'hidden',
padding: '2px',
borderRadius: '16px',
display: 'flex',
'&::before': {
content: "''",
display: 'block',
background: `linear-gradient(90deg, #3BF7F4 0%, #FFBC57 100%)`,
width: '100%',
paddingBottom: '100%',
position: 'absolute',
left: '50%',
top: '50%',
transform: 'translate(-50%, -50%)',
},
},
}))();

return isPremium ? (
<div className={classes.premiumContainer}>
<Avatar src={getGravatarUrl(iconUrl)} style={styles.premiumAvatar} />
</div>
) : (
<Avatar src={getGravatarUrl(iconUrl)} style={styles.avatar} />
);
}
67 changes: 49 additions & 18 deletions newIDE/app/src/UI/User/UserChip.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// @flow
import * as React from 'react';
import { Trans } from '@lingui/macro';
import Avatar from '@material-ui/core/Avatar';
import { getGravatarUrl } from '../GravatarUrl';
import RaisedButton from '../RaisedButton';
import { shortenString } from '../../Utils/StringHelpers';
Expand All @@ -10,44 +9,76 @@ import { LineStackLayout } from '../Layout';
import AuthenticatedUserContext from '../../Profile/AuthenticatedUserContext';
import CircularProgress from '../CircularProgress';
import User from '../CustomSvgIcons/User';
import { SubscriptionSuggestionContext } from '../../Profile/Subscription/SubscriptionSuggestionContext';
import { Line } from '../Grid';
import { hasValidSubscriptionPlan } from '../../Utils/GDevelopServices/Usage';
import CrownShining from '../CustomSvgIcons/CrownShining';
import UserAvatar from './UserAvatar';

const styles = {
avatar: {
width: 20,
height: 20,
},
buttonContainer: { flexShrink: 0 },
};

const GetPremiumButton = () => {
const { openSubscriptionDialog } = React.useContext(
SubscriptionSuggestionContext
);
return (
<RaisedButton
icon={<CrownShining />}
onClick={() => {
openSubscriptionDialog({
analyticsMetadata: {
reason: 'Account get premium',
},
});
}}
id="get-premium-button"
label={<Trans>Get premium</Trans>}
color="premium"
/>
);
};

type Props = {|
onOpenProfile: () => void,
|};

const UserChip = ({ onOpenProfile }: Props) => {
const authenticatedUser = React.useContext(AuthenticatedUserContext);
const { profile, onOpenCreateAccountDialog, loginState } = authenticatedUser;
const {
profile,
onOpenCreateAccountDialog,
loginState,
subscription,
} = authenticatedUser;

const isPremium = hasValidSubscriptionPlan(subscription);

return !profile && loginState === 'loggingIn' ? (
<CircularProgress size={25} />
) : profile ? (
<TextButton
label={shortenString(profile.username || profile.email, 20)}
onClick={onOpenProfile}
allowBrowserAutoTranslate={false}
icon={
<Avatar
src={getGravatarUrl(profile.email || '', { size: 50 })}
style={styles.avatar}
/>
}
/>
<Line noMargin>
<TextButton
label={shortenString(profile.username || profile.email, 20)}
onClick={onOpenProfile}
allowBrowserAutoTranslate={false}
icon={
<UserAvatar
iconUrl={getGravatarUrl(profile.email || '', { size: 50 })}
isPremium={isPremium}
/>
}
/>
{isPremium ? null : <GetPremiumButton />}
</Line>
) : (
<div style={styles.buttonContainer}>
<LineStackLayout noMargin alignItems="center">
<RaisedButton
label={
<span>
<Trans>Create account</Trans>
<Trans>Account</Trans>
</span>
}
onClick={onOpenCreateAccountDialog}
Expand Down
3 changes: 2 additions & 1 deletion newIDE/app/src/Utils/Analytics/EventSender.js
Original file line number Diff line number Diff line change
Expand Up @@ -375,7 +375,8 @@ export type SubscriptionDialogDisplayReason =
| 'Callout in Classroom tab'
| 'Unlock build type'
| 'Manage subscription as teacher'
| 'Unlock course chapter';
| 'Unlock course chapter'
| 'Account get premium';

export const sendSubscriptionDialogShown = (metadata: {|
reason: SubscriptionDialogDisplayReason,
Expand Down
Loading

0 comments on commit d651606

Please sign in to comment.