Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/Api/weatherApi.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,13 @@ export const getCurrentWeather = async (longitude, latitude) => {
export const getLocationByCoords = async (longitude, latitude) => {
const result = await instance.get(`/location/${longitude},${latitude}`);
return {
id: result.data.id,
city: result.data.name,
country: result.data.country
};
};

export const getHourlyWeather = async (longitude, latitude) => {
const result = await instance.get(`/forecast/hourly/${longitude},${latitude}`);
return result.data.forecast;
};
9 changes: 9 additions & 0 deletions src/Components/CurrentLocation/CurrentLocation.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
function CurrentLocation({ currentLocation }) {
return (
<h2>
{currentLocation.city}, {currentLocation.country}
</h2>
);
}

export default CurrentLocation;
15 changes: 15 additions & 0 deletions src/Components/HourlyWeatherItem/HourlyWeatherItem.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { toReadableTime } from '../../helpers/formatHelper';
import SafeWeatherImage from '../SafeImage/SafeWeatherImage';

function HourlyWeatherItem({ hourly }) {
return (
<div>
<p>
{toReadableTime(hourly.time)} temperature: {hourly.temperature}° precipProb:{' '}
{hourly.precipProb} % <SafeWeatherImage symbolCode={hourly.symbol} />
</p>
</div>
);
}

export default HourlyWeatherItem;
24 changes: 24 additions & 0 deletions src/Components/Pages/DetailedForesastPage/DetailedForecastPage.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,31 @@
import { useEffect } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { getLocation } from '../../../Store/selectors/geoSelectors';
import HourlyWeatherItem from '../../HourlyWeatherItem/HourlyWeatherItem';
import { fetchUserLocationDetailedWeather } from './detailedForecastPageActions';
import { getHourlyWeather, getLoading } from './detailedForecastPageSelectors';
import Loader from '../../Loader/Loader';
import CurrentLocation from '../../CurrentLocation/CurrentLocation';

function DetailedForecastPage() {
const dispatch = useDispatch();
const location = useSelector(getLocation);
const hourlyWeather = useSelector(getHourlyWeather);
const loading = useSelector(getLoading);

useEffect(async () => {
dispatch(fetchUserLocationDetailedWeather());
}, []);

return (
<div>
<h1>Detailed Page</h1>
{loading && <Loader />}
{location && <CurrentLocation currentLocation={location}/>}
{hourlyWeather &&
hourlyWeather.map(hourlyItem => (
<HourlyWeatherItem key={`${location.id}_${hourlyItem.time}`} hourly={hourlyItem} />
))}
</div>
);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { fetchUserGeoData } from '../../../Store/actions/geoActions';
import { getPosition } from '../../../Store/selectors/geoSelectors';
import { getHourlyWeather } from '../../../Api/weatherApi';

export const DETAILED_FORECAST_PAGE_ACTIONS = {
USER_POSITION_DETAILED_WEATHER_REQUESTED: 'USER_POSITION_DETAILED_WEATHER_REQUESTED',
USER_POSITION_DETAILED_WEATHER_RECEIVED: 'USER_POSITION_DETAILED_WEATHER_RECEIVED',
USER_POSITION_DETAILED_WEATHER_FAILED: 'USER_POSITION_DETAILED_WEATHER_FAILED'
};

const userPositionDetailedWeatherRequested = () => ({
type: DETAILED_FORECAST_PAGE_ACTIONS.USER_POSITION_DETAILED_WEATHER_REQUESTED
});

const userPositionDetailedWeatherReceived = ({ hourlyWeather }) => ({
type: DETAILED_FORECAST_PAGE_ACTIONS.USER_POSITION_DETAILED_WEATHER_RECEIVED,
payload: { hourlyWeather }
});

const userPositionDetailedWeatherFailed = ({ error }) => ({
type: DETAILED_FORECAST_PAGE_ACTIONS.USER_POSITION_DETAILED_WEATHER_FAILED,
payload: error
});

export const fetchUserLocationDetailedWeather = () => async (dispatch, getState) => {
dispatch(userPositionDetailedWeatherRequested());

try {
await dispatch(fetchUserGeoData());
const { longitude, latitude } = getPosition(getState());
const hourlyWeather = await getHourlyWeather(longitude, latitude);
dispatch(userPositionDetailedWeatherReceived({ hourlyWeather }));
} catch (error) {
dispatch(userPositionDetailedWeatherFailed(error));
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's discuss that by call

};
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
const initialState = {
hourlyWeather: null,
loading: false,
error: null
};

export default initialState;
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import initialState from './detailedForecastPageInitialState';
import { DETAILED_FORECAST_PAGE_ACTIONS } from './detailedForecastPageActions';
import produce from 'immer';

export const detailedForecastPageReducer = (state = initialState, { type, payload }) => {
switch (type) {
case DETAILED_FORECAST_PAGE_ACTIONS.USER_POSITION_DETAILED_WEATHER_REQUESTED:
return produce(state, draft => {
draft.loading = true;
draft.error = null;
});
case DETAILED_FORECAST_PAGE_ACTIONS.USER_POSITION_DETAILED_WEATHER_RECEIVED:
return produce(state, draft => {
draft.loading = false;
draft.hourlyWeather = payload.hourlyWeather;
});
case DETAILED_FORECAST_PAGE_ACTIONS.USER_POSITION_DETAILED_WEATHER_FAILED:
return produce(state, draft => {
draft.loading = false;
draft.error = payload;
});
default:
return state;
}
};

export default detailedForecastPageReducer;
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const getHourlyWeather = state => state.detailedForecastPage.hourlyWeather;
export const getLoading = state => state.detailedForecastPage.loading;
7 changes: 2 additions & 5 deletions src/Components/Pages/HomePage/HomePage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import Loader from '../../Loader/Loader';
import { capitalize, toReadableDate, toReadableTime } from '../../../helpers/formatHelper';
import { getLocation } from '../../../Store/selectors/geoSelectors';
import { getCurrentWeather, getLoading } from './homePageSelectors';
import CurrentLocation from '../../CurrentLocation/CurrentLocation';

function HomePage() {
const dispatch = useDispatch();
Expand All @@ -20,12 +21,8 @@ function HomePage() {
return (
<>
<h1>Home</h1>
{location && (
<h2>
{location.city}, {location.country}
</h2>
)}
{loading && <Loader />}
{location && <CurrentLocation currentLocation={location}/>}
{currentWeather && <p>{toReadableDate(currentWeather.current.time)}</p>}
{currentWeather && <p>{toReadableTime(currentWeather.current.time)}</p>}
{currentWeather && <p>Probability of precipitation: {currentWeather.current.precipProb}%</p>}
Expand Down
2 changes: 2 additions & 0 deletions src/Store/store.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ import thunk from 'redux-thunk';

import homePageReducer from '../Components/Pages/HomePage/homePageReducer';
import geoReducer from './reducers/geoReducer';
import detailedForecastPageReducer from '../Components/Pages/DetailedForesastPage/detailedForecastPageReducer';

const rootReducer = combineReducers({
homePage: homePageReducer,
detailedForecastPage: detailedForecastPageReducer,
geoData: geoReducer
});

Expand Down