mirror of
https://github.com/kingomarnajjar/flex-template-web.git
synced 2026-07-31 02:26:50 +10:00
SearchPage
This commit is contained in:
parent
06a9da19d0
commit
798f71edfe
5 changed files with 348 additions and 140 deletions
|
|
@ -1,10 +1,44 @@
|
|||
@import '../../marketplace.css';
|
||||
|
||||
:root {
|
||||
--containerHeight: calc(100vh - var(--topbarHeightDesktop));
|
||||
}
|
||||
|
||||
.topbar {
|
||||
@media (--desktopViewport) {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
/* We need to raise Topbar above .container */
|
||||
z-index: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.container {
|
||||
/* Layout */
|
||||
width: 100%;
|
||||
flex-grow: 1;
|
||||
display: flex;
|
||||
|
||||
@media (--desktopViewport) {
|
||||
position: relative;
|
||||
padding-top: var(--topbarHeightDesktop);
|
||||
min-height: var(--containerHeight);
|
||||
}
|
||||
}
|
||||
|
||||
.searchResultContainer {
|
||||
flex-grow: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
@media (--desktopViewport) {
|
||||
/**
|
||||
* .container is using flexbox,
|
||||
* This specifies that searchResultContainer is taking 60% from the viewport width
|
||||
*/
|
||||
flex-basis: 60%;
|
||||
}
|
||||
}
|
||||
|
||||
.searchResultSummary {
|
||||
|
|
@ -17,6 +51,7 @@
|
|||
}
|
||||
|
||||
.searchString {
|
||||
/* Search string should not break on white spaces - i.e. line-break should happen before. */
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
|
|
@ -29,3 +64,33 @@
|
|||
.searchListingsPanel {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.mapPanel {
|
||||
display: none;
|
||||
|
||||
@media (--desktopViewport) {
|
||||
/**
|
||||
* .container is using flexbox,
|
||||
* This specifies that mapPanel is taking 40% from the viewport width
|
||||
*/
|
||||
flex-basis: 40%;
|
||||
|
||||
/* Own layout settings */
|
||||
display: flex;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.map {
|
||||
@media (--desktopViewport) {
|
||||
/* Map is fixed so that it doesn't scroll along search results */
|
||||
position: fixed;
|
||||
top: var(--topbarHeightDesktop);
|
||||
right: 0;
|
||||
|
||||
/* Fixed content needs width relative to viewport */
|
||||
width: 40vw;
|
||||
height: var(--containerHeight);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,10 @@ export const SEARCH_LISTINGS_REQUEST = 'app/SearchPage/SEARCH_LISTINGS_REQUEST';
|
|||
export const SEARCH_LISTINGS_SUCCESS = 'app/SearchPage/SEARCH_LISTINGS_SUCCESS';
|
||||
export const SEARCH_LISTINGS_ERROR = 'app/SearchPage/SEARCH_LISTINGS_ERROR';
|
||||
|
||||
export const SEARCH_MAP_LISTINGS_REQUEST = 'app/SearchPage/SEARCH_MAP_LISTINGS_REQUEST';
|
||||
export const SEARCH_MAP_LISTINGS_SUCCESS = 'app/SearchPage/SEARCH_MAP_LISTINGS_SUCCESS';
|
||||
export const SEARCH_MAP_LISTINGS_ERROR = 'app/SearchPage/SEARCH_MAP_LISTINGS_ERROR';
|
||||
|
||||
// ================ Reducer ================ //
|
||||
|
||||
const initialState = {
|
||||
|
|
@ -14,6 +18,8 @@ const initialState = {
|
|||
searchInProgress: false,
|
||||
searchListingsError: null,
|
||||
currentPageResultIds: [],
|
||||
searchMapListingIds: [],
|
||||
searchMapListingsError: null,
|
||||
};
|
||||
|
||||
const resultIds = data => data.data.map(l => l.id);
|
||||
|
|
@ -40,6 +46,23 @@ const listingPageReducer = (state = initialState, action = {}) => {
|
|||
// eslint-disable-next-line no-console
|
||||
console.error(payload);
|
||||
return { ...state, searchInProgress: false, searchListingsError: payload };
|
||||
|
||||
case SEARCH_MAP_LISTINGS_REQUEST:
|
||||
return {
|
||||
...state,
|
||||
//searchMapListingIds: [],
|
||||
searchMapListingsError: null,
|
||||
};
|
||||
case SEARCH_MAP_LISTINGS_SUCCESS:
|
||||
return {
|
||||
...state,
|
||||
searchMapListingIds: state.searchMapListingIds.concat(resultIds(payload.data)),
|
||||
};
|
||||
case SEARCH_MAP_LISTINGS_ERROR:
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(payload);
|
||||
return { ...state, searchMapListingsError: payload };
|
||||
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
|
|
@ -65,6 +88,19 @@ export const searchListingsError = e => ({
|
|||
payload: e,
|
||||
});
|
||||
|
||||
export const searchMapListingsRequest = () => ({ type: SEARCH_MAP_LISTINGS_REQUEST });
|
||||
|
||||
export const searchMapListingsSuccess = response => ({
|
||||
type: SEARCH_MAP_LISTINGS_SUCCESS,
|
||||
payload: { data: response.data },
|
||||
});
|
||||
|
||||
export const searchMapListingsError = e => ({
|
||||
type: SEARCH_MAP_LISTINGS_ERROR,
|
||||
error: true,
|
||||
payload: e,
|
||||
});
|
||||
|
||||
export const searchListings = searchParams =>
|
||||
(dispatch, getState, sdk) => {
|
||||
dispatch(searchListingsRequest(searchParams));
|
||||
|
|
@ -87,3 +123,26 @@ export const searchListings = searchParams =>
|
|||
throw e;
|
||||
});
|
||||
};
|
||||
|
||||
export const searchMapListings = searchParams =>
|
||||
(dispatch, getState, sdk) => {
|
||||
dispatch(searchMapListingsRequest(searchParams));
|
||||
|
||||
const { origin, include = [], page = 1, perPage } = searchParams;
|
||||
|
||||
// TODO: API can't handle camelCase request parameter yet.
|
||||
const searchOrQuery = origin
|
||||
? sdk.listings.search({ ...searchParams, page, per_page: perPage })
|
||||
: sdk.listings.query({ include, page, per_page: perPage });
|
||||
|
||||
return searchOrQuery
|
||||
.then(response => {
|
||||
dispatch(addMarketplaceEntities(response));
|
||||
dispatch(searchMapListingsSuccess(response));
|
||||
return response;
|
||||
})
|
||||
.catch(e => {
|
||||
dispatch(searchMapListingsError(e));
|
||||
throw e;
|
||||
});
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,145 +1,193 @@
|
|||
import React, { PropTypes } from 'react';
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import { connect } from 'react-redux';
|
||||
import { compose } from 'redux';
|
||||
import { withRouter } from 'react-router-dom';
|
||||
import { unionWith } from 'lodash';
|
||||
import config from '../../config';
|
||||
import { parse, stringify } from '../../util/urlHelpers';
|
||||
import * as propTypes from '../../util/propTypes';
|
||||
import { getListingsById } from '../../ducks/marketplaceData.duck';
|
||||
import { logout, authenticationInProgress } from '../../ducks/Auth.duck';
|
||||
import { manageDisableScrolling, isScrollingDisabled } from '../../ducks/UI.duck';
|
||||
import { PageLayout, SearchResultsPanel, Topbar } from '../../components';
|
||||
import { searchListings } from './SearchPage.duck';
|
||||
import { SearchMap, ModalInMobile, PageLayout, SearchResultsPanel, Topbar } from '../../components';
|
||||
import { searchListings, searchMapListings } from './SearchPage.duck';
|
||||
import css from './SearchPage.css';
|
||||
|
||||
// TODO Pagination page size might need to be dynamic on responsive page layouts
|
||||
const RESULT_PAGE_SIZE = 12;
|
||||
const SHARETRIBE_API_MAX_PAGE_SIZE = 100;
|
||||
const MAX_SEARCH_RESULT_PAGES_ON_MAP = 5;
|
||||
// 100 * 5 = 500 listings are shown on a map.
|
||||
|
||||
const pickSearchParamsOnly = params => {
|
||||
const { address, origin, bounds } = params || {};
|
||||
return { address, origin, bounds };
|
||||
};
|
||||
|
||||
export const SearchPageComponent = props => {
|
||||
const {
|
||||
authInfoError,
|
||||
authInProgress,
|
||||
currentUser,
|
||||
currentUserHasListings,
|
||||
history,
|
||||
isAuthenticated,
|
||||
listings,
|
||||
location,
|
||||
logoutError,
|
||||
notificationCount,
|
||||
onLogout,
|
||||
onManageDisableScrolling,
|
||||
pagination,
|
||||
scrollingDisabled,
|
||||
searchInProgress,
|
||||
searchListingsError,
|
||||
searchParams,
|
||||
tab,
|
||||
} = props;
|
||||
export class SearchPageComponent extends Component {
|
||||
componentDidMount() {
|
||||
const { location, onSearchMapListings } = this.props;
|
||||
const searchInURL = parse(location.search, {
|
||||
latlng: ['origin'],
|
||||
latlngBounds: ['bounds'],
|
||||
});
|
||||
const perPage = SHARETRIBE_API_MAX_PAGE_SIZE;
|
||||
const page = 1;
|
||||
const searchParamsForMapResults = { ...searchInURL, page, perPage };
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const { page, ...searchInURL } = parse(location.search, {
|
||||
latlng: ['origin'],
|
||||
latlngBounds: ['bounds'],
|
||||
});
|
||||
// Search more listings
|
||||
onSearchMapListings(searchParamsForMapResults)
|
||||
.then(response => {
|
||||
const hasNextPage = page < response.data.meta.totalPages &&
|
||||
page < MAX_SEARCH_RESULT_PAGES_ON_MAP;
|
||||
if (hasNextPage) {
|
||||
onSearchMapListings({ ...searchParamsForMapResults, page: page + 1 });
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
// In case of error, stop recursive loop and report error.
|
||||
console.error(`An error (${error} occured while trying to retrieve map listings`);
|
||||
});
|
||||
}
|
||||
|
||||
// Page transition might initially use values from previous search
|
||||
const searchParamsInURL = stringify(pickSearchParamsOnly(searchInURL));
|
||||
const searchParamsInProps = stringify(pickSearchParamsOnly(searchParams));
|
||||
const searchParamsMatch = searchParamsInURL === searchParamsInProps;
|
||||
render() {
|
||||
const {
|
||||
authInfoError,
|
||||
authInProgress,
|
||||
currentUser,
|
||||
currentUserHasListings,
|
||||
history,
|
||||
isAuthenticated,
|
||||
listings,
|
||||
location,
|
||||
logoutError,
|
||||
mapListings,
|
||||
notificationCount,
|
||||
onLogout,
|
||||
onManageDisableScrolling,
|
||||
pagination,
|
||||
scrollingDisabled,
|
||||
searchInProgress,
|
||||
searchListingsError,
|
||||
searchParams,
|
||||
tab,
|
||||
} = this.props;
|
||||
|
||||
const hasPaginationInfo = !!pagination && pagination.totalItems != null;
|
||||
const totalItems = searchParamsMatch && hasPaginationInfo ? pagination.totalItems : 0;
|
||||
const listingsAreLoaded = !searchInProgress && searchParamsMatch && hasPaginationInfo;
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const { page, ...searchInURL } = parse(location.search, {
|
||||
latlng: ['origin'],
|
||||
latlngBounds: ['bounds'],
|
||||
});
|
||||
|
||||
const searchError = (
|
||||
<h2 className={css.error}>
|
||||
<FormattedMessage id="SearchPage.searchError" />
|
||||
</h2>
|
||||
);
|
||||
// Page transition might initially use values from previous search
|
||||
const searchParamsInURL = stringify(pickSearchParamsOnly(searchInURL));
|
||||
const searchParamsInProps = stringify(pickSearchParamsOnly(searchParams));
|
||||
const searchParamsMatch = searchParamsInURL === searchParamsInProps;
|
||||
|
||||
const resultsFoundNoAddress = (
|
||||
<h2>
|
||||
<FormattedMessage id="SearchPage.foundResults" values={{ count: totalItems }} />
|
||||
</h2>
|
||||
);
|
||||
const address = searchInURL && searchInURL.address
|
||||
? <span className={css.searchString}>{searchInURL.address.split(', ')[0]}</span>
|
||||
: null;
|
||||
const resultsFoundWithAddress = (
|
||||
<h2>
|
||||
<FormattedMessage
|
||||
id="SearchPage.foundResultsWithAddress"
|
||||
values={{ count: totalItems, address }}
|
||||
/>
|
||||
</h2>
|
||||
);
|
||||
const resultsFound = address ? resultsFoundWithAddress : resultsFoundNoAddress;
|
||||
const { address, bounds, origin } = searchInURL || {};
|
||||
|
||||
const noResults = (
|
||||
<h2>
|
||||
<FormattedMessage id="SearchPage.noResults" />
|
||||
</h2>
|
||||
);
|
||||
const hasPaginationInfo = !!pagination && pagination.totalItems != null;
|
||||
const totalItems = searchParamsMatch && hasPaginationInfo ? pagination.totalItems : 0;
|
||||
const listingsAreLoaded = !searchInProgress && searchParamsMatch && hasPaginationInfo;
|
||||
|
||||
const loadingResults = (
|
||||
<h2>
|
||||
<FormattedMessage id="SearchPage.loadingResults" />
|
||||
</h2>
|
||||
);
|
||||
const searchError = (
|
||||
<h2 className={css.error}>
|
||||
<FormattedMessage id="SearchPage.searchError" />
|
||||
</h2>
|
||||
);
|
||||
|
||||
const searchParamsForPagination = parse(location.search);
|
||||
const resultsFoundNoAddress = (
|
||||
<h2>
|
||||
<FormattedMessage id="SearchPage.foundResults" values={{ count: totalItems }} />
|
||||
</h2>
|
||||
);
|
||||
const addressNode = address
|
||||
? <span className={css.searchString}>{searchInURL.address.split(', ')[0]}</span>
|
||||
: null;
|
||||
const resultsFoundWithAddress = (
|
||||
<h2>
|
||||
<FormattedMessage
|
||||
id="SearchPage.foundResultsWithAddress"
|
||||
values={{ count: totalItems, address: addressNode }}
|
||||
/>
|
||||
</h2>
|
||||
);
|
||||
const resultsFound = address ? resultsFoundWithAddress : resultsFoundNoAddress;
|
||||
|
||||
return (
|
||||
<PageLayout
|
||||
authInfoError={authInfoError}
|
||||
logoutError={logoutError}
|
||||
title={`Search page: ${tab}`}
|
||||
scrollingDisabled={scrollingDisabled}
|
||||
>
|
||||
<Topbar
|
||||
isAuthenticated={isAuthenticated}
|
||||
authInProgress={authInProgress}
|
||||
currentUser={currentUser}
|
||||
currentUserHasListings={currentUserHasListings}
|
||||
notificationCount={notificationCount}
|
||||
history={history}
|
||||
location={location}
|
||||
onLogout={onLogout}
|
||||
onManageDisableScrolling={onManageDisableScrolling}
|
||||
/>
|
||||
<div className={css.searchResultSummary}>
|
||||
{searchListingsError ? searchError : null}
|
||||
{listingsAreLoaded && totalItems > 0 ? resultsFound : null}
|
||||
{listingsAreLoaded && totalItems === 0 ? noResults : null}
|
||||
{searchInProgress ? loadingResults : null}
|
||||
</div>
|
||||
<div className={css.container}>
|
||||
<div className={css.listings}>
|
||||
<SearchResultsPanel
|
||||
className={css.searchListingsPanel}
|
||||
currencyConfig={config.currencyConfig}
|
||||
listings={listingsAreLoaded ? listings : []}
|
||||
pagination={listingsAreLoaded ? pagination : null}
|
||||
search={searchParamsForPagination}
|
||||
/>
|
||||
const noResults = (
|
||||
<h2>
|
||||
<FormattedMessage id="SearchPage.noResults" />
|
||||
</h2>
|
||||
);
|
||||
|
||||
const loadingResults = (
|
||||
<h2>
|
||||
<FormattedMessage id="SearchPage.loadingResults" />
|
||||
</h2>
|
||||
);
|
||||
|
||||
const searchParamsForPagination = parse(location.search);
|
||||
|
||||
return (
|
||||
<PageLayout
|
||||
authInfoError={authInfoError}
|
||||
logoutError={logoutError}
|
||||
title={`Search page: ${tab}`}
|
||||
scrollingDisabled={scrollingDisabled}
|
||||
>
|
||||
<Topbar
|
||||
className={css.topbar}
|
||||
isAuthenticated={isAuthenticated}
|
||||
authInProgress={authInProgress}
|
||||
currentUser={currentUser}
|
||||
currentUserHasListings={currentUserHasListings}
|
||||
notificationCount={notificationCount}
|
||||
history={history}
|
||||
location={location}
|
||||
onLogout={onLogout}
|
||||
onManageDisableScrolling={onManageDisableScrolling}
|
||||
/>
|
||||
<div className={css.container}>
|
||||
<div className={css.searchResultContainer}>
|
||||
<div className={css.searchResultSummary}>
|
||||
{searchListingsError ? searchError : null}
|
||||
{listingsAreLoaded && totalItems > 0 ? resultsFound : null}
|
||||
{listingsAreLoaded && totalItems === 0 ? noResults : null}
|
||||
{searchInProgress ? loadingResults : null}
|
||||
</div>
|
||||
<div className={css.listings}>
|
||||
<SearchResultsPanel
|
||||
className={css.searchListingsPanel}
|
||||
currencyConfig={config.currencyConfig}
|
||||
listings={listingsAreLoaded ? listings : []}
|
||||
pagination={listingsAreLoaded ? pagination : null}
|
||||
search={searchParamsForPagination}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<ModalInMobile
|
||||
className={css.mapPanel}
|
||||
id="SearchPage.map"
|
||||
isModalOpenOnMobile={false}
|
||||
onManageDisableScrolling={onManageDisableScrolling}
|
||||
>
|
||||
<div className={css.map}>
|
||||
<SearchMap bounds={bounds} center={origin} listings={mapListings || []} />
|
||||
</div>
|
||||
</ModalInMobile>
|
||||
</div>
|
||||
</div>
|
||||
</PageLayout>
|
||||
);
|
||||
};
|
||||
</PageLayout>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
SearchPageComponent.defaultProps = {
|
||||
authInfoError: null,
|
||||
currentUser: null,
|
||||
listings: [],
|
||||
logoutError: null,
|
||||
mapListings: [],
|
||||
notificationCount: 0,
|
||||
pagination: null,
|
||||
searchListingsError: null,
|
||||
|
|
@ -156,10 +204,12 @@ SearchPageComponent.propTypes = {
|
|||
currentUserHasListings: bool.isRequired,
|
||||
isAuthenticated: bool.isRequired,
|
||||
listings: array,
|
||||
mapListings: array,
|
||||
logoutError: instanceOf(Error),
|
||||
notificationCount: number,
|
||||
onLogout: func.isRequired,
|
||||
onManageDisableScrolling: func.isRequired,
|
||||
onSearchMapListings: func.isRequired,
|
||||
pagination: propTypes.pagination,
|
||||
scrollingDisabled: bool.isRequired,
|
||||
searchInProgress: bool.isRequired,
|
||||
|
|
@ -183,6 +233,7 @@ const mapStateToProps = state => {
|
|||
searchInProgress,
|
||||
searchListingsError,
|
||||
searchParams,
|
||||
searchMapListingIds,
|
||||
} = state.SearchPage;
|
||||
const { authInfoError, isAuthenticated, logoutError } = state.Auth;
|
||||
const {
|
||||
|
|
@ -190,10 +241,17 @@ const mapStateToProps = state => {
|
|||
currentUserHasListings,
|
||||
currentUserNotificationCount: notificationCount,
|
||||
} = state.user;
|
||||
const pageListings = getListingsById(state, currentPageResultIds);
|
||||
const mapListings = getListingsById(
|
||||
state,
|
||||
unionWith(currentPageResultIds, searchMapListingIds, (id1, id2) => id1.uuid === id2.uuid)
|
||||
);
|
||||
|
||||
return {
|
||||
authInfoError,
|
||||
logoutError,
|
||||
listings: getListingsById(state, currentPageResultIds),
|
||||
listings: pageListings,
|
||||
mapListings,
|
||||
pagination,
|
||||
searchInProgress,
|
||||
searchListingsError,
|
||||
|
|
@ -211,6 +269,7 @@ const mapDispatchToProps = dispatch => ({
|
|||
onLogout: historyPush => dispatch(logout(historyPush)),
|
||||
onManageDisableScrolling: (componentId, disableScrolling) =>
|
||||
dispatch(manageDisableScrolling(componentId, disableScrolling)),
|
||||
onSearchMapListings: searchParams => dispatch(searchMapListings(searchParams)),
|
||||
});
|
||||
|
||||
const SearchPage = compose(connect(mapStateToProps, mapDispatchToProps), withRouter)(
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ describe('SearchPageComponent', () => {
|
|||
isAuthenticated: false,
|
||||
onLogout: noop,
|
||||
onManageDisableScrolling: noop,
|
||||
onSearchMapListings: noop,
|
||||
};
|
||||
const tree = renderShallow(<SearchPageComponent {...props} />);
|
||||
expect(tree).toMatchSnapshot();
|
||||
|
|
|
|||
|
|
@ -22,44 +22,68 @@ exports[`SearchPageComponent matches snapshot 1`] = `
|
|||
notificationCount={0}
|
||||
onLogout={[Function]}
|
||||
onManageDisableScrolling={[Function]} />
|
||||
<div>
|
||||
<h2>
|
||||
<FormattedMessage
|
||||
id="SearchPage.foundResults"
|
||||
values={
|
||||
Object {
|
||||
"count": 22,
|
||||
}
|
||||
} />
|
||||
</h2>
|
||||
</div>
|
||||
<div>
|
||||
<div>
|
||||
<SearchResultsPanel
|
||||
className={null}
|
||||
currencyConfig={
|
||||
Object {
|
||||
"currency": "USD",
|
||||
"currencyDisplay": "symbol",
|
||||
"maximumFractionDigits": 2,
|
||||
"minimumFractionDigits": 2,
|
||||
"style": "currency",
|
||||
"subUnitDivisor": 100,
|
||||
"useGrouping": true,
|
||||
<div>
|
||||
<h2>
|
||||
<FormattedMessage
|
||||
id="SearchPage.foundResults"
|
||||
values={
|
||||
Object {
|
||||
"count": 22,
|
||||
}
|
||||
} />
|
||||
</h2>
|
||||
</div>
|
||||
<div>
|
||||
<SearchResultsPanel
|
||||
className={null}
|
||||
currencyConfig={
|
||||
Object {
|
||||
"currency": "USD",
|
||||
"currencyDisplay": "symbol",
|
||||
"maximumFractionDigits": 2,
|
||||
"minimumFractionDigits": 2,
|
||||
"style": "currency",
|
||||
"subUnitDivisor": 100,
|
||||
"useGrouping": true,
|
||||
}
|
||||
}
|
||||
}
|
||||
listings={Array []}
|
||||
pagination={
|
||||
Object {
|
||||
"page": 1,
|
||||
"perPage": 12,
|
||||
"totalItems": 22,
|
||||
"totalPages": 2,
|
||||
listings={Array []}
|
||||
pagination={
|
||||
Object {
|
||||
"page": 1,
|
||||
"perPage": 12,
|
||||
"totalItems": 22,
|
||||
"totalPages": 2,
|
||||
}
|
||||
}
|
||||
}
|
||||
rootClassName={null}
|
||||
search={Object {}} />
|
||||
rootClassName={null}
|
||||
search={Object {}} />
|
||||
</div>
|
||||
</div>
|
||||
<ModalInMobile
|
||||
className=""
|
||||
id="SearchPage.map"
|
||||
isModalOpenOnMobile={false}
|
||||
onClose={null}
|
||||
onManageDisableScrolling={[Function]}
|
||||
showAsModalMaxWidth={0}>
|
||||
<div>
|
||||
<SearchMap
|
||||
bounds={null}
|
||||
center={
|
||||
LatLng {
|
||||
"lat": 0,
|
||||
"lng": 0,
|
||||
}
|
||||
}
|
||||
className=""
|
||||
listings={Array []}
|
||||
rootClassName={null}
|
||||
zoom={11} />
|
||||
</div>
|
||||
</ModalInMobile>
|
||||
</div>
|
||||
</withRouter(PageLayout)>
|
||||
`;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue