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
47 changes: 47 additions & 0 deletions app/components/renderHumidity.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { useSelector } from "react-redux";
import { WeatherData, WeatherContainer } from "../store/slices/weather";
import {
Sparklines,
SparklinesLine,
SparklinesReferenceLine,
} from "react-sparklines";

export default function RenderHumidity() {
const conditions = useSelector((state: WeatherData) => state.weather.weather); //pulls current state in redux store

const findHumidity = (condition: WeatherContainer) => {
return condition?.list?.map?.(
(weather: WeatherContainer) => weather.main.humidity
); //takes the humidity over the next 5 days
};

return (
<div className="text-center">
{conditions?.map((condition: WeatherContainer, index: number) => {
const humidityArray = findHumidity(condition); //sets that humidity in an array

const sum = humidityArray?.reduce(
(accumulator: number, currentValue: number) => {
return accumulator + currentValue;
},
0
);
const averageTotal = sum / humidityArray?.length; //finds average humidity
const humidityAverage = Math.round(averageTotal); //rounds to whole number

if (condition === undefined) {
return; //if no conditions are passed through, do not return anything
}
return (
<div key={index} className="my-4">
<Sparklines data={humidityArray}>
<SparklinesLine color="green" />
<SparklinesReferenceLine type="mean" />
</Sparklines>
<p>{humidityAverage}%</p>
</div>
);
})}
</div>
);
}
47 changes: 47 additions & 0 deletions app/components/renderPressure.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { useSelector } from "react-redux";
import { WeatherData, WeatherContainer } from "../store/slices/weather";
import {
Sparklines,
SparklinesLine,
SparklinesReferenceLine,
} from "react-sparklines";

export default function RenderPressure() {
const conditions = useSelector((state: WeatherData) => state.weather.weather); //pulls current state in redux store

const findPressure = (condition: WeatherContainer) => {
return condition?.list?.map?.(
(weather: WeatherContainer) => weather.main.pressure
); //takes the pressure over the next 5 days
};

return (
<div className="text-center">
{conditions?.map((condition: WeatherContainer, index: number) => {
const pressureArray = findPressure(condition); //sets that pressure in an array

const sum = pressureArray?.reduce(
(accumulator: number, currentValue: number) => {
return accumulator + currentValue;
},
0
);
const averageTotal = sum / pressureArray?.length; //finds average pressure
const pressureAverage = Math.round(averageTotal); //rounds to whole number

if (condition === undefined) {
return; //if no conditions are passed through, do not return anything
}
return (
<div key={index} className="my-4">
<Sparklines data={pressureArray}>
<SparklinesLine color="red" />
<SparklinesReferenceLine type="mean" />
</Sparklines>
<p>{pressureAverage}hPa</p>
</div>
);
})}
</div>
);
}
47 changes: 47 additions & 0 deletions app/components/renderTemp.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { useSelector } from "react-redux";
import { WeatherData, WeatherContainer } from "../store/slices/weather";
import {
Sparklines,
SparklinesLine,
SparklinesReferenceLine,
} from "react-sparklines";

export default function RenderTemp() {
const conditions = useSelector((state: WeatherData) => state.weather.weather); //pulls current state in redux store

const findTemp = (condition: WeatherContainer) => {
return condition?.list?.map?.(
(weather: WeatherContainer) => weather.main.temp
); //takes the temperature over the next 5 days
};

return (
<div className="text-center">
{conditions?.map((condition: WeatherContainer, index: number) => {
const tempArray = findTemp(condition); //sets that temp in an array

const sum = tempArray?.reduce(
(accumulator: number, currentValue: number) => {
return accumulator + currentValue;
},
0
);
const averageTotal = sum / tempArray?.length; //finds average temperature
const tempAverage = Math.round(averageTotal); //rounds to whole number

if (condition === undefined) {
return; //if no conditions are passed through, do not return anything
}
return (
<div key={index} className="my-4">
<Sparklines data={tempArray}>
<SparklinesLine color="blue" />
<SparklinesReferenceLine type="mean" />
</Sparklines>
<p>{tempAverage}ºF</p>
</div>
);
})}
</div>
);
}
27 changes: 27 additions & 0 deletions app/components/renderWeather.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import RenderHumidity from "./renderHumidity";
import RenderPressure from "./renderPressure";
import RenderTemp from "./renderTemp";
import SearchCity from "./searchCity";

const RenderWeather = () => {
return (
<div className="container-fluid">
<div className="row">
<div className="col-md-3">
<SearchCity />
</div>
<div className="col-md-3">
<RenderTemp />
</div>
<div className="col-md-3">
<RenderHumidity />
</div>
<div className="col-md-3">
<RenderPressure />
</div>
</div>
</div>
);
};

export default RenderWeather;
39 changes: 39 additions & 0 deletions app/components/searchBar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
"use client";
import styles from "../page.module.css";
import { useState } from "react";
import { useDispatch } from "react-redux";
import { fetchLocation } from "../store/slices/locations";
import { AppDispatch } from "../store/configureStore";

interface SearchBarProps {
placeholder: string;
}

const SearchBar = ({ placeholder}: SearchBarProps): JSX.Element => {
const dispatch = useDispatch<AppDispatch>(); //allows store to listen to events
const [query, setQuery] = useState<string>(""); //allows query to be set as state

const handleSubmit = (e: React.FormEvent<HTMLFormElement>): void => {
e.preventDefault(); //prevents running default requests when submitted
setQuery(""); //reverts to empty search field
dispatch(fetchLocation(query));
};
return (
<div className="text-center">
<form onSubmit={handleSubmit}>
<input
placeholder={placeholder}
value={query}
onChange={(e: React.ChangeEvent<HTMLInputElement>): void => {
setQuery(e.target.value);
}}
/>
<button className={styles.button} type="submit">
Search
</button>
</form>
</div>
);
};

export default SearchBar;
34 changes: 34 additions & 0 deletions app/components/searchCity.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
"use client";
import { useSelector, useDispatch } from "react-redux";
import { LocationParams } from "../store/slices/locations";
import { useEffect } from "react";
import { AppDispatch } from "../store/configureStore";
import { fetchWeather } from "../store/slices/weather";

export default function SearchCity() {
const locations = useSelector(
(state: LocationParams) => state.location.location
);

const dispatch = useDispatch<AppDispatch>();
useEffect(() => {
dispatch(fetchWeather(locations));
}, [dispatch, locations]);

return locations?.map((location: LocationParams, index: number) => {
if (locations[locations.length - 1][0] === undefined) {
alert("Please enter a valid city name");
return;
// trying to address edge casing or invalid entry, alert is mapped in response but I could not figure out how to only alert once.
}
return (
<div key={index} className="text-center">
<br />
<br />
<p>{location[location.length - 1].name}</p>
<br />
<br />
</div>
);
});
}
6 changes: 3 additions & 3 deletions app/globals.css
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
:root {
--max-width: 1100px;
--border-radius: 12px;
--font-mono: ui-monospace, Menlo, Monaco, 'Cascadia Mono', 'Segoe UI Mono',
'Roboto Mono', 'Oxygen Mono', 'Ubuntu Monospace', 'Source Code Pro',
'Fira Mono', 'Droid Sans Mono', 'Courier New', monospace;
--font-mono: ui-monospace, Menlo, Monaco, "Cascadia Mono", "Segoe UI Mono",
"Roboto Mono", "Oxygen Mono", "Ubuntu Monospace", "Source Code Pro",
"Fira Mono", "Droid Sans Mono", "Courier New", monospace;

--foreground-rgb: 0, 0, 0;
--background-start-rgb: 214, 219, 220;
Expand Down
14 changes: 7 additions & 7 deletions app/layout.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import './globals.css'
import { Inter } from 'next/font/google'
'use client'
import { Inter } from 'next/font/google';
import { Provider } from 'react-redux';
import store from './store/configureStore';

const inter = Inter({ subsets: ['latin'] })

export const metadata = {
title: 'Create Next App',
description: 'Generated by create next app',
}

export default function RootLayout({ children }) {
return (
<html lang="en">
<body className={inter.className}>{children}</body>
<body className={inter.className}>
<Provider store={store}>{children}</Provider>
</body>
</html>
)
}
95 changes: 0 additions & 95 deletions app/page.js

This file was deleted.

Loading