{"version":3,"sources":["images/weather-logo.png","images/loading-indicator.gif","reducers/initialState.js","reducers/index.js","actions/types.js","store/store.js","store/configureStore.js","components/LocationSearchForm.js","components/WeatherDisplayPanel.js","components/index.js","selectors/index.js","containers/index.js","actions/index.js","serviceWorker/serviceWorker.js","index.js"],"names":["module","exports","initialState","fromJS","weatherApp","isWeatherDataLoading","hasWeatherDataLoadingError","data","reducer","state","get","action","type","setIn","payload","store","createStore","compose","applyMiddleware","thunk","apiMiddleware","devToolsEnhancer","configureStore","LocationSearchForm","fetchWeatherData","searchInput","useRef","clearIcon","useState","address","setAddress","handleSubmit","input","geocodeByAddress","then","results","getLatLng","latLng","catch","error","console","clearInput","current","focus","className","highlightFirstSuggestion","value","onChange","onSelect","e","getInputProps","suggestions","getSuggestionItemProps","Fragment","placeholder","ref","length","map","suggestion","active","description","onKeyDown","keyCode","onClick","WeatherDisplayPanel","weatherData","src","loading","alt","name","weather","main","parseInt","temp","icon","logo","defaultProps","WeatherApp","getWeatherData","getIn","toJS","connect","dispatch","location","createAction","endpoint","lat","lng","method","types","Boolean","window","hostname","match","ReactDOM","render","document","getElementById","navigator","serviceWorker","ready","registration","unregister","message"],"mappings":"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","file":"static/js/main.0ce5e5ce.chunk.js","sourcesContent":["module.exports = __webpack_public_path__ + \"static/media/weather-logo.f6792e41.png\";","module.exports = __webpack_public_path__ + \"static/media/loading-indicator.9f0bb82a.gif\";","import { fromJS } from 'immutable';\n\nconst initialState = fromJS({\n weatherApp: {\n isWeatherDataLoading: false,\n hasWeatherDataLoadingError: false,\n data: null\n }\n});\n\nexport default initialState;\n","import { fromJS } from 'immutable';\nimport initialState from './initialState';\nimport * as types from '../actions/types';\n\nconst reducer = (state = initialState.get('weatherApp'), action) => {\n switch (action.type) {\n case types.FETCH_WEATHER_DATA:\n return state\n .setIn(['weatherApp', 'hasWeatherDataLoadingError'], false)\n .setIn(['weatherApp', 'isWeatherDataLoading'], true);\n case types.FETCH_WEATHER_DATA_SUCCESS:\n return state\n .setIn(['weatherApp', 'isWeatherDataLoading'], false)\n .setIn(['weatherApp', 'data'], fromJS(action.payload));\n case types.FETCH_WEATHER_DATA_ERROR:\n return state\n .setIn(['weatherApp', 'isWeatherDataLoading'], false)\n .setIn(['weatherApp', 'hasWeatherDataLoadingError'], true);\n default:\n return state;\n }\n}\n\nexport default reducer\n","export const FETCH_WEATHER_DATA = 'FETCH_WEATHER_DATA';\nexport const FETCH_WEATHER_DATA_SUCCESS = 'FETCH_WEATHER_DATA_SUCCESS';\nexport const FETCH_WEATHER_DATA_ERROR = 'FETCH_WEATHER_DATA_ERROR';\n","import configureStore from './configureStore';\nimport initialState from '../reducers/initialState';\n\nconst store = configureStore(initialState);\n\nexport default store;\n","import { createStore, applyMiddleware, compose } from 'redux';\nimport { devToolsEnhancer } from 'redux-devtools-extension';\nimport { apiMiddleware } from 'redux-api-middleware';\nimport thunk from 'redux-thunk';\nimport reducer from '../reducers';\n\nconst configureStore = (state) => {\n return createStore(\n reducer,\n state,\n compose(\n applyMiddleware(thunk, apiMiddleware),\n devToolsEnhancer()\n )\n );\n};\n\nexport default configureStore;\n","import React, { useState, useRef } from 'react';\nimport PropTypes from 'prop-types';\nimport PlacesAutocomplete, {\n geocodeByAddress,\n getLatLng,\n} from 'react-places-autocomplete';\nimport { FaSearch, FaTimes } from 'react-icons/fa';\n\nimport '../styles/LocationSearchForm.css';\n\nconst LocationSearchForm = ({ fetchWeatherData }) => {\n let searchInput = useRef(null);\n let clearIcon = useRef(null);\n const [address, setAddress] = useState('');\n\n const handleChange = input => {\n setAddress(input);\n };\n\n const handleSelect = (input, e) => {\n if (e) {\n setAddress(input);\n clearIcon.current.focus()\n handleSubmit(input);\n }\n };\n\n const handleSubmit = (input) => {\n geocodeByAddress(input)\n .then(results => getLatLng(results[0]))\n .then(latLng => fetchWeatherData(latLng))\n .catch(error => console.error('Error', error));\n };\n\n const handleKeyPress = (e) => {\n if (e.keyCode === 13) {\n clearInput();\n }\n };\n\n const handleClick = () => {\n clearInput();\n };\n\n const clearInput = () => {\n setAddress('');\n searchInput.current.focus();\n };\n\n return (\n
\n
\n \n {({ getInputProps, suggestions, getSuggestionItemProps }) => (\n \n \n {suggestions && suggestions.length > 1 &&\n
\n {suggestions.map(suggestion => {\n const className = suggestion.active\n ? 'suggestion-item-active'\n : 'suggestion-item';\n return (\n
\n {suggestion.description}\n
\n );\n })}\n
\n }\n
\n )}\n \n {address ?\n \n \n :\n \n }\n
\n
\n );\n};\n\nLocationSearchForm.propTypes = {\n fetchWeatherData: PropTypes.func.isRequired\n};\n\nexport default LocationSearchForm;\n","import React from 'react';\nimport PropTypes from 'prop-types';\nimport logo from '../images/weather-logo.png';\nimport loading from '../images/loading-indicator.gif';\n\nimport '../styles/WeatherDisplayPanel.css';\n\nconst WeatherDisplayPanel = ({ weatherData, isWeatherDataLoading, hasWeatherDataLoadingError }) => {\n const renderLoadingIndicator = () => {\n return \"\"\n };\n\n const renderContent = () => {\n if (hasWeatherDataLoadingError) {\n return There was a problem with your submission. Please try again.\n } else if (weatherData) {\n return (\n
\n
{weatherData.name}
\n
{weatherData.weather[0].main}
\n
{parseInt(weatherData.main.temp)}°
\n \"Weather\n
\n )\n } else {\n return (\n
\n

React Weather App

\n \"Get\n
\n );\n }\n };\n\n return (\n
\n {isWeatherDataLoading ?\n renderLoadingIndicator() :\n renderContent()\n }\n
\n );\n};\n\nWeatherDisplayPanel.defaultProps = {\n weatherData: null\n};\n\nWeatherDisplayPanel.propTypes = {\n isWeatherDataLoading: PropTypes.bool.isRequired,\n hasWeatherDataLoadingError: PropTypes.bool.isRequired,\n weatherData: PropTypes.object\n};\n\nexport default WeatherDisplayPanel;\n","import React from 'react';\nimport PropTypes from 'prop-types';\nimport LocationSearchForm from './LocationSearchForm';\nimport WeatherDisplayPanel from './WeatherDisplayPanel';\n\nimport '../styles/WeatherApp.css';\n\nconst WeatherApp = ({\n weatherData,\n fetchWeatherData,\n isWeatherDataLoading,\n hasWeatherDataLoadingError\n}) => {\n return (\n
\n \n \n
\n );\n};\n\nWeatherApp.defaultProps = {\n weatherData: null\n};\n\nWeatherApp.propTypes = {\n isWeatherDataLoading: PropTypes.bool.isRequired,\n hasWeatherDataLoadingError: PropTypes.bool.isRequired,\n fetchWeatherData: PropTypes.func.isRequired,\n weatherData: PropTypes.object\n};\n\nexport default WeatherApp;\n","export const getWeatherData = state => {\n const weatherData = state.getIn(['weatherApp', 'data']);\n if (weatherData) {\n return weatherData.toJS();\n }\n}\n\nexport const isWeatherDataLoading = state => state.getIn(['weatherApp', 'isWeatherDataLoading']);\n\nexport const hasWeatherDataLoadingError = state => state.getIn(['weatherApp', 'hasWeatherDataLoadingError']);\n","import { connect } from 'react-redux';\nimport WeatherApp from '../components';\nimport {\n getWeatherData,\n isWeatherDataLoading,\n hasWeatherDataLoadingError\n} from '../selectors';\nimport { fetchWeatherData } from '../actions';\n\nconst mapStateToProps = state => ({\n weatherData: getWeatherData(state),\n isWeatherDataLoading: isWeatherDataLoading(state),\n hasWeatherDataLoadingError: hasWeatherDataLoadingError(state)\n});\n\nconst mapDispatchToProps = dispatch => ({\n fetchWeatherData: location => dispatch(fetchWeatherData(location))\n});\n\nexport default connect(mapStateToProps, mapDispatchToProps)(WeatherApp);\n","import { createAction } from 'redux-api-middleware';\nimport * as types from './types';\n\nexport const fetchWeatherData = (latLng) => (\n createAction({\n endpoint: `https://api.openweathermap.org/data/2.5/weather?lat=${latLng.lat}&lon=${latLng.lng}&units=imperial&APPID=9f37eae0ba52698e13ef6b9efcf42e37`,\n method: 'GET',\n types: [\n types.FETCH_WEATHER_DATA,\n types.FETCH_WEATHER_DATA_SUCCESS,\n types.FETCH_WEATHER_DATA_ERROR\n ]\n })\n);\n","// This optional code is used to register a service worker.\n// register() is not called by default.\n\n// This lets the app load faster on subsequent visits in production, and gives\n// it offline capabilities. However, it also means that developers (and users)\n// will only see deployed updates on subsequent visits to a page, after all the\n// existing tabs open on the page have been closed, since previously cached\n// resources are updated in the background.\n\n// To learn more about the benefits of this model and instructions on how to\n// opt-in, read https://bit.ly/CRA-PWA\n\nconst isLocalhost = Boolean(\n window.location.hostname === 'localhost' ||\n // [::1] is the IPv6 localhost address.\n window.location.hostname === '[::1]' ||\n // 127.0.0.0/8 are considered localhost for IPv4.\n window.location.hostname.match(\n /^127(?:\\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/\n )\n);\n\nexport function register(config) {\n if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {\n // The URL constructor is available in all browsers that support SW.\n const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href);\n if (publicUrl.origin !== window.location.origin) {\n // Our service worker won't work if PUBLIC_URL is on a different origin\n // from what our page is served on. This might happen if a CDN is used to\n // serve assets; see https://github.com/facebook/create-react-app/issues/2374\n return;\n }\n\n window.addEventListener('load', () => {\n const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;\n\n if (isLocalhost) {\n // This is running on localhost. Let's check if a service worker still exists or not.\n checkValidServiceWorker(swUrl, config);\n\n // Add some additional logging to localhost, pointing developers to the\n // service worker/PWA documentation.\n navigator.serviceWorker.ready.then(() => {\n console.log(\n 'This web app is being served cache-first by a service ' +\n 'worker. To learn more, visit https://bit.ly/CRA-PWA'\n );\n });\n } else {\n // Is not localhost. Just register service worker\n registerValidSW(swUrl, config);\n }\n });\n }\n}\n\nfunction registerValidSW(swUrl, config) {\n navigator.serviceWorker\n .register(swUrl)\n .then(registration => {\n registration.onupdatefound = () => {\n const installingWorker = registration.installing;\n if (installingWorker == null) {\n return;\n }\n installingWorker.onstatechange = () => {\n if (installingWorker.state === 'installed') {\n if (navigator.serviceWorker.controller) {\n // At this point, the updated precached content has been fetched,\n // but the previous service worker will still serve the older\n // content until all client tabs are closed.\n console.log(\n 'New content is available and will be used when all ' +\n 'tabs for this page are closed. See https://bit.ly/CRA-PWA.'\n );\n\n // Execute callback\n if (config && config.onUpdate) {\n config.onUpdate(registration);\n }\n } else {\n // At this point, everything has been precached.\n // It's the perfect time to display a\n // \"Content is cached for offline use.\" message.\n console.log('Content is cached for offline use.');\n\n // Execute callback\n if (config && config.onSuccess) {\n config.onSuccess(registration);\n }\n }\n }\n };\n };\n })\n .catch(error => {\n console.error('Error during service worker registration:', error);\n });\n}\n\nfunction checkValidServiceWorker(swUrl, config) {\n // Check if the service worker can be found. If it can't reload the page.\n fetch(swUrl, {\n headers: { 'Service-Worker': 'script' }\n })\n .then(response => {\n // Ensure service worker exists, and that we really are getting a JS file.\n const contentType = response.headers.get('content-type');\n if (\n response.status === 404 ||\n (contentType != null && contentType.indexOf('javascript') === -1)\n ) {\n // No service worker found. Probably a different app. Reload the page.\n navigator.serviceWorker.ready.then(registration => {\n registration.unregister().then(() => {\n window.location.reload();\n });\n });\n } else {\n // Service worker found. Proceed as normal.\n registerValidSW(swUrl, config);\n }\n })\n .catch(() => {\n console.log(\n 'No internet connection found. App is running in offline mode.'\n );\n });\n}\n\nexport function unregister() {\n if ('serviceWorker' in navigator) {\n navigator.serviceWorker.ready\n .then(registration => {\n registration.unregister();\n })\n .catch(error => {\n console.error(error.message);\n });\n }\n}\n","import React from 'react';\nimport ReactDOM from 'react-dom';\nimport { Provider } from 'react-redux';\nimport store from './store/store';\nimport WeatherApp from './containers';\nimport * as serviceWorker from './serviceWorker/serviceWorker';\n\nimport './styles/index.css';\n\nReactDOM.render(\n \n \n ,\n document.getElementById('root')\n);\n\n// If you want your app to work offline and load faster, you can change\n// unregister() to register() below. Note this comes with some pitfalls.\n// Learn more about service workers: https://bit.ly/CRA-PWA\nserviceWorker.unregister();\n"],"sourceRoot":""}