import Cookies from '../vendor/jscookie';
import customEvent from '../utils/customEvent';
import populateElement from '../utils/populateElement';
/**
* Weather Widget
*
* @example
* <div class="c-weather">
* <div class="c-weather__inner">
* <div class="c-loader c-weather__loader"></div>
* <div class="c-weather__header">
* <button class="c-weather__region toggle-switch"
* data-toggle-outside-click="true" data-track-region="" data-title="CHANGE REGION">
* <svg class="c-weather__icon c-icon" focusable="false">
* <use xlink:href="" />
* </svg>
* <span class="c-weather__location" data-map="region_name"></span>
* <span class="c-weather__province" data-map="region_state_abbr"></span>
* <select class="c-weather__select toggle-on"></select>
* </button>
* </div>
* <a class="c-weather__link c-weather__link--left"
* data-map="weather_url" title="Weather" data-track-region="">
* <div class="c-weather__imageContainer u-hide-tablet-landscape">
* <img class="c-weather__image" data-map="icon" src="" alt="" />
* </div>
* <div class="c-weather__info">
* <div class="c-weather__degree c-weather__degree--current" data-map="current"></div>
* <div class="c-weather__prediction">
* <span class="c-weather__degree" data-map="high"></span>
* <span class="c-weather__degree" data-map="low"></span>
* </div>
* </div>
* </a>
* <a class="c-weather__link c-weather__link--right u-show-tablet-landscape"
* data-map="weather_url" title="Weather" data-track-region="">
* <div class="c-weather__imageContainer">
* <div>
* <img class="c-weather__image" data-map="icon" src="" alt="" />
* <div class="c-weather__text c-weather__conditions" data-map="conditions"></div>
* </div>
* </div>
* </a>
* </div>
* <a class="c-weather__link c-weather__link--bottom"
* data-map="traffic_url" href="" data-track-region="">
* <span class="c-weather__label">Traffic</span>
* <span class="c-weather__text">Travel times & incidents</span>
* <div class="c-weather__traffic">
* <div class="c-weather__trafficTitle">
* <svg class="c-weather__alert c-icon" focusable="false">
* <use xlink:href="" />
* </svg>
* <span data-map="top_traffic_title"></span>
* </div>
* <span class="c-weather__trafficDesc" data-map="top_traffic_desc"></span>
* </div>
* </a>
* </div>
* </div>
*
* @module WeatherWidget
* @prop {string} selector - DOM selector for a weather widget
* @prop {string} regionButtonSelector - DOM selector for the region select button
* @prop {string} dropdownSelector - DOM selector for the dropdown
* @prop {string} regionLabelSelector - DOM selector for region label
* @prop {string} loadingCss - CSS class of the loading state
* @prop {string} hiddenCss - CSS class of the hidden state
* @prop {string} cookieName - Cookie name for storing user selected region
*/
const WeatherWidget = {
selector: '.c-weather',
regionButtonSelector: '.c-weather__region',
dropdownSelector: '.c-weather__select',
regionLabelSelector: '[data-map="region_name"]',
loadingCss: 'c-weather--loading',
nightModeCSS: 'c-weather--night',
trafficCSS: 'c-weather--traffic',
hiddenCss: 'is-hidden',
cookieName: 'gn-weatherRegion',
/* global gnca_settings */
/**
* Set up button click listener and region drop down listeners.
* Get weather data for selected region.
*
* @method init
*/
init() {
const $targets = document.querySelectorAll( this.selector );
[].forEach.call( $targets, ( $target, index ) => {
const id = `c-weatherTraffic${index}`;
$target.id = id; // eslint-disable-line no-param-reassign
$target.classList.add( this.loadingCss );
const $regionButton = $target.querySelector( this.regionButtonSelector );
$regionButton.dataset.target = id;
const $dropdown = $target.querySelector( this.dropdownSelector );
$dropdown.addEventListener( 'change', evt => this.handleLocationChange( evt ) );
$dropdown.dataset.target = id;
$dropdown.setAttribute( 'size', 10 );
const regionCode = Cookies.get( this.cookieName );
this.getData( $target, gnca_settings.user_region, regionCode );
});
window.addEventListener( customEvent.REGION_CHANGE, () => this.handleRegionChange() );
},
/**
* Handler for location change.
* Get data for selected location.
*
* @method handleLocationChange
* @param {object} evt
*/
handleLocationChange( evt ) {
const code = evt.target.selectedOptions[0].value;
const $target = document.querySelector( `#${evt.currentTarget.dataset.target}` );
const $label = $target.querySelector( this.regionLabelSelector );
$label.textContent = evt.target.selectedOptions[0].textContent;
evt.currentTarget.classList.add( this.hiddenCss );
$target.querySelector( this.regionButtonSelector ).classList.remove( this.hiddenCss );
$target.classList.add( this.loadingCss );
this.trackRegionChange( $label.textContent, evt );
this.getData( $target, gnca_settings.user_region, code );
},
/**
* Handler for region change by region picker.
* Clear weather region cookie.
*
* @method handleRegionChange
*/
handleRegionChange() {
Cookies.remove( this.cookieName );
},
/**
* Track region change in Google and Adobe analytics
* @method trackRegionChange
*/
trackRegionChange( region, event ) {
/* global gn_analytics */
/* eslint-disable camelcase */
if ( 'undefined' !== typeof ( gn_analytics ) && 'undefined' !== typeof ( gn_analytics.Analytics ) ) {
const trackAction = `${region}`;
gn_analytics.Analytics.track(['ga', 'adobe'], {
eventType: 'Weather Region Change',
action: trackAction,
target: event.currentTarget,
data: {
weatherRegionChange: trackAction,
},
});
}
/* eslint-enable camelcase */
},
/**
* Get weather data for specified region and code
* Populate data into the target element and remember the selected region
*
* @method getData
* @param {element} $target
* @param {string} region
* @param {string} code
*/
getData( $target, region, code ) {
const regionCode = 'string' === typeof ( code ) && 'undefined' !== code ? code : '';
fetch( `/gnca-ajax-redesign/weather/{"default_region":"${region}","region_code":"${regionCode}"}` )
.then( response => response.text() )
.then( ( content ) => {
const data = JSON.parse( content );
this.populate( $target, data );
$target.classList.remove( this.loadingCss );
// Remember region code, if one exists
if ( data.region_code ) {
Cookies.set( this.cookieName, data.region_code, { expires: 90, path: '/' });
}
});
},
/**
* Populate data into target element
*
* @method populate
* @param {element} $target
* @param {object} data
*/
populate( $target, data ) {
// Populate data fields in the widget
populateElement( $target, data );
// Update night mode if weather is at night
if ( true === data.night_mode ) {
$target.classList.add( this.nightModeCSS );
} else {
$target.classList.remove( this.nightModeCSS );
}
// Toggle traffic conditions mode if there are traffic conditions to show
if ( true === data.has_top_traffic ) {
$target.classList.add( this.trafficCSS );
} else {
$target.classList.remove( this.trafficCSS );
}
// Populate location picker for selected region
const $dropdown = $target.querySelector( this.dropdownSelector );
if ( 0 === $dropdown.querySelectorAll( 'option' ).length && data.region_picker ) {
const regionList = data.region_picker;
const regionCodes = Object.keys( regionList );
[].forEach.call( regionCodes, ( code ) => {
const $option = document.createElement( 'option' );
$option.id = code;
$option.setAttribute( 'value', code );
$option.textContent = regionList[code];
$dropdown.appendChild( $option );
});
}
},
};
export default WeatherWidget;