Updated paid and free account design

no refs.
- updated design of account page to use global list styles for paid members
- removed "Contact support" from free members
This commit is contained in:
Peter Zimon 2020-07-23 11:33:41 +02:00
parent c3cb46da02
commit 4dcdfb7cad
6 changed files with 139 additions and 129 deletions

View File

@ -9,6 +9,7 @@ import {AccountHomePageStyles} from './pages/AccountHomePage';
import {InputFieldStyles} from './common/InputField';
import {SignupPageStyles} from './pages/SignupPage';
import {PlanSectionStyles} from './common/PlansSection';
import {AvatarStyles} from './common/MemberGravatar';
// Global styles
export const GlobalStyles = `
@ -161,6 +162,12 @@ export const GlobalStyles = `
letter-spacing: 0.35px;
}
.gh-portal-setting-data {
font-size: 1.3rem;
color: #7f7f7f;
line-height: 1.15em;
}
/* Buttons
/* ----------------------------------------------------- */
.gh-portal-btn {
@ -217,6 +224,10 @@ export const GlobalStyles = `
opacity: 0.85;
}
.gh-portal-btn-branded {
color: var(--brandcolor);
}
/* Global layout styles
/* ----------------------------------------------------- */
.gh-portal-popup-container {
@ -283,6 +294,61 @@ export const GlobalStyles = `
.gh-portal-detail-footer .gh-portal-btn {
min-width: 90px;
}
/* Lists */
.gh-portal-list {
background: #fff;
box-shadow: 0px 2px 4px 0px rgba(0, 0, 0, 0.07), 0px 1px 1.5px 0px rgba(0, 0, 0, 0.05);
border-radius: 3px;
padding: 20px;
}
.gh-portal-list section {
display: flex;
align-items: center;
margin: 0 -20px 20px;
padding: 0 20px 20px;
border-bottom: 1px solid #eaeaea;
}
.gh-portal-list section:last-of-type {
margin-bottom: 0;
padding-bottom: 0;
border: none;
}
.gh-portal-list-detail {
flex-grow: 1;
}
.gh-portal-list-detail h3 {
font-size: 1.5rem;
font-weight: 500;
}
.gh-portal-list-detail p {
font-size: 1.3rem;
letter-spacing: 0.3px;
line-height: 1.15em;
padding: 0;
margin: 2px 0 0;
color: #7f7f7f;
}
.gh-portal-btn-list {
height: 38px;
font-size: 1.4rem;
width: unset;
padding: 0 4px;
margin: 0 -4px;
box-shadow: none;
color: var(--brandcolor);
}
.gh-portal-btn-list:hover {
box-shadow: none;
opacity: 0.75;
}
`;
// Append all styles as string which we want to pass to iframe
@ -293,6 +359,7 @@ const FrameStyle =
PlanSectionStyles +
SwitchStyles +
ActionButtonStyles +
AvatarStyles +
SignupPageStyles;
export default FrameStyle;

View File

@ -1,6 +1,18 @@
import React from 'react';
import {ReactComponent as UserIcon} from '../../images/icons/user.svg';
export const AvatarStyles = `
.gh-portal-avatar {
position: relative;
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
margin-bottom: 12px;
border-radius: 999px;
}
`;
const Styles = ({style = {}}) => {
return {
userIcon: {
@ -28,7 +40,7 @@ const Styles = ({style = {}}) => {
function MemberGravatar({gravatar, style}) {
let Style = Styles({style});
return (
<figure>
<figure className='gh-portal-avatar'>
<UserIcon style={Style.userIcon} />
{gravatar ? <img src={gravatar} alt="Gravatar" style={Style.gravatar} /> : null}
</figure>

View File

@ -30,8 +30,8 @@ export const SwitchStyles = `
left: 0;
right: 0;
bottom: 0;
background: #f4f4f4;
border: 1px solid #e4e4e4;
background: #f8f8f8;
border: 1px solid #e0e0e0;
transition: .3s;
width: 36px !important;
height: 22px !important;
@ -63,7 +63,7 @@ export const SwitchStyles = `
}
.gh-portal-for-switch input:checked + .input-toggle-component:before {
transform: translateX(22px);
transform: translateX(14px);
box-shadow: none;
}
@ -71,21 +71,6 @@ export const SwitchStyles = `
width: 38px !important;
height: 22px !important;
}
.gh-portal-for-switch.small .input-toggle-component {
width: 38px !important;
height: 22px !important;
}
.gh-portal-for-switch.small .input-toggle-component:before {
height: 16px !important;
width: 16px !important;
box-shadow: 0 0 1px rgba(0,0,0,.45), 0 1px 2px rgba(0,0,0,.1);
}
.gh-portal-for-switch.small input:checked + .input-toggle-component:before {
transform: translateX(16px);
}
`;
function Switch({id, label, onToggle, checked = false}) {

View File

@ -6,16 +6,23 @@ import Switch from '../common/Switch';
const React = require('react');
export const AccountHomePageStyles = `
.gh-portal-account-main {
background: #f8f8f8;
margin: -32px -32px 0;
padding: 32px;
border-bottom: 1px solid #eaeaea;
}
.gh-portal-account-header {
display: flex;
flex-direction: column;
align-items: center;
margin-bottom: 20px;
margin: 0 0 32px;
}
.gh-portal-account-footer {
display: flex;
margin-top: -16px;
margin-top: 32px;
}
.gh-portal-account-footer.paid {
@ -36,75 +43,12 @@ export const AccountHomePageStyles = `
.gh-portal-account-footermenu li:last-of-type {
margin-right: 0;
}
.gh-portal-accountdetail-section {
display: flex;
align-items: flex-start;
margin-bottom: 40px;
}
.gh-portal-accountdetail-section:first-of-type {
margin-top: 32px;
margin-bottom: 22px;
}
.gh-portal-account-divider {
margin: 12px -32px;
border: none;
border-bottom: 1px solid #EDEDED;
}
.gh-portal-account-divider:last-of-type {
margin-bottom: 40px;
}
.gh-portal-btn-accountdetail {
height: 38px;
font-size: 1.3rem;
width: 78px;
padding: 0 12px;
}
.gh-portal-accountdetail-data {
line-height: 1em;
margin-top: 2px;
color: #777;
}
.gh-portal-accountdetail-data.small {
font-size: 1.3rem;
margin-top: 5px;
}
.gh-portal-setting-heading.paid-home {
font-weight: 600;
}
/* Avatar styles */
.gh-portal-avatar-container {
position: relative;
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
width: 64px;
height: 64px;
margin-bottom: 8px;
border-radius: 999px;
box-shadow: 0 0 0 3px #fff;
}
`;
const Divider = () => {
return (
<hr className='gh-portal-account-divider' />
);
};
const UserAvatar = ({avatar, brandColor}) => {
return (
<div className='gh-portal-avatar-container'>
<MemberAvatar gravatar={avatar} style={{userIcon: {color: brandColor, width: '45px', height: '45px'}}} />
<div>
<MemberAvatar gravatar={avatar} style={{userIcon: {color: brandColor, width: '56px', height: '56px'}}} />
</div>
);
};
@ -113,15 +57,19 @@ const AccountFooter = ({onLogout, onSettings, brandColor}) => {
return (
<div className='gh-portal-account-footer'>
<ul className='gh-portal-account-footermenu'>
<li><div className='gh-portal-text-disabled' role='button'>Contact support</div></li>
{onSettings ? null :
<li><button className='gh-portal-btn gh-portal-btn-branded'>Contact support</button></li>
}
{onSettings
? <li><button className='gh-portal-btn gh-portal-btn-branded' onClick={onSettings}>Settings</button></li>
: null
}
</ul>
<div className='flex flex-grow-1 justify-end'>
<ul className='gh-portal-account-footermenu'>
{onSettings
? <li><div className='gh-portal-link' style={{color: brandColor}} onClick={onSettings} role='button'>Settings</div></li>
: null
}
<li><div className='gh-portal-link' style={{color: brandColor}} onClick={onLogout} role='button'>Logout</div></li>
<li>
<button className='gh-portal-btn' onClick={onLogout}>Logout</button>
</li>
</ul>
</div>
</div>
@ -133,7 +81,7 @@ const UserHeader = ({member, brandColor}) => {
return (
<div className='gh-portal-account-header'>
<UserAvatar avatar={avatar} brandColor={brandColor} />
<h2 className="gh-portal-main-title">Your Account</h2>
<h2 className="gh-portal-main-title">Your account</h2>
</div>
);
};
@ -177,7 +125,7 @@ class FreeAccountHomePage extends React.Component {
const {title: siteTitle} = this.context.site;
return (
<div className='gh-portal-section'>
<div>
<p className='gh-portal-text-center'>
Hey <strong>{firstname || name || email}! </strong>
You are subscribed to free updates from <strong>{siteTitle}</strong>, but you don't have a paid subscription to unlock full access
@ -191,8 +139,10 @@ class FreeAccountHomePage extends React.Component {
const {member, brandColor} = this.context;
return (
<div>
<UserHeader member={member} brandColor={brandColor} />
{this.renderAccountDetail()}
<div className='gh-portal-account-main'>
<UserHeader member={member} brandColor={brandColor} />
{this.renderAccountDetail()}
</div>
<AccountFooter onLogout={e => this.handleSignout(e)} onSettings={e => this.openSettings(e)} brandColor={brandColor} />
</div>
);
@ -266,38 +216,35 @@ class PaidAccountHomePage extends React.Component {
} = subscriptions[0];
return (
<div>
<section className='gh-portal-accountdetail-section'>
<div className='flex flex-column flex-grow-1'>
<h3 className='gh-portal-setting-heading paid-home'>Profile</h3>
<div>
<div className='gh-portal-accountdetail-data'>{name}</div>
<div className='gh-portal-accountdetail-data small'>{email}</div>
</div>
<div className='gh-portal-list'>
<section>
<div className='gh-portal-list-detail'>
<h3>{name}</h3>
<p>{email}</p>
</div>
<button className='gh-portal-btn gh-portal-btn-accountdetail' onClick={e => this.openEditProfile(e)}>Edit</button>
<button className='gh-portal-btn gh-portal-btn-list' onClick={e => this.openEditProfile(e)}>Edit</button>
</section>
<section className='gh-portal-accountdetail-section'>
<div className='flex flex-column flex-grow-1'>
<h3 className='gh-portal-setting-heading paid-home'>Plan</h3>
<div className='gh-portal-accountdetail-data'>{this.getPlanLabel(plan)}</div>
<section>
<div className='gh-portal-list-detail'>
<h3>Plan</h3>
<p>{this.getPlanLabel(plan)}</p>
</div>
<button className='gh-portal-btn gh-portal-btn-accountdetail' onClick={e => this.openUpdatePlan(e)}>Change</button>
<button className='gh-portal-btn gh-portal-btn-list' onClick={e => this.openUpdatePlan(e)}>Change</button>
</section>
<section className='gh-portal-accountdetail-section'>
<div className='flex flex-column flex-grow-1'>
<h3 className='gh-portal-setting-heading paid-home'>Billing Info</h3>
<div className='gh-portal-accountdetail-data'>{this.getCardLabel({defaultCardLast4})}</div>
<section>
<div className='gh-portal-list-detail'>
<h3>Billing Info</h3>
<p>{this.getCardLabel({defaultCardLast4})}</p>
</div>
<button className='gh-portal-btn gh-portal-btn-accountdetail' onClick={e => this.onEditBilling(e)}>Update</button>
<button className='gh-portal-btn gh-portal-btn-list' onClick={e => this.onEditBilling(e)}>Update</button>
</section>
<section className='gh-portal-accountdetail-section'>
<div className='flex flex-column flex-grow-1'>
<h3 className='gh-portal-setting-heading paid-home'>Newsletter</h3>
<div className='gh-portal-accountdetail-data'>You are subscribed to email newsletters</div>
<section>
<div className='gh-portal-list-detail'>
<h3>Newsletter</h3>
<p>Not subscribed to email newsletters</p>
</div>
<div>
<Switch onToggle={(e) => {
@ -313,11 +260,10 @@ class PaidAccountHomePage extends React.Component {
const {member, brandColor} = this.context;
return (
<div>
<UserHeader member={member} brandColor={brandColor} />
{/* {this.renderAccountWelcome()} */}
<Divider />
{this.renderAccountDetails()}
<Divider />
<div className='gh-portal-account-main'>
<UserHeader member={member} brandColor={brandColor} />
{this.renderAccountDetails()}
</div>
<AccountFooter onLogout={e => this.handleSignout(e)} brandColor={brandColor} />
</div>
);

View File

@ -165,12 +165,12 @@ export default class AccountProfilePage extends React.Component {
if (paid) {
return null;
}
const label = subscribed ? 'You are subscribed to email newsletters' : 'You are not subscribed to email newsletters';
const label = subscribed ? 'Subscribed to email newsletters' : 'Not subscribed to email newsletters';
return (
<div className='flex items-center justify-between' style={{marginTop: '24px'}}>
<div className='flex flex-column flex-grow-1'>
<h3 className='gh-portal-setting-heading paid-home'>Newsletter</h3>
<div className='gh-portal-accountdetail-data'>{label}</div>
<h3 className='gh-portal-setting-heading'>Newsletter</h3>
<div className='gh-portal-setting-data'>{label}</div>
</div>
<div>
<Switch onToggle={(e) => {
@ -189,7 +189,7 @@ export default class AccountProfilePage extends React.Component {
return (
<div>
{this.renderHeader()}
<div className='gh-portal-section form'>
<div className='gh-portal-section'>
{this.renderProfileData()}
{this.renderNewsletterOption()}
</div>

View File

@ -1 +1 @@
<svg id="Regular" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><defs><style>.cls-1{fill:none;stroke:currentColor;stroke-linecap:round;stroke-linejoin:round;stroke-width:1px}</style></defs><title>single-neutral</title><circle class="cls-1" cx="12" cy="6" r="5.25"/><path class="cls-1" d="M2.25 23.25a9.75 9.75 0 0 1 19.5 0"/></svg>
<svg id="Regular" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><defs><style>.cls-1{fill:none;stroke:currentColor;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.8px;}</style></defs><title>single-neutral-circle</title><circle class="cls-1" cx="12" cy="9.75" r="5.25"/><path class="cls-1" d="M18.913,20.876a9.746,9.746,0,0,0-13.826,0"/><circle class="cls-1" cx="12" cy="12" r="11.25"/></svg>

Before

Width:  |  Height:  |  Size: 340 B

After

Width:  |  Height:  |  Size: 409 B