mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-02-17 23:44:39 -05:00
Refined plan change confirmation
no refs. - refined copy and design for plan change and confirmation
This commit is contained in:
parent
a32683fbb0
commit
7985c658fe
4 changed files with 151 additions and 34 deletions
|
@ -13,7 +13,7 @@ const DEV_MODE_DATA = {
|
||||||
showPopup: true,
|
showPopup: true,
|
||||||
site: Fixtures.site,
|
site: Fixtures.site,
|
||||||
member: Fixtures.member.paid,
|
member: Fixtures.member.paid,
|
||||||
page: 'signup'
|
page: 'accountPlan'
|
||||||
};
|
};
|
||||||
export default class App extends React.Component {
|
export default class App extends React.Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
|
|
|
@ -337,7 +337,7 @@ const GlobalStyles = `
|
||||||
}
|
}
|
||||||
|
|
||||||
.gh-portal-container-narrow {
|
.gh-portal-container-narrow {
|
||||||
width: 380px;
|
width: 388px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.gh-portal-popup-container.preview {
|
.gh-portal-popup-container.preview {
|
||||||
|
@ -452,6 +452,11 @@ const GlobalStyles = `
|
||||||
box-shadow: 0px 2px 4px 0px rgba(0, 0, 0, 0.07), 0px 1px 1.5px 0px rgba(0, 0, 0, 0.05);
|
box-shadow: 0px 2px 4px 0px rgba(0, 0, 0, 0.07), 0px 1px 1.5px 0px rgba(0, 0, 0, 0.05);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.gh-portal-list.outline {
|
||||||
|
box-shadow: none;
|
||||||
|
border: 1px solid var(--grey12);
|
||||||
|
}
|
||||||
|
|
||||||
.gh-portal-list section {
|
.gh-portal-list section {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
@ -497,6 +502,96 @@ const GlobalStyles = `
|
||||||
.gh-portal-icon {
|
.gh-portal-icon {
|
||||||
color: var(--brandcolor);
|
color: var(--brandcolor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Spacing modifiers
|
||||||
|
/* ----------------------------------------------------- */
|
||||||
|
.mt1 { margin-top: 4px; }
|
||||||
|
.mt2 { margin-top: 8px; }
|
||||||
|
.mt3 { margin-top: 12px; }
|
||||||
|
.mt4 { margin-top: 16px; }
|
||||||
|
.mt5 { margin-top: 20px; }
|
||||||
|
.mt6 { margin-top: 24px; }
|
||||||
|
.mt7 { margin-top: 28px; }
|
||||||
|
.mt8 { margin-top: 32px; }
|
||||||
|
.mt9 { margin-top: 36px; }
|
||||||
|
.mt10 { margin-top: 40px; }
|
||||||
|
|
||||||
|
.mr1 { margin-right: 4px; }
|
||||||
|
.mr2 { margin-right: 8px; }
|
||||||
|
.mr3 { margin-right: 12px; }
|
||||||
|
.mr4 { margin-right: 16px; }
|
||||||
|
.mr5 { margin-right: 20px; }
|
||||||
|
.mr6 { margin-right: 24px; }
|
||||||
|
.mr7 { margin-right: 28px; }
|
||||||
|
.mr8 { margin-right: 32px; }
|
||||||
|
.mr9 { margin-right: 36px; }
|
||||||
|
.mr10 { margin-right: 40px; }
|
||||||
|
|
||||||
|
.mb1 { margin-bottom: 4px; }
|
||||||
|
.mb2 { margin-bottom: 8px; }
|
||||||
|
.mb3 { margin-bottom: 12px; }
|
||||||
|
.mb4 { margin-bottom: 16px; }
|
||||||
|
.mb5 { margin-bottom: 20px; }
|
||||||
|
.mb6 { margin-bottom: 24px; }
|
||||||
|
.mb7 { margin-bottom: 28px; }
|
||||||
|
.mb8 { margin-bottom: 32px; }
|
||||||
|
.mb9 { margin-bottom: 36px; }
|
||||||
|
.mb10 { margin-bottom: 40px; }
|
||||||
|
|
||||||
|
.ml1 { margin-left: 4px; }
|
||||||
|
.ml2 { margin-left: 8px; }
|
||||||
|
.ml3 { margin-left: 12px; }
|
||||||
|
.ml4 { margin-left: 16px; }
|
||||||
|
.ml5 { margin-left: 20px; }
|
||||||
|
.ml6 { margin-left: 24px; }
|
||||||
|
.ml7 { margin-left: 28px; }
|
||||||
|
.ml8 { margin-left: 32px; }
|
||||||
|
.ml9 { margin-left: 36px; }
|
||||||
|
.ml10 { margin-left: 40px; }
|
||||||
|
|
||||||
|
.pt1 { padding-top: 4px; }
|
||||||
|
.pt2 { padding-top: 8px; }
|
||||||
|
.pt3 { padding-top: 12px; }
|
||||||
|
.pt4 { padding-top: 16px; }
|
||||||
|
.pt5 { padding-top: 20px; }
|
||||||
|
.pt6 { padding-top: 24px; }
|
||||||
|
.pt7 { padding-top: 28px; }
|
||||||
|
.pt8 { padding-top: 32px; }
|
||||||
|
.pt9 { padding-top: 36px; }
|
||||||
|
.pt10 { padding-top: 40px; }
|
||||||
|
|
||||||
|
.pr1 { padding-right: 4px; }
|
||||||
|
.pr2 { padding-right: 8px; }
|
||||||
|
.pr3 { padding-right: 12px; }
|
||||||
|
.pr4 { padding-right: 16px; }
|
||||||
|
.pr5 { padding-right: 20px; }
|
||||||
|
.pr6 { padding-right: 24px; }
|
||||||
|
.pr7 { padding-right: 28px; }
|
||||||
|
.pr8 { padding-right: 32px; }
|
||||||
|
.pr9 { padding-right: 36px; }
|
||||||
|
.pr10 { padding-right: 40px; }
|
||||||
|
|
||||||
|
.pb1 { padding-bottom: 4px; }
|
||||||
|
.pb2 { padding-bottom: 8px; }
|
||||||
|
.pb3 { padding-bottom: 12px; }
|
||||||
|
.pb4 { padding-bottom: 16px; }
|
||||||
|
.pb5 { padding-bottom: 20px; }
|
||||||
|
.pb6 { padding-bottom: 24px; }
|
||||||
|
.pb7 { padding-bottom: 28px; }
|
||||||
|
.pb8 { padding-bottom: 32px; }
|
||||||
|
.pb9 { padding-bottom: 36px; }
|
||||||
|
.pb10 { padding-bottom: 40px; }
|
||||||
|
|
||||||
|
.pl1 { padding-left: 4px; }
|
||||||
|
.pl2 { padding-left: 8px; }
|
||||||
|
.pl3 { padding-left: 12px; }
|
||||||
|
.pl4 { padding-left: 16px; }
|
||||||
|
.pl5 { padding-left: 20px; }
|
||||||
|
.pl6 { padding-left: 24px; }
|
||||||
|
.pl7 { padding-left: 28px; }
|
||||||
|
.pl8 { padding-left: 32px; }
|
||||||
|
.pl9 { padding-left: 36px; }
|
||||||
|
.pl10 { padding-left: 40px; }
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const MobileStyles = `
|
const MobileStyles = `
|
||||||
|
|
|
@ -20,7 +20,7 @@ const React = require('react');
|
||||||
|
|
||||||
function getConfirmationPageTitle({confirmationType}) {
|
function getConfirmationPageTitle({confirmationType}) {
|
||||||
if (confirmationType === 'changePlan') {
|
if (confirmationType === 'changePlan') {
|
||||||
return 'Change plan';
|
return 'Confirm subscription';
|
||||||
} else if (confirmationType === 'cancel') {
|
} else if (confirmationType === 'cancel') {
|
||||||
return 'Confirm cancellation';
|
return 'Confirm cancellation';
|
||||||
} else if (confirmationType === 'subscribe') {
|
} else if (confirmationType === 'subscribe') {
|
||||||
|
@ -102,7 +102,7 @@ const CancelContinueSubscription = ({member, onCancelContinueSubscription, onAct
|
||||||
};
|
};
|
||||||
|
|
||||||
const Header = ({member, lastPage, brandColor, onBack, showConfirmation, confirmationType}) => {
|
const Header = ({member, lastPage, brandColor, onBack, showConfirmation, confirmationType}) => {
|
||||||
let title = member.paid ? 'Choose plan' : 'Choose your plan';
|
let title = member.paid ? 'Change plan' : 'Choose a plan';
|
||||||
if (showConfirmation) {
|
if (showConfirmation) {
|
||||||
title = getConfirmationPageTitle({confirmationType});
|
title = getConfirmationPageTitle({confirmationType});
|
||||||
}
|
}
|
||||||
|
@ -115,22 +115,26 @@ const Header = ({member, lastPage, brandColor, onBack, showConfirmation, confirm
|
||||||
};
|
};
|
||||||
|
|
||||||
const PlanConfirmation = ({action, member, plan, type, brandColor, onConfirm}) => {
|
const PlanConfirmation = ({action, member, plan, type, brandColor, onConfirm}) => {
|
||||||
let actionDescription = '';
|
|
||||||
let confirmMessage = 'Are you sure ?';
|
|
||||||
if (type === 'changePlan') {
|
|
||||||
actionDescription = `You are switching to a ${plan.name} plan with pricing ${plan.currency} ${plan.price} / ${plan.type} `;
|
|
||||||
} else if (type === 'subscribe') {
|
|
||||||
actionDescription = `You are subscribing to a ${plan.name} plan with pricing ${plan.currency} ${plan.price} / ${plan.type} `;
|
|
||||||
} else if (type === 'cancel') {
|
|
||||||
const subscription = getMemberSubscription({member});
|
const subscription = getMemberSubscription({member});
|
||||||
actionDescription = `If you confirm and end your subscription now, you can still access it until ${getDateString(subscription.current_period_end)}`;
|
|
||||||
}
|
|
||||||
const isRunning = ['updateSubscription:running', 'checkoutPlan:running', 'cancelSubscription:running'].includes(action);
|
const isRunning = ['updateSubscription:running', 'checkoutPlan:running', 'cancelSubscription:running'].includes(action);
|
||||||
const label = 'Confirm';
|
const label = 'Confirm';
|
||||||
|
if (type === 'changePlan') {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div> {actionDescription} </div>
|
<div className='gh-portal-list outline mb6'>
|
||||||
<div> {confirmMessage} </div>
|
<section>
|
||||||
|
<div className='gh-portal-list-detail'>
|
||||||
|
<h3>Account</h3>
|
||||||
|
<p>{member.email}</p>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<div className='gh-portal-list-detail'>
|
||||||
|
<h3>Price</h3>
|
||||||
|
<p>{plan.currency}{plan.price}/{plan.type} – Starting {getDateString(subscription.current_period_end)}</p>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
<ActionButton
|
<ActionButton
|
||||||
onClick={e => onConfirm(e, plan)}
|
onClick={e => onConfirm(e, plan)}
|
||||||
isRunning={isRunning}
|
isRunning={isRunning}
|
||||||
|
@ -144,6 +148,24 @@ const PlanConfirmation = ({action, member, plan, type, brandColor, onConfirm}) =
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
} else {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<p>If you confirm and end your subscription now, you can still access it until <strong>{getDateString(subscription.current_period_end)}</strong>.</p>
|
||||||
|
<ActionButton
|
||||||
|
onClick={e => onConfirm(e, plan)}
|
||||||
|
isRunning={isRunning}
|
||||||
|
isPrimary={true}
|
||||||
|
brandColor={brandColor}
|
||||||
|
label={label}
|
||||||
|
style={{
|
||||||
|
width: '100%',
|
||||||
|
height: '40px'
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const PlanChooser = ({plans, selectedPlan, errors, member, onAction, onCancelContinueSubscription, action, brandColor, onPlanSelect}) => {
|
const PlanChooser = ({plans, selectedPlan, errors, member, onAction, onCancelContinueSubscription, action, brandColor, onPlanSelect}) => {
|
||||||
|
@ -178,7 +200,7 @@ const PlanMain = ({
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<PlanConfirmation {...{action, member, plan: confirmationPlan, type: confirmationType, onConfirm}}/>
|
<PlanConfirmation {...{action, member, plan: confirmationPlan, type: confirmationType, onConfirm, brandColor}}/>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
export default class AccountPlanPage extends React.Component {
|
export default class AccountPlanPage extends React.Component {
|
||||||
|
|
|
@ -6,7 +6,7 @@ export const site = {
|
||||||
accent_color: '#AB19E4',
|
accent_color: '#AB19E4',
|
||||||
url: 'http://localhost:2368/',
|
url: 'http://localhost:2368/',
|
||||||
plans: {
|
plans: {
|
||||||
monthly: 12,
|
monthly: 5,
|
||||||
yearly: 110,
|
yearly: 110,
|
||||||
currency: 'USD',
|
currency: 'USD',
|
||||||
currency_symbol: '$'
|
currency_symbol: '$'
|
||||||
|
@ -15,7 +15,7 @@ export const site = {
|
||||||
is_stripe_configured: true,
|
is_stripe_configured: true,
|
||||||
portal_button: true,
|
portal_button: true,
|
||||||
portal_name: true,
|
portal_name: true,
|
||||||
portal_plans: ['free', 'yearly'],
|
portal_plans: ['free', 'monthly', 'yearly'],
|
||||||
portal_button_icon: 'icon-1',
|
portal_button_icon: 'icon-1',
|
||||||
portal_button_signup_text: 'Subscribe now',
|
portal_button_signup_text: 'Subscribe now',
|
||||||
portal_button_style: 'icon-and-text',
|
portal_button_style: 'icon-and-text',
|
||||||
|
|
Loading…
Add table
Reference in a new issue