diff --git a/front-end/package.json b/front-end/package.json index 467cf33..8aed160 100644 --- a/front-end/package.json +++ b/front-end/package.json @@ -8,7 +8,8 @@ "@testing-library/user-event": "^13.5.0", "react": "^18.2.0", "react-dom": "^18.2.0", - "react-scripts": "5.0.1", + "react-router-dom": "^6.17.0", + "react-scripts": "^5.0.1", "web-vitals": "^2.1.4" }, "scripts": { diff --git a/front-end/src/App.js b/front-end/src/App.js index 3784575..6f7dc3a 100644 --- a/front-end/src/App.js +++ b/front-end/src/App.js @@ -1,24 +1,27 @@ -import logo from './logo.svg'; +import React from 'react'; import './App.css'; +import { BrowserRouter as Router, Route, Link, Routes } from 'react-router-dom'; +import FriendsPage from './components/FriendsPage'; + function App() { return ( -
-
- logo -

- Edit src/App.js and save to reload. -

- - Learn React - -
-
+ +
+ + + + {" "} + } /> + +
+
); } diff --git a/front-end/src/components/FriendsPage.css b/front-end/src/components/FriendsPage.css new file mode 100644 index 0000000..3e5d12b --- /dev/null +++ b/front-end/src/components/FriendsPage.css @@ -0,0 +1,111 @@ +.page-title { + font-size: 2em; + text-align: center; + margin-bottom: 20px; +} + +.balance-section { + display: flex; + align-items: center; + justify-content: center; + background-color: #E5E5E5; + padding: 15px; + border-radius: 10px; + margin-bottom: 20px; +} + +.avatar { + border-radius: 50%; + width: 50px; + height: 50px; + margin-right: 20px; +} + +.balance-title { + font-weight: bold; + margin-bottom: 10px; +} + +.balance-details { + display: flex; + flex-direction: column; +} + +.friends-list h3 { + margin-top: 20px; + margin-bottom: 10px; +} + +.friend-item { + display: flex; + align-items: center; + gap: 10px; +} + +.friend-avatar { + border-radius: 50%; + margin-right: 10px; + width: 50px; + height: 50px; +} + +.positive-balance { + color: green; +} + +.negative-balance { + color: red; +} + + +.navbar { + position: absolute; + top: 10px; + left: 10px; + background-color: #E5E5E5; + padding: 5px 10px; + border-radius: 5px; +} + +.add-friends-btn { + position: absolute; + top: 10px; + right: 10px; + padding: 5px 10px; + background-color: #007BFF; + color: white; + border: none; + border-radius: 5px; + cursor: pointer; +} + +.modal { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-color: rgba(0, 0, 0, 0.5); + display: flex; + justify-content: center; + align-items: center; +} + +.modal-content { + background-color: white; + padding: 20px; + border-radius: 10px; + width: 300px; + position: relative; +} + +.close { + position: absolute; + right: 10px; + top: 5px; + cursor: pointer; +} + +.modal-content h2 { + margin-top: 0; +} \ No newline at end of file diff --git a/front-end/src/components/FriendsPage.jsx b/front-end/src/components/FriendsPage.jsx new file mode 100644 index 0000000..3f24263 --- /dev/null +++ b/front-end/src/components/FriendsPage.jsx @@ -0,0 +1,86 @@ +import React, { useState, useEffect } from 'react'; +import './FriendsPage.css'; + +function FriendsPage() { + const [userData, setUserData] = useState(null); + const [showModal, setShowModal] = useState(false); + + const backupData = {"id":1,"name":"Carmon Stickel","email":"cstickel0@shutterfly.com","phone":"574-505-0071","avatar":"https://robohash.org/expeditaautemlaudantium.png?size=50x50\u0026set=set1","friends":[{"id":4,"name":"Leeanne Dunrige","email":"ldunrige0@comcast.net","phone":"594-821-5418","balance":"$62.71"},{"id":2,"name":"Doti Sorrel","email":"dsorrel1@google.com.hk","phone":"852-501-6560","balance":"$55.97"},{"id":5,"name":"Hobart Sallan","email":"hsallan2@cnet.com","phone":"476-640-9589","balance":"$-36.35"},{"id":3,"name":"Anetta Heningam","email":"aheningam3@networksolutions.com","phone":"180-587-2730","balance":"$-54.82"}]}; + + useEffect(() => { + async function fetchData() { + try { + const response = await fetch("https://my.api.mockaroo.com/users.json?key=04d5ee10"); + if (!response.ok) { + throw new Error(`HTTP error! Status: ${response.status}`); + } + const data = await response.json(); + setUserData(data); + } catch (error) { + console.error("Error fetching user data:", error); + console.log(backupData); + // Setting backup data when API call fails + setUserData(backupData); + } + } + fetchData(); + }, []); + + if (!userData) return
Loading...
; + + const totalBalance = userData.friends && userData.friends.length ? userData.friends.reduce((acc, friend) => acc + parseFloat(friend.balance.replace('$', '')), 0) : 0; + + return ( +
+

Friends

+
+ Navigation Bar +
+ +
+ User Avatar +
+
Total balance
+
+ {totalBalance > 0 ? ( +
You are owed ${totalBalance.toFixed(2)}
+ ) : ( +
You owe ${Math.abs(totalBalance).toFixed(2)}
+ )} +
+
+
+ +
+ +
+ + + {showModal && ( +
+
+ setShowModal(false)}>× +

Add Friends

+ + +
+
+ )} + +
+ ); +} + +export default FriendsPage; \ No newline at end of file