Skip to content

Commit f326eba

Browse files
committed
added new feature and fixed previous ones
1 parent d3e74c5 commit f326eba

28 files changed

+1554
-468
lines changed

client/package-lock.json

Lines changed: 316 additions & 32 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

client/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
"private": true,
55
"proxy": "http://localhost:3000",
66
"dependencies": {
7+
"@material-ui/core": "^4.12.4",
78
"@testing-library/jest-dom": "^5.16.5",
89
"@testing-library/react": "^13.4.0",
910
"@testing-library/user-event": "^13.5.0",

client/src/App.js

Lines changed: 59 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,83 @@
1-
import './App.css';
2-
import React, { useState, useEffect } from 'react';
3-
import { useRoutes } from 'react-router-dom'
4-
import ReadSneakers from './pages/ReadSneakers'
5-
import SneakerDetails from './pages/SneakerDetails'
6-
import CreateComment from './pages/CreateComment'
7-
import About from './pages/About'
8-
import PageNotFound from './pages/PageNotFound'
9-
10-
1+
import "./App.css";
2+
import React, { useState, useEffect } from "react";
3+
import { useRoutes } from "react-router-dom";
4+
import ReadSneakers from "./pages/ReadSneakers";
5+
import SneakerDetails from "./pages/SneakerDetails";
6+
import CreateComment from "./pages/CreateComment";
7+
import About from "./pages/About";
8+
import PageNotFound from "./pages/PageNotFound";
9+
import CartPage from "./pages/cart";
10+
import Login from "./pages/Login";
11+
import Orders from "./pages/order";
12+
import CreateSneaker from "./pages/CreateSneaker";
13+
import EditSneaker from "./pages/EditSneaker";
1114
const App = () => {
12-
15+
const API_URL = "http://localhost:3000";
1316
const [sneakers, setSneakers] = useState([]);
17+
const [user, setUser] = useState([]);
1418

1519
useEffect(() => {
1620
const fetchSneakers = async () => {
17-
const response = await fetch('/api/sneakers')
18-
const data = await response.json()
19-
setSneakers(data)
20-
}
21-
22-
fetchSneakers()
21+
const response = await fetch("/api/sneakers");
22+
const data = await response.json();
23+
setSneakers(data);
24+
};
25+
// const getUser = async () => {
26+
// const response = await fetch(`${API_URL}/auth/login/success`, {
27+
// credentials: "include",
28+
// });
29+
// const json = await response.json();
30+
// setUser(json.user);
31+
// };
32+
// getUser();
33+
fetchSneakers();
2334
}, []);
2435

2536
// Sets up routes
2637
let element = useRoutes([
38+
{
39+
path: "/login",
40+
element: <Login api_url={API_URL} />,
41+
},
42+
{
43+
path: "/orders",
44+
element: <Orders />,
45+
},
2746
{
2847
path: "/",
29-
element:<ReadSneakers data={sneakers}/>
48+
element: <ReadSneakers data={sneakers} />,
3049
},
3150
{
3251
path: "/sneaker/get/:id",
33-
element:<SneakerDetails data={sneakers}/>
52+
element: <SneakerDetails data={sneakers} />,
53+
},
54+
{
55+
path: "/reviews/create/:id",
56+
element: <CreateComment />,
3457
},
3558
{
36-
path:"/reviews/create/:sneaker_id",
37-
element: <CreateComment />
59+
path: "/new",
60+
element: <CreateSneaker />,
3861
},
3962
{
40-
path:"/about",
41-
element: <About />
63+
path: "/edit/:id",
64+
element: <EditSneaker data={sneakers} />,
4265
},
4366
{
44-
path:"/*",
45-
element: <PageNotFound />
46-
}
67+
path: "/about",
68+
element: <About />,
69+
},
70+
{
71+
path: "/cart",
72+
element: <CartPage />,
73+
},
74+
{
75+
path: "/*",
76+
element: <PageNotFound />,
77+
},
4778
]);
4879

49-
50-
return (
51-
52-
<div className="App">
53-
{element}
54-
</div>
55-
56-
);
57-
}
80+
return <div className="App">{element}</div>;
81+
};
5882

5983
export default App;
60-

client/src/components/CommentBtn.js

Lines changed: 12 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,14 @@
1-
import React, {useState} from 'react';
2-
import './CommentBtn.css'
3-
4-
const CommentBtn = (props) => {
5-
6-
const [num_votes, setNumVotes] = useState(props.num_votes)
7-
8-
const updateCount = () => {
9-
const options = {
10-
method: 'PATCH',
11-
headers: {
12-
'Content-Type': 'application/json'
13-
},
14-
body: JSON.stringify({num_votes: num_votes + 1})
15-
}
16-
17-
fetch('/api/reviews/' + props.id, options)
18-
setNumVotes((num_votes) => num_votes + 1)
19-
}
1+
import React from "react";
202

3+
const Review = ({ id, rating, reviewText }) => {
214
return (
22-
<button className='commentBtn' id={props.id} onClick={updateCount}>
23-
{num_votes + ' ❤️ ' } <br/ > <br/ > {props.reviews}
24-
</button>
25-
)
26-
27-
}
28-
29-
export default CommentBtn;
30-
5+
<div className="review">
6+
{/* <p>Review ID: {id}</p> */}
7+
<p>Rating: {rating}</p>
8+
<p>Review: {reviewText}</p>
9+
<hr />
10+
</div>
11+
);
12+
};
13+
14+
export default Review;

client/src/components/NavBar.js

Lines changed: 27 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,32 @@
11
import React from "react";
22
import { Link } from "react-router-dom";
33
import "./NavBar.css";
4-
5-
6-
function NavBar(){
7-
8-
9-
return(
10-
11-
<header className="header">
12-
{/* <a href="/" className="logo">👟 Sneaker World</a> */}
13-
<div className="logo">Sneaker World</div>
14-
15-
<nav className="topnav">
16-
<Link to="/about">🔍 About</Link>
17-
<Link to="/">👟 Sneakers</Link>
18-
<Link to="/order">🗒️ Order </Link>
19-
</nav>
20-
</header>
21-
22-
);
4+
const API_URL = "http://localhost:3000";
5+
const logout = async () => {
6+
const url = `${API_URL}/auth/logout`;
7+
const response = await fetch(url);
8+
await response.json();
9+
window.location.href = "/";
10+
};
11+
12+
function NavBar() {
13+
return (
14+
<header className="header">
15+
{/* <a href="/" className="logo">👟 Sneaker World</a> */}
16+
<div className="logo">Sneaker World</div>
17+
18+
<nav className="topnav">
19+
<Link to="/about">🔍 About</Link>
20+
<Link to="/">👟 Sneakers</Link>
21+
<Link to="/orders">🗒️ Order </Link>
22+
<Link to="/cart">🗒️ Cart</Link>
23+
<Link to="/new">👟 New Sneaker</Link>
24+
<button onClick={logout} className="headerBtn">
25+
Logout
26+
</button>
27+
</nav>
28+
</header>
29+
);
2330
}
2431

25-
export default NavBar;
32+
export default NavBar;

client/src/pages/CreateComment.js

Lines changed: 63 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,70 @@
1-
import React, { useState } from 'react';
2-
import { useParams } from 'react-router-dom';
3-
import './CreateComment.css'
1+
import React, { useState } from "react";
2+
import { TextField, Button, Typography } from "@material-ui/core";
3+
import { useParams } from "react-router-dom";
44

5-
const CreateComment = () => {
5+
const CreateReview = () => {
6+
const { id } = useParams();
7+
const [reviewData, setReviewData] = useState({
8+
product_id: id, // Assign the product ID from the URL
9+
user_id: 1, // Assuming you have a logged-in user with an ID
10+
rating: "",
11+
review_text: "",
12+
review_date: new Date().toISOString().split("T")[0], // Get today's date in YYYY-MM-DD format
13+
});
614

7-
const [comment, setComment] = useState({comment: "" })
8-
const {sneaker_id} = useParams();
15+
const handleChange = (e) => {
16+
const { name, value } = e.target;
17+
setReviewData({ ...reviewData, [name]: value });
18+
};
919

20+
const handleSubmit = async (e) => {
21+
e.preventDefault();
22+
try {
23+
const response = await fetch(`/api/reviews/${id}`, {
24+
method: "POST",
25+
headers: {
26+
"Content-Type": "application/json",
27+
},
28+
body: JSON.stringify(reviewData),
29+
});
1030

11-
const handleChange = (event) => {
12-
const {name, value} = event.target;
13-
setComment( (prev) => {
14-
return {
15-
...prev,
16-
[name]:value,
17-
}
18-
})
31+
if (response.ok) {
32+
console.log("Review created successfully!");
33+
// Optionally, handle success state or redirect the user
34+
} else {
35+
console.error("Failed to create review");
36+
// Optionally, handle the failure case
37+
}
38+
} catch (error) {
39+
console.error("Error creating review:", error);
1940
}
20-
21-
const createComment = async (event) => {
22-
event.preventDefault();
23-
24-
const options = {
25-
method: 'POST',
26-
headers: {
27-
'Content-Type': 'application/json'
28-
},
29-
body: JSON.stringify(comment)
30-
}
31-
32-
await fetch('/api/reviews/' + sneaker_id, options)
33-
window.location.href = '/'
34-
}
35-
36-
return (
37-
<div>
38-
<form>
39-
<label>💬 Leave a Comment </label> <br />
40-
<input type="text" id="comment" name="comment" value={comment.comment} onChange={handleChange}/><br />
41-
<br/>
42-
43-
{/* <label>Comment ID</label><br />
44-
<input type="number" id="sneaker_id" name="sneaker_id" value={sneaker_id} readOnly/><br />
45-
<br/> */}
46-
47-
<input type="submit" value="Submit" className="submit-button" onClick={createComment} />
48-
</form>
49-
</div>
50-
)
51-
}
52-
53-
export default CreateComment
54-
41+
};
5542

43+
return (
44+
<form onSubmit={handleSubmit}>
45+
<Typography variant="h5">Leave a Review</Typography>
46+
<TextField
47+
name="rating"
48+
label="Rating (1-5)"
49+
type="number"
50+
InputProps={{ inputProps: { min: 1, max: 5 } }}
51+
value={reviewData.rating}
52+
onChange={handleChange}
53+
required
54+
/>
55+
<TextField
56+
name="review_text"
57+
label="Review Text"
58+
multiline
59+
value={reviewData.review_text}
60+
onChange={handleChange}
61+
required
62+
/>
63+
<Button type="submit" variant="contained" color="primary">
64+
Submit Review
65+
</Button>
66+
</form>
67+
);
68+
};
5669

70+
export default CreateReview;

client/src/pages/CreateSneaker.css

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
.CreateSneaker {
2+
margin-left: 200px;
3+
margin-right: 200px;
4+
}
5+
6+
.AddSneaker {
7+
margin-top: 100px;
8+
margin-bottom: 50px;
9+
}
10+
11+
input {
12+
margin-top: 10px;
13+
width: 100%;
14+
height: 45px;
15+
border-radius: 8px;
16+
border: 1px solid;
17+
font-size: 14px;
18+
padding-left: 10px;
19+
}
20+
21+
label {
22+
font-size: 18px;
23+
}
24+
25+
textarea {
26+
border-radius: 8px;
27+
width: 100%;
28+
border: 1px solid;
29+
font-size: 14px;
30+
}
31+
32+
input[type="submit"] {
33+
width: 100%;
34+
height: 50px;
35+
cursor: pointer;
36+
border-radius: 8px;
37+
border: 1px solid transparent;
38+
font-size: 20px;
39+
font-weight: 500;
40+
font-family: inherit;
41+
background-color: #0b3653;
42+
color: white;
43+
cursor: pointer;
44+
transition: border-color 0.25s;
45+
margin-top: 20px;
46+
margin-bottom: 50px;
47+
}

0 commit comments

Comments
 (0)