diff --git a/src/App.css b/src/App.css index 7d268be..7594784 100644 --- a/src/App.css +++ b/src/App.css @@ -7,3 +7,11 @@ margin: 0 auto; max-width: 700px; } + +.people-in-space { + margin-top: 50px; +} + +.people-list { + list-style-type: none; +} diff --git a/src/App.js b/src/App.js index 1447b5e..977d414 100644 --- a/src/App.js +++ b/src/App.js @@ -1,12 +1,19 @@ -import React from 'react'; +import React, { useContext } from 'react'; import './App.css'; import ISSLocation from './components/ISSLocation'; +import ToggleMap from './components/ToggleMap'; +import ISSContext from './context/ISSContext'; +import PeopleInSpace from './components/PeopleInSpace'; function App() { + const { showMap } = useContext(ISSContext); + return (

International Space Station Location Tracker

- + + {showMap && } +
); } diff --git a/src/components/ISSLocation.js b/src/components/ISSLocation.js index 5f5e5b0..329ed88 100644 --- a/src/components/ISSLocation.js +++ b/src/components/ISSLocation.js @@ -1,54 +1,46 @@ -import React, { Component } from 'react'; +import React, { useContext, useEffect } from 'react'; import Map from 'pigeon-maps'; import Marker from 'pigeon-marker'; import ISSContext from '../context/ISSContext'; - -class ISSLocation extends Component { - componentDidMount() { - const { getCurrentISSLocation } = this.context; - - this.timer = setInterval( - getCurrentISSLocation, - 2000, - ); - } - - componentWillUnmount() { - clearInterval(this.timer); - } - - render() { - const { - error, - isFetching, - latitude, - longitude, - } = this.context; - const isLocationPresent = latitude && longitude; - - return ( -
-
- - {!isFetching && isLocationPresent && } - -
- {isFetching && 'Loading...'} - {!isFetching && isLocationPresent && `Current ISS location: latitude = ${latitude}, longitude = ${longitude}`} - {!isFetching && error} +import useTimer from '../effects/useTimer'; + +function ISSLocation() { + const { + error, + isFetching, + latitude, + longitude, + getCurrentISSLocation, + } = useContext(ISSContext); + const isLocationPresent = latitude && longitude; + + useTimer(getCurrentISSLocation, 2000); + + useEffect(() => { + const now = new Date(); + document.title = now.toLocaleTimeString(); + }); + + return ( +
+
+ + {!isFetching && isLocationPresent && } +
- ); - } + {isFetching && 'Loading...'} + {!isFetching && isLocationPresent && `Current ISS location: latitude = ${latitude}, longitude = ${longitude}`} + {!isFetching && error} +
+ ); } -ISSLocation.contextType = ISSContext; - export default ISSLocation; diff --git a/src/components/PeopleInSpace.js b/src/components/PeopleInSpace.js new file mode 100644 index 0000000..91c7fb2 --- /dev/null +++ b/src/components/PeopleInSpace.js @@ -0,0 +1,25 @@ +import React, { useContext } from 'react'; + +import ISSContext from '../context/ISSContext'; +import useTimer from '../effects/useTimer'; + +const PeopleInSpace = () => { + const { peopleInSpace, getPeopleInSpace } = useContext(ISSContext); + + useTimer(getPeopleInSpace, 5000); + + if (!peopleInSpace) return null; + + return ( +
+ {`Number of people in space now: ${peopleInSpace.length}`} + +
+ ); +}; + +export default PeopleInSpace; diff --git a/src/components/ToggleMap.js b/src/components/ToggleMap.js new file mode 100644 index 0000000..72c9d65 --- /dev/null +++ b/src/components/ToggleMap.js @@ -0,0 +1,17 @@ +import React, { useContext } from 'react'; +import ISSContext from '../context/ISSContext'; + +const ToggleMap = () => { + const { showMap, toggleMap } = useContext(ISSContext); + + return ( + + ); +}; + +export default ToggleMap; diff --git a/src/context/Provider.js b/src/context/Provider.js index e66b3fe..fc2c276 100644 --- a/src/context/Provider.js +++ b/src/context/Provider.js @@ -2,7 +2,7 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; import ISSContext from './ISSContext'; -import { getCurrentISSLocation } from '../services/issAPI'; +import { getCurrentISSLocation, getPeopleInSpace } from '../services/issAPI'; class Provider extends Component { constructor(props) { @@ -12,11 +12,16 @@ class Provider extends Component { isFetching: false, latitude: null, longitude: null, + showMap: true, + peopleInSpace: undefined, }; this.fetchISSLocation = this.fetchISSLocation.bind(this); this.handleISSLocationSuccess = this.handleISSLocationSuccess.bind(this); this.handleISSLocationFailure = this.handleISSLocationFailure.bind(this); + this.handleToggleMap = this.handleToggleMap.bind(this); + this.fetchNumberOfPeopleInSpace = this.fetchNumberOfPeopleInSpace.bind(this); + this.handlePepoleInSpaceSuccess = this.handlePepoleInSpaceSuccess.bind(this); } fetchISSLocation() { @@ -30,6 +35,10 @@ class Provider extends Component { .then(this.handleISSLocationSuccess, this.handleISSLocationFailure); } + fetchNumberOfPeopleInSpace() { + getPeopleInSpace().then(this.handlePepoleInSpaceSuccess); + } + handleISSLocationSuccess(response) { const { iss_position: { latitude, longitude } } = response; @@ -47,10 +56,20 @@ class Provider extends Component { }); } + handlePepoleInSpaceSuccess(response) { + this.setState({ peopleInSpace: response.people }); + } + + handleToggleMap() { + this.setState(({ showMap }) => ({ showMap: !showMap })); + } + render() { const contextValue = { ...this.state, getCurrentISSLocation: this.fetchISSLocation, + toggleMap: this.handleToggleMap, + getPeopleInSpace: this.fetchNumberOfPeopleInSpace, }; const { children } = this.props; diff --git a/src/effects/useTimer.js b/src/effects/useTimer.js new file mode 100644 index 0000000..f0bf174 --- /dev/null +++ b/src/effects/useTimer.js @@ -0,0 +1,18 @@ +import { useEffect } from 'react'; + +const useTimer = (func, interval) => { + useEffect(() => { + func(); + + const timer = setInterval( + func, + interval, + ); + + return () => { + clearInterval(timer); + }; + }, []); +}; + +export default useTimer; diff --git a/src/services/issAPI.js b/src/services/issAPI.js index bfb7015..fe49d76 100644 --- a/src/services/issAPI.js +++ b/src/services/issAPI.js @@ -9,4 +9,12 @@ export const getCurrentISSLocation = () => ( )) ); +export const getPeopleInSpace = () => ( + fetch(`${ISS_BASE_API}/astros.json`) + .then((response) => ( + response.json() + .then((json) => (response.ok ? Promise.resolve(json) : Promise.reject(json))) + )) +); + export default getCurrentISSLocation;