mirror of
https://github.com/kingomarnajjar/flex-template-web.git
synced 2026-07-27 19:42:11 +10:00
commit
389e376abf
9 changed files with 121 additions and 71 deletions
|
|
@ -9,7 +9,7 @@ import { Avatar, InlineButton, NamedLink } from '../../components';
|
|||
import css from './MobileMenu.css';
|
||||
|
||||
const MobileMenu = props => {
|
||||
const { isAuthenticated, name, onLogout } = props;
|
||||
const { isAuthenticated, currentUserHasListings, name, onLogout } = props;
|
||||
|
||||
if (!isAuthenticated) {
|
||||
return (
|
||||
|
|
@ -31,6 +31,12 @@ const MobileMenu = props => {
|
|||
);
|
||||
}
|
||||
|
||||
const inboxLink = (
|
||||
<NamedLink name={currentUserHasListings ? 'InboxSalesPage' : 'InboxOrdersPage'}>
|
||||
<FormattedMessage id="MobileMenu.inboxLink" />
|
||||
</NamedLink>
|
||||
);
|
||||
|
||||
return (
|
||||
<div className={css.root}>
|
||||
<div className={css.user}>
|
||||
|
|
@ -43,9 +49,7 @@ const MobileMenu = props => {
|
|||
</div>
|
||||
</div>
|
||||
<div className={css.content}>
|
||||
<NamedLink name="InboxPage" params={{ tab: 'orders' }}>
|
||||
<FormattedMessage id="MobileMenu.inboxLink" />
|
||||
</NamedLink>
|
||||
{inboxLink}
|
||||
</div>
|
||||
<div className={css.footer}>
|
||||
<InlineButton className={css.logoutButton} onClick={onLogout}>
|
||||
|
|
@ -62,6 +66,7 @@ const { bool, func, string } = PropTypes;
|
|||
|
||||
MobileMenu.propTypes = {
|
||||
isAuthenticated: bool.isRequired,
|
||||
currentUserHasListings: bool.isRequired,
|
||||
name: string,
|
||||
onLogout: func.isRequired,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { addMarketplaceEntities } from '../../ducks/marketplaceData.duck';
|
||||
import { createStripeAccount } from '../../ducks/user.duck';
|
||||
import { createStripeAccount, fetchCurrentUserHasListingsSuccess } from '../../ducks/user.duck';
|
||||
|
||||
const requestAction = actionType => params => ({ type: actionType, payload: { params } });
|
||||
|
||||
|
|
@ -162,6 +162,13 @@ export function requestCreateListing(data) {
|
|||
dispatch(requestShowListing({ id, include: ['author', 'images'] }));
|
||||
return response;
|
||||
})
|
||||
.then(response => {
|
||||
// We must update the user duck since this might be the first
|
||||
// listing for the user, therefore changing the
|
||||
// currentUserHasListings flag in the store.
|
||||
dispatch(fetchCurrentUserHasListingsSuccess({ hasListings: true }));
|
||||
return response;
|
||||
})
|
||||
.catch(e => dispatch(createListingError(e)));
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
import { reverse, sortBy } from 'lodash';
|
||||
import { parse } from '../../util/urlHelpers';
|
||||
import { addMarketplaceEntities } from '../../ducks/marketplaceData.duck';
|
||||
import { fetchCurrentUser } from '../../ducks/user.duck';
|
||||
|
||||
const sortedTransactions = txs =>
|
||||
reverse(
|
||||
|
|
@ -16,10 +15,6 @@ export const FETCH_ORDERS_OR_SALES_REQUEST = 'app/InboxPage/FETCH_ORDERS_OR_SALE
|
|||
export const FETCH_ORDERS_OR_SALES_SUCCESS = 'app/InboxPage/FETCH_ORDERS_OR_SALES_SUCCESS';
|
||||
export const FETCH_ORDERS_OR_SALES_ERROR = 'app/InboxPage/FETCH_ORDERS_OR_SALES_ERROR';
|
||||
|
||||
export const FETCH_CURRENT_USER_HAS_LISTINGS_REQUEST = 'app/InboxPage/FETCH_CURRENT_USER_HAS_LISTINGS_REQUEST';
|
||||
export const FETCH_CURRENT_USER_HAS_LISTINGS_SUCCESS = 'app/InboxPage/FETCH_CURRENT_USER_HAS_LISTINGS_SUCCESS';
|
||||
export const FETCH_CURRENT_USER_HAS_LISTINGS_ERROR = 'app/InboxPage/FETCH_CURRENT_USER_HAS_LISTINGS_ERROR';
|
||||
|
||||
// ================ Reducer ================ //
|
||||
|
||||
const entityRefs = entities =>
|
||||
|
|
@ -33,8 +28,6 @@ const initialState = {
|
|||
fetchOrdersOrSalesError: null,
|
||||
pagination: null,
|
||||
transactionRefs: [],
|
||||
currentUserHasListingsError: null,
|
||||
currentUserHasListings: false,
|
||||
};
|
||||
|
||||
export default function checkoutPageReducer(state = initialState, action = {}) {
|
||||
|
|
@ -55,14 +48,6 @@ export default function checkoutPageReducer(state = initialState, action = {}) {
|
|||
console.error(payload); // eslint-disable-line
|
||||
return { ...state, fetchInProgress: false, fetchOrdersOrSalesError: payload };
|
||||
|
||||
case FETCH_CURRENT_USER_HAS_LISTINGS_REQUEST:
|
||||
return { ...state, currentUserHasListingsError: null };
|
||||
case FETCH_CURRENT_USER_HAS_LISTINGS_SUCCESS:
|
||||
return { ...state, currentUserHasListings: payload.hasListings };
|
||||
case FETCH_CURRENT_USER_HAS_LISTINGS_ERROR:
|
||||
console.error(payload); // eslint-disable-line
|
||||
return { ...state, currentUserHasListingsError: payload };
|
||||
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
|
|
@ -81,46 +66,8 @@ const fetchOrdersOrSalesError = e => ({
|
|||
payload: e,
|
||||
});
|
||||
|
||||
const fetchCurrentUserHasListingsRequest = () => ({
|
||||
type: FETCH_CURRENT_USER_HAS_LISTINGS_REQUEST,
|
||||
});
|
||||
|
||||
const fetchCurrentUserHasListingsSuccess = hasListings => ({
|
||||
type: FETCH_CURRENT_USER_HAS_LISTINGS_SUCCESS,
|
||||
payload: { hasListings },
|
||||
});
|
||||
|
||||
const fetchCurrentUserHasListingsError = e => ({
|
||||
type: FETCH_CURRENT_USER_HAS_LISTINGS_ERROR,
|
||||
error: true,
|
||||
payload: e,
|
||||
});
|
||||
|
||||
// ================ Thunks ================ //
|
||||
|
||||
const fetchCurrentUserHasListings = () =>
|
||||
(dispatch, getState, sdk) => {
|
||||
dispatch(fetchCurrentUserHasListingsRequest());
|
||||
dispatch(fetchCurrentUser())
|
||||
.then(() => {
|
||||
const currentUserId = getState().user.currentUser.id;
|
||||
const params = {
|
||||
author_id: currentUserId,
|
||||
|
||||
// Since we are only interested in if the user has
|
||||
// listings, we only need at most one result.
|
||||
page: 1,
|
||||
per_page: 1,
|
||||
};
|
||||
return sdk.listings.query(params);
|
||||
})
|
||||
.then(response => {
|
||||
const hasListings = response.data.data && response.data.data.length > 0;
|
||||
dispatch(fetchCurrentUserHasListingsSuccess(hasListings));
|
||||
})
|
||||
.catch(e => dispatch(fetchCurrentUserHasListingsError(e)));
|
||||
};
|
||||
|
||||
const INBOX_PAGE_SIZE = 10;
|
||||
|
||||
export const loadData = (params, search) =>
|
||||
|
|
@ -138,7 +85,6 @@ export const loadData = (params, search) =>
|
|||
}
|
||||
|
||||
dispatch(fetchOrdersOrSalesRequest());
|
||||
dispatch(fetchCurrentUserHasListings());
|
||||
|
||||
const { page = 1 } = parse(search);
|
||||
|
||||
|
|
|
|||
|
|
@ -33,7 +33,6 @@ describe('InboxPage', () => {
|
|||
lastTransitionedAt: new Date(Date.UTC(2016, 0, 15)),
|
||||
}),
|
||||
],
|
||||
currentUserHasListings: true,
|
||||
intl: fakeIntl,
|
||||
};
|
||||
|
||||
|
|
@ -67,7 +66,6 @@ describe('InboxPage', () => {
|
|||
lastTransitionedAt: new Date(Date.UTC(2016, 0, 15)),
|
||||
}),
|
||||
],
|
||||
currentUserHasListings: true,
|
||||
intl: fakeIntl,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ export const OrderPageComponent = props => {
|
|||
if (isDataAvailable && !isOwnSale) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error('Tried to access an order that was not owned by the current user');
|
||||
return <NamedRedirect name="InboxPage" params={{ tab: 'orders' }} />;
|
||||
return <NamedRedirect name="InboxOrdersPage" />;
|
||||
}
|
||||
|
||||
const detailsProps = {
|
||||
|
|
|
|||
|
|
@ -14,7 +14,15 @@ import css from './SalePage.css';
|
|||
// SalePage handles data loading
|
||||
// It show loading data text or SaleDetailsPanel (and later also another panel for messages).
|
||||
export const SalePageComponent = props => {
|
||||
const { currentUser, fetchSaleError, intl, onAcceptSale, onRejectSale, params, transaction } = props;
|
||||
const {
|
||||
currentUser,
|
||||
fetchSaleError,
|
||||
intl,
|
||||
onAcceptSale,
|
||||
onRejectSale,
|
||||
params,
|
||||
transaction,
|
||||
} = props;
|
||||
const currentTransaction = ensureTransaction(transaction);
|
||||
const currentListing = ensureListing(currentTransaction.listing);
|
||||
const title = currentListing.attributes.title;
|
||||
|
|
@ -29,7 +37,7 @@ export const SalePageComponent = props => {
|
|||
if (isDataAvailable && !isOwnSale) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error('Tried to access a sale that was not owned by the current user');
|
||||
return <NamedRedirect name="InboxPage" params={{ tab: 'sales' }} />;
|
||||
return <NamedRedirect name="InboxSalesPage" />;
|
||||
}
|
||||
|
||||
const detailsProps = {
|
||||
|
|
|
|||
|
|
@ -84,6 +84,7 @@ class TopbarComponent extends Component {
|
|||
isAuthenticated,
|
||||
authInProgress,
|
||||
currentUser,
|
||||
currentUserHasListings,
|
||||
intl,
|
||||
location,
|
||||
togglePageClassNames,
|
||||
|
|
@ -100,7 +101,12 @@ class TopbarComponent extends Component {
|
|||
const isMobileMenuOpen = mobilemenu === 'open';
|
||||
const isMobileSearchOpen = mobilesearch === 'open';
|
||||
const mobileMenu = (
|
||||
<MobileMenu isAuthenticated={isAuthenticated} name={name} onLogout={this.handleLogout} />
|
||||
<MobileMenu
|
||||
isAuthenticated={isAuthenticated}
|
||||
currentUserHasListings={currentUserHasListings}
|
||||
name={name}
|
||||
onLogout={this.handleLogout}
|
||||
/>
|
||||
);
|
||||
|
||||
// Only render current search if full place object is available in the URL params
|
||||
|
|
@ -161,6 +167,7 @@ TopbarComponent.propTypes = {
|
|||
isAuthenticated: bool.isRequired,
|
||||
authInProgress: bool.isRequired,
|
||||
currentUser: propTypes.currentUser,
|
||||
currentUserHasListings: bool.isRequired,
|
||||
onLogout: func.isRequired,
|
||||
togglePageClassNames: func.isRequired,
|
||||
|
||||
|
|
@ -181,11 +188,12 @@ TopbarComponent.propTypes = {
|
|||
|
||||
const mapStateToProps = state => {
|
||||
const { isAuthenticated } = state.Auth;
|
||||
const { currentUser } = state.user;
|
||||
const { currentUser, currentUserHasListings } = state.user;
|
||||
return {
|
||||
isAuthenticated,
|
||||
authInProgress: authenticationInProgress(state),
|
||||
currentUser,
|
||||
currentUserHasListings,
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -10,11 +10,17 @@ export const STRIPE_ACCOUNT_CREATE_REQUEST = 'app/user/STRIPE_ACCOUNT_CREATE_REQ
|
|||
export const STRIPE_ACCOUNT_CREATE_SUCCESS = 'app/user/STRIPE_ACCOUNT_CREATE_SUCCESS';
|
||||
export const STRIPE_ACCOUNT_CREATE_ERROR = 'app/user/STRIPE_ACCOUNT_CREATE_ERROR';
|
||||
|
||||
export const FETCH_CURRENT_USER_HAS_LISTINGS_REQUEST = 'app/user/FETCH_CURRENT_USER_HAS_LISTINGS_REQUEST';
|
||||
export const FETCH_CURRENT_USER_HAS_LISTINGS_SUCCESS = 'app/user/FETCH_CURRENT_USER_HAS_LISTINGS_SUCCESS';
|
||||
export const FETCH_CURRENT_USER_HAS_LISTINGS_ERROR = 'app/user/FETCH_CURRENT_USER_HAS_LISTINGS_ERROR';
|
||||
|
||||
// ================ Reducer ================ //
|
||||
|
||||
const initialState = {
|
||||
currentUser: null,
|
||||
usersMeError: null,
|
||||
currentUserHasListings: false,
|
||||
currentUserHasListingsError: null,
|
||||
};
|
||||
|
||||
export default function reducer(state = initialState, action = {}) {
|
||||
|
|
@ -30,7 +36,21 @@ export default function reducer(state = initialState, action = {}) {
|
|||
return { ...state, usersMeError: payload };
|
||||
|
||||
case CLEAR_CURRENT_USER:
|
||||
return { ...state, currentUser: null, usersMeError: null };
|
||||
return {
|
||||
...state,
|
||||
currentUser: null,
|
||||
usersMeError: null,
|
||||
currentUserHasListings: false,
|
||||
currentUserHasListingsError: null,
|
||||
};
|
||||
|
||||
case FETCH_CURRENT_USER_HAS_LISTINGS_REQUEST:
|
||||
return { ...state, currentUserHasListingsError: null };
|
||||
case FETCH_CURRENT_USER_HAS_LISTINGS_SUCCESS:
|
||||
return { ...state, currentUserHasListings: payload.hasListings };
|
||||
case FETCH_CURRENT_USER_HAS_LISTINGS_ERROR:
|
||||
console.error(payload); // eslint-disable-line
|
||||
return { ...state, currentUserHasListingsError: payload };
|
||||
|
||||
default:
|
||||
return state;
|
||||
|
|
@ -67,8 +87,55 @@ export const stripeAccountCreateError = e => ({
|
|||
error: true,
|
||||
});
|
||||
|
||||
const fetchCurrentUserHasListingsRequest = () => ({
|
||||
type: FETCH_CURRENT_USER_HAS_LISTINGS_REQUEST,
|
||||
});
|
||||
|
||||
const fetchCurrentUserHasListingsSuccess = hasListings => ({
|
||||
type: FETCH_CURRENT_USER_HAS_LISTINGS_SUCCESS,
|
||||
payload: { hasListings },
|
||||
});
|
||||
|
||||
const fetchCurrentUserHasListingsError = e => ({
|
||||
type: FETCH_CURRENT_USER_HAS_LISTINGS_ERROR,
|
||||
error: true,
|
||||
payload: e,
|
||||
});
|
||||
|
||||
// ================ Thunks ================ //
|
||||
|
||||
export const fetchCurrentUserHasListings = () =>
|
||||
(dispatch, getState, sdk) => {
|
||||
dispatch(fetchCurrentUserHasListingsRequest());
|
||||
const { currentUser } = getState().user;
|
||||
|
||||
if (!currentUser) {
|
||||
dispatch(fetchCurrentUserHasListingsSuccess(false));
|
||||
return Promise.resolve(null);
|
||||
}
|
||||
|
||||
const currentUserId = currentUser.id;
|
||||
const params = {
|
||||
author_id: currentUserId,
|
||||
|
||||
// Since we are only interested in if the user has
|
||||
// listings, we only need at most one result.
|
||||
page: 1,
|
||||
per_page: 1,
|
||||
};
|
||||
|
||||
return sdk.listings
|
||||
.query(params)
|
||||
.then(response => {
|
||||
const hasListings = response.data.data && response.data.data.length > 0;
|
||||
dispatch(fetchCurrentUserHasListingsSuccess(!!hasListings));
|
||||
})
|
||||
.catch(e => {
|
||||
// TODO: dispatch flash message
|
||||
dispatch(fetchCurrentUserHasListingsError(e));
|
||||
});
|
||||
};
|
||||
|
||||
export const fetchCurrentUser = () =>
|
||||
(dispatch, getState, sdk) => {
|
||||
dispatch(usersMeRequest());
|
||||
|
|
@ -84,6 +151,9 @@ export const fetchCurrentUser = () =>
|
|||
.then(response => {
|
||||
dispatch(usersMeSuccess(response.data.data));
|
||||
})
|
||||
.then(() => {
|
||||
dispatch(fetchCurrentUserHasListings());
|
||||
})
|
||||
.catch(e => {
|
||||
// TODO: dispatch flash message
|
||||
dispatch(usersMeError(e));
|
||||
|
|
|
|||
|
|
@ -158,14 +158,22 @@ const routesConfiguration = [
|
|||
auth: true,
|
||||
exact: true,
|
||||
name: 'InboxBasePage',
|
||||
component: () => <NamedRedirect name="InboxPage" params={{ tab: 'orders' }} />,
|
||||
component: () => <NamedRedirect name="InboxSalesPage" />,
|
||||
},
|
||||
{
|
||||
path: '/inbox/:tab',
|
||||
path: '/inbox/sales',
|
||||
auth: true,
|
||||
exact: true,
|
||||
name: 'InboxPage',
|
||||
component: props => <InboxPage {...props} />,
|
||||
name: 'InboxSalesPage',
|
||||
component: props => <InboxPage {...props} tab="sales" />,
|
||||
loadData: (params, search) => InboxPage.loadData(params, search),
|
||||
},
|
||||
{
|
||||
path: '/inbox/orders',
|
||||
auth: true,
|
||||
exact: true,
|
||||
name: 'InboxOrdersPage',
|
||||
component: props => <InboxPage {...props} tab="orders" />,
|
||||
loadData: (params, search) => InboxPage.loadData(params, search),
|
||||
},
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue