design review done for verify-email flow

review, synced all the modals and other small fixes
This commit is contained in:
Janne Koivistoinen 2017-09-15 14:21:18 +03:00 committed by Vesa Luusua
parent 96c0faef41
commit f9dca7520f
33 changed files with 623 additions and 681 deletions

View file

@ -47,13 +47,13 @@
left: 12px;
width: 10px;
height: 10px;
fill: var(--matterColorLight);
stroke: var(--matterColorLight);
fill: var(--matterColorAnti);
stroke: var(--matterColorAnti);
}
&:hover svg {
fill: var(--matterColorAnti);
stroke: var(--matterColorAnti);
fill: var(--matterColorLight);
stroke: var(--matterColorLight);
}
}

View file

@ -13,37 +13,37 @@
flex-grow: 1;
}
.payoutModalOpen {
padding: 0;
/* ================ Modal ================ */
.error {
@apply --marketplaceModalErrorStyles;
}
.payoutDetails {
margin: 24px;
@media (--viewportLarge) {
margin: 0 60px 60px;
}
}
.modalHeading {
margin-top: 89px;
.modalHeaderWrapper {
margin-top: 58px;
margin-bottom: 36px;
padding: 0 24px;
padding: 0;
@media (--viewportLarge) {
margin-top: 67px;
padding: 0 60px;
}
}
.payoutModalTitle {
@apply --marketplaceModalTitle;
@media (--viewportLarge) {
@media (--viewportMedium) {
margin-top: 0;
padding: 0;
}
}
/* ================ Typography ================ */
/* Title of the modal */
.modalTitle {
@apply --marketplaceModalTitleStyles;
}
/* Paragraph for the Modal */
.modalMessage {
@apply --marketplaceModalParagraphStyles;
}
/* This is the title for the Edit Photos component */
.title {
margin-bottom: 19px;

View file

@ -118,6 +118,7 @@ class EditListingPhotosPanel extends Component {
updateError={errors.updateListingError}
updateInProgress={updateInProgress}
/>
<Modal
id="EditListingPhotosPanel.payoutModal"
className={css.payoutModal}
@ -125,13 +126,13 @@ class EditListingPhotosPanel extends Component {
onClose={this.handlePayoutModalClose}
onManageDisableScrolling={onManageDisableScrolling}
>
<div className={css.modalHeading}>
<h1 className={css.payoutModalTitle}>
<div className={css.modalHeaderWrapper}>
<h1 className={css.modalTitle}>
<FormattedMessage id="EditListingPhotosPanel.payoutModalTitleOneMoreThing" />
<br />
<FormattedMessage id="EditListingPhotosPanel.payoutModalTitlePayoutPreferences" />
</h1>
<p>
<p className={css.modalMessage}>
<FormattedMessage id="EditListingPhotosPanel.payoutModalInfo" />
</p>
</div>
@ -141,6 +142,7 @@ class EditListingPhotosPanel extends Component {
onSubmit={this.handlePayoutSubmit}
/>
</Modal>
</div>
);
}

View file

@ -38,7 +38,7 @@
left: 0;
right: 0;
width: 100%;
border-radius: 2px;
border-radius: var(--borderRadius);
}
.info {

View file

@ -12,29 +12,29 @@
width: 100%;
z-index: 100;
/* scrollLayer is the .root for the Modal */
& .scrollLayer {
@apply --marketplaceModalRootStyles;
/* Additional styles for the modal window, dimming the background and positioning the modal */
min-height: 100vh;
overflow: auto;
-webkit-overflow-scrolling: touch;
background-color: var(--matterColorBright);
@media (--viewportMedium) {
padding: 126px 0;
padding: 0;
background-color: rgba(0, 0, 0, 0.4);
background-image: none;
}
}
& .container {
position: relative;
height: 100vh;
@apply --marketplaceModalBaseStyles;
height: 100%;
@media (--viewportMedium) {
-webkit-overflow-scrolling: auto;
width: 576px;
height: auto;
margin: 0 auto;
background-color: var(--matterColorBright);
border-radius: 2px;
flex-basis: 576px;
}
}
}
@ -47,42 +47,15 @@
}
.close {
/* Position inside modal */
position: absolute;
top: 0;
right: 0;
@apply --marketplaceModalCloseStyles;
}
/* Some content (like map) is positioning itself on top of close button without z-index handling */
z-index: calc(var(--zIndexModal) + 1);
.closeText {
@apply --marketplaceModalCloseText;
}
/* Safari didn't know how to baseline-align svg icon and text */
display: flex;
align-items: flex-start;
width: auto;
/* Sizing (touch area) */
padding: 23px 24px;
margin: 0;
border: 0;
/* Colors */
background-color: transparent;
color: var(--matterColor);
cursor: pointer;
&:enabled:hover {
background-color: transparent;
color: var(--matterColorDark);
box-shadow: none;
}
&:enabled:active {
background-color: transparent;
color: var(--matterColorDark);
}
&:disabled {
background-color: transparent;
}
.closeIcon {
@apply --marketplaceModalCloseIcon;
}
.closeLight {
@ -94,29 +67,3 @@
color: var(--matterColorLight);
}
}
.closeText {
/* Font */
@apply --marketplaceH6FontStyles;
margin: -2.5px 0 0 0;
@media (--viewportMedium) {
margin-top: -1px;
}
}
.closeIcon {
display: inline-block;
margin-left: 8px;
padding: 2px 0 4px;
box-sizing: content-box;
}
.content {
flex-grow: 1;
display: flex;
flex: 1;
flex-direction: column;
overflow: auto;
height: 100%;
}

View file

@ -6,6 +6,10 @@
.root {
width: 100%;
/* Top Bar's drop shadow should always be visible */
z-index: 10;
position: relative;
}
.container {
@ -132,84 +136,48 @@
z-index: -1;
}
/* Verify email reminder (modal) */
/* ================ Modal ================ */
.verifyEmailModal {
position: relative;
height: 100vh;
padding: 24px 24px 98px 24px;
@media (--viewportMedium) {
-webkit-overflow-scrolling: auto;
width: 480px;
min-height: 573px;
height: auto;
margin: 7.5vh auto;
padding: 72px 64px;
background-color: var(--matterColorBright);
border-radius: 2px;
}
@apply --marketplaceModalBaseStyles;
padding-top: 70px;
}
.verifyEmailContent {}
.verifyTitle {
@apply --marketplaceModalTitle;
margin: 21px 0 0 0;
@media (--viewportMedium) {
margin: 22px 0 0 0;
}
/* Title of the modal */
.modalTitle {
@apply --marketplaceModalTitleStyles;
}
.verifyHelpText {
margin: 17px 0 0 0;
@media (--viewportMedium) {
margin: 16px 0 0 0;
}
/* Paragraph for the Modal */
.modalMessage {
@apply --marketplaceModalParagraphStyles;
}
/* Make the email pop */
.email {
font-weight: bold;
@apply --marketplaceModalHighlightEmail;
}
.verifyLink {
@apply --marketplaceH5FontStyles;
color: var(--matterColor);
margin: 0;
@media (--viewportMedium) {
margin: 0;
}
.helperLink {
@apply --marketplaceModalHelperLink;
}
.resendEmail {
@apply --marketplaceH5FontStyles;
color: var(--matterColorAnti);
margin: 59px 0 0 0;
@media (--viewportMedium) {
margin: 63px 0 0 0;
}
.helperText {
@apply --marketplaceModalHelperText;
}
.resendError {
color: var(--failColor);
margin: 66px 0 0 0;
@media (--viewportMedium) {
margin: 72px 0 0 0;
}
.error {
@apply --marketplaceModalErrorStyles;
}
.fixEmail {
@apply --marketplaceH5FontStyles;
color: var(--matterColorAnti);
margin: 0;
.bottomWrapper {
@apply --marketplaceModalBottomWrapper;
@media (--viewportMedium) {
margin: 0;
}
/* Align the helper links to the left since there isn't a Primary Button anymore */
text-align: left;
}
.modalIcon {
@apply --marketplaceModalIconStyles;
}

View file

@ -207,12 +207,12 @@ class TopbarComponent extends Component {
const email = user.id ? <span className={css.email}>{user.attributes.email}</span> : '';
const resendEmailLink = (
<InlineTextButton className={css.verifyLink} onClick={onResendVerificationEmail}>
<InlineTextButton className={css.helperLink} onClick={onResendVerificationEmail}>
<FormattedMessage id="Topbar.resendEmailLinkText" />
</InlineTextButton>
);
const fixEmailLink = (
<NamedLink className={css.verifyLink} name="ProfileSettingsPage">
<NamedLink className={css.helperLink} name="ProfileSettingsPage">
<FormattedMessage id="Topbar.fixEmailLinkText" />
</NamedLink>
);
@ -223,7 +223,7 @@ class TopbarComponent extends Component {
? 'Topbar.resendFailedTooManyRequests'
: 'Topbar.resendFailed';
const resendErrorMessage = sendVerificationEmailError
? <p className={css.resendError}>
? <p className={css.error}>
<FormattedMessage id={resendErrorTranslationId} />
</p>
: null;
@ -290,6 +290,7 @@ class TopbarComponent extends Component {
</p>
</div>
</Modal>
<Modal
id="EmailVerificationReminder"
containerClassName={css.verifyEmailModal}
@ -301,25 +302,30 @@ class TopbarComponent extends Component {
closeButtonMessage={closeButtonMessage}
>
<div className={css.verifyEmailContent}>
<IconEmailAttention />
<h1 className={css.verifyTitle}>
<IconEmailAttention className={css.modalIcon}/>
<h1 className={css.modalTitle}>
<FormattedMessage id="Topbar.verifyEmailTitle" />
</h1>
<p className={css.verifyHelpText}>
<p className={css.modalMessage}>
<FormattedMessage id="Topbar.verifyEmailText" />
</p>
<p className={css.checkInboxText}>
<p className={css.modalMessage}>
<FormattedMessage id="Topbar.checkInbox" values={{ email }} />
</p>
{resendErrorMessage}
<p className={css.resendEmail}>
{sendVerificationEmailInProgress
? <FormattedMessage id="Topbar.sendingEmail" />
: <FormattedMessage id="Topbar.resendEmail" values={{ resendEmailLink }} />}
</p>
<p className={css.fixEmail}>
<FormattedMessage id="Topbar.fixEmail" values={{ fixEmailLink }} />
</p>
<div className={css.bottomWrapper}>
<p className={css.helperText}>
{sendVerificationEmailInProgress
? <FormattedMessage id="Topbar.sendingEmail" />
: <FormattedMessage id="Topbar.resendEmail" values={{ resendEmailLink }} />}
</p>
<p className={css.helperText}>
<FormattedMessage id="Topbar.fixEmail" values={{ fixEmailLink }} />
</p>
</div>
</div>
</Modal>
</div>

View file

@ -42,8 +42,8 @@
.greeting {
/* Font */
@apply --marketplaceH1FontStyles;
margin-bottom: 12px;
margin-bottom: 1px;
margin-top: 16px;
}
.logoutButton {
@ -59,22 +59,22 @@
.inbox {
/* Font */
@apply --marketplaceH1FontStyles;
@apply --marketplaceH2FontStyles;
color: var(--marketplaceColor);
position: relative;
margin-top: auto;
margin-bottom: 18px;
margin-bottom: 13px;
}
.navigationLink {
/* Font */
@apply --marketplaceH1FontStyles;
@apply --marketplaceH2FontStyles;
color: var(--marketplaceColor);
/* Layout */
margin-top: 0;
margin-bottom: 25px;
margin-bottom: 11px;
}
.currentPageLink {
color: var(--marketplaceColorDark);

View file

@ -1,45 +1,17 @@
@import '../../marketplaceFonts.css';
@import '../../marketplace.css';
.root {
@apply --backgroundImage;
/* PageLayout is using flex: AuthenticationPage's .root takes all available space */
flex-grow: 1;
/* AuthenticationPage's root uses flexbox */
display: flex;
@media (--viewportMedium) {
justify-content: center;
align-items: flex-start;
}
@apply --marketplaceModalRootStyles;
}
.content {
flex-grow: 1;
/* Create context so the close button can be positioned within it */
position: relative;
/* Display and dimensions */
display: flex;
flex-direction: column;
padding: 30px 24px 98px 24px;
background-color: var(--matterColorLight);
border-radius: 2px;
@media (--viewportMedium) {
flex-basis: 480px;
flex-grow: 0;
min-height: 573px;
padding: 60px;
margin-top: 7.5vh;
margin-bottom: 7.5vh;
}
@apply --marketplaceModalBaseStyles;
padding-top: 29px;
}
/* ================ Tabs & Form ================ */
.tabs {
@media (--viewportMedium) {
margin-top: 6px;
@ -47,24 +19,33 @@
}
.tab {
@apply --marketplaceModalTitle;
@apply --marketplaceModalTitleStyles;
margin-top: 0;
margin-bottom: 0;
}
.form {
margin-top: 49px;
@media (--viewportMedium) {
margin-top: 38px;
margin-top: 0;
}
}
.error {
.form {
margin-top: 24px;
color: var(--failColor);
@media (--viewportMedium) {
margin-top: 30px;
}
}
.bottomWrapper {
@apply --marketplaceModalBottomWrapper;
/* Align the helper links to the left since there isn't a Primary Button anymore */
text-align: left;
}
/* ================ Hide Top bar in screens smaller than 768px ================ */
.hideOnMobile {
display: none;
@ -73,101 +54,64 @@
}
}
/* ================ Close icon ================ */
.verifyClose {
/* Position */
position: absolute;
top: 0;
right: 0;
/* Display and dimensions */
display: flex;
align-items: flex-start;
width: auto;
padding: 23px 24px;
/* Colors */
color: var(--matterColor);
&:hover {
color: var(--matterColorDark);
text-decoration: none;
}
@apply --marketplaceModalCloseStyles;
}
.closeText {
@apply --marketplaceH6FontStyles;
margin: -2.5px 0 0 0;
@media (--viewportMedium) {
margin-top: -1px;
}
@apply --marketplaceModalCloseText;
}
.closeIcon {
display: inline-block;
margin-left: 8px;
padding: 2px 0 4px;
/* SVG elements work better as a content-box */
box-sizing: content-box;
@apply --marketplaceModalCloseIcon;
}
.verifyTitle {
@apply --marketplaceModalTitle;
margin: 21px 0 0 0;
@media (--viewportMedium) {
margin: 22px 0 0 0;
}
/* ================ Typography ================ */
/* Title of the modal */
.modalTitle {
@apply --marketplaceModalTitleStyles;
}
.verifyHelpText {
margin: 17px 0 0 0;
@media (--viewportMedium) {
margin: 16px 0 0 0;
}
/* Paragraph for the Modal */
.modalMessage {
@apply --marketplaceModalParagraphStyles;
}
/* Make the email pop */
.email {
font-weight: bold;
@apply --marketplaceModalHighlightEmail;
}
.verifyLink {
@apply --marketplaceH5FontStyles;
color: var(--matterColor);
margin: 0;
/* Helper links */
.modalHelperLink {
@apply --marketplaceModalHelperLink;
}
/* Helper texts for the links, not the actual links */
.modalHelperText {
@apply --marketplaceModalHelperText;
}
.modalIcon {
@apply --marketplaceModalIconStyles;
/* Align the icon and rest of the content in the modal. Sign & Login doesn't use an icon, maybe we should add one? */
margin-top: 47px;
@media (--viewportMedium) {
margin: 0;
margin-top: 0;
}
}
.resendEmail {
@apply --marketplaceH5FontStyles;
color: var(--matterColorAnti);
margin: 59px 0 0 0;
@media (--viewportMedium) {
margin: 63px 0 0 0;
}
}
.resendError {
color: var(--failColor);
margin: 66px 0 0 0;
@media (--viewportMedium) {
margin: 72px 0 0 0;
}
}
.fixEmail {
@apply --marketplaceH5FontStyles;
color: var(--matterColorAnti);
margin: 0;
@media (--viewportMedium) {
margin: 0;
}
/* ================ Errors ================ */
.error {
@apply --marketplaceModalErrorStyles;
}

View file

@ -141,12 +141,12 @@ export const AuthenticationPageComponent = props => {
const email = <span className={css.email}>{user.attributes.email}</span>;
const resendEmailLink = (
<InlineTextButton className={css.verifyLink} onClick={onResendVerificationEmail}>
<InlineTextButton className={css.modalHelperLink} onClick={onResendVerificationEmail}>
<FormattedMessage id="AuthenticationPage.resendEmailLinkText" />
</InlineTextButton>
);
const fixEmailLink = (
<NamedLink className={css.verifyLink} name="ProfileSettingsPage">
<NamedLink className={css.modalHelperLink} name="ProfileSettingsPage">
<FormattedMessage id="AuthenticationPage.fixEmailLinkText" />
</NamedLink>
);
@ -157,7 +157,7 @@ export const AuthenticationPageComponent = props => {
? 'AuthenticationPage.resendFailedTooManyRequests'
: 'AuthenticationPage.resendFailed';
const resendErrorMessage = sendVerificationEmailError
? <p className={css.resendError}>
? <p className={css.error}>
<FormattedMessage id={resendErrorTranslationId} />
</p>
: null;
@ -170,22 +170,27 @@ export const AuthenticationPageComponent = props => {
</span>
<IconClose rootClassName={css.closeIcon} />
</NamedLink>
<IconEmailSent />
<h1 className={css.verifyTitle}>
<IconEmailSent className={css.modalIcon}/>
<h1 className={css.modalTitle}>
<FormattedMessage id="AuthenticationPage.verifyEmailTitle" values={{ name }} />
</h1>
<p className={css.verifyHelpText}>
<p className={css.modalMessage}>
<FormattedMessage id="AuthenticationPage.verifyEmailText" values={{ email }} />
</p>
{resendErrorMessage}
<p className={css.resendEmail}>
{sendVerificationEmailInProgress
? <FormattedMessage id="AuthenticationPage.sendingEmail" />
: <FormattedMessage id="AuthenticationPage.resendEmail" values={{ resendEmailLink }} />}
</p>
<p className={css.fixEmail}>
<FormattedMessage id="AuthenticationPage.fixEmail" values={{ fixEmailLink }} />
</p>
<div className={css.bottomWrapper}>
<p className={css.modalHelperText}>
{sendVerificationEmailInProgress
? <FormattedMessage id="AuthenticationPage.sendingEmail" />
: <FormattedMessage id="AuthenticationPage.resendEmail" values={{ resendEmailLink }} />}
</p>
<p className={css.modalHelperText}>
<FormattedMessage id="AuthenticationPage.fixEmail" values={{ fixEmailLink }} />
</p>
</div>
</div>
);

View file

@ -59,7 +59,7 @@ const EditListingDescriptionFormComponent = props => {
: saveActionMsg;
const classes = classNames(css.root, className);
const buttonDisabled = invalid || submitting || disabled || updateInProgress;
const submitDisabled = invalid || submitting || disabled || updateInProgress;
return (
<form className={classes} onSubmit={handleSubmit}>
@ -85,7 +85,7 @@ const EditListingDescriptionFormComponent = props => {
validate={[required(descriptionRequiredMessage)]}
/>
<Button className={css.submitButton} type="submit" disabled={buttonDisabled}>
<Button className={css.submitButton} type="submit" disabled={submitDisabled}>
{buttonContent}
</Button>
</form>

View file

@ -48,7 +48,7 @@ export const EditListingLocationFormComponent = props => {
: null;
const classes = classNames(css.root, className);
const buttonDisabled = invalid || submitting || disabled || updateInProgress;
const submitDisabled = invalid || submitting || disabled || updateInProgress;
return (
<form className={classes} onSubmit={handleSubmit}>
@ -78,7 +78,7 @@ export const EditListingLocationFormComponent = props => {
placeholder={buildingPlaceholderMessage}
/>
<Button className={css.submitButton} type="submit" disabled={buttonDisabled}>
<Button className={css.submitButton} type="submit" disabled={submitDisabled}>
{updated ? <FormattedMessage id="EditListingLocationForm.updated" /> : saveActionMsg}
</Button>
</form>

View file

@ -36,7 +36,7 @@ export const EditListingPricingFormComponent = props => {
: null;
const classes = classNames(css.root, className);
const buttonDisabled = invalid || submitting || disabled || updateInProgress;
const submitDisabled = invalid || submitting || disabled || updateInProgress;
return (
<form className={classes} onSubmit={handleSubmit}>
@ -52,7 +52,7 @@ export const EditListingPricingFormComponent = props => {
validate={[required(priceRequiredMessage)]}
/>
<Button className={css.submitButton} type="submit" disabled={buttonDisabled}>
<Button className={css.submitButton} type="submit" disabled={submitDisabled}>
{updated ? <FormattedMessage id="EditListingPricingForm.updated" /> : saveActionMsg}
</Button>
</form>

View file

@ -1,38 +1,34 @@
@import '../../marketplace.css';
.root {
display: flex;
flex-direction: column;
flex: 1;
justify-content: space-between;
height: 100%;
@apply --marketplaceModalFormRootStyles;
}
.title {
@apply --marketplaceModalTitle;
margin: 28px 0 17px 0;
@media (--viewportMedium) {
margin: 28px 0 24px 0;
}
.bottomWrapper {
@apply --marketplaceModalBottomWrapper;
}
.button {
@apply --marketplaceButtonStylesPrimary;
margin-top: 24px;
align-self: stretch;
/* ================ Typography ================ */
@media (--viewportMedium) {
margin-top: 72px;
}
/* Title of the modal */
.modalTitle {
@apply --marketplaceModalTitleStyles;
}
/* Paragraph for the Modal */
.modalMessage {
@apply --marketplaceModalParagraphStyles;
}
.error {
color: var(--failColor);
margin: 23px 0 24px 0;
@media (--viewportMedium) {
margin: 28px 0 24px 0;
}
@apply --marketplaceModalErrorStyles;
}
.submitButton {
@apply --marketplaceButtonStylesPrimary;
}
.modalIcon {
@apply --marketplaceModalIconStyles;
}

View file

@ -2,7 +2,7 @@ import React, { PropTypes } from 'react';
import { compose } from 'redux';
import { FormattedMessage, injectIntl } from 'react-intl';
import { reduxForm, Field, propTypes as formPropTypes } from 'redux-form';
import { PrimaryButton, NamedLink, IconEmailAttention, IconEmailSuccess } from '../../components';
import { NamedLink, IconEmailAttention, IconEmailSuccess } from '../../components';
import * as propTypes from '../../util/propTypes';
import css from './EmailVerificationForm.css';
@ -28,12 +28,12 @@ const EmailVerificationFormComponent = props => {
const verifyEmail = (
<div className={css.root}>
<div>
<IconEmailAttention />
<h1 className={css.title}>
<IconEmailAttention className={css.modalIcon}/>
<h1 className={css.modalTitle}>
<FormattedMessage id="EmailVerificationForm.verifyEmailAddress" />
</h1>
<p>
<p className={css.modalMessage}>
<FormattedMessage id="EmailVerificationForm.finishAccountSetup" values={{ email }} />
</p>
@ -44,12 +44,15 @@ const EmailVerificationFormComponent = props => {
<form onSubmit={handleSubmit}>
<Field component="input" type="hidden" name="verificationToken" />
<PrimaryButton className={css.button} type="submit" disabled={submitting || inProgress}>
<div className={css.bottomWrapper}>
<NamedLink className={css.submitButton} type="submit" disabled={submitting || inProgress}>
{submitting || inProgress
? <FormattedMessage id="EmailVerificationForm.verifying" />
: <FormattedMessage id="EmailVerificationForm.verify" />}
</PrimaryButton>
{submitting || inProgress
? <FormattedMessage id="EmailVerificationForm.verifying" />
: <FormattedMessage id="EmailVerificationForm.verify" />}
</NamedLink>
</div>
</form>
</div>
);
@ -57,20 +60,22 @@ const EmailVerificationFormComponent = props => {
const alreadyVerified = (
<div className={css.root}>
<div>
<IconEmailSuccess />
<h1 className={css.title}>
<IconEmailSuccess className={css.modalIcon}/>
<h1 className={css.modalTitle}>
<FormattedMessage id="EmailVerificationForm.successTitle" values={{ name }} />
</h1>
<p>
<p className={css.modalMessage}>
<FormattedMessage id="EmailVerificationForm.successText" />
</p>
</div>
<NamedLink className={css.button} name="LandingPage">
<FormattedMessage id="EmailVerificationForm.successButtonText" />
</NamedLink>
<div className={css.bottomWrapper}>
<NamedLink className={css.submitButton} name="LandingPage">
<FormattedMessage id="EmailVerificationForm.successButtonText" />
</NamedLink>
</div>
</div>
);

View file

@ -1,39 +1,13 @@
@import '../../marketplace.css';
.root {
@apply --backgroundImage;
/* PageLayout is using flex: EmailVerificationPage's .root takes all available space */
flex-grow: 1;
/* EmailVerificationPage's root uses flexbox */
display: flex;
@media (--viewportMedium) {
justify-content: center;
align-items: flex-start;
}
@apply --marketplaceModalRootStyles;
}
.content {
flex-grow: 1;
display: flex;
flex-direction: column;
padding: 30px 24px 98px 24px;
background-color: var(--matterColorLight);
border-radius: 2px;
@media (--viewportMedium) {
flex-basis: 480px;
flex-grow: 0;
min-height: 573px;
padding: 60px;
margin-top: 7.5vh;
margin-bottom: 7.5vh;
}
@apply --marketplaceModalBaseStyles;
}
.error {
margin-top: 24px;
color: var(--failColor);
@apply --marketplaceModalErrorStyles;
}

View file

@ -119,11 +119,12 @@
height: calc(0.41 * 100vw);
max-height: 50vh;
object-fit: cover;
border-radius: 2px;
}
border-radius: var(--borderRadius);
&:hover {
opacity: 0.85;
&:hover {
transform: scale(1.005);
box-shadow: var(--boxShadowListingCard);
}
}
}

View file

@ -1,32 +1,26 @@
@import '../../marketplace.css';
.root {
display: flex;
flex-direction: column;
flex: 1;
justify-content: space-between;
height: 100%;
@apply --marketplaceModalFormRootStyles;
}
.password {
margin-top: 24px;
margin-bottom: 24px;
@media (--viewportMedium) {
margin-top: 30px;
}
@apply --marketplaceModalPasswordMargins;
}
.bottomWrapper {
margin-top: auto;
text-align: center;
@apply --marketplaceModalBottomWrapper;
}
/* Adjust the bottomWrapper's margin to match modals without the helper text */
.bottomWrapperText {
@apply --marketplaceModalBottomWrapperText;
}
.recoveryLink {
color: var(--matterColor);
@apply --marketplaceModalHelperLink;
}
.recoveryLinkInfo {
@apply --marketplaceH5FontStyles;
color: var(--matterColorAnti);
@apply --marketplaceModalHelperText;
}

View file

@ -3,7 +3,7 @@ import { compose } from 'redux';
import { FormattedMessage, injectIntl, intlShape } from 'react-intl';
import { reduxForm, propTypes as formPropTypes } from 'redux-form';
import classNames from 'classnames';
import { Button, TextInputField, NamedLink } from '../../components';
import { PrimaryButton, TextInputField, NamedLink } from '../../components';
import * as validators from '../../util/validators';
import css from './LoginForm.css';
@ -55,6 +55,7 @@ const LoginFormComponent = props => {
return (
<form className={classes} onSubmit={handleSubmit}>
<div>
<TextInputField
type="email"
@ -74,14 +75,16 @@ const LoginFormComponent = props => {
validate={passwordRequired}
/>
</div>
<p className={css.bottomWrapper}>
<span className={css.recoveryLinkInfo}>
<FormattedMessage id="LoginForm.forgotPasswordInfo" values={{ passwordRecoveryLink }} />
</span>
</p>
<Button type="submit" disabled={submitDisabled}>
<FormattedMessage id="LoginForm.logIn" />
</Button>
<div className={css.bottomWrapper}>
<p className={css.bottomWrapperText}>
<span className={css.recoveryLinkInfo}>
<FormattedMessage id="LoginForm.forgotPasswordInfo" values={{ passwordRecoveryLink }} />
</span>
</p>
<PrimaryButton className={css.submitButton} type="submit" disabled={submitDisabled}>
<FormattedMessage id="LoginForm.logIn" />
</PrimaryButton>
</div>
</form>
);
};

View file

@ -1,12 +1,7 @@
@import '../../marketplace.css';
.root {
display: flex;
flex-direction: column;
flex: 1;
justify-content: space-between;
height: 100%;
min-height: 306px;
@apply --marketplaceModalFormRootStyles;
}
.email {
@ -18,23 +13,20 @@ display: flex;
}
.bottomWrapper {
margin-top: auto;
@apply --marketplaceModalBottomWrapper;
}
.bottomText {
@apply --marketplaceH5FontStyles;
color: var(--matterColorAnti);
margin: 0;
@media (--viewportMedium) {
margin: 0;
}
/* Adjust the bottomWrapper's margin to match modals without the helper text */
.bottomWrapperText {
@apply --marketplaceModalBottomWrapperText;
}
.submitButton {
margin-top: 26px;
/* Helper links */
.modalHelperLink {
@apply --marketplaceModalHelperLink;
}
.loginLink {
color: var(--matterColor);
/* Helper texts for the links, not the actual links */
.modalHelperText {
@apply --marketplaceModalHelperText;
}

View file

@ -43,11 +43,11 @@ const PasswordRecoveryFormComponent = props => {
? emailNotFoundMessage
: null;
const initialEmail = initialValues ? initialValues.email : null;
const buttonDisabled = (pristine && !initialEmail) || submitting;
const submitDisabled = (pristine && !initialEmail) || submitting;
const classes = classNames(rootClassName || css.root, className);
const loginLink = (
<NamedLink name="LoginPage" className={css.loginLink}>
<NamedLink name="LoginPage" className={css.modalHelperLink}>
<FormattedMessage id="PasswordRecoveryForm.loginLinkText" />
</NamedLink>
);
@ -66,17 +66,22 @@ const PasswordRecoveryFormComponent = props => {
/>
<div className={css.bottomWrapper}>
<p className={css.bottomText}>
<FormattedMessage id="PasswordRecoveryForm.loginLinkInfo" values={{ loginLink }} />
<p className={css.bottomWrapperText}>
<span className={css.modalHelperText}>
<FormattedMessage id="PasswordRecoveryForm.loginLinkInfo" values={{ loginLink }} />
</span>
</p>
<PrimaryButton className={css.submitButton} type="submit" disabled={buttonDisabled}>
<PrimaryButton className={css.submitButton} type="submit" disabled={submitDisabled}>
<FormattedMessage id="PasswordRecoveryForm.sendInstructions" />
</PrimaryButton>
</div>
</form>
);
};
PasswordRecoveryFormComponent.defaultProps = {
rootClassName: null,
className: null,

View file

@ -1,118 +1,48 @@
@import '../../marketplace.css';
:root {
--baseContent: {
flex-grow: 1;
display: flex;
flex-direction: column;
padding: 32px 24px 98px 24px;
background-color: var(--matterColorLight);
border-radius: 2px;
@media (--viewportMedium) {
flex-basis: 480px;
flex-grow: 0;
padding: 55px;
margin-top: 7.5vh;
margin-bottom: 7.5vh;
}
}
}
.root {
@apply --backgroundImage;
display: flex;
flex: 1;
@media (--viewportMedium) {
justify-content: center;
align-items: flex-start;
}
}
.submitEmailContent {
@apply --baseContent;
}
.emailSubmittedContent {
@apply --baseContent;
padding-bottom: 99px;
@media (--viewportMedium) {
padding-bottom: 62px;
min-height: 508px;
}
@apply --marketplaceModalRootStyles;
}
.submitEmailContent,
.genericErrorContent,
.emailSubmittedContent,
.emailNotVerifiedContent {
@apply --baseContent;
padding-top: 30px;
@media (--viewportMedium) {
padding-top: 53px;
padding-bottom: 80px;
}
}
.genericErrorContent {
@apply --baseContent;
}
.keysIconRoot {
width: 100%;
height: 100%;
}
.title {
@apply --marketplaceModalTitle;
margin-top: 31px;
margin-bottom: 0px;
}
.message {
margin-top: 23px;
margin-bottom: 0px;
@media (--viewportMedium) {
margin-top: 24px;
margin-bottom: 0px;
}
}
.submittedEmail {
font-weight: bold;
}
.emailNotVerifiedBottomText {
margin-top: 30px;
margin-bottom: 0px;
@media (--viewportMedium) {
margin-top: 32px;
}
@apply --marketplaceModalBaseStyles;
}
.bottomWrapper {
margin-top: auto;
@apply --marketplaceModalBottomWrapper;
/* Align the helper links to the left since there isn't a Primary Button anymore */
text-align: left;
}
.bottomInfo {
@apply --marketplaceH5FontStyles;
margin: 0;
color: var(--matterColorAnti);
@media (--viewportMedium) {
margin: 0;
}
.modalIcon {
@apply --marketplaceModalIconStyles;
}
.bottomLink {
@apply --marketplaceH5FontStyles;
margin: 0;
color: var(--matterColor);
/* ================ Typography ================ */
@media (--viewportMedium) {
margin: 0;
}
/* Title of the modal */
.modalTitle {
@apply --marketplaceModalTitleStyles;
}
/* Paragraph for the Modal */
.modalMessage {
@apply --marketplaceModalParagraphStyles;
}
/* Make the email pop */
.email {
@apply --marketplaceModalHighlightEmail;
}
.helperLink {
@apply --marketplaceModalHelperLink;
}
.helperText {
@apply --marketplaceModalHelperText;
}

View file

@ -55,24 +55,24 @@ export const PasswordRecoveryPageComponent = props => {
});
const resendEmailLink = (
<InlineTextButton className={css.bottomLink} onClick={() => onSubmitEmail(submittedEmail)}>
<InlineTextButton className={css.helperLink} onClick={() => onSubmitEmail(submittedEmail)}>
<FormattedMessage id="PasswordRecoveryPage.resendEmailLinkText" />
</InlineTextButton>
);
const fixEmailLink = (
<InlineTextButton className={css.bottomLink} onClick={onRetypeEmail}>
<InlineTextButton className={css.helperLink} onClick={onRetypeEmail}>
<FormattedMessage id="PasswordRecoveryPage.fixEmailLinkText" />
</InlineTextButton>
);
const submitEmailContent = (
<div className={css.submitEmailContent}>
<IconKeys />
<h1 className={css.title}>
<IconKeys className={css.modalIcon} />
<h1 className={css.modalTitle}>
<FormattedMessage id="PasswordRecoveryPage.forgotPasswordTitle" />
</h1>
<p className={css.message}>
<p className={css.modalMessage}>
<FormattedMessage id="PasswordRecoveryPage.forgotPasswordMessage" />
</p>
<PasswordRecoveryForm
@ -85,23 +85,23 @@ export const PasswordRecoveryPageComponent = props => {
);
const submittedEmailText = passwordRequested
? <span className={css.submittedEmail}>{initialEmail}</span>
: <span className={css.submittedEmail}>{submittedEmail}</span>;
? <span className={css.email}>{initialEmail}</span>
: <span className={css.email}>{submittedEmail}</span>;
const emailSubmittedContent = (
<div className={css.emailSubmittedContent}>
<IconKeys />
<h1 className={css.title}>
<IconKeys className={css.modalIcon} />
<h1 className={css.modalTitle}>
<FormattedMessage id="PasswordRecoveryPage.emailSubmittedTitle" />
</h1>
<p className={css.message}>
<p className={css.modalMessage}>
<FormattedMessage
id="PasswordRecoveryPage.emailSubmittedMessage"
values={{ submittedEmailText }}
/>
</p>
<div className={css.bottomWrapper}>
<p className={css.bottomInfo}>
<p className={css.helperText}>
{recoveryInProgress
? <FormattedMessage id="PasswordRecoveryPage.resendingEmailInfo" />
: <FormattedMessage
@ -109,27 +109,27 @@ export const PasswordRecoveryPageComponent = props => {
values={{ resendEmailLink }}
/>}
</p>
<p className={css.bottomInfo}>
<FormattedMessage id="PasswordRecoveryPage.fixEmailInfo" values={{ fixEmailLink }} />
<p className={css.helperText}>
<FormattedMessage id="PasswordRecoveryPage.fixEmailInfo" values={{ fixEmailLink }} />
</p>
</div>
</div>
);
const initialEmailText = <span className={css.submittedEmail}>{initialEmail}</span>;
const initialEmailText = <span className={css.email}>{initialEmail}</span>;
const emailNotVerifiedContent = (
<div className={css.emailNotVerifiedContent}>
<DoorIcon />
<h1 className={css.title}>
<DoorIcon className={css.modalIcon}/>
<h1 className={css.modalTitle}>
<FormattedMessage id="PasswordRecoveryPage.emailNotVerifiedTitle" />
</h1>
<p className={css.message}>
<p className={css.modalMessage}>
<FormattedMessage
id="PasswordRecoveryPage.emailNotVerifiedMessage"
values={{ initialEmailText }}
/>
</p>
<p className={css.emailNotVerifiedBottomText}>
<p className={css.modalMessage}>
<FormattedMessage id="PasswordRecoveryPage.emailNotVerifiedContactAdmin" />
</p>
</div>
@ -137,11 +137,11 @@ export const PasswordRecoveryPageComponent = props => {
const genericErrorContent = (
<div className={css.genericErrorContent}>
<IconKeys />
<h1 className={css.title}>
<IconKeys className={css.modalIcon} />
<h1 className={css.modalTitle}>
<FormattedMessage id="PasswordRecoveryPage.actionFailedTitle" />
</h1>
<p>
<p className={css.modalMessage}>
<FormattedMessage id="PasswordRecoveryPage.actionFailedMessage" />
</p>
</div>

View file

@ -1,15 +1,9 @@
@import '../../marketplace.css';
.root {
}
.passwordInput {
/* Leave space between the input and the button below when the
viewport height is small */
margin-bottom: 24px;
}
.submitButton {
/* In a flexbox context, this makes the button position itself to the
bottom */
margin-top: auto;
.password {
@apply --marketplaceModalPasswordMargins;
}

View file

@ -62,7 +62,7 @@ const PasswordResetFormComponent = props => {
return (
<form className={classes} onSubmit={handleSubmit}>
<TextInputField
className={css.passwordInput}
className={css.password}
type="password"
name="password"
id={`${form}.password`}

View file

@ -1,70 +1,51 @@
@import '../../marketplace.css';
.root {
@apply --backgroundImage;
flex-grow: 1;
display: flex;
@media (--viewportMedium) {
justify-content: center;
align-items: flex-start;
}
@apply --marketplaceModalRootStyles;
}
.content {
flex-grow: 1;
display: flex;
flex-direction: column;
padding: 30px 24px 98px 24px;
background-color: var(--matterColorLight);
border-radius: 2px;
@media (--viewportMedium) {
flex-basis: 480px;
flex-grow: 0;
min-height: 573px;
padding: 60px;
margin-top: 7.5vh;
margin-bottom: 7.5vh;
}
}
.error {
color: var(--failColor);
}
.mainHeading {
margin-top: 26px;
@media (--viewportMedium) {
margin-top: 23px;
}
}
.helpText {
margin-top: 12px;
@media (--viewportMedium) {
margin-top: 15px;
}
@apply --marketplaceModalBaseStyles;
}
.form {
flex: 1;
display: flex;
flex-direction: column;
margin-top: 37px;
@media (--viewportMedium) {
margin-top: 38px;
}
@apply --marketplaceModalFormRootStyles;
}
.buttonLink {
.error {
@apply --marketplaceModalErrorStyles;
}
/* ================ Typography ================ */
/* Title of the modal */
.modalTitle {
@apply --marketplaceModalTitleStyles;
}
/* Paragraph for the Modal */
.modalMessage {
@apply --marketplaceModalParagraphStyles;
}
/* Make the email pop */
.email {
@apply --marketplaceModalHighlightEmail;
}
.helperLink {
@apply --marketplaceModalHelperLink;
}
.helperText {
@apply --marketplaceModalHelperText;
}
.submitButton {
@apply --marketplaceButtonStylesPrimary;
/* Pull the button to the bottom of the flex container */
margin-top: auto;
}
.modalIcon {
@apply --marketplaceModalIconStyles;
}

View file

@ -81,11 +81,11 @@ export class PasswordResetPageComponent extends Component {
const resetFormContent = (
<div className={css.content}>
<IconKeys />
<h1 className={css.mainHeading}>
<IconKeys className={css.modalIcon} />
<h1 className={css.modalTitle}>
<FormattedMessage id="PasswordResetPage.mainHeading" />
</h1>
<p className={css.helpText}>
<p className={css.modalMessage}>
<FormattedMessage id="PasswordResetPage.helpText" />
</p>
{resetPasswordError
@ -103,14 +103,14 @@ export class PasswordResetPageComponent extends Component {
const resetDoneContent = (
<div className={css.content}>
<IconKeysSuccess />
<h1 className={css.mainHeading}>
<IconKeysSuccess className={css.modalIcon} />
<h1 className={css.modalTitle}>
<FormattedMessage id="PasswordResetPage.passwordChangedHeading" />
</h1>
<p className={css.helpText}>
<p className={css.modalMessage}>
<FormattedMessage id="PasswordResetPage.passwordChangedHelpText" />
</p>
<NamedLink name="LoginPage" className={css.buttonLink}>
<NamedLink name="LoginPage" className={css.submitButton}>
<FormattedMessage id="PasswordResetPage.loginButtonText" />
</NamedLink>
</div>

View file

@ -60,9 +60,5 @@
}
.error {
color: red;
}
.submitButton {
margin-top: 40px;
}
@apply --marketplaceModalErrorStyles;
}

View file

@ -1,11 +1,7 @@
@import '../../marketplace.css';
.root {
display: flex;
flex-direction: column;
flex: 1;
justify-content: space-between;
height: 100%;
@apply --marketplaceModalFormRootStyles;
}
.name {
@ -27,18 +23,9 @@
}
.password {
margin-top: 24px;
@media (--viewportMedium) {
margin-top: 30px;
}
@apply --marketplaceModalPasswordMargins;
}
.button {
margin-top: 24px;
align-self: stretch;
@media (--viewportMedium) {
margin-top: 72px;
}
.bottomWrapper {
@apply --marketplaceModalBottomWrapper;
}

View file

@ -3,7 +3,7 @@ import { compose } from 'redux';
import { FormattedMessage, injectIntl, intlShape } from 'react-intl';
import { reduxForm, propTypes as formPropTypes } from 'redux-form';
import classNames from 'classnames';
import { Button, TextInputField } from '../../components';
import { PrimaryButton, TextInputField } from '../../components';
import * as validators from '../../util/validators';
import css from './SignupForm.css';
@ -137,9 +137,13 @@ const SignupFormComponent = props => {
validate={passwordValidators}
/>
</div>
<Button className={css.button} type="submit" disabled={submitDisabled}>
<FormattedMessage id="SignupForm.signUp" />
</Button>
<div className={css.bottomWrapper}>
<PrimaryButton className={css.submitButton} type="submit" disabled={submitDisabled}>
<FormattedMessage id="SignupForm.signUp" />
</PrimaryButton>
</div>
</form>
);
};

View file

@ -286,6 +286,224 @@
outline: none;
}
}
/* ================ Modals ================ */
--marketplaceModalRootStyles {
/* PageLayout is using flex: AuthenticationPage's .root takes all available space */
flex-grow: 1;
/* AuthenticationPage's root uses flexbox */
display: flex;
@media (--viewportMedium) {
justify-content: center;
align-items: flex-start;
@apply --backgroundImage;
}
}
--marketplaceModalFormRootStyles {
display: flex;
flex-direction: column;
flex: 1;
justify-content: space-between;
height: 100%;
}
--marketplaceModalBaseStyles {
flex-grow: 1;
/* Create context so the close button can be positioned within it */
position: relative;
/* Display and dimensions */
display: flex;
flex-direction: column;
padding: 24px 24px 48px 24px;
background-color: var(--matterColorLight);
border-radius: var(--borderRadius);
@media (--viewportMedium) {
flex-basis: 480px;
flex-grow: 0;
/* min-height: 568px; */
padding: 55px 60px 55px 60px;
margin-top: 12.5vh;
margin-bottom: 12.5vh;
}
}
/* Modal title */
--marketplaceModalTitleStyles {
font-weight: var(--fontWeightSemiBold);
font-size: 30px;
line-height: 36px;
letter-spacing: -0.5px;
margin: 0;
font-weight: var(--fontWeightBold);
@media (--viewportMedium) {
font-weight: var(--fontWeightSemiBold);
line-height: 40px;
letter-spacing: -0.9px;
margin: 0;
}
}
/* Modal message */
--marketplaceModalParagraphStyles {
margin: 18px 0 0 0;
@media (--viewportMedium) {
margin: 24px 0 0 0;
}
}
/* Bottom wrapper for the modal */
--marketplaceModalBottomWrapper {
text-align: center;
margin-top: 60px;
align-self: stretch;
@media (--viewportMedium) {
margin-top: 96px;
}
}
/* Adjust the bottomWrapper's margin to match modals without the helper text */
--marketplaceModalBottomWrapperText {
margin-top: -24px;
padding-bottom: 8px;
@media (--viewportMedium) {
padding-bottom: 0;
}
}
--marketplaceModalHelperText {
@apply --marketplaceH5FontStyles;
color: var(--matterColorAnti);
margin: 0;
@media (--viewportMedium) {
margin: 0;
}
}
--marketplaceModalHelperLink {
@apply --marketplaceH5FontStyles;
color: var(--matterColor);
margin: 0;
@media (--viewportMedium) {
margin: 0;
}
}
/* Modal Close icon */
--marketplaceModalCloseStyles {
/* Position inside modal */
position: absolute;
top: 0;
right: 0;
/* Some content (like map) is positioning itself on top of close button without z-index handling */
z-index: calc(var(--zIndexModal) + 1);
/* Safari didn't know how to baseline-align svg icon and text */
display: flex;
align-items: flex-start;
width: auto;
/* Sizing (touch area) */
padding: 24px 30px;
margin: 0;
border: 0;
@media (--viewportMedium) {
padding: 27px 30px;
}
/* Colors */
background-color: transparent;
color: var(--matterColor);
cursor: pointer;
&:enabled:hover {
background-color: transparent;
color: var(--matterColorDark);
box-shadow: none;
text-decoration: none;
}
&:enabled:active {
background-color: transparent;
color: var(--matterColorDark);
}
&:disabled {
background-color: transparent;
}
}
--marketplaceModalIconStyles {
height: 48px;
margin-bottom: 12px;
@media (--viewportMedium) {
height: 64px;
margin-bottom: 23px;
}
}
--marketplaceModalCloseText {
/* Font */
@apply --marketplaceH6FontStyles;
margin: -2.5px 0 0 0;
@media (--viewportMedium) {
margin-top: -1px;
}
}
--marketplaceModalCloseIcon {
display: inline-block;
margin-left: 8px;
padding: 2px 0 4px;
box-sizing: content-box;
}
--marketplaceModalErrorStyles {
@apply --marketplaceH4FontStyles;
margin-top: 24px;
color: var(--failColor);
}
--marketplaceModalHighlightEmail {
font-weight: var(--fontWeightBold);
}
--marketplaceModalPasswordMargins {
/* Leave space between the input and the button below when the
viewport height is small */
margin-top: 24px;
@media (--viewportMedium) {
margin-top: 30px;
}
}
}

View file

@ -198,20 +198,6 @@
}
/* This font is specific to Modal's (Lightbox) titles */
--marketplaceModalTitle: {
font-weight: var(--fontWeightSemiBold);
font-size: 30px;
line-height: 36px;
letter-spacing: -0.5px;
@media (--viewportMedium) {
line-height: 40px;
letter-spacing: -0.9px;
}
}
/* ================ Tabbed navigation font styles ================ */
--marketplaceTabNavFontStyles {

View file

@ -74,6 +74,10 @@ label {
}
}
button {
font-family: "sofiapro", Helvetica, Arial, sans-serif;
}
select {
@apply --marketplaceSelectStyles;
}