Merge pull request #535 from sharetribe/flash-messages

Flash messages
This commit is contained in:
Kimmo Puputti 2017-11-06 09:28:40 +02:00 committed by GitHub
commit 33a844e386
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
47 changed files with 138 additions and 255 deletions

View file

@ -2,13 +2,12 @@ import React, { Component } from 'react';
import PropTypes from 'prop-types';
import Helmet from 'react-helmet';
import { withRouter } from 'react-router-dom';
import { FormattedMessage, injectIntl, intlShape } from 'react-intl';
import { injectIntl, intlShape } from 'react-intl';
import classNames from 'classnames';
import routeConfiguration from '../../routeConfiguration';
import config from '../../config';
import { metaTagProps } from '../../util/seo';
import { canonicalRoutePath } from '../../util/routes';
import * as propTypes from '../../util/propTypes';
import facebookImage from '../../assets/saunatimeFacebook-1200x630.jpg';
import twitterImage from '../../assets/saunatimeTwitter-600x314.jpg';
@ -49,7 +48,6 @@ class PageComponent extends Component {
children,
location,
intl,
logoutError,
scrollingDisabled,
author,
contentType,
@ -64,14 +62,6 @@ class PageComponent extends Component {
updated,
} = this.props;
// TODO: use FlashMessages for auth errors
/* eslint-disable no-console */
if (logoutError && console && console.error) {
console.error(logoutError);
}
/* eslint-enable no-console */
const classes = classNames(rootClassName || css.root, className, {
[css.scrollingDisabled]: scrollingDisabled,
});
@ -171,11 +161,6 @@ class PageComponent extends Component {
{metaTags}
<script type="application/ld+json">{schemaArrayJSONString}</script>
</Helmet>
{logoutError ? (
<div style={{ color: 'red' }}>
<FormattedMessage id="Page.logoutFailed" />
</div>
) : null}
<div className={css.content}>{children}</div>
</div>
);
@ -188,8 +173,6 @@ PageComponent.defaultProps = {
className: null,
rootClassName: null,
children: null,
logoutError: null,
scrollingDisabled: false,
author: null,
contentType: 'website',
description: null,
@ -206,8 +189,7 @@ PageComponent.propTypes = {
className: string,
rootClassName: string,
children: any,
logoutError: propTypes.error,
scrollingDisabled: bool,
scrollingDisabled: bool.isRequired,
// SEO related props
author: string,

View file

@ -189,3 +189,51 @@
.modalIcon {
@apply --marketplaceModalIconStyles;
}
.genericError {
position: fixed;
top: calc(var(--topbarHeight) + 15px);
/* Place enough to the right to hide the error */
right: -355px;
max-width: 340px;
margin: 0 15px;
/* Animate error from the right */
transition: right var(--transitionStyle);
/* Bleed the bg color from the bottom */
padding-bottom: 4px;
background-color: var(--marketplaceColor);
border-radius: 4px;
/* Place on top of everything */
z-index: var(--zIndexGenericError);
@media (--viewportMedium) {
top: calc(var(--topbarHeightDesktop) + 15px);
}
}
.genericErrorVisible {
right: 0;
}
.genericErrorContent {
padding: 16px 22px;
border-radius: 4px;
background-color: var(--marketplaceColorLight);
border-radius: 4px;
}
.genericErrorText {
@apply --marketplaceH5FontStyles;
font-weight: var(--fontWeightSemiBold);
margin: 0;
color: var(--matterColorLight);
@media (--viewportMedium) {
margin: 0;
}
}

View file

@ -67,6 +67,28 @@ const isTooManyVerificationRequestsApiError = error => {
return apiError && apiError.code === ERROR_CODE_TOO_MANY_VERIFICATION_REQUESTS;
};
const GenericError = props => {
const { show } = props;
const classes = classNames(css.genericError, {
[css.genericErrorVisible]: show,
});
return (
<div className={classes}>
<div className={css.genericErrorContent}>
<p className={css.genericErrorText}>
<FormattedMessage id="Topbar.genericError" />
</p>
</div>
</div>
);
};
const { bool } = PropTypes;
GenericError.propTypes = {
show: bool.isRequired,
};
class TopbarComponent extends Component {
constructor(props) {
super(props);
@ -149,7 +171,6 @@ class TopbarComponent extends Component {
window.location = path;
}
// TODO: show flash message
console.log('logged out'); // eslint-disable-line
});
}
@ -174,6 +195,7 @@ class TopbarComponent extends Component {
onResendVerificationEmail,
sendVerificationEmailInProgress,
sendVerificationEmailError,
showGenericError,
} = this.props;
const { mobilemenu, mobilesearch, address, origin, bounds, country } = parse(location.search, {
@ -342,6 +364,7 @@ class TopbarComponent extends Component {
</div>
</div>
</Modal>
<GenericError show={showGenericError} />
</div>
);
}
@ -360,7 +383,7 @@ TopbarComponent.defaultProps = {
sendVerificationEmailError: null,
};
const { bool, func, number, shape, string } = PropTypes;
const { func, number, shape, string } = PropTypes;
TopbarComponent.propTypes = {
className: string,
@ -380,6 +403,7 @@ TopbarComponent.propTypes = {
onResendVerificationEmail: func.isRequired,
sendVerificationEmailInProgress: bool.isRequired,
sendVerificationEmailError: propTypes.error,
showGenericError: bool.isRequired,
// These are passed from Page to keep Topbar rendering aware of location changes
history: shape({

View file

@ -49,7 +49,6 @@ export class AuthenticationPageComponent extends Component {
isAuthenticated,
location,
loginError,
logoutError,
scrollingDisabled,
signupError,
submitLogin,
@ -79,15 +78,6 @@ export class AuthenticationPageComponent extends Component {
return <NamedRedirect name="LandingPage" />;
}
/* eslint-disable no-console */
if (loginError && console && console.error) {
console.error(loginError);
}
if (signupError && console && console.error) {
console.error(signupError);
}
/* eslint-enable no-console */
const loginErrorMessage = (
<div className={css.error}>
<FormattedMessage id="AuthenticationPage.loginFailed" />
@ -224,7 +214,6 @@ export class AuthenticationPageComponent extends Component {
return (
<Page
logoutError={logoutError}
title={schemaTitle}
scrollingDisabled={scrollingDisabled}
schema={{
@ -267,7 +256,6 @@ export class AuthenticationPageComponent extends Component {
AuthenticationPageComponent.defaultProps = {
currentUser: null,
loginError: null,
logoutError: null,
signupError: null,
tab: 'signup',
sendVerificationEmailError: null,
@ -280,7 +268,6 @@ AuthenticationPageComponent.propTypes = {
currentUser: propTypes.currentUser,
isAuthenticated: bool.isRequired,
loginError: propTypes.error,
logoutError: propTypes.error,
scrollingDisabled: bool.isRequired,
signupError: propTypes.error,
submitLogin: func.isRequired,
@ -300,14 +287,13 @@ AuthenticationPageComponent.propTypes = {
};
const mapStateToProps = state => {
const { isAuthenticated, loginError, logoutError, signupError } = state.Auth;
const { isAuthenticated, loginError, signupError } = state.Auth;
const { currentUser, sendVerificationEmailInProgress, sendVerificationEmailError } = state.user;
return {
authInProgress: authenticationInProgress(state),
currentUser,
isAuthenticated,
loginError,
logoutError,
scrollingDisabled: isScrollingDisabled(state),
signupError,
sendVerificationEmailInProgress,

View file

@ -2,7 +2,6 @@
exports[`AuthenticationPageComponent matches snapshot 1`] = `
<Page
logoutError={null}
schema={
Object {
"@context": "http://schema.org",

View file

@ -23,6 +23,7 @@ import {
ResponsiveImage,
} from '../../components';
import { StripePaymentForm } from '../../containers';
import { isScrollingDisabled } from '../../ducks/UI.duck';
import { initiateOrder, setInitialValues, speculateTransaction } from './CheckoutPage.duck';
import { storeData, storedData, clearData } from './CheckoutPageSessionHelpers';
@ -125,7 +126,7 @@ export class CheckoutPageComponent extends Component {
render() {
const {
logoutError,
scrollingDisabled,
speculateTransactionInProgress,
speculateTransactionError,
speculatedTransaction,
@ -262,7 +263,7 @@ export class CheckoutPageComponent extends Component {
</div>
);
const pageProps = { logoutError, title };
const pageProps = { title, scrollingDisabled };
if (isLoading) {
return (
@ -376,13 +377,13 @@ CheckoutPageComponent.defaultProps = {
bookingDates: null,
speculateTransactionError: null,
speculatedTransaction: null,
logoutError: null,
currentUser: null,
};
const { func, instanceOf, shape, string, bool } = PropTypes;
CheckoutPageComponent.propTypes = {
scrollingDisabled: bool.isRequired,
listing: propTypes.listing,
bookingDates: shape({
bookingStart: instanceOf(Date).isRequired,
@ -393,7 +394,6 @@ CheckoutPageComponent.propTypes = {
speculateTransactionError: propTypes.error,
speculatedTransaction: propTypes.transaction,
initiateOrderError: propTypes.error,
logoutError: propTypes.error,
currentUser: propTypes.currentUser,
params: shape({
id: string,
@ -420,10 +420,9 @@ const mapStateToProps = state => {
initiateOrderError,
} = state.CheckoutPage;
const { currentUser } = state.user;
const { logoutError } = state.Auth;
return {
scrollingDisabled: isScrollingDisabled(state),
currentUser,
logoutError,
bookingDates,
speculateTransactionInProgress,
speculateTransactionError,

View file

@ -22,6 +22,7 @@ describe('CheckoutPage', () => {
sendOrderRequest: noop,
fetchSpeculatedTransaction: noop,
speculateTransactionInProgress: false,
scrollingDisabled: false,
};
const tree = renderShallow(<CheckoutPageComponent {...props} />);
expect(tree).toMatchSnapshot();

View file

@ -2,7 +2,7 @@
exports[`CheckoutPage matches snapshot 1`] = `
<Page
logoutError={null}
scrollingDisabled={false}
title="CheckoutPage.title"
>
<div>

View file

@ -28,7 +28,6 @@ export const ContactDetailsPageComponent = props => {
changeEmailInProgress,
currentUser,
emailChanged,
logoutError,
onChange,
scrollingDisabled,
sendVerificationEmailInProgress,
@ -73,7 +72,7 @@ export const ContactDetailsPageComponent = props => {
) : null;
return (
<Page logoutError={logoutError} title="Contact details" scrollingDisabled={scrollingDisabled}>
<Page title="Contact details" scrollingDisabled={scrollingDisabled}>
<LayoutSideNavigation>
<LayoutWrapperTopbar>
<TopbarContainer
@ -103,7 +102,6 @@ export const ContactDetailsPageComponent = props => {
ContactDetailsPageComponent.defaultProps = {
changeEmailError: null,
currentUser: null,
logoutError: null,
sendVerificationEmailError: null,
};
@ -114,7 +112,6 @@ ContactDetailsPageComponent.propTypes = {
changeEmailInProgress: bool.isRequired,
currentUser: propTypes.currentUser,
emailChanged: bool.isRequired,
logoutError: propTypes.error,
onChange: func.isRequired,
onSubmitChangeEmail: func.isRequired,
scrollingDisabled: bool.isRequired,
@ -124,8 +121,6 @@ ContactDetailsPageComponent.propTypes = {
};
const mapStateToProps = state => {
// Page needs logoutError, Topbar needs isAuthenticated
const { isAuthenticated, logoutError } = state.Auth;
// Topbar needs user info.
const { currentUser, sendVerificationEmailInProgress, sendVerificationEmailError } = state.user;
const { changeEmailError, changeEmailInProgress, emailChanged } = state.ContactDetailsPage;
@ -134,8 +129,6 @@ const mapStateToProps = state => {
changeEmailInProgress,
currentUser,
emailChanged,
isAuthenticated,
logoutError,
scrollingDisabled: isScrollingDisabled(state),
sendVerificationEmailInProgress,
sendVerificationEmailError,

View file

@ -2,7 +2,6 @@
exports[`ContactDetailsPage matches snapshot 1`] = `
<Page
logoutError={null}
scrollingDisabled={false}
title="Contact details"
>

View file

@ -49,7 +49,6 @@ export const EditListingPageComponent = props => {
getListing,
history,
intl,
logoutError,
onCreateListing,
onUpdateListing,
onCreateListingDraft,
@ -115,7 +114,7 @@ export const EditListingPageComponent = props => {
: intl.formatMessage({ id: 'EditListingPage.titleEditListing' });
return (
<Page logoutError={logoutError} title={title} scrollingDisabled={scrollingDisabled}>
<Page title={title} scrollingDisabled={scrollingDisabled}>
<TopbarContainer
className={css.topbar}
mobileRootClassName={css.mobileTopbar}
@ -155,7 +154,9 @@ export const EditListingPageComponent = props => {
const loadingPageMsg = {
id: 'EditListingPage.loadingListingData',
};
return <Page title={intl.formatMessage(loadingPageMsg)} />;
return (
<Page title={intl.formatMessage(loadingPageMsg)} scrollingDisabled={scrollingDisabled} />
);
}
};
@ -165,7 +166,6 @@ EditListingPageComponent.defaultProps = {
currentUserHasOrders: null,
listing: null,
listingDraft: null,
logoutError: null,
notificationCount: 0,
sendVerificationEmailError: null,
};
@ -177,7 +177,6 @@ EditListingPageComponent.propTypes = {
currentUser: propTypes.currentUser,
fetchInProgress: bool.isRequired,
getListing: func.isRequired,
logoutError: propTypes.error,
onCreateListing: func.isRequired,
onCreateListingDraft: func.isRequired,
onImageUpload: func.isRequired,
@ -209,7 +208,6 @@ EditListingPageComponent.propTypes = {
const mapStateToProps = state => {
const page = state.EditListingPage;
const { logoutError } = state.Auth;
const { createStripeAccountInProgress, createStripeAccountError, currentUser } = state.user;
const fetchInProgress = createStripeAccountInProgress;
@ -223,7 +221,6 @@ const mapStateToProps = state => {
currentUser,
fetchInProgress,
getListing,
logoutError,
page,
scrollingDisabled: isScrollingDisabled(state),
};

View file

@ -2,7 +2,6 @@
exports[`EditListingPageComponent matches snapshot 1`] = `
<Page
logoutError={null}
scrollingDisabled={false}
title="EditListingPage.titleCreateListing"
>

View file

@ -46,7 +46,6 @@ export const EmailVerificationPageComponent = props => {
const {
currentUser,
intl,
logoutError,
scrollingDisabled,
submitVerification,
emailVerificationInProgress,
@ -60,7 +59,7 @@ export const EmailVerificationPageComponent = props => {
const initialValues = { verificationToken: parseVerificationToken(location) };
return (
<Page title={title} logoutError={logoutError} scrollingDisabled={scrollingDisabled}>
<Page title={title} scrollingDisabled={scrollingDisabled}>
<LayoutSingleColumn>
<LayoutWrapperTopbar>
<TopbarContainer />
@ -92,7 +91,6 @@ export const EmailVerificationPageComponent = props => {
EmailVerificationPageComponent.defaultProps = {
currentUser: null,
logoutError: null,
verificationError: null,
};
@ -100,7 +98,6 @@ const { bool, func, shape, string } = PropTypes;
EmailVerificationPageComponent.propTypes = {
currentUser: propTypes.currentUser,
logoutError: propTypes.error,
scrollingDisabled: bool.isRequired,
submitVerification: func.isRequired,
emailVerificationInProgress: bool.isRequired,
@ -116,14 +113,12 @@ EmailVerificationPageComponent.propTypes = {
};
const mapStateToProps = state => {
const { logoutError } = state.Auth;
const { currentUser } = state.user;
const { verificationError, verificationInProgress } = state.EmailVerification;
return {
verificationError,
emailVerificationInProgress: verificationInProgress,
currentUser,
logoutError,
scrollingDisabled: isScrollingDisabled(state),
};
};

View file

@ -170,7 +170,6 @@ export const InboxPageComponent = props => {
fetchInProgress,
fetchOrdersOrSalesError,
intl,
logoutError,
pagination,
params,
providerNotificationCount,
@ -260,7 +259,7 @@ export const InboxPageComponent = props => {
const nav = <TabNav rootClassName={css.tabs} tabRootClassName={css.tab} tabs={tabs} />;
return (
<Page logoutError={logoutError} title={title} scrollingDisabled={scrollingDisabled}>
<Page title={title} scrollingDisabled={scrollingDisabled}>
<LayoutSideNavigation>
<LayoutWrapperTopbar>
<TopbarContainer
@ -296,7 +295,6 @@ InboxPageComponent.defaultProps = {
currentUser: null,
currentUserHasOrders: null,
fetchOrdersOrSalesError: null,
logoutError: null,
pagination: null,
providerNotificationCount: 0,
sendVerificationEmailError: null,
@ -310,7 +308,6 @@ InboxPageComponent.propTypes = {
currentUser: propTypes.currentUser,
fetchInProgress: bool.isRequired,
fetchOrdersOrSalesError: propTypes.error,
logoutError: propTypes.error,
pagination: propTypes.pagination,
providerNotificationCount: number,
scrollingDisabled: bool.isRequired,
@ -322,13 +319,11 @@ InboxPageComponent.propTypes = {
const mapStateToProps = state => {
const { fetchInProgress, fetchOrdersOrSalesError, pagination, transactionRefs } = state.InboxPage;
const { logoutError } = state.Auth;
const { currentUser, currentUserNotificationCount: providerNotificationCount } = state.user;
return {
currentUser,
fetchInProgress,
fetchOrdersOrSalesError,
logoutError,
pagination,
providerNotificationCount,
scrollingDisabled: isScrollingDisabled(state),

View file

@ -2,7 +2,6 @@
exports[`InboxPage matches snapshot 1`] = `
<Page
logoutError={null}
scrollingDisabled={false}
title="InboxPage.ordersTitle"
>
@ -358,7 +357,6 @@ exports[`InboxPage matches snapshot 2`] = `
exports[`InboxPage matches snapshot 3`] = `
<Page
logoutError={null}
scrollingDisabled={false}
title="InboxPage.salesTitle"
>

View file

@ -4,7 +4,6 @@ import { compose } from 'redux';
import { connect } from 'react-redux';
import { withRouter } from 'react-router-dom';
import { injectIntl, intlShape } from 'react-intl';
import * as propTypes from '../../util/propTypes';
import { isScrollingDisabled } from '../../ducks/UI.duck';
import config from '../../config';
import {
@ -25,7 +24,7 @@ import twitterImage from '../../assets/saunatimeTwitter-600x314.jpg';
import css from './LandingPage.css';
export const LandingPageComponent = props => {
const { history, intl, location, logoutError, scrollingDisabled } = props;
const { history, intl, location, scrollingDisabled } = props;
// Schema for search engines (helps them to understand what this page is about)
// http://schema.org
@ -38,7 +37,6 @@ export const LandingPageComponent = props => {
return (
<Page
className={css.root}
logoutError={logoutError}
scrollingDisabled={scrollingDisabled}
contentType="website"
description={schemaDescription}
@ -72,14 +70,9 @@ export const LandingPageComponent = props => {
);
};
LandingPageComponent.defaultProps = {
logoutError: null,
};
const { bool, object } = PropTypes;
LandingPageComponent.propTypes = {
logoutError: propTypes.error,
scrollingDisabled: bool.isRequired,
// from withRouter
@ -91,9 +84,7 @@ LandingPageComponent.propTypes = {
};
const mapStateToProps = state => {
const { logoutError } = state.Auth;
return {
logoutError,
scrollingDisabled: isScrollingDisabled(state),
};
};

View file

@ -13,7 +13,6 @@ exports[`LandingPage matches snapshot 1`] = `
},
]
}
logoutError={null}
schema={
Object {
"@context": "http://schema.org",

View file

@ -179,7 +179,6 @@ export class ListingPageComponent extends Component {
currentUser,
getListing,
intl,
logoutError,
onManageDisableScrolling,
params,
scrollingDisabled,
@ -214,7 +213,7 @@ export class ListingPageComponent extends Component {
// Other error in fetching listing
return (
<Page title={errorTitle}>
<Page title={errorTitle} scrollingDisabled={scrollingDisabled}>
<LayoutSingleColumn className={css.pageRoot}>
<LayoutWrapperTopbar>{topbar}</LayoutWrapperTopbar>
<LayoutWrapperMain>
@ -232,7 +231,7 @@ export class ListingPageComponent extends Component {
// Still loading the listing
return (
<Page title={loadingTitle}>
<Page title={loadingTitle} scrollingDisabled={scrollingDisabled}>
<LayoutSingleColumn className={css.pageRoot}>
<LayoutWrapperTopbar>{topbar}</LayoutWrapperTopbar>
<LayoutWrapperMain>
@ -366,7 +365,6 @@ export class ListingPageComponent extends Component {
return (
<Page
logoutError={logoutError}
title={schemaTitle}
scrollingDisabled={scrollingDisabled}
author={currentAuthorDisplayName}
@ -520,7 +518,6 @@ export class ListingPageComponent extends Component {
ListingPageComponent.defaultProps = {
currentUser: null,
logoutError: null,
showListingError: null,
tab: 'listing',
};
@ -540,7 +537,6 @@ ListingPageComponent.propTypes = {
}).isRequired,
currentUser: propTypes.currentUser,
getListing: func.isRequired,
logoutError: propTypes.error,
onManageDisableScrolling: func.isRequired,
scrollingDisabled: bool.isRequired,
showListingError: propTypes.error,
@ -550,7 +546,6 @@ ListingPageComponent.propTypes = {
const mapStateToProps = state => {
const { showListingError } = state.ListingPage;
const { logoutError } = state.Auth;
const { currentUser } = state.user;
const getListing = id => {
@ -561,7 +556,6 @@ const mapStateToProps = state => {
return {
currentUser,
getListing,
logoutError,
scrollingDisabled: isScrollingDisabled(state),
showListingError,
};

View file

@ -6,7 +6,6 @@ exports[`ListingPage matches snapshot 1`] = `
contentType="website"
description="listing1 description"
facebookImages={Array []}
logoutError={null}
schema={
Object {
"@context": "http://schema.org",

View file

@ -49,7 +49,6 @@ export class ManageListingsPageComponent extends Component {
closingListing,
closingListingError,
listings,
logoutError,
onCloseListing,
onOpenListing,
openingListing,
@ -111,7 +110,7 @@ export class ManageListingsPageComponent extends Component {
const openingErrorListingId = !!openingListingError && openingListingError.listingId;
return (
<Page logoutError={logoutError} scrollingDisabled={scrollingDisabled} title="Manage listings">
<Page scrollingDisabled={scrollingDisabled} title="Manage listings">
<LayoutSingleColumn>
<LayoutWrapperTopbar>
<TopbarContainer currentPage="ManageListingsPage" />
@ -152,7 +151,6 @@ export class ManageListingsPageComponent extends Component {
ManageListingsPageComponent.defaultProps = {
listings: [],
logoutError: null,
pagination: null,
queryListingsError: null,
queryParams: null,
@ -171,7 +169,6 @@ ManageListingsPageComponent.propTypes = {
error: propTypes.error.isRequired,
}),
listings: arrayOf(propTypes.listing),
logoutError: propTypes.error,
onCloseListing: func.isRequired,
onOpenListing: func.isRequired,
openingListing: shape({ uuid: string.isRequired }),
@ -199,12 +196,9 @@ const mapStateToProps = state => {
closingListingError,
} = state.ManageListingsPage;
const listings = getListingsById(state, currentPageResultIds);
// Page needs logoutError
const { logoutError } = state.Auth;
return {
currentPageResultIds,
listings,
logoutError,
pagination,
queryInProgress,
queryListingsError,

View file

@ -2,7 +2,6 @@
exports[`ContactDetailsPage matches snapshot 1`] = `
<Page
logoutError={null}
scrollingDisabled={false}
title="Manage listings"
>

View file

@ -5,7 +5,6 @@ import { compose } from 'redux';
import { connect } from 'react-redux';
import { withRouter } from 'react-router-dom';
import routeConfiguration from '../../routeConfiguration';
import * as propTypes from '../../util/propTypes';
import { createResourceLocatorString } from '../../util/routes';
import { isScrollingDisabled } from '../../ducks/UI.duck';
import {
@ -30,7 +29,7 @@ export class NotFoundPageComponent extends Component {
}
render() {
const { history, logoutError, intl, scrollingDisabled } = this.props;
const { history, intl, scrollingDisabled } = this.props;
const title = intl.formatMessage({
id: 'NotFoundPage.title',
@ -46,7 +45,7 @@ export class NotFoundPageComponent extends Component {
};
return (
<Page logoutError={logoutError} title={title} scrollingDisabled={scrollingDisabled}>
<Page title={title} scrollingDisabled={scrollingDisabled}>
<LayoutSingleColumn>
<LayoutWrapperTopbar>
<TopbarContainer />
@ -75,14 +74,12 @@ export class NotFoundPageComponent extends Component {
}
NotFoundPageComponent.defaultProps = {
logoutError: null,
staticContext: {},
};
const { bool, func, object, shape } = PropTypes;
NotFoundPageComponent.propTypes = {
logoutError: propTypes.error,
scrollingDisabled: bool.isRequired,
// context object from StaticRouter, injected by the withRouter wrapper
@ -98,10 +95,7 @@ NotFoundPageComponent.propTypes = {
};
const mapStateToProps = state => {
// Page needs logoutError
const { logoutError } = state.Auth;
return {
logoutError,
scrollingDisabled: isScrollingDisabled(state),
};
};

View file

@ -2,7 +2,6 @@
exports[`NotFoundPageComponent matches snapshot 1`] = `
<Page
logoutError={null}
scrollingDisabled={false}
title="NotFoundPage.title"
>

View file

@ -26,15 +26,7 @@ import css from './OrderPage.css';
// OrderPage handles data loading
// It show loading data text or OrderDetailsPanel (and later also another panel for messages).
export const OrderPageComponent = props => {
const {
currentUser,
fetchOrderError,
intl,
logoutError,
params,
scrollingDisabled,
transaction,
} = props;
const { currentUser, fetchOrderError, intl, params, scrollingDisabled, transaction } = props;
const currentTransaction = ensureTransaction(transaction);
const currentListing = ensureListing(currentTransaction.listing);
const listingTitle = currentListing.attributes.title;
@ -76,7 +68,6 @@ export const OrderPageComponent = props => {
return (
<Page
logoutError={logoutError}
title={intl.formatMessage({ id: 'OrderPage.title' }, { listingTitle })}
scrollingDisabled={scrollingDisabled}
>
@ -96,7 +87,6 @@ export const OrderPageComponent = props => {
OrderPageComponent.defaultProps = {
currentUser: null,
fetchOrderError: null,
logoutError: null,
transaction: null,
};
@ -106,7 +96,6 @@ OrderPageComponent.propTypes = {
currentUser: propTypes.currentUser,
fetchOrderError: propTypes.error,
intl: intlShape.isRequired,
logoutError: propTypes.error,
params: shape({ id: string }).isRequired,
scrollingDisabled: bool.isRequired,
tab: oneOf(['details', 'discussion']).isRequired,
@ -115,7 +104,6 @@ OrderPageComponent.propTypes = {
const mapStateToProps = state => {
const { fetchOrderError, transactionRef } = state.OrderPage;
const { logoutError } = state.Auth;
const { currentUser } = state.user;
const transactions = getMarketplaceEntities(state, transactionRef ? [transactionRef] : []);
const transaction = transactions.length > 0 ? transactions[0] : null;
@ -123,7 +111,6 @@ const mapStateToProps = state => {
return {
currentUser,
fetchOrderError,
logoutError,
scrollingDisabled: isScrollingDisabled(state),
transaction,
};

View file

@ -2,7 +2,6 @@
exports[`OrderPage matches snapshot 1`] = `
<Page
logoutError={null}
scrollingDisabled={false}
title="OrderPage.title"
>

View file

@ -25,7 +25,6 @@ export const PasswordChangePageComponent = props => {
changePasswordError,
changePasswordInProgress,
currentUser,
logoutError,
onChange,
onSubmitChangePassword,
passwordChanged,
@ -63,7 +62,7 @@ export const PasswordChangePageComponent = props => {
) : null;
return (
<Page logoutError={logoutError} title="Contact details" scrollingDisabled={scrollingDisabled}>
<Page title="Contact details" scrollingDisabled={scrollingDisabled}>
<LayoutSideNavigation>
<LayoutWrapperTopbar>
<TopbarContainer
@ -93,7 +92,6 @@ export const PasswordChangePageComponent = props => {
PasswordChangePageComponent.defaultProps = {
changePasswordError: null,
currentUser: null,
logoutError: null,
};
const { bool, func } = PropTypes;
@ -102,7 +100,6 @@ PasswordChangePageComponent.propTypes = {
changePasswordError: propTypes.error,
changePasswordInProgress: bool.isRequired,
currentUser: propTypes.currentUser,
logoutError: propTypes.error,
onChange: func.isRequired,
onSubmitChangePassword: func.isRequired,
passwordChanged: bool.isRequired,
@ -110,8 +107,6 @@ PasswordChangePageComponent.propTypes = {
};
const mapStateToProps = state => {
// Page needs logoutError
const { logoutError } = state.Auth;
// Topbar needs user info.
const {
changePasswordError,
@ -123,7 +118,6 @@ const mapStateToProps = state => {
changePasswordError,
changePasswordInProgress,
currentUser,
logoutError,
passwordChanged,
scrollingDisabled: isScrollingDisabled(state),
};

View file

@ -2,7 +2,6 @@
exports[`PasswordChangePage matches snapshot 1`] = `
<Page
logoutError={null}
scrollingDisabled={false}
title="Contact details"
>

View file

@ -31,7 +31,7 @@ import css from './PasswordRecoveryPage.css';
export const PasswordRecoveryPageComponent = props => {
const {
logoutError,
scrollingDisabled,
initialEmail,
submittedEmail,
recoveryError,
@ -159,7 +159,7 @@ export const PasswordRecoveryPageComponent = props => {
}
return (
<Page logoutError={logoutError} title={title}>
<Page title={title} scrollingDisabled={scrollingDisabled}>
<LayoutSingleColumn>
<LayoutWrapperTopbar>
<TopbarContainer />
@ -176,7 +176,6 @@ export const PasswordRecoveryPageComponent = props => {
};
PasswordRecoveryPageComponent.defaultProps = {
logoutError: null,
sendVerificationEmailError: null,
initialEmail: null,
submittedEmail: null,
@ -186,7 +185,7 @@ PasswordRecoveryPageComponent.defaultProps = {
const { bool, func, string } = PropTypes;
PasswordRecoveryPageComponent.propTypes = {
logoutError: propTypes.error,
scrollingDisabled: bool.isRequired,
initialEmail: string,
submittedEmail: string,
recoveryError: propTypes.error,
@ -201,9 +200,6 @@ PasswordRecoveryPageComponent.propTypes = {
};
const mapStateToProps = state => {
// Page needs logoutError
const { logoutError } = state.Auth;
const {
initialEmail,
submittedEmail,
@ -212,7 +208,6 @@ const mapStateToProps = state => {
passwordRequested,
} = state.PasswordRecoveryPage;
return {
logoutError,
scrollingDisabled: isScrollingDisabled(state),
initialEmail,
submittedEmail,

View file

@ -2,7 +2,7 @@
exports[`ContactDetailsPage matches snapshot 1`] = `
<Page
logoutError={null}
scrollingDisabled={false}
title="PasswordRecoveryPage.title"
>
<LayoutSingleColumn

View file

@ -37,7 +37,6 @@ export class PasswordResetPageComponent extends Component {
render() {
const {
intl,
logoutError,
scrollingDisabled,
location,
resetPasswordInProgress,
@ -121,7 +120,7 @@ export class PasswordResetPageComponent extends Component {
}
return (
<Page title={title} logoutError={logoutError} scrollingDisabled={scrollingDisabled}>
<Page title={title} scrollingDisabled={scrollingDisabled}>
<LayoutSingleColumn>
<LayoutWrapperTopbar>
<TopbarContainer />
@ -139,14 +138,12 @@ export class PasswordResetPageComponent extends Component {
}
PasswordResetPageComponent.defaultProps = {
logoutError: null,
resetPasswordError: null,
};
const { bool, func, shape, string } = PropTypes;
PasswordResetPageComponent.propTypes = {
logoutError: propTypes.error,
scrollingDisabled: bool.isRequired,
resetPasswordInProgress: bool.isRequired,
resetPasswordError: propTypes.error,
@ -162,10 +159,8 @@ PasswordResetPageComponent.propTypes = {
};
const mapStateToProps = state => {
const { logoutError } = state.Auth;
const { resetPasswordInProgress, resetPasswordError } = state.PasswordResetPage;
return {
logoutError,
scrollingDisabled: isScrollingDisabled(state),
resetPasswordInProgress,
resetPasswordError,

View file

@ -2,7 +2,6 @@ import React from 'react';
import PropTypes from 'prop-types';
import { compose } from 'redux';
import { connect } from 'react-redux';
import * as propTypes from '../../util/propTypes';
import { isScrollingDisabled } from '../../ducks/UI.duck';
import {
Page,
@ -15,14 +14,10 @@ import {
import { TopbarContainer } from '../../containers';
export const PayoutPreferencesPageComponent = props => {
const { logoutError, scrollingDisabled } = props;
const { scrollingDisabled } = props;
return (
<Page
logoutError={logoutError}
title="Payout preferences"
scrollingDisabled={scrollingDisabled}
>
<Page title="Payout preferences" scrollingDisabled={scrollingDisabled}>
<LayoutSingleColumn>
<LayoutWrapperTopbar>
<TopbarContainer />
@ -36,22 +31,14 @@ export const PayoutPreferencesPageComponent = props => {
);
};
PayoutPreferencesPageComponent.defaultProps = {
logoutError: null,
};
const { bool } = PropTypes;
PayoutPreferencesPageComponent.propTypes = {
logoutError: propTypes.error,
scrollingDisabled: bool.isRequired,
};
const mapStateToProps = state => {
// Page needs logoutError
const { logoutError } = state.Auth;
return {
logoutError,
scrollingDisabled: isScrollingDisabled(state),
};
};

View file

@ -2,7 +2,6 @@
exports[`PayoutPreferencesPage matches snapshot 1`] = `
<Page
logoutError={null}
scrollingDisabled={false}
title="Payout preferences"
>

View file

@ -3,7 +3,6 @@ import PropTypes from 'prop-types';
import { compose } from 'redux';
import { connect } from 'react-redux';
import { injectIntl, intlShape, FormattedMessage } from 'react-intl';
import * as propTypes from '../../util/propTypes';
import { isScrollingDisabled } from '../../ducks/UI.duck';
import { TopbarContainer } from '../../containers';
import {
@ -21,7 +20,7 @@ import config from '../../config';
import css from './PrivacyPolicyPage.css';
const PrivacyPolicyPageComponent = props => {
const { logoutError, scrollingDisabled, intl } = props;
const { scrollingDisabled, intl } = props;
const tabs = [
{
@ -47,12 +46,7 @@ const PrivacyPolicyPageComponent = props => {
name: schemaTitle,
};
return (
<Page
title={schemaTitle}
logoutError={logoutError}
scrollingDisabled={scrollingDisabled}
schema={schema}
>
<Page title={schemaTitle} scrollingDisabled={scrollingDisabled} schema={schema}>
<LayoutSideNavigation>
<LayoutWrapperTopbar>
<TopbarContainer currentPage="PrivacyPolicyPage" />
@ -74,14 +68,9 @@ const PrivacyPolicyPageComponent = props => {
);
};
PrivacyPolicyPageComponent.defaultProps = {
logoutError: null,
};
const { bool } = PropTypes;
PrivacyPolicyPageComponent.propTypes = {
logoutError: propTypes.error,
scrollingDisabled: bool.isRequired,
// from injectIntl
@ -89,9 +78,7 @@ PrivacyPolicyPageComponent.propTypes = {
};
const mapStateToProps = state => {
const { logoutError } = state.Auth;
return {
logoutError,
scrollingDisabled: isScrollingDisabled(state),
};
};

View file

@ -31,7 +31,6 @@ const { UUID } = types;
export const ProfilePageComponent = props => {
const {
logoutError,
scrollingDisabled,
currentUser,
user,
@ -124,7 +123,6 @@ export const ProfilePageComponent = props => {
return (
<Page
logoutError={logoutError}
scrollingDisabled={scrollingDisabled}
title={schemaTitle}
schema={{
@ -148,7 +146,6 @@ export const ProfilePageComponent = props => {
};
ProfilePageComponent.defaultProps = {
logoutError: null,
currentUser: null,
user: null,
userShowError: null,
@ -158,7 +155,6 @@ ProfilePageComponent.defaultProps = {
const { bool, arrayOf } = PropTypes;
ProfilePageComponent.propTypes = {
logoutError: propTypes.error,
scrollingDisabled: bool.isRequired,
currentUser: propTypes.currentUser,
user: propTypes.user,
@ -171,15 +167,12 @@ ProfilePageComponent.propTypes = {
};
const mapStateToProps = state => {
// Page needs logoutError
const { logoutError } = state.Auth;
const { currentUser } = state.user;
const { userId, userShowError, queryListingsError, userListingRefs } = state.ProfilePage;
const userMatches = getMarketplaceEntities(state, [{ type: 'user', id: userId }]);
const user = userMatches.length === 1 ? userMatches[0] : null;
const listings = getMarketplaceEntities(state, userListingRefs);
return {
logoutError,
scrollingDisabled: isScrollingDisabled(state),
currentUser,
user,

View file

@ -2,7 +2,6 @@
exports[`ProfilePage matches snapshot 1`] = `
<Page
logoutError={null}
schema={
Object {
"@context": "http://schema.org",

View file

@ -37,7 +37,6 @@ export class ProfileSettingsPageComponent extends Component {
const {
currentUser,
image,
logoutError,
onChange,
onImageUpload,
onUpdateProfile,
@ -96,12 +95,7 @@ export class ProfileSettingsPageComponent extends Component {
) : null;
return (
<Page
className={css.root}
logoutError={logoutError}
title="Profile settings"
scrollingDisabled={scrollingDisabled}
>
<Page className={css.root} title="Profile settings" scrollingDisabled={scrollingDisabled}>
<LayoutSingleColumn>
<LayoutWrapperTopbar>
<TopbarContainer currentPage="ProfileSettingsPage" />
@ -137,7 +131,6 @@ export class ProfileSettingsPageComponent extends Component {
ProfileSettingsPageComponent.defaultProps = {
currentUser: null,
logoutError: null,
uploadImageError: null,
updateProfileError: null,
image: null,
@ -153,7 +146,6 @@ ProfileSettingsPageComponent.propTypes = {
file: object,
uploadedImage: propTypes.image,
}),
logoutError: propTypes.error,
onChange: func.isRequired,
onImageUpload: func.isRequired,
onUpdateProfile: func.isRequired,
@ -165,8 +157,6 @@ ProfileSettingsPageComponent.propTypes = {
};
const mapStateToProps = state => {
// Page needs logoutError
const { logoutError } = state.Auth;
const { currentUser } = state.user;
const {
image,
@ -178,7 +168,6 @@ const mapStateToProps = state => {
return {
currentUser,
image,
logoutError,
scrollingDisabled: isScrollingDisabled(state),
updateInProgress,
updateProfileError,

View file

@ -2,7 +2,6 @@
exports[`ContactDetailsPage matches snapshot 1`] = `
<Page
logoutError={null}
scrollingDisabled={false}
title="Profile settings"
>

View file

@ -34,7 +34,6 @@ export const SalePageComponent = props => {
acceptInProgress,
declineInProgress,
intl,
logoutError,
onAcceptSale,
onDeclineSale,
params,
@ -98,7 +97,6 @@ export const SalePageComponent = props => {
return (
<Page
logoutError={logoutError}
title={intl.formatMessage({ id: 'SalePage.title' }, { title: listingTitle })}
scrollingDisabled={scrollingDisabled}
>
@ -122,7 +120,6 @@ SalePageComponent.defaultProps = {
fetchSaleError: null,
acceptSaleError: null,
declineSaleError: null,
logoutError: null,
transaction: null,
};
@ -136,7 +133,6 @@ SalePageComponent.propTypes = {
acceptInProgress: bool.isRequired,
declineInProgress: bool.isRequired,
intl: intlShape.isRequired,
logoutError: propTypes.error,
onAcceptSale: func.isRequired,
onDeclineSale: func.isRequired,
params: shape({ id: string }).isRequired,
@ -154,7 +150,6 @@ const mapStateToProps = state => {
declineInProgress,
transactionRef,
} = state.SalePage;
const { logoutError } = state.Auth;
const { currentUser } = state.user;
const transactions = getMarketplaceEntities(state, transactionRef ? [transactionRef] : []);
@ -167,7 +162,6 @@ const mapStateToProps = state => {
declineSaleError,
acceptInProgress,
declineInProgress,
logoutError,
scrollingDisabled: isScrollingDisabled(state),
transaction,
};

View file

@ -2,7 +2,6 @@
exports[`SalePage matches snapshot 1`] = `
<Page
logoutError={null}
scrollingDisabled={false}
title="SalePage.title"
>

View file

@ -136,7 +136,7 @@ export class SearchPageComponent extends Component {
})
.catch(error => {
// In case of error, stop recursive loop and report error.
// TODO: Show a flash message
// TODO: Show and error in the listings column
// eslint-disable-next-line no-console
console.error(`An error (${error} occured while trying to retrieve map listings`);
});
@ -147,7 +147,6 @@ export class SearchPageComponent extends Component {
intl,
listings,
location,
logoutError,
mapListings,
onManageDisableScrolling,
pagination,
@ -270,7 +269,6 @@ export class SearchPageComponent extends Component {
/* eslint-disable jsx-a11y/no-static-element-interactions */
return (
<Page
logoutError={logoutError}
scrollingDisabled={scrollingDisabled}
description={schemaDescription}
title={schemaTitle}
@ -341,7 +339,6 @@ export class SearchPageComponent extends Component {
SearchPageComponent.defaultProps = {
listings: [],
logoutError: null,
mapListings: [],
pagination: null,
searchListingsError: null,
@ -354,7 +351,6 @@ const { array, bool, func, oneOf, object, shape, string } = PropTypes;
SearchPageComponent.propTypes = {
listings: array,
mapListings: array,
logoutError: propTypes.error,
onManageDisableScrolling: func.isRequired,
onSearchMapListings: func.isRequired,
pagination: propTypes.pagination,
@ -385,7 +381,6 @@ const mapStateToProps = state => {
searchParams,
searchMapListingIds,
} = state.SearchPage;
const { logoutError } = state.Auth;
const pageListings = getListingsById(state, currentPageResultIds);
const mapListings = getListingsById(
state,
@ -394,7 +389,6 @@ const mapStateToProps = state => {
return {
listings: pageListings,
logoutError,
mapListings,
pagination,
scrollingDisabled: isScrollingDisabled(state),

View file

@ -3,7 +3,6 @@
exports[`SearchPageComponent matches snapshot 1`] = `
<Page
description="SearchPage.schemaDescription"
logoutError={null}
schema={
Object {
"@context": "http://schema.org",

View file

@ -18,9 +18,7 @@ StaticPageComponent.propTypes = {
};
const mapStateToProps = state => {
const { logoutError } = state.Auth;
return {
logoutError,
scrollingDisabled: isScrollingDisabled(state),
};
};

View file

@ -3,7 +3,6 @@ import PropTypes from 'prop-types';
import { compose } from 'redux';
import { connect } from 'react-redux';
import { injectIntl, intlShape, FormattedMessage } from 'react-intl';
import * as propTypes from '../../util/propTypes';
import { isScrollingDisabled } from '../../ducks/UI.duck';
import { TopbarContainer } from '../../containers';
import {
@ -21,7 +20,7 @@ import config from '../../config';
import css from './TermsOfServicePage.css';
const TermsOfServicePageComponent = props => {
const { logoutError, scrollingDisabled, intl } = props;
const { scrollingDisabled, intl } = props;
const tabs = [
{
@ -47,12 +46,7 @@ const TermsOfServicePageComponent = props => {
name: schemaTitle,
};
return (
<Page
title={schemaTitle}
logoutError={logoutError}
scrollingDisabled={scrollingDisabled}
schema={schema}
>
<Page title={schemaTitle} scrollingDisabled={scrollingDisabled} schema={schema}>
<LayoutSideNavigation>
<LayoutWrapperTopbar>
<TopbarContainer currentPage="TermsOfServicePage" />
@ -74,14 +68,9 @@ const TermsOfServicePageComponent = props => {
);
};
TermsOfServicePageComponent.defaultProps = {
logoutError: null,
};
const { bool } = PropTypes;
TermsOfServicePageComponent.propTypes = {
logoutError: propTypes.error,
scrollingDisabled: bool.isRequired,
// from injectIntl
@ -89,9 +78,7 @@ TermsOfServicePageComponent.propTypes = {
};
const mapStateToProps = state => {
const { logoutError } = state.Auth;
return {
logoutError,
scrollingDisabled: isScrollingDisabled(state),
};
};

View file

@ -4,7 +4,7 @@ import { compose } from 'redux';
import { connect } from 'react-redux';
import { withRouter } from 'react-router-dom';
import * as propTypes from '../../util/propTypes';
import { sendVerificationEmail } from '../../ducks/user.duck';
import { sendVerificationEmail, hasCurrentUserErrors } from '../../ducks/user.duck';
import { logout, authenticationInProgress } from '../../ducks/Auth.duck';
import { manageDisableScrolling } from '../../ducks/UI.duck';
import { Topbar } from '../../components';
@ -17,6 +17,7 @@ export const TopbarContainerComponent = props => {
currentUserHasOrders,
history,
isAuthenticated,
hasGenericError,
location,
notificationCount,
onLogout,
@ -42,6 +43,7 @@ export const TopbarContainerComponent = props => {
onResendVerificationEmail={onResendVerificationEmail}
sendVerificationEmailInProgress={sendVerificationEmailInProgress}
sendVerificationEmailError={sendVerificationEmailError}
showGenericError={hasGenericError}
{...rest}
/>
);
@ -68,6 +70,7 @@ TopbarContainerComponent.propTypes = {
sendVerificationEmailInProgress: bool.isRequired,
sendVerificationEmailError: propTypes.error,
onResendVerificationEmail: func.isRequired,
hasGenericError: bool.isRequired,
// from withRouter
history: shape({
@ -78,7 +81,7 @@ TopbarContainerComponent.propTypes = {
const mapStateToProps = state => {
// Topbar needs isAuthenticated
const { isAuthenticated } = state.Auth;
const { isAuthenticated, logoutError } = state.Auth;
// Topbar needs user info.
const {
currentUser,
@ -88,6 +91,7 @@ const mapStateToProps = state => {
sendVerificationEmailInProgress,
sendVerificationEmailError,
} = state.user;
const hasGenericError = !!(logoutError || hasCurrentUserErrors(state));
return {
authInProgress: authenticationInProgress(state),
currentUser,
@ -97,6 +101,7 @@ const mapStateToProps = state => {
isAuthenticated,
sendVerificationEmailInProgress,
sendVerificationEmailError,
hasGenericError,
};
};

View file

@ -143,6 +143,16 @@ export default function reducer(state = initialState, action = {}) {
// ================ Selectors ================ //
export const hasCurrentUserErrors = state => {
const { user } = state;
return (
user.currentUserShowError ||
user.currentUserHasListingsError ||
user.currentUserNotificationCountError ||
user.currentUserHasOrdersError
);
};
export const verificationSendingInProgress = state => {
return state.user.sendVerificationEmailInProgress;
};
@ -267,10 +277,7 @@ export const fetchCurrentUserHasListings = () => (dispatch, getState, sdk) => {
const hasListings = response.data.data && response.data.data.length > 0;
dispatch(fetchCurrentUserHasListingsSuccess(!!hasListings));
})
.catch(e => {
// TODO: dispatch flash message: "Something went wrong while retrieving user info"
dispatch(fetchCurrentUserHasListingsError(storableError(e)));
});
.catch(e => dispatch(fetchCurrentUserHasListingsError(storableError(e))));
};
export const fetchCurrentUserHasOrders = () => (dispatch, getState, sdk) => {
@ -293,10 +300,7 @@ export const fetchCurrentUserHasOrders = () => (dispatch, getState, sdk) => {
const hasOrders = response.data.data && response.data.data.length > 0;
dispatch(fetchCurrentUserHasOrdersSuccess(!!hasOrders));
})
.catch(e => {
// TODO: dispatch flash message: "Something went wrong while retrieving user info"
dispatch(fetchCurrentUserHasOrdersError(storableError(e)));
});
.catch(e => dispatch(fetchCurrentUserHasOrdersError(storableError(e))));
};
// Notificaiton page size is max (100 items on page)
@ -318,11 +322,7 @@ export const fetchCurrentUserNotifications = () => (dispatch, getState, sdk) =>
const transactions = response.data.data;
dispatch(fetchCurrentUserNotificationsSuccess(transactions));
})
.catch(e => {
// TODO: dispatch flash message: "Something went wrong while retrieving user info"
dispatch(fetchCurrentUserNotificationsError(storableError(e)));
throw e;
});
.catch(e => dispatch(fetchCurrentUserNotificationsError(storableError(e))));
};
export const fetchCurrentUser = () => (dispatch, getState, sdk) => {
@ -362,7 +362,6 @@ export const fetchCurrentUser = () => (dispatch, getState, sdk) => {
// Make sure auth info is up to date
dispatch(authInfo());
// TODO: dispatch flash message: "Something went wrong while retrieving user info"
dispatch(currentUserShowError(storableError(e)));
});
};

View file

@ -72,6 +72,8 @@
--zIndexPopup: 50;
/* modals and UI overlays should use z-indexes above 100 */
--zIndexModal: 100;
/* generic error message should overlay even modals */
--zIndexGenericError: 200;
/* ================ Border radius ================ */

View file

@ -274,7 +274,6 @@
"OrderPage.fetchOrderFailed": "Fetching order data failed.",
"OrderPage.loadingData": "Loading order data.",
"OrderPage.title": "Order details: {listingTitle}",
"Page.logoutFailed": "Logout failed. Please try again.",
"Page.schemaDescription": "You can book a sauna from Saunatime or get some income by sharing your own sauna",
"Page.schemaTitle": "Book saunas everywhere | {siteTitle}",
"PaginationLinks.next": "Next page",
@ -457,12 +456,12 @@
"SectionHero.subTitle": "The largest online community to rent saunas in Finland.",
"SectionHero.title": "Book saunas everywhere.",
"SectionHowItWorks.createListingLink": "Ps. You can also become a Saunatime host in few clicks.",
"SectionHowItWorks.part1Title": "1. Browse and book",
"SectionHowItWorks.part1Text": "Start by searching for a location. Once you find a sauna you like, simply check the availability, book it, and make a secure payment right away.",
"SectionHowItWorks.part2Title": "2. Have a great bath",
"SectionHowItWorks.part1Title": "1. Browse and book",
"SectionHowItWorks.part2Text": "Meet your host on the date you chose and enjoy the home sauna experience. We'll handle the payment to the host after your experience.",
"SectionHowItWorks.part3Title": "3. Review the host",
"SectionHowItWorks.part2Title": "2. Have a great bath",
"SectionHowItWorks.part3Text": "If you enjoyed the experience, let others know by giving a review to your sauna host. This way others will know where to go.",
"SectionHowItWorks.part3Title": "3. Review the host",
"SectionHowItWorks.titleLineOne": "The holy sauna ritual",
"SectionHowItWorks.titleLineTwo": "(or how does Saunatime work).",
"SectionLocations.listingsInLocation": "Saunas in {location}",
@ -546,6 +545,7 @@
"Topbar.closeVerifyEmailReminder": "Later",
"Topbar.fixEmail": "Whoops, typo in your email? {fixEmailLink}",
"Topbar.fixEmailLinkText": "Fix it.",
"Topbar.genericError": "Oh no, something went wrong. Please check your network connection and try again.",
"Topbar.logoIcon": "Go to homepage",
"Topbar.menuIcon": "Open menu",
"Topbar.mobileSearchHelp": "Tip: You can also search saunas by zip code, for example \"00500\" or city district \"Sörnäinen\".",