Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Marina's Bigfoot JSON frontend #37

Open
wants to merge 16 commits into
base: main
Choose a base branch
from
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
1,022 changes: 1,008 additions & 14 deletions package-lock.json

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,13 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"@emotion/react": "^11.11.3",
"@emotion/styled": "^11.11.0",
"@mui/material": "^5.15.7",
"axios": "^1.6.7",
"react": "^18.1.0",
"react-dom": "^18.1.0",
"react-router-dom": "^6.21.3",
"react-scripts": "5.0.1"
},
"scripts": {
Expand Down
22 changes: 21 additions & 1 deletion src/App.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
body {
margin: 0;
padding: 0;
background-color: #282c34;
}

.App {
text-align: center;
}
Expand All @@ -8,7 +14,6 @@
}

.App-header {
background-color: #282c34;
min-height: 100vh;
display: flex;
flex-direction: column;
Expand All @@ -17,3 +22,18 @@
font-size: calc(10px + 2vmin);
color: white;
}

.page-title {
color: aliceblue;
}

.input {
line-height: 30px;
height: 30px;
}

.query {
color: aliceblue;
display: flex;
justify-content: center;
}
40 changes: 34 additions & 6 deletions src/App.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,48 @@
import React from "react";
import logo from "./logo.png";
import bigfoot from "./bigfoot.png";
import "./App.css";
import { Button } from "@mui/material";
import { useNavigate, Link } from "react-router-dom";

function AppWrapper() {
const navigate = useNavigate();

return <App navigate={navigate} />;
}

class App extends React.Component {
handleClick = () => {
const navigate = this.props.navigate;
navigate("/sightings");
};

linkStyle = {
textDecoration: "none",
color: "white",
};
Comment on lines +19 to +22
Copy link

Choose a reason for hiding this comment

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

could use your css file for this


render() {
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>
<h1>Bigfoot sightings</h1>
<img src={bigfoot} className="bigfoot" alt="bigfoot" width={400} />
<Link to={"/sightings"} style={this.linkStyle}>
<h4>Click here to view Bigfoot sightings</h4>
</Link>
<Button
variant="standard"
sx={{ backgroundColor: "orange" }}
onClick={this.handleClick}
>
View sightings
</Button>
</header>
</div>
);
}
}

export default App;
// export default App;

export default AppWrapper;
26 changes: 26 additions & 0 deletions src/Components/GoBackButton.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import React from "react";
import { useNavigate } from "react-router-dom";
import { Button } from "@mui/material";

export default function GoBackButton() {
const navigate = useNavigate();
const handleGoBack = () => {
navigate(-1);
};

return (
<div>
<Button
variant="standard"
sx={{
backgroundColor: "orange",
marginTop: 1,
marginLeft: 1,
}}
onClick={handleGoBack}
>
Go back
</Button>
</div>
);
}
43 changes: 43 additions & 0 deletions src/Components/SearchPage.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import React from "react";
import { Container } from "@mui/material";

export default function SearchPage(props) {
const handleSubmit = (e) => {
e.preventDefault();
const form = e.target;
const query = form.search.value;
Comment on lines +7 to +8
Copy link

Choose a reason for hiding this comment

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

why not e.target.form.search.value? :D


if (isNaN(query)) {
props.setSearchParams({ state: query });
} else {
props.setSearchParams({ year: query });
}
Comment on lines +10 to +14
Copy link

Choose a reason for hiding this comment

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

not bad, validating data type here. But why is NaN equal to state?

};

return (
<div>
<p className="query">
Make your query either by year or by the name of a US state.{" "}
</p>
<Container
sx={{
display: "flex",
justifyContent: "center",
marginTop: 3,
marginBottom: 3,
Comment on lines +24 to +27
Copy link

Choose a reason for hiding this comment

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

use your css file for this

}}
>
<form onSubmit={handleSubmit}>
<input
type="search"
name="search"
size="35"
className="input"
placeholder="Enter a year/state name"
></input>
<input type="submit" value="Search" className="input"></input>
</form>
</Container>
</div>
);
}
60 changes: 60 additions & 0 deletions src/Components/SightingPage.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import React from "react";
import { useParams } from "react-router-dom";
import { useEffect, useState } from "react";
import axios from "axios";
import { Card, CardContent } from "@mui/material";
import GoBackButton from "./GoBackButton";
import { BACKEND_URL } from "../constants.js";

export default function SightingPage() {
const { REPORT_NUMBER } = useParams();
const [sighting, setSighting] = useState();
useEffect(() => {
const fetchSightingData = async () => {
try {
const data = await axios.get(
`${BACKEND_URL}/sightings/${REPORT_NUMBER}`
Copy link

Choose a reason for hiding this comment

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

what if report number is undefined or a number? you will still make a request

);
setSighting(data.data);
} catch (error) {
console.log(error);
}
};
fetchSightingData();
}, [REPORT_NUMBER]);

const newSighting = sighting ? (
<Card
sx={{
width: 800,
minHeight: 300,
display: "flex",
justifyContent: "center",
marginTop: 20,
marginLeft: "auto",
marginRight: "auto",
Comment on lines +29 to +35
Copy link

Choose a reason for hiding this comment

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

cssssssss

}}
>
<CardContent>
<h4>
{sighting.STATE} {sighting.YEAR}
</h4>
<p>Season: {sighting.SEASON}</p>
<p>
Date: {sighting.MONTH} {sighting.DATE}{" "}
</p>
<p>County: {sighting.COUNTY}</p>
<p>Location: {sighting.LOCATION_DETAILS}</p>
<p>{sighting.OBSERVED}</p>
<p>Report number: {sighting.REPORT_NUMBER}</p>
</CardContent>
Comment on lines +38 to +50
Copy link

Choose a reason for hiding this comment

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

This could almost be a separate component imo

</Card>
) : null;
Copy link

Choose a reason for hiding this comment

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

no need for ternary operator. Just use sighting && (insert html here)


return (
<div className="sighting-page">
<GoBackButton />
{newSighting}
</div>
);
}
78 changes: 78 additions & 0 deletions src/Components/SightingsList.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import React from "react";
import { useState, useEffect } from "react";
import axios from "axios";
import Card from "@mui/material/Card";
import { CardContent, Container } from "@mui/material";
import { Link, useSearchParams } from "react-router-dom";
import GoBackButton from "./GoBackButton";
import { BACKEND_URL } from "../constants.js";
import SearchPage from "./SearchPage.js";

export default function SightingsList() {
const [sightings, setSightings] = useState([]);
const [searchParams, setSearchParams] = useSearchParams();
const stateQuery = searchParams.get("state") || "";
const yearQuery = searchParams.get("year") || "";

useEffect(() => {
const fetchData = async () => {
try {
const query = {};
if (stateQuery) {
query.state = stateQuery;
}
if (yearQuery) {
query.year = yearQuery;
}
const { data } = await axios.get(`${BACKEND_URL}/sightings`, {
params: query,
});
Comment on lines +20 to +29
Copy link

Choose a reason for hiding this comment

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

Suggested change
const query = {};
if (stateQuery) {
query.state = stateQuery;
}
if (yearQuery) {
query.year = yearQuery;
}
const { data } = await axios.get(`${BACKEND_URL}/sightings`, {
params: query,
});
const { data } = await axios.get(`${BACKEND_URL}/sightings`, {
params: {
...(stateQuery && { state: stateQuery}),
...(yearQuery && {year: yearQuery}),
},
});

setSightings(data);
} catch (error) {
console.log(error);
}
};
fetchData();
}, [stateQuery, yearQuery]);

console.log(sightings);
Copy link

Choose a reason for hiding this comment

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

remove logs


const newSightings = sightings.map((sighting, index) =>
sighting.YEAR && sighting.STATE ? (
<Link to={`./${sighting.REPORT_NUMBER}`} key={index}>
<Container
sx={{
display: "flex",
justifyContent: "center",
}}
>
<Card sx={{ marginBottom: 3, width: 300 }}>
<CardContent sx={{ display: "flex", justifyContent: "flex-start" }}>
<p>
{index + 1}. {sighting.STATE} {sighting.YEAR}
Copy link

Choose a reason for hiding this comment

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

the index + 1 doesnt make much sense here. Would put into variable

</p>
</CardContent>
</Card>
</Container>
</Link>
Comment on lines +42 to +57
Copy link

Choose a reason for hiding this comment

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

Should make this whole thing a component

) : null
Copy link

Choose a reason for hiding this comment

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

no need for ternary operator when using null for else. Just use && shorthand

);

return (
<div>
<GoBackButton />
<Container
sx={{
display: "flex",
justifyContent: "center",
marginTop: 3,
marginBottom: 3,
}}
>
<h1 className="page-title">Bigfoot sightings</h1>
</Container>
<SearchPage setSearchParams={setSearchParams} />
{newSightings}
</div>
);
}
Binary file added src/bigfoot.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions src/constants.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const BACKEND_URL = "http://localhost:3000";
16 changes: 15 additions & 1 deletion src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,20 @@ import React from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
import App from "./App";
import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
import SightingPage from "./Components/SightingPage";
import SightingsList from "./Components/SightingsList";

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<App />);
root.render(
<Router>
<Routes>
<Route path="/" element={<App />}></Route>
<Route path="/sightings">
<Route index element={<SightingsList />}></Route>
<Route path=":REPORT_NUMBER" element={<SightingPage />}></Route>
</Route>
<Route path="*" element={"Sorry, page not found!"} />
</Routes>
</Router>
);