Skip to content

Commit b838ecd

Browse files
committed
Second version
1 parent b11c8cf commit b838ecd

File tree

8 files changed

+513
-29
lines changed

8 files changed

+513
-29
lines changed

.gitignore

+4
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,7 @@
2121
npm-debug.log*
2222
yarn-debug.log*
2323
yarn-error.log*
24+
25+
26+
# IDE
27+
.idea

package-lock.json

+294
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+6
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,15 @@
66
"@testing-library/jest-dom": "^5.16.4",
77
"@testing-library/react": "^13.3.0",
88
"@testing-library/user-event": "^13.5.0",
9+
"axios": "^0.27.2",
10+
"bootstrap": "^5.1.3",
911
"react": "^18.2.0",
12+
"react-bootstrap": "^2.4.0",
1013
"react-dom": "^18.2.0",
14+
"react-router-dom": "^6.3.0",
1115
"react-scripts": "5.0.1",
16+
"react-toastify": "^9.0.5",
17+
"styled-components": "^5.3.5",
1218
"web-vitals": "^2.1.4"
1319
},
1420
"scripts": {

src/App.js

+30-22
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,33 @@
1-
import logo from './logo.svg';
2-
import './App.css';
1+
import CreateUser from "./components/CreateUser";
2+
import RetrieveUser from "./components/RetrieveUser";
3+
import UsersList from "./components/UsersList";
4+
import "bootstrap/dist/css/bootstrap.min.css";
5+
import { Container } from "react-bootstrap";
6+
import { BrowserRouter, Routes, Route } from "react-router-dom";
7+
import { ToastContainer } from "react-toastify";
8+
import "react-toastify/dist/ReactToastify.min.css";
9+
import { createGlobalStyle } from "styled-components";
310

4-
function App() {
11+
const BackgroundColor = createGlobalStyle`
12+
body {
13+
background-color: ${(props) => (props?.light ? "#f2f2f2" : "white")};
14+
}
15+
`;
16+
17+
export default () => {
518
return (
6-
<div className="App">
7-
<header className="App-header">
8-
<img src={logo} className="App-logo" alt="logo" />
9-
<p>
10-
Edit <code>src/App.js</code> and save to reload.
11-
</p>
12-
<a
13-
className="App-link"
14-
href="https://reactjs.org"
15-
target="_blank"
16-
rel="noopener noreferrer"
17-
>
18-
Learn React
19-
</a>
20-
</header>
21-
</div>
19+
<>
20+
<BackgroundColor light />
21+
<ToastContainer />
22+
<Container fluid className="mt-4 mt-3">
23+
<BrowserRouter>
24+
<Routes>
25+
<Route path="/" element={<UsersList />} />
26+
<Route path="/create" element={<CreateUser />} />
27+
<Route path="/profile/:id" element={<RetrieveUser />} />
28+
</Routes>
29+
</BrowserRouter>
30+
</Container>
31+
</>
2232
);
23-
}
24-
25-
export default App;
33+
};

src/components/CreateUser.jsx

+86
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
import axios from "axios";
2+
import React, { useState } from "react";
3+
import { Button, Col, Container, Form, Row } from "react-bootstrap";
4+
import { toast } from "react-toastify";
5+
6+
const CreateUser = () => {
7+
const createUsersUrl = "http://localhost:4000/v1/user";
8+
9+
const [name, setName] = useState("");
10+
const [email, setEmail] = useState("");
11+
const [city, setCity] = useState("");
12+
const [country, setCountry] = useState("");
13+
14+
const submitForm = async (event) => {
15+
event.preventDefault();
16+
17+
const payload = {
18+
name,
19+
email,
20+
city,
21+
country,
22+
};
23+
24+
try {
25+
const res = await axios.post(`${createUsersUrl}`, payload);
26+
27+
res.data.status
28+
? toast.success("User added!")
29+
: toast.warn(`User couldn't be added`);
30+
} catch (err) {
31+
toast.error("Snap, an error has occurred...");
32+
}
33+
};
34+
35+
return (
36+
<Container className="mb-5">
37+
<Row className="justify-content-center">
38+
<Col lg={6}>
39+
<Form>
40+
<Form.Group className="mb-3">
41+
<Form.Label>Name</Form.Label>
42+
<Form.Control
43+
type="text"
44+
placeholder="Name"
45+
onChange={(elName) => setName(elName.target.value)}
46+
/>
47+
</Form.Group>
48+
49+
<Form.Group className="mb-3">
50+
<Form.Label>Email</Form.Label>
51+
<Form.Control
52+
type="email"
53+
placeholder="Email"
54+
onChange={(elEmail) => setEmail(elEmail.target.value)}
55+
/>
56+
</Form.Group>
57+
58+
<Form.Group className="mb-3">
59+
<Form.Label>City</Form.Label>
60+
<Form.Control
61+
type="text"
62+
placeholder="City"
63+
onChange={(elCity) => setCity(elCity.target.value)}
64+
/>
65+
</Form.Group>
66+
67+
<Form.Group className="mb-3">
68+
<Form.Label>Country</Form.Label>
69+
<Form.Control
70+
type="text"
71+
placeholder="Country"
72+
onChange={(elCountry) => setCountry(elCountry.target.value)}
73+
/>
74+
</Form.Group>
75+
76+
<Button variant="primary" type="submit" onClick={submitForm}>
77+
Add User
78+
</Button>
79+
</Form>
80+
</Col>
81+
</Row>
82+
</Container>
83+
);
84+
};
85+
86+
export default CreateUser;

src/components/RetrieveUser.jsx

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import axios from "axios";
2+
import React, { useEffect, useState } from "react";
3+
import { Col, Container, Row } from "react-bootstrap";
4+
import { useParams } from "react-router-dom";
5+
import { toast } from "react-toastify";
6+
7+
const RetrieveUser = () => {
8+
const getAllUserUrl = "http://localhost:4000/v1/user";
9+
10+
const [user, setUser] = useState({});
11+
const { id } = useParams();
12+
13+
const fetchUsers = async () => {
14+
const {
15+
data: { user },
16+
} = await axios.get(`${getAllUserUrl}/${id}`);
17+
18+
if (user) {
19+
setUser(user);
20+
} else {
21+
toast.warn("User not found");
22+
}
23+
};
24+
25+
useEffect(() => {
26+
fetchUsers();
27+
}, [id]);
28+
29+
return (
30+
<Container className="mt-5 mb-5">
31+
<h3 className="text-center mb-3"></h3>
32+
<Row className="justify-content-center">
33+
<Col lg={4}>
34+
<h4>{user.name}</h4>
35+
<p>{user.email}</p>
36+
{user.city && user.country && (
37+
<p>
38+
{user.city} - {user.country}
39+
</p>
40+
)}
41+
</Col>
42+
</Row>
43+
</Container>
44+
);
45+
};
46+
47+
export default RetrieveUser;

src/components/UsersList.jsx

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import React, {useEffect, useState} from 'react';
2+
import { Card, Col, Container, Row } from 'react-bootstrap';
3+
import axios from 'axios';
4+
5+
const UsersList = () => {
6+
const getAllUsersUrl = 'http://localhost:4000/v1/user/all';
7+
8+
const [users, setUsers] = useState({}); // important, default need to be empty object
9+
10+
const fetchUsers = async () => {
11+
const res = await axios.get(`${getAllUsersUrl}`);
12+
console.log(res.data);
13+
14+
setUsers(res.data);
15+
}
16+
17+
useEffect(() => {
18+
fetchUsers();
19+
}, []);
20+
21+
return (
22+
<Container className='mt-5 mb-5'>
23+
<h3 className='text-center mb-3'>
24+
Users
25+
</h3>
26+
{Object.values(users).map(user => (
27+
<Row className='justify-content-center'>
28+
<Col lg={4}>
29+
<Card>
30+
<Card.Body>
31+
<h4>{user.name}</h4>
32+
<p>{user.email}</p>
33+
{user.city && user.country && (
34+
<p>{user.city} - {user.country}</p>
35+
)}
36+
</Card.Body>
37+
</Card>
38+
</Col>
39+
</Row>
40+
))}
41+
</Container>
42+
)
43+
}
44+
45+
export default UsersList;

src/index.js

+1-7
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,10 @@ import React from 'react';
22
import ReactDOM from 'react-dom/client';
33
import './index.css';
44
import App from './App';
5-
import reportWebVitals from './reportWebVitals';
65

76
const root = ReactDOM.createRoot(document.getElementById('root'));
87
root.render(
98
<React.StrictMode>
109
<App />
1110
</React.StrictMode>
12-
);
13-
14-
// If you want to start measuring performance in your app, pass a function
15-
// to log results (for example: reportWebVitals(console.log))
16-
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
17-
reportWebVitals();
11+
);

0 commit comments

Comments
 (0)