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,046 changes: 22,508 additions & 24,538 deletions package-lock.json

Large diffs are not rendered by default.

9 changes: 8 additions & 1 deletion 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",
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

lots of packages missing

"axios": "^1.4.0",
"bootstrap": "^5.3.0",
"react": "^17.0.2",
"react-bootstrap": "^2.7.4",
"react-bootstrap-validation": "^0.1.11",
"react-dom": "^17.0.2",
"react-scripts": "4.0.3",
"react-redux": "^8.1.0",
"react-scripts": "^2.1.3",
"react-sparklines": "^1.7.0",
"redux": "^4.2.1",
"web-vitals": "^1.1.1"
},
"scripts": {
Expand Down
41 changes: 23 additions & 18 deletions src/App.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,30 @@
import logo from './logo.svg';
import './App.css';
import React from 'react';
import { Container } from 'react-bootstrap';
import Row from 'react-bootstrap/Row';
import Col from 'react-bootstrap/Col';
import Header from './components/header';
import CitySearch from './components/city-search';
import CreateDisplay from './components/weather-display';
import 'bootstrap/dist/css/bootstrap.min.css';

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-item-center'>
<Row className='ms-5'>
<Col>
<CitySearch />
<Header />
<CreateDisplay/>
</Col>
</Row>
</Container>
)


}



export default App;
26 changes: 26 additions & 0 deletions src/actions/actions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import axios from "axios";
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

axios is missing from your package.json


export const FETCH_WEATHER = "FETCH_WEATHER";
export const FETCH_AVERAGE = "FETCH_AVERAGE";

export function fetchWeather(city) {
return async (dispatch) => {
try {
const response = await axios.get(`https://api.openweathermap.org/data/2.5/forecast?q=${city}&appid=40a22fcb01995614a7b68804376359eb`);
dispatch({
type: FETCH_WEATHER,
payload: response.data
});
} catch (error) {
// Handle error here
console.log(error);
}
};
}

export function fetchAvg(math) {
return {
type: FETCH_AVERAGE,
payload: math
};
}
31 changes: 31 additions & 0 deletions src/components/city-search.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { fetchWeather } from "../actions/actions";
import { useState } from "react";
import { useDispatch } from "react-redux";
import { Container } from 'react-bootstrap';
import Row from 'react-bootstrap/Row';
import Col from 'react-bootstrap/Col';


const CitySearch = () => {
const [city, citySet] = useState('');
const dispatch = useDispatch('');

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

return (
<Container>
<Row>
<Col>
<input className="form-control" type="text" placeholder="City" aria-label="City" value={city} onChange={(e) => citySet(e.target.value)}/>
<button type="button" onClick={handleWeatherDisplay} class="btn btn-primary">Submit</button>
</Col>
</Row>
</Container>
)

}


export default CitySearch;
21 changes: 21 additions & 0 deletions src/components/header.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import React from 'react'
import { Container } from 'react-bootstrap';
import Row from 'react-bootstrap/Row';
import Col from 'react-bootstrap/Col';



const Header = () => {
return (
<Container>
<Row className='table table-bordered align-items-center my-5 mx-5'>
<Col><h5 style={{textAlign: "center"}}>City</h5></Col>
<Col><h5 style={{textAlign: "center"}}>Temperature(F)</h5></Col>
<Col><h5 style={{textAlign: "center"}}>Pressure(hPa)</h5></Col>
<Col><h5 style={{textAlign: "center"}}>Humidity(%)</h5></Col>
</Row>
</Container>
);
};

export default Header;
69 changes: 69 additions & 0 deletions src/components/weather-display.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
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 WeatherDisplay = () => {
const weather = useSelector((state) => state.weather);

const handleAvg = (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 handleWeatherDisplay = () => {
let data = [];
let cityName = '';

if (weather.length >= 1) {
weather.forEach((city) => {
let cityInfo = [];
for (const key in city) {
if (key === 'name') {
cityName = <Col key={key} style={{ textAlign: 'center' }}>{city[key]}</Col>;
} else {
cityInfo.push(
<Col key={key}>
<Sparklines data={city[key]}>
<SparklinesLine />
<SparklinesReferenceLine type="avg" />
</Sparklines>
<div key={`${city.name}-${key}`} style={{ textAlign: 'center' }}>
{handleAvg(city[key], key)}
</div>
</Col>
);
}
}
data.push(
<Row key={city.name} className="align-items-center mt-4 ms-4">
{cityName}
{cityInfo}
</Row>
);
});
}

return data;
};

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

export default WeatherDisplay;
16 changes: 11 additions & 5 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,21 @@ import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import promise from 'redux-promise';
import { configureStore, applyMiddleware } from 'redux';
import { Provider } from 'react-redux';
import rootReducer from './reducers/rootReducer'; // Import your root reducer

const createStoreWithMiddleware = applyMiddleware(promise)(configureStore);
const store = createStoreWithMiddleware(rootReducer); // Create the Redux store with the root reducer

ReactDOM.render(
<React.StrictMode>
<App />
<Provider store={store}>
<App />
</Provider>
</React.StrictMode>,
document.getElementById('root')
);

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();
reportWebVitals();
37 changes: 37 additions & 0 deletions src/store/reducers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { FETCH_WEATHER } from "../actions/actions";

const cityReducer = function (state = [], action) {
switch (action.type) {
case FETCH_WEATHER:
let temperature = [];
let humidity = [];
let pressure = [];
let cityName = '';

action.payload.data.list.forEach((section) => {
temperature.push(section.main.temp);
humidity.push(section.main.humidity);
pressure.push(section.main.pressure);
cityName = action.payload.data.cityName;
});

temperature = temperature.map((day) => Math.round((day - 273) * (9 / 5) + 32));
humidity = humidity.map((day) => Math.round(day));
pressure = pressure.map((day) => Math.round(day));

return [
{
cityName,
temperature,
humidity,
pressure
},
...state
];

default:
return state;
}
};

export default cityReducer;