diff --git a/.gitignore b/.gitignore index 8f322f0..e842897 100644 --- a/.gitignore +++ b/.gitignore @@ -25,7 +25,7 @@ yarn-debug.log* yarn-error.log* # local env files -.env*.local +# .env*.local # vercel .vercel @@ -33,3 +33,5 @@ yarn-error.log* # typescript *.tsbuildinfo next-env.d.ts +app/layout.js +app/page.js diff --git a/app/components/CityList.tsx b/app/components/CityList.tsx new file mode 100644 index 0000000..3a12561 --- /dev/null +++ b/app/components/CityList.tsx @@ -0,0 +1,193 @@ +import React from 'react'; +import { useSelector, useDispatch } from 'react-redux'; +import { Sparklines, SparklinesLine, SparklinesReferenceLine } from 'react-sparklines'; +import { removeSearchedCity } from '../store/slice/weatherSlice'; +import { RootState } from '../store/rootReducer'; + +const CityList = () => { + const dispatch = useDispatch(); + const searchedCities = useSelector((state: RootState) => state.weather.searchedCities); + + const getChartData = (list: any[], field: string) => { + return list.map(item => item.main[field]); + }; + + const calculateAverage = (data: number[]) => { + const sum = data.reduce((a, b) => a + b, 0); + return Math.round(sum / data.length); + }; + + return ( +
+

Searched Cities

+ {searchedCities.map((cityData) => ( +
+
+
+

{cityData.city.name}

+ {cityData.city.country && ( + {cityData.city.country} + )} +
+ +
+ +
+
+

Temperature (°F)

+ + + + +
+ Average: {calculateAverage(getChartData(cityData.list, 'temp'))}°F +
+
+ +
+

Pressure (hPa)

+ + + + +
+ Average: {calculateAverage(getChartData(cityData.list, 'pressure'))} hPa +
+
+ +
+

Humidity (%)

+ + + + +
+ Average: {calculateAverage(getChartData(cityData.list, 'humidity'))}% +
+
+
+
+ ))} + + +
+ ); +}; + +export default CityList; diff --git a/app/components/ReduxProvider.tsx b/app/components/ReduxProvider.tsx new file mode 100644 index 0000000..ec582c3 --- /dev/null +++ b/app/components/ReduxProvider.tsx @@ -0,0 +1,15 @@ +'use client'; + +import React from 'react'; +import { Provider } from 'react-redux'; +import { store } from '../store/configStore'; + +interface ReduxProviderProps { + children: React.ReactNode; +} + +const ReduxProvider: React.FC = ({ children }) => { + return {children}; +}; + +export default ReduxProvider; diff --git a/app/components/WeatherChart.tsx b/app/components/WeatherChart.tsx new file mode 100644 index 0000000..c2128e0 --- /dev/null +++ b/app/components/WeatherChart.tsx @@ -0,0 +1,28 @@ +import React from 'react'; +import { Sparklines, SparklinesLine, SparklinesCurve, SparklinesReferenceLine } from 'react-sparklines'; + +interface WeatherChartProps { + data: number[]; + color: string; + unit: string; + title: string; +} + +const WeatherChart: React.FC = ({ data, color, unit, title }) => { + const average = data.reduce((sum, value) => sum + value, 0) / data.length; + + return ( +
+

{title}

+ + + + +
+ Average: {average.toFixed(2)} {unit} +
+
+ ); +}; + +export default WeatherChart; diff --git a/app/components/WeatherMap.tsx b/app/components/WeatherMap.tsx new file mode 100644 index 0000000..4b31483 --- /dev/null +++ b/app/components/WeatherMap.tsx @@ -0,0 +1,114 @@ +import React from 'react'; +import Image from 'next/image'; +import { useSelector, useDispatch } from 'react-redux'; +import { fetchWeatherData } from '../store/slice/weatherSlice'; +import { WeatherState } from '../types/weather'; +import { AppDispatch } from '../store/configStore'; + +interface WeatherMapProps { + lat: number; + lon: number; +} + +const WeatherMap: React.FC = ({ lat, lon }) => { + const dispatch = useDispatch(); + const { nearbyCities } = useSelector((state: { weather: WeatherState }) => state.weather); + + const handleCityClick = (cityName: string) => { + dispatch(fetchWeatherData(cityName)); + }; + + return ( +
+