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
806 changes: 774 additions & 32 deletions package-lock.json

Large diffs are not rendered by default.

7 changes: 7 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,16 @@
"@testing-library/jest-dom": "^5.11.10",
"@testing-library/react": "^11.2.6",
"@testing-library/user-event": "^12.8.3",
"axios": "^0.24.0",
"bootstrap": "^5.2.3",
"react": "^17.0.2",
"react-bootstrap": "^2.7.0",
"react-dom": "^17.0.2",
"react-redux": "^8.0.5",
"react-scripts": "4.0.3",
"react-sparklines": "^1.7.0",
"redux": "^4.2.0",
"redux-promise": "^0.6.0",
"web-vitals": "^1.1.1"
},
"scripts": {
Expand Down
5 changes: 2 additions & 3 deletions src/App.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@
text-align: center;
}

.App-logo {
height: 40vmin;
pointer-events: none;
.top-header {
text-align: "center" !important;
}

@media (prefers-reduced-motion: no-preference) {
Expand Down
46 changes: 27 additions & 19 deletions src/App.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,33 @@
import logo from './logo.svg';
import React from 'react'
import CreateDisplay from './components/Create-Display';
import InputCity from './components/Input-City';
import Header from './components/Header';
import Row from 'react-bootstrap/Row';
import Col from 'react-bootstrap/Col';
import { Container } from 'react-bootstrap';
import './App.css';

function App() {




function App () {



return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
</div>
);
<Container className='align-items-center'>
<Row className='ms-5 me-5'>
<Col>
<InputCity />
<Header />
<CreateDisplay />
</Col>
</Row>
</Container>
)
}

export default App;

//the issue we are having is that useEffect is going before everything else in Display-Humidity. So we can't get it to wait till we type something in for state we are screwed.
26 changes: 26 additions & 0 deletions src/action-creators/actions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import axios from "axios";
export const FETCH_WEATHER = 'FETCH_WEATHER';
export const FETCH_AVERAGE = 'FETCH_AVERAGE'


export function fetchWeather (city) {

const query = axios.get(`https://api.openweathermap.org/data/2.5/forecast?q=${city}&appid=651b4326c31add8e66f753623aae609d`)

return {
type: FETCH_WEATHER,
payload: query
};
}

export function fetchAverage (data, measurement) {

return {
type: FETCH_AVERAGE,
payload: {
measurement,
data
}
}
}

61 changes: 61 additions & 0 deletions src/components/Create-Display.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { useSelector } from "react-redux";
import { Sparklines, SparklinesLine, SparklinesReferenceLine } from 'react-sparklines';
import Container from 'react-bootstrap/Container';
import Row from 'react-bootstrap/Row';
import Col from 'react-bootstrap/Col';

const CreateDisplay = () => {
let weather = useSelector((state) => state.weather);

const handleAverage = (data, measurement) => {
const average = array => array.reduce((a, b) => a+b) / array.length
let correct = 0;

if(measurement === 'temperature') {
correct = Math.round(average(data))
return <h6>{correct}&deg;F</h6>
} else if (measurement === 'pressure') {
correct = Math.round(average(data))
return <h6>{correct} <small>hPa</small></h6>
} else if (measurement === 'humidity') {
correct = Math.round(average(data))
return <h6>{correct}%</h6>
};
}

const handleDisplay = () => {
console.log(weather[0])
let data = [];
let cityName = '';
if(weather.length >= 1) {
weather.map((city, index) => {
let cityInfo = [];
for (const key in city) {
if(key === 'name') {
cityName = <Col key={index.toString()} style={{textAlign: 'center'}}>{city[key]}</Col>
} else {
cityInfo.push(
<Col key={city.id}>
<Sparklines data={city[key]}>
<SparklinesLine />
<SparklinesReferenceLine type="avg" />
</Sparklines>
<div key={city.toString()} style={{textAlign: 'center'}}>{handleAverage(city[key], key)}</div>
</Col>
)
}
}
data.push(<Row className="align-items-center mt-5 ms-5">{cityName}{cityInfo}</Row>)
})
};
return data;
}

return (
<Container>
{handleDisplay()}
</Container>
);
}

export default CreateDisplay;
19 changes: 19 additions & 0 deletions src/components/Header.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import Container from 'react-bootstrap/Container';
import Row from 'react-bootstrap/Row';
import Col from 'react-bootstrap/Col';


const Header = () => {
return (
<Container className='top-header align-items-center'>
<Row className='mt-5 ms-5'>
<Col><h6 style={{textAlign: 'center'}}>City</h6></Col>
<Col><h6 style={{textAlign: 'center'}}>Temperature(F)</h6></Col>
<Col><h6 style={{textAlign: 'center'}}>Pressure(hPa)</h6></Col>
<Col><h6 style={{textAlign: 'center'}}>Humidity(%)</h6></Col>
</Row>
</Container>
)
}

export default Header
60 changes: 60 additions & 0 deletions src/components/Input-City.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { useSelector, useDispatch } from "react-redux";
import { fetchWeather } from '../action-creators/actions';
import { useState } from 'react'
import 'bootstrap/dist/css/bootstrap.min.css';
import Button from 'react-bootstrap/Button';
import Form from 'react-bootstrap/Form';
import InputGroup from 'react-bootstrap/InputGroup';
import Col from 'react-bootstrap/Col';
import Row from 'react-bootstrap/Row';
import Container from 'react-bootstrap/Container';

const InputCity = () => {
const [city, setCity] = useState('');
const dispatch = useDispatch();

const handleDisplay = () => {
dispatch(fetchWeather(city))
}

return(
<Container>
<h1 style={{textAlign: 'center'}}>Redux Weather</h1>
<Row className="justify-content-md-center mt-4" xs={1} md={2} gap={3}>
<Col >
<InputGroup className="mb-3">
<Form.Control
placeholder="City..."
aria-label="City"
aria-describedby="basic-addon2"
value={city}
onChange={(e) => setCity(e.target.value)}
/>
<Button variant="primary" id="button-addon2" onClick={handleDisplay}>
Button
</Button>
</InputGroup>
</Col>
</Row>
</Container>

)
}

export default InputCity;

// it loops through weather looking for the property humidity. It returns an array with that object and then we use map to display the data.




// if(weather.length === 3) {
// const humidityData = weather.filter((measurement) => {
// measurement.hasOwnProperty('humidity')
// return measurement.humidity;
// });

// if(humidityData) {
// return humidityData[0].humidity.map((data) => <li>{data}</li>);
// }
// } else (console.log('wait'))
11 changes: 10 additions & 1 deletion src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,19 @@ import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import promise from 'redux-promise';

import { Provider } from 'react-redux';
import { createStore, applyMiddleware } from 'redux';
import rootReducer from './store/combine-reducers'

const createStoreWithMiddleware = applyMiddleware(promise)(createStore)

ReactDOM.render(
<React.StrictMode>
<App />
<Provider store={createStoreWithMiddleware(rootReducer)}>
<App />
</Provider>
</React.StrictMode>,
document.getElementById('root')
);
Expand Down
8 changes: 8 additions & 0 deletions src/store/combine-reducers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { combineReducers } from "redux";
import citiesReducer from "./reducers";

const rootReducer = combineReducers({
weather: citiesReducer,
});

export default rootReducer;
34 changes: 34 additions & 0 deletions src/store/reducers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { FETCH_WEATHER } from "../action-creators/actions";

const citiesReducer = function (state = [], action) {
switch(action.type) {
case FETCH_WEATHER:
let temperature = [];
let pressure = [];
let humidity = [];
let name = ''
action.payload.data.list.map((section, index) => {
temperature.push(section.main.temp)
pressure.push(section.main.pressure)
humidity.push(section.main.humidity)
name = action.payload.data.city.name
});
temperature = temperature.map((day) => Math.round(((day) - 273.15) * (9/5) + 32))
pressure = pressure.map((day) => Math.round((day)))
humidity = humidity.map((day) => Math.round((day)))

return [{
name, temperature, pressure, humidity
}, ...state]

default:
return state;
};


};

export default citiesReducer;



78 changes: 78 additions & 0 deletions src/store/trial.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// switch(action.type) {
// case FETCH_TEMP:
// let dayOne = 0
// let dayTwo = 0
// let dayThree = 0
// let dayFour = 0
// let dayFive = 0
// let temper = [];
// action.payload.data.list.forEach((section, index) => {
// if(index <= 7){
// dayOne = dayOne + section.main.temp
// } else if (index > 7 && index <= 15) {
// dayTwo = dayTwo + section.main.temp
// } else if (index > 15 && index <= 23) {
// dayThree = dayThree + section.main.temp
// } else if (index > 23 && index <= 31) {
// dayFour = dayFour + section.main.temp
// } else if (index > 31 && index <= 40) {
// dayFive = dayFive + section.main.temp
// }
// });
// temper.push((dayOne/8), (dayTwo/8), (dayThree/8), (dayFour/8), (dayFive/8));
// const temperature = temper.map((day) => Math.round(((day-273.15)*(9/5)+32)))
// return [{temp: temperature, ...state}]

// case FETCH_PRESSURE:
// let dayOneP = 0
// let dayTwoP = 0
// let dayThreeP = 0
// let dayFourP = 0
// let dayFiveP = 0
// let press = [];
// action.payload.data.list.forEach((section, index) => {
// if(index <= 7){
// dayOneP = dayOneP + section.main.pressure
// } else if (index > 7 && index <= 15) {
// dayTwoP = dayTwoP + section.main.pressure
// } else if (index > 15 && index <= 23) {
// dayThreeP = dayThreeP + section.main.pressure
// } else if (index > 23 && index <= 31) {
// dayFourP = dayFourP + section.main.pressure
// } else if (index > 31 && index <= 40) {
// dayFiveP = dayFiveP + section.main.pressure
// }
// });
// press.push((dayOneP/8), (dayTwoP/8), (dayThreeP/8), (dayFourP/8), (dayFiveP/8));
// const pressure = press.map((day) => Math.round(day));
// return [{pressure: pressure, ...state}]

// case FETCH_HUMIDITY:
// let dayOneH = 0
// let dayTwoH = 0
// let dayThreeH = 0
// let dayFourH = 0
// let dayFiveH = 0
// let hum = [];
// action.payload.data.list.forEach((section, index) => {
// if(index <= 7){
// dayOneH = dayOneH + section.main.humidity
// } else if (index > 7 && index <= 15) {
// dayTwoH = dayTwoH + section.main.humidity
// } else if (index > 15 && index <= 23) {
// dayThreeH = dayThreeH + section.main.humidity
// } else if (index > 23 && index <= 31) {
// dayFourH = dayFourH + section.main.humidity
// } else if (index > 31 && index <= 40) {
// dayFiveH = dayFiveH + section.main.humidity
// }
// });
// hum.push((dayOneH/8), (dayTwoH/8), (dayThreeH/8), (dayFourH/8), (dayFiveH/8));
// const humidity = hum.map((day) => Math.round(day))
// return [{humidity: humidity, ...state}]

// case FETCH_ALL:
// return [{word: action.payload, ...state}]
// default:
// return state;
// };