diff --git a/.env-template b/.env-template index a541b75f..8733b0e1 100644 --- a/.env-template +++ b/.env-template @@ -2,8 +2,11 @@ # Mandatory configuration # REACT_APP_SHARETRIBE_SDK_CLIENT_ID= -REACT_APP_GOOGLE_MAPS_API_KEY= REACT_APP_STRIPE_PUBLISHABLE_KEY= +REACT_APP_MAPBOX_ACCESS_TOKEN= + +# Or set up an alternative map provider (Google Maps). Check documentation. +# REACT_APP_GOOGLE_MAPS_API_KEY= # Defaults # diff --git a/CHANGELOG.md b/CHANGELOG.md index d307d189..6546e9a1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,20 +11,40 @@ way to update this template, but currently, we follow a pattern: * Patch (v0.0.**X**): Bug fixes and small changes to components. --- + +## v2.0.0 2018-09-19 + +* [add] New default map provider (Mapbox) and complete refactoring to all map and geocoding + components. [#888](https://github.com/sharetribe/flex-template-web/pull/888) + + **Note:** Before updating to version 2.0.0, you should very carefully track customizations that + you have made to following components: + + * **LocationAutocompleteInput** + * **Map** + * **SearchPage** (especially previous `onIdle` function) + * **SearchMap** + * **SearchMapPriceLabel** + * **SearchMapGroupLabel** + * **SearchMapInfoCard** + + To get a better understanding of what has changed, you should read documents about how to + [integrate to map providers](./docs/map-providers.md) and especially + [changing map provider to Google Maps](./docs/google-maps.md) + ## v1.4.3 2018-09-15 + * [fix] fuzzy location didn't change when listing location changed. [#931](https://github.com/sharetribe/flex-template-web/pull/931) -* [fix] obfuscatedCoordinatesImpl didn't always return coordinates within given - offset radius. +* [fix] obfuscatedCoordinatesImpl didn't always return coordinates within given offset radius. [#930](https://github.com/sharetribe/flex-template-web/pull/930) -* [fix] LocationAutocompleteInput: blur input when selecting by enter - to prevent flash of default predictions. - [#928](https://github.com/sharetribe/flex-template-web/pull/928) -* [fix] LocationAutocompleteInput: selecting with enter key prevented - while fetching predictions. +* [fix] LocationAutocompleteInput: blur input when selecting by enter to prevent flash of default + predictions. [#928](https://github.com/sharetribe/flex-template-web/pull/928) +* [fix] LocationAutocompleteInput: selecting with enter key prevented while fetching predictions. [#923](https://github.com/sharetribe/flex-template-web/pull/923) ## v1.4.2 2018-09-06 + * [add] Reduce character queries on LocationAutocompleteInput to reduce geocoding costs. [#883](https://github.com/sharetribe/flex-template-web/pull/883) * [change] Update git links and improve documentation @@ -37,26 +57,24 @@ way to update this template, but currently, we follow a pattern: [#906](https://github.com/sharetribe/flex-template-web/pull/906) ## v1.4.1 2018-08-21 + * [fix] Fix window resize redirecting to search page with reusable map component [#905](https://github.com/sharetribe/flex-template-web/pull/905) -* [change] Maps configuration has been restructured. The new - configuration is agnostic of the maps provider in use and works with - both Google Maps as well as Mapbox. +* [change] Maps configuration has been restructured. The new configuration is agnostic of the maps + provider in use and works with both Google Maps as well as Mapbox. - The fuzzy location circle has less configuration, but otherwise all - the previous settings can be set also in the new configuration. See - `config.js` for details. + The fuzzy location circle has less configuration, but otherwise all the previous settings can be + set also in the new configuration. See `config.js` for details. - The default location searches are now enabled in the - `.env-template`. For old installations, the - `REACT_APP_DEFAULT_SEARCHES_ENABLED` env var should be set to - `true`. The default searches can then be configured in - `src/default-location-searches.js`. + The default location searches are now enabled in the `.env-template`. For old installations, the + `REACT_APP_DEFAULT_SEARCHES_ENABLED` env var should be set to `true`. The default searches can + then be configured in `src/default-location-searches.js`. [#900](https://github.com/sharetribe/flex-template-web/pull/900) ## v1.4.0 2018-08-17 + * [change] Put availability calendar behind a feature flag [#902](https://github.com/sharetribe/flex-template-web/pull/902) * [fix] Drop date time from time slots request query params @@ -65,37 +83,36 @@ way to update this template, but currently, we follow a pattern: [#901](https://github.com/sharetribe/flex-template-web/pull/901) * [add] Map component (used in ListingPage) using Mapbox instead of Google Maps [#896](https://github.com/sharetribe/flex-template-web/pull/896) -* [add] Listing availability - [#868](https://github.com/sharetribe/flex-template-web/pull/868), [#873](https://github.com/sharetribe/flex-template-web/pull/873), [#891](https://github.com/sharetribe/flex-template-web/pull/891) & [#892](https://github.com/sharetribe/flex-template-web/pull/892) -* [add] Add support for user's current location as a default - suggestion in the location autocomplete search. - [#895](https://github.com/sharetribe/flex-template-web/pull/895) -* [add] Add support for default locations in the - LocationAutocompleteInput component. Common searches can be - configured to show when the input has focus. This reduces typing and - Google Places geolocation API usage. The defaults can be configured - in `src/components/LocationAutocompleteInput/GeocoderGoogleMaps.js`. +* [add] Listing availability [#868](https://github.com/sharetribe/flex-template-web/pull/868), + [#873](https://github.com/sharetribe/flex-template-web/pull/873), + [#891](https://github.com/sharetribe/flex-template-web/pull/891) & + [#892](https://github.com/sharetribe/flex-template-web/pull/892) +* [add] Add support for user's current location as a default suggestion in the location autocomplete + search. [#895](https://github.com/sharetribe/flex-template-web/pull/895) +* [add] Add support for default locations in the LocationAutocompleteInput component. Common + searches can be configured to show when the input has focus. This reduces typing and Google Places + geolocation API usage. The defaults can be configured in + `src/components/LocationAutocompleteInput/GeocoderGoogleMaps.js`. [#894](https://github.com/sharetribe/flex-template-web/pull/894) -* [change] Removed the `country` parameter from the search page as it - was not used anywhere. +* [change] Removed the `country` parameter from the search page as it was not used anywhere. [#893](https://github.com/sharetribe/flex-template-web/pull/893) ## v1.3.2 2018-08-07 -* [change] Update the Sharetribe Flex SDK to the 1.0.0 version in NPM. - All the `sharetribe-sdk` imports are now using the new package name - `sharetribe-flex-sdk`. + +* [change] Update the Sharetribe Flex SDK to the 1.0.0 version in NPM. All the `sharetribe-sdk` + imports are now using the new package name `sharetribe-flex-sdk`. [#884](https://github.com/sharetribe/flex-template-web/pull/884) * [change] Reusable SearchMap. Fixed the original reverted version. (Includes audit exception 678) [#882](https://github.com/sharetribe/flex-template-web/pull/882) ## v1.3.1 -* [fix] Hotfix: reverting the usage of ReusableMapContainer due to - production build error. + +* [fix] Hotfix: reverting the usage of ReusableMapContainer due to production build error. [#881](https://github.com/sharetribe/flex-template-web/pull/881) ## v1.3.0 -* [change] Reusable SearchMap. - [#877](https://github.com/sharetribe/flex-template-web/pull/877) + +* [change] Reusable SearchMap. [#877](https://github.com/sharetribe/flex-template-web/pull/877) * [fix] Fix a search filters panel bug where selecting an option in a multi select filter ends up invoking a mobile filter callback function. [#876](https://github.com/sharetribe/flex-template-web/pull/876) @@ -103,22 +120,26 @@ way to update this template, but currently, we follow a pattern: [#874](https://github.com/sharetribe/flex-template-web/pull/874) ## v1.2.2 + * [change] Change static map to dynamic map when clicked. [#871](https://github.com/sharetribe/flex-template-web/pull/871) ## v1.2.1 + * [fix] Lazy load map only if the map is near current viewport. [#871](https://github.com/sharetribe/flex-template-web/pull/871) ## v1.2.0 -* [change] Use Google's static map on ListingPage. - This is a reaction to pricing change of Google Maps APIs. - [#869](https://github.com/sharetribe/flex-template-web/pull/869) -* [change] Use sessionTokens and fields for Autocomplete calls to Google Maps. - This is a reaction to pricing change of Google Maps APIs. + +* [change] Use Google's static map on ListingPage. This is a reaction to pricing change of Google + Maps APIs. [#869](https://github.com/sharetribe/flex-template-web/pull/869) +* [change] Use sessionTokens and fields for Autocomplete calls to Google Maps. This is a reaction to + pricing change of Google Maps APIs. [#867](https://github.com/sharetribe/flex-template-web/pull/867) * [change] Change TransactionPage state management in loadData. - [#863](https://github.com/sharetribe/flex-template-web/pull/863), [#865](https://github.com/sharetribe/flex-template-web/pull/865) & [#866](https://github.com/sharetribe/flex-template-web/pull/866) + [#863](https://github.com/sharetribe/flex-template-web/pull/863), + [#865](https://github.com/sharetribe/flex-template-web/pull/865) & + [#866](https://github.com/sharetribe/flex-template-web/pull/866) * [fix] Fix submit button state on contact details page. [#864](https://github.com/sharetribe/flex-template-web/pull/864) * [fix] Fix listing page host section layout bug. @@ -126,24 +147,23 @@ way to update this template, but currently, we follow a pattern: * [fix] Fix initial message input clearing too early in checkout page. [#861](https://github.com/sharetribe/flex-template-web/pull/861) * [fix] Fix setting Topbar search input initial value. -* [change] Update Redux to v4 - [#859](https://github.com/sharetribe/flex-template-web/pull/859) +* [change] Update Redux to v4 [#859](https://github.com/sharetribe/flex-template-web/pull/859) * [fix] Fix setting Topbar search input initial value [#857](https://github.com/sharetribe/flex-template-web/pull/857) ## v1.1.0 + * [fix] Improve slug creation (slashes were breaking rendering in some environments) [#850](https://github.com/sharetribe/flex-template-web/pull/850) * [fix] Anonymous user should see contact link on UserCard [#851](https://github.com/sharetribe/flex-template-web/pull/851) * [fix] Persisting booking request details across authentication [#852](https://github.com/sharetribe/flex-template-web/pull/852) -* [change] Footer styles changed to more generic (no disappearing columns etc.) - If you have made changes to Footer, consider extracting it to different component before update. +* [change] Footer styles changed to more generic (no disappearing columns etc.) If you have made + changes to Footer, consider extracting it to different component before update. [#853](https://github.com/sharetribe/flex-template-web/pull/853) * [change] Logo customization refactored to be easier. Check CheckoutPage, TopbarDesktop and Footer - after update. - [#854](https://github.com/sharetribe/flex-template-web/pull/854) + after update. [#854](https://github.com/sharetribe/flex-template-web/pull/854) * [fix] Fix showing reviews from banned users. [#855](https://github.com/sharetribe/flex-template-web/pull/855) @@ -156,9 +176,8 @@ way to update this template, but currently, we follow a pattern: [#846](https://github.com/sharetribe/flex-template-web/pull/846) * [fix] Add missing styles for ModalMissingInformation from Topbar [#847](https://github.com/sharetribe/flex-template-web/pull/847) -* [fix] API does not return all image variants anymore, this adds correct variants to update - contact details call. - [#848](https://github.com/sharetribe/flex-template-web/pull/848) +* [fix] API does not return all image variants anymore, this adds correct variants to update contact + details call. [#848](https://github.com/sharetribe/flex-template-web/pull/848) ## v0.3.1 diff --git a/docs/README.md b/docs/README.md index 9f67f5d3..d67c8651 100644 --- a/docs/README.md +++ b/docs/README.md @@ -35,6 +35,7 @@ Documentation for specific topics can be found in the following files: * [Customization guide](customization-guide.md) * [Folder structure](folder-structure.md) +* [Integration to map providers](map-providers.md) * [Translations](translations.md) * [Styling a marketplace](styling.md) * [Static pages](static-pages.md) @@ -49,7 +50,6 @@ Documentation for specific topics can be found in the following files: * [Content Security Policy (CSP)](content-security-policy.md) * [Original create-react-app documentation](https://github.com/sharetribe/create-react-app/blob/master/packages/react-scripts/template/README.md) * [Customization checklist](customization-checklist.md) -* [Google Maps](google-maps.md) * [Icons](icons.md) The application was bootstrapped with a forked version of diff --git a/docs/customization-checklist.md b/docs/customization-checklist.md index 9b15fd90..1e95a4a8 100644 --- a/docs/customization-checklist.md +++ b/docs/customization-checklist.md @@ -11,7 +11,8 @@ Some generic things to update and check when starting to customize the template. * [Terms of Service](terms-of-service-and-privacy-policy.md#terms-of-service) * [Privacy Policy](terms-of-service-and-privacy-policy.md#privacy-policy) * [Social media sharing graphics](../src/components/Page/Page.js); -* [Logo](../src/components/Logo/Logo.js) Change and check that it works on Topbar, Footer, and CheckoutPage +* [Logo](../src/components/Logo/Logo.js) Change and check that it works on Topbar, Footer, and + CheckoutPage * [Default background image](../src/assets/background-1440.jpg) * [Maps Marker icon](../src/components/Map/images/marker-32x32.png) * [Config: update environment variables](../src/config.js) diff --git a/docs/env.md b/docs/env.md index ed7cdfec..74ed7f96 100644 --- a/docs/env.md +++ b/docs/env.md @@ -5,7 +5,8 @@ them have defaults that work for development environment. For production deploys | Variable | Description | | ----------------------------------------- | ----------------------------------------------------------------------------------------------------------------- | -| REACT_APP_GOOGLE_MAPS_API_KEY | See: [Google Maps API key](./google-maps.md) | +| REACT_APP_MAPBOX_ACCESS_TOKEN | See: [Integrating to map providers](./map-providers.md) | +| REACT_APP_GOOGLE_MAPS_API_KEY | See: [Google Maps API key](./google-maps.md) (Alternative map provider) | | REACT_APP_SHARETRIBE_SDK_CLIENT_ID | Client ID (API key). You will get this from the Sharetribe team. | | REACT_APP_STRIPE_PUBLISHABLE_KEY | Stripe publishable API key for generating tokens with Stripe API. Use test key (prefix pk*test*) for development. | | REACT_APP_SHARETRIBE_SDK_BASE_URL | The base url to access the Sharetribe Flex Marketplace API. | diff --git a/docs/folder-structure.md b/docs/folder-structure.md index 66dfe172..4e048af5 100644 --- a/docs/folder-structure.md +++ b/docs/folder-structure.md @@ -42,8 +42,8 @@ After cloning the repo, your project should look like this: ## public/index.html -This is the page template. It includes fonts, Stripe SDK, Google Maps JavaScript API, and app icons. -It also specifies placeholders for tags generated by +This is the page template. It includes fonts, Stripe SDK, Mapbox API (and Google Maps JavaScript +API), and app icons. It also specifies placeholders for tags generated by [React Helmet](https://github.com/nfl/react-helmet) ## src/ diff --git a/docs/google-maps.md b/docs/google-maps.md index 4455a47e..8d42ed91 100644 --- a/docs/google-maps.md +++ b/docs/google-maps.md @@ -1,8 +1,14 @@ # Google Maps -The Flex template for web uses the Google Maps API for showing a map and in searching locations in -the search autocompletion. This document describes how to setup the API key for the API requests to -work properly. +Flex Template for Web (FTW) offers out of the box support for Google Maps API for showing a map and +searching locations with search autocompletion. This document describes how to set up the API key +for the API requests to work properly. + +> Note: before making the change to Google Maps, you should consider if you are OK with their +> current pricing. There's a pricing calculator available in their +> [pricing page](https://cloud.google.com/maps-platform/pricing/). FTW's default map provider is +> Mapbox, which is often cheaper. +> [Learn more about how to use Mapbox or some other map provider instead of Google Maps](https://github.com/sharetribe/flex-template-web/blob/e6034c7690c095553f44092b032689cd6b6f7546/docs/map-providers.md). ## Generate a Google Maps API key @@ -28,15 +34,147 @@ REACT_APP_GOOGLE_MAPS_API_KEY=my-key-here ## Setup common locations to reduce typing -The location autocomplete input in the landing page and the topbar can -be configured to have specific locations shown by default when the -user focuses on the input and hasn't yet typed in any searches. This -reduces the typing required for common searches, and also reduces the -need to use the Google Places geolocation API that much. +The location autocomplete-input in the landing page and the topbar can be configured to have +specific locations shown by default when the user focuses on the input and hasn't yet typed in any +searches. This reduces the typing required for common searches and also reduces the need to use +Google Map Places API that much. -The default locations can be configured in -[src/components/LocationAutocompleteInput/GeocoderGoogleMaps.js](../src/components/LocationAutocompleteInput/GeocoderGoogleMaps.js). +To use default searches, another environment variable needs to be set: -You can also setup a default location that asks the user's current -location. This will enable e.g. searching listings near the user. The -current location is configured in the same file. +``` +REACT_APP_DEFAULT_SEARCHES_ENABLED=true +``` + +The default locations have been described in file: +[src/default-location-searches.js](../src/default-location-searches.js). + +The same environment variable also shows "current location" suggestion, which will make the browser +to ask user's current location. This is a fast way to search listings nearby. You can specify +whether to use the current location from [config.js](../src/config.js). Search for variables: +`suggestCurrentLocation` and `currentLocationBoundsDistance`. + +## Change components: use Google Map versions instead of Mapbox + +If you wish to use Google Maps instead of Mapbox, you need to make some changes to FTW default +setup. + +### 1. Include Google Map script instead of Mapbox scripts + +Mapbox related scripts can be removed from index.html and instead use Google Map script described in +comments. + +_public/index.html:_ + +```html + + + + + +``` + +### 2. Searching with Google's geocoding API + +Location search aka LocationAutocompleteInput should use Google Map specific geocoder. The correct +import is written to the comments of LocationAutocompleteInput component. + +_src/components/LocationAutocompleteInput/LocationAutocompleteInputImpl.js:_ + +```js +import Geocoder, { GeocoderAttribution, CURRENT_LOCATION_ID } from './GeocoderMapbox'; +// import Geocoder, { GeocoderAttribution, CURRENT_LOCATION_ID } from './GeocoderGoogleMaps'; +``` + +Furthermore, Google Map states in their terms of service that Google logo needs to be visible when +using their geocoding service. It is available as a background image below the autocomplete +predictions. However, there needs to be enough padding for that logo. You can change the padding +through `marketplace.css`. + +_src/marketplace.css:_ + +```js +/* Google Maps needs 72px bottom padding to accommodate logo, Mapbox doesn't have one */ +--locationAutocompleteBottomPadding: 8px; +``` + +### 3. Show correct map on ListingPage (Map component) + +Google Map version (containing both static and dynamic maps) can be taken into use by importing +correct map subcomponent. + +_src/components/Map/Map.js:_ + +```js +import { StaticMap, DynamicMap, isMapsLibLoaded } from './MapboxMap'; +// import { StaticMap, DynamicMap, isMapsLibLoaded } from './GoogleMap'; +``` + +### 4. SearchMap.js + +The most complex change is happening in SearchPage. First, you need to import `SearchMapWithMapbox` +instead of `SearchMapWithGoogleMap`. + +_src/components/SearchMap/SearchMap.js:_ + +Remove this: + +```js +import SearchMapWithMapbox, { + LABEL_HANDLE, + INFO_CARD_HANDLE, + getMapBounds, + getMapCenter, + fitMapToBounds, + isMapsLibLoaded, +} from './SearchMapWithMapbox'; +``` + +And add this instead: + +```js +import SearchMapWithGoogleMap, { + LABEL_HANDLE, + INFO_CARD_HANDLE, + getMapBounds, + getMapCenter, + fitMapToBounds, + isMapsLibLoaded, +} from './SearchMapWithGoogleMap'; +``` + +Then, in `render` method, you need to put `SearchMapWithGoogleMap` component into use by replacing +`SearchMapWithMapbox` which is defined inside `ReusableMapContainer`. The component with correct +props is already there in the comments: + +```js +// When changing from default map provider to Google Maps, you should use the following +// component instead of SearchMapWithMapbox: +// +// +// } +// mapElement={
} +// bounds={bounds} +// center={center} +// location={location} +// infoCardOpen={infoCardOpen} +// listings={listings} +// activeListingId={activeListingId} +// mapComponentRefreshToken={this.state.mapReattachmentCount} +// createURLToListing={this.createURLToListing} +// onListingClicked={this.onListingClicked} +// onListingInfoCardClicked={this.onListingInfoCardClicked} +// onMapLoad={this.onMapLoadHandler} +// onMapMoveEnd={onMapMoveEnd} +// zoom={zoom} +// /> +``` + +The only extra step is to make `mapRootClassName` property available from `this.props` at the +beginning of the `render` method. diff --git a/docs/map-providers.md b/docs/map-providers.md new file mode 100644 index 00000000..8906db06 --- /dev/null +++ b/docs/map-providers.md @@ -0,0 +1,70 @@ +# Integrating to map providers + +Choice of map provider can significantly impact your costs. Flex Template for Web (FTW) originally +supported only [Google Maps](./google-maps.md) out of the box, but after Google increased the +pricing of its APIs a lot, the default provider was changed to Mapbox. The template now supports +both Mapbox and Google Maps, and the map library used by Mapbox is used also by several other map +providers, so integrating new providers that support this is rather easy (see instructions at the +end of this doc). + +## Setting up the Mapbox integration (the default map provider) + +### 1. Generate a Mapbox access key + +Sign up for a Mapbox and go to [account page](https://www.mapbox.com/account/). Then click +`Create access token`. + +> Read more about +> [access tokens and consider rotating them](https://www.mapbox.com/help/how-access-tokens-work/). + +### 2. Setup the application to use the access key + +The application uses the `REACT_APP_MAPBOX_ACCESS_TOKEN` environment variable for the key value. For +local development, you can add the variable in the Gitignored `.env` file in the project root: + +``` +REACT_APP_MAPBOX_ACCESS_TOKEN=my-access-token-here +``` + +### 3. Setup common locations to reduce typing + +The location autocomplete input in the landing page and the topbar can be configured to have +specific locations shown by default when the user focuses on the input and hasn't yet typed in any +searches. This reduces the typing required for common searches and also reduces the need to use +Mapbox geolocation API that much. + +To use default searches, another environment variable needs to be set: + +``` +REACT_APP_DEFAULT_SEARCHES_ENABLED=true +``` + +The default locations are described in +[src/default-location-searches.js](../src/default-location-searches.js). + +The same environment variable also shows "current location" suggestion, which will make the browser +to ask user's current location. This is a fast way to search listings nearby. You can specify +whether to use the current location from [config.js](../src/config.js). Search for variables: +`suggestCurrentLocation` and `currentLocationBoundsDistance`. + +### 4. Check rare default configurations + +Mapbox geocoding API doesn't always return bounding boxes for locations. Without bounding box +SearchMap component can't adjust zoom level right for that particular place. Therefore there are +default bounding boxes defined to different place types in +[Mapbox specific geocoder](../src/components/LocationAutocompleteInput/GeocoderMapbox.js). + +## Changing the map providers + +### How to change from Mapbox to Google Maps + +It is possible to use Google Map instead of the default map provider. Read more from +[Google Map setup guide](./google-maps.md) + +### How to use other map providers + +The default map setup of FTW uses library called `mapbox-gl-js`. It is supported by quite many other +map providers too. Thus, if you wish to use a map provider other than Google Maps or Mapbox, first +check if the map provider you are considering is supporting this library. If they are, the change +might be quite easy. Note: if you change the map tile provider you should also change geocoding API +too (i.e. the API endpoint for `LocationAutocompleteInput` component). diff --git a/package.json b/package.json index 27df6e0d..d85462bd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "app", - "version": "1.4.3", + "version": "2.0.0", "private": true, "license": "Apache-2.0", "dependencies": { @@ -24,6 +24,7 @@ "final-form-arrays": "^1.0.4", "helmet": "^3.12.0", "lodash": "^4.17.5", + "mapbox-gl-multitouch": "^1.0.3", "moment": "^2.20.1", "object.entries": "^1.0.4", "object.values": "^1.0.4", diff --git a/public/index.html b/public/index.html index b2a9739e..672374cc 100644 --- a/public/index.html +++ b/public/index.html @@ -143,7 +143,22 @@ })(document); - + + + + + + +