From ca661c2892c3a0e6cb5140fda84be222dea8eb44 Mon Sep 17 00:00:00 2001 From: HedwigO Date: Mon, 20 Nov 2023 18:05:52 -0500 Subject: [PATCH 1/8] add greetings and dashboard for Home page --- front-end/src/components/Home.jsx | 98 ++++++++++++++++++++++--------- front-end/src/styles/Home.css | 52 ++++++++++++---- 2 files changed, 110 insertions(+), 40 deletions(-) diff --git a/front-end/src/components/Home.jsx b/front-end/src/components/Home.jsx index 56fc84b..cec6110 100644 --- a/front-end/src/components/Home.jsx +++ b/front-end/src/components/Home.jsx @@ -2,9 +2,28 @@ import React, { useState, useEffect } from "react"; import "../styles/Home.css"; import Navbar from "./Navbar"; import axios from "axios"; +import { Link } from "react-router-dom"; const Home = ({ isDarkMode }) => { const [backendData, setBackendData] = useState({}); + const [userName, setUserName] = useState(""); + + const backupNames = { + "id": 1, + "name": "Bryn", + "email": "btaylot0@booking.com", + "avatar": "https://robohash.org/utetquibusdam.png?size=50x50\u0026set=set1", + "user": [ + { + "id": 5, + "name": "Jdavie", + }, + { + "id": 2, + "name": "Emmie", + } + ] + }; function calculateTotalSpending(expenses) { return expenses.reduce((total, expense) => total + expense.amount, 0); @@ -66,41 +85,64 @@ const Home = ({ isDarkMode }) => { fetchHome(); }, []); + useEffect(() => { + const fetchUserName = async () => { + try { + const result = await axios.get("http://localhost:3001/user"); + setUserName(result.data.name); // Assuming the user object has a 'name' property + } catch (err) { + console.error(err); + setUserName(backupNames.name); // Use name from backupData + } + }; + + fetchUserName(); + }, []); + return ( -
-
-
-

- {backendData && - Array.isArray(backendData.expenses) && - backendData.expenses.length > 0 && ( -

- Total Spending: $ - {calculateTotalSpending(backendData.expenses)} -

- )} -

-
    - {backendData && - backendData.expenses && - backendData.expenses.length > 0 ? ( - backendData.expenses.map((expense) => ( -
  • -
    -

    {expense.name}

    -

    ${expense.amount}

    -
    -
  • - )) +
    + +
    +

    Good Morning, {userName}

    +
    +
    +
    +
    +

    Total Spending:

    +

    ${calculateTotalSpending(backendData.expenses || [])}

    +
    +
    + {backendData && backendData.expenses && backendData.expenses.length > 0 ? ( +
      + {backendData.expenses.map((expense) => ( +
    • +
      +

      {expense.name}

      +

      ${expense.amount}

      +
      +
    • + ))} +
    ) : (

    No expenses available.

    )} -
+
+
+
+

Events Pending Payment

+ View All Events + {/* Implement event mapping */} +
+
+

Friends Pending Payment

+ View All Friends + {/* Implement friend mapping */}
- ); + + }; -export default Home; +export default Home; \ No newline at end of file diff --git a/front-end/src/styles/Home.css b/front-end/src/styles/Home.css index d4fdfc3..7eddac9 100644 --- a/front-end/src/styles/Home.css +++ b/front-end/src/styles/Home.css @@ -1,18 +1,38 @@ .home-container { - @apply p-6 rounded-lg shadow-md bg-white max-w-2xl; - @apply mx-auto my-8; - @apply min-h-[80vh] p-6 rounded-lg shadow-md bg-white max-w-4xl mx-auto; + @apply p-6 rounded-lg shadow-md bg-white max-w-2xl mx-auto my-8 min-h-[80vh]; } + +.greeting h1 { + @apply text-3xl md:text-2xl font-bold mb-2 p-2; +} + +.dashboard { + @apply grid gap-2 mb-4 place-content-center; +} + .box { - @apply p-4 rounded-md bg-cyan-100 my-4; - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; + @apply p-4 rounded-md bg-cyan-100 my-2 flex flex-col cursor-pointer; /* Reduced margin y-axis from my-4 to my-2 */ + width: 100%; + @apply overflow-auto; /* Allows scrolling if content exceeds the height */ + height: 150px; /* or adjust as necessary for your design */ } .box h2 { - @apply text-2xl font-semibold text-black; + @apply text-lg font-semibold text-black whitespace-nowrap; +} + +.total-spending-header { + @apply flex justify-between items-center w-full; +} + +.expenses-list-container { + @apply overflow-auto h-48; /* Set a fixed height and allow scrolling */ +} + +@media (min-width: 768px) { + .box { + width: calc(100% - 1rem); /* Adjust width based on the gap specified in the grid */ + } } .home-money { @@ -32,7 +52,7 @@ } .home-expense-text { - @apply text-lg font-semibold; + @apply text-sm font-semibold; } .home-expense-amount { @@ -44,7 +64,11 @@ } .heading2 { - @apply text-center text-2xl mb-4; + @apply text-lg mb-2; +} + +.total-amount { + @apply text-lg mb-2; /* Make sure this matches the style of .heading2 if they are different */ } .border { @@ -56,7 +80,7 @@ } .small { - @apply mb-4; + @apply mb-2; } /* Dark Mode for Home Page */ @@ -76,4 +100,8 @@ .dark-mode .home-expense-text, .dark-mode .home-expense-amount { @apply text-white; +} + +.dark-mode .greeting h1 { + @apply text-left; /* Align text to the left in dark mode if needed */ } \ No newline at end of file From 85b4568365a7deb801faa63497306c7fa109df16 Mon Sep 17 00:00:00 2001 From: HedwigO Date: Mon, 20 Nov 2023 18:15:43 -0500 Subject: [PATCH 2/8] update route for Home page --- back-end/routes/homeRoute.js | 41 ++++++++++++++++++++++++++++++- front-end/src/components/Home.jsx | 6 ++++- front-end/src/styles/Home.css | 14 +++++------ 3 files changed, 52 insertions(+), 9 deletions(-) diff --git a/back-end/routes/homeRoute.js b/back-end/routes/homeRoute.js index 16ac172..7ff09da 100644 --- a/back-end/routes/homeRoute.js +++ b/back-end/routes/homeRoute.js @@ -1,7 +1,7 @@ const express = require("express"); const router = express.Router(); -router.get("/", async (req, res) => { +router.get("/home", async (req, res) => { // assemble an object with the data we want to send const body = { id: 1, @@ -57,4 +57,43 @@ router.get("/", async (req, res) => { res.json(body); }); +// Hardcoded user data to simulate a database +const userName = { + "id": 2, + "name": "Jackie", + "email": "jlennarde1@chron.com", + "avatar": "https://robohash.org/adquiearum.png?size=50x50&set=set1", + "user": [ + { + "id": 1, + "name": "Gram" + }, + { + "id": 3, + "name": "Guglielma" + }, + { + "id": 4, + "name": "Rayshell" + }, + { + "id": 5, + "name": "Abram" + }, + { + "id": 6, + "name": "Tommi" + }, + { + "id": 7, + "name": "Nicolai" + } + ] +} + +// Endpoint to get user data with friends +router.get('/user', (req, res) => { + res.json(userName); +}); + module.exports = router; diff --git a/front-end/src/components/Home.jsx b/front-end/src/components/Home.jsx index cec6110..0242212 100644 --- a/front-end/src/components/Home.jsx +++ b/front-end/src/components/Home.jsx @@ -8,6 +8,7 @@ const Home = ({ isDarkMode }) => { const [backendData, setBackendData] = useState({}); const [userName, setUserName] = useState(""); + /* backupData for name in greeting*/ const backupNames = { "id": 1, "name": "Bryn", @@ -29,6 +30,7 @@ const Home = ({ isDarkMode }) => { return expenses.reduce((total, expense) => total + expense.amount, 0); } + /* useEffect for controlling DarkMode of the margin around the page */ useEffect(() => { if (isDarkMode) { document.body.classList.add('body-dark-mode'); @@ -41,6 +43,7 @@ const Home = ({ isDarkMode }) => { }; }, [isDarkMode]); + /* useEffect for fetching total spending expenses */ useEffect(() => { const fetchHome = async () => { try { @@ -85,6 +88,7 @@ const Home = ({ isDarkMode }) => { fetchHome(); }, []); + /* useEffect for fetching name for greeting */ useEffect(() => { const fetchUserName = async () => { try { @@ -101,7 +105,6 @@ const Home = ({ isDarkMode }) => { return (
-

Good Morning, {userName}

@@ -139,6 +142,7 @@ const Home = ({ isDarkMode }) => { {/* Implement friend mapping */}
+ ); diff --git a/front-end/src/styles/Home.css b/front-end/src/styles/Home.css index 7eddac9..d5e4cce 100644 --- a/front-end/src/styles/Home.css +++ b/front-end/src/styles/Home.css @@ -11,10 +11,10 @@ } .box { - @apply p-4 rounded-md bg-cyan-100 my-2 flex flex-col cursor-pointer; /* Reduced margin y-axis from my-4 to my-2 */ + @apply p-4 rounded-md bg-cyan-100 my-2 flex flex-col cursor-pointer; width: 100%; - @apply overflow-auto; /* Allows scrolling if content exceeds the height */ - height: 150px; /* or adjust as necessary for your design */ + @apply overflow-auto; + height: 150px; /* if the sections exceed the page, reduce this height */ } .box h2 { @@ -26,12 +26,12 @@ } .expenses-list-container { - @apply overflow-auto h-48; /* Set a fixed height and allow scrolling */ + @apply overflow-auto h-48; } @media (min-width: 768px) { .box { - width: calc(100% - 1rem); /* Adjust width based on the gap specified in the grid */ + width: calc(100% - 1rem); } } @@ -68,7 +68,7 @@ } .total-amount { - @apply text-lg mb-2; /* Make sure this matches the style of .heading2 if they are different */ + @apply text-lg mb-2; } .border { @@ -103,5 +103,5 @@ } .dark-mode .greeting h1 { - @apply text-left; /* Align text to the left in dark mode if needed */ + @apply text-left; } \ No newline at end of file From b3a37e41a491a227f4f41b3b49e2dbd058ef7dc9 Mon Sep 17 00:00:00 2001 From: HedwigO Date: Mon, 20 Nov 2023 19:02:11 -0500 Subject: [PATCH 3/8] summarize friends dashboard --- front-end/src/components/Home.jsx | 56 ++++++++++++++++++++++++++----- front-end/src/styles/Home.css | 10 ++++-- 2 files changed, 54 insertions(+), 12 deletions(-) diff --git a/front-end/src/components/Home.jsx b/front-end/src/components/Home.jsx index 0242212..68d778c 100644 --- a/front-end/src/components/Home.jsx +++ b/front-end/src/components/Home.jsx @@ -5,10 +5,13 @@ import axios from "axios"; import { Link } from "react-router-dom"; const Home = ({ isDarkMode }) => { - const [backendData, setBackendData] = useState({}); + const [backendData, setBackendData] = useState({ + expenses: [], + friends: [] + }); const [userName, setUserName] = useState(""); - /* backupData for name in greeting*/ + /* backupData for name in greeting */ const backupNames = { "id": 1, "name": "Bryn", @@ -26,6 +29,8 @@ const Home = ({ isDarkMode }) => { ] }; + const backupData = {"id":1,"name":"Bryn","email":"btaylot0@booking.com","phone":"850-479-2094","avatar":"https://robohash.org/utetquibusdam.png?size=50x50\u0026set=set1","friends":[{"id":5,"name":"Jdavie","email":"jzecchinii0@yahoo.co.jp","phone":"967-156-0272","balance":"$57.06"},{"id":2,"name":"Emmie","email":"esworder1@xinhuanet.com","phone":"832-141-0597","balance":"$60.04"}]}; + function calculateTotalSpending(expenses) { return expenses.reduce((total, expense) => total + expense.amount, 0); } @@ -43,7 +48,7 @@ const Home = ({ isDarkMode }) => { }; }, [isDarkMode]); - /* useEffect for fetching total spending expenses */ + /* useEffect for fetching total spending expenses */ useEffect(() => { const fetchHome = async () => { try { @@ -88,15 +93,39 @@ const Home = ({ isDarkMode }) => { fetchHome(); }, []); + /* useEffect for fetching friends and their expenses */ + useEffect(() => { + const fetchFriendsData = async () => { + try { + const friendsResult = await axios.get("http://localhost:3001/friends"); + setBackendData(prevData => ({ + ...prevData, + friends: friendsResult.data.friends + })); + } catch (err) { + console.error(err); + setBackendData(prevData => ({ + ...prevData, + friends: backupData.friends + })); + } + }; + + fetchFriendsData(); + }, []); + + /* since spaces are limited, only display 2 friends, the user can access the rest by clicking "view more" */ + const friendsPendingPayment = backendData.friends ? backendData.friends.slice(0, 2) : []; + /* useEffect for fetching name for greeting */ useEffect(() => { const fetchUserName = async () => { try { const result = await axios.get("http://localhost:3001/user"); - setUserName(result.data.name); // Assuming the user object has a 'name' property + setUserName(result.data.name); } catch (err) { console.error(err); - setUserName(backupNames.name); // Use name from backupData + setUserName(backupNames.name); } }; @@ -133,13 +162,22 @@ const Home = ({ isDarkMode }) => {

Events Pending Payment

- View All Events + View All {/* Implement event mapping */}
-

Friends Pending Payment

- View All Friends - {/* Implement friend mapping */} +

Friends Pending Payment

+
    + {friendsPendingPayment.map((friend) => ( +
  • +
    +

    {friend.name}

    +

    {friend.balance}

    +
    +
  • + ))} +
+ View All
diff --git a/front-end/src/styles/Home.css b/front-end/src/styles/Home.css index d5e4cce..c580590 100644 --- a/front-end/src/styles/Home.css +++ b/front-end/src/styles/Home.css @@ -44,7 +44,7 @@ } .home-list { - @apply rounded-lg p-4 mt-4; + @apply rounded-lg p-4 mt-1; } .home-list2 { @@ -59,12 +59,16 @@ @apply text-gray-600; } +.view-all { + @apply text-center text-sm text-blue-500 mx-auto; +} + .center { @apply flex justify-between items-center; } .heading2 { - @apply text-lg mb-2; + @apply text-lg mb-0; } .total-amount { @@ -80,7 +84,7 @@ } .small { - @apply mb-2; + @apply mb-1; } /* Dark Mode for Home Page */ From 50060f01a92660318eb0c41a541617f1f4eef652 Mon Sep 17 00:00:00 2001 From: HedwigO Date: Mon, 20 Nov 2023 19:56:59 -0500 Subject: [PATCH 4/8] update Expenses Pending Payment dashboard --- front-end/src/components/Home.jsx | 69 +++++++++++++++++++++++++++++-- 1 file changed, 65 insertions(+), 4 deletions(-) diff --git a/front-end/src/components/Home.jsx b/front-end/src/components/Home.jsx index 68d778c..a2db57b 100644 --- a/front-end/src/components/Home.jsx +++ b/front-end/src/components/Home.jsx @@ -7,7 +7,8 @@ import { Link } from "react-router-dom"; const Home = ({ isDarkMode }) => { const [backendData, setBackendData] = useState({ expenses: [], - friends: [] + friends: [], + events: [] }); const [userName, setUserName] = useState(""); @@ -31,10 +32,27 @@ const Home = ({ isDarkMode }) => { const backupData = {"id":1,"name":"Bryn","email":"btaylot0@booking.com","phone":"850-479-2094","avatar":"https://robohash.org/utetquibusdam.png?size=50x50\u0026set=set1","friends":[{"id":5,"name":"Jdavie","email":"jzecchinii0@yahoo.co.jp","phone":"967-156-0272","balance":"$57.06"},{"id":2,"name":"Emmie","email":"esworder1@xinhuanet.com","phone":"832-141-0597","balance":"$60.04"}]}; + const backupEventsData = { + id: 2, + name: "LA Road Trip", + events: [ + {"id":1, "name":"Lunch", "amount":358, "creator":"Jane", "date":"06/16/2023"}, + {"id":2, "name":"Flights to LA", "amount":261, "creator":"Tom", "date":"01/21/2023"}, + {"id":3, "name":"Hotels", "amount":170, "creator":"David", "date":"08/02/2023"} + ], + description: "Road trip with friends", + } + + function calculateTotalSpending(expenses) { return expenses.reduce((total, expense) => total + expense.amount, 0); } + const eventsWithTotalExpenses = backendData.events ? backendData.events.map(event => ({ + ...event, + totalExpense: calculateTotalSpending(event.expenses || []) + })) : []; + /* useEffect for controlling DarkMode of the margin around the page */ useEffect(() => { if (isDarkMode) { @@ -93,6 +111,36 @@ const Home = ({ isDarkMode }) => { fetchHome(); }, []); + /* useEffect for fetching events and their expenses */ + useEffect(() => { + const fetchEventsData = async () => { + try { + const eventsResult = await axios.get("http://localhost:3001/events"); + if (Array.isArray(eventsResult.data)) { + setBackendData(prevData => ({ + ...prevData, + events: eventsResult.data, + })); + } else { + // If it's not an array, log the structure to understand what's being returned + console.error('Data fetched is not an array:', eventsResult.data); + throw new Error('Data fetched is not an array.'); + } + } catch (error) { + console.error('Error fetching events:', error); + // Use the array within backupEventsData, not the object itself + setBackendData(prevData => ({ + ...prevData, + events: backupEventsData.events, // Ensure this is an array + })); + } + }; + + fetchEventsData(); + }, []); + + + /* useEffect for fetching friends and their expenses */ useEffect(() => { const fetchFriendsData = async () => { @@ -114,8 +162,11 @@ const Home = ({ isDarkMode }) => { fetchFriendsData(); }, []); - /* since spaces are limited, only display 2 friends, the user can access the rest by clicking "view more" */ + + + /* since spaces are limited, only display 2 event expenses/friends, the user can access the rest by clicking "view more" */ const friendsPendingPayment = backendData.friends ? backendData.friends.slice(0, 2) : []; + const eventsPending = backupEventsData.events ? backupEventsData.events.slice(0, 2) : []; /* useEffect for fetching name for greeting */ useEffect(() => { @@ -161,8 +212,18 @@ const Home = ({ isDarkMode }) => {
-

Events Pending Payment

- View All +

Expenses Pending Payment

+
    + {eventsPending.map(event => ( +
  • +
    +

    {event.name}

    +

    ${event.amount.toFixed(2)}

    +
    +
  • + ))} +
+ View All {/* Implement event mapping */}
From 31dc4ffaccae218204a01cb28e8d3e762240060b Mon Sep 17 00:00:00 2001 From: HedwigO Date: Mon, 20 Nov 2023 20:07:50 -0500 Subject: [PATCH 5/8] change good morning to welcome in greetings --- front-end/src/components/Home.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/front-end/src/components/Home.jsx b/front-end/src/components/Home.jsx index a2db57b..f889039 100644 --- a/front-end/src/components/Home.jsx +++ b/front-end/src/components/Home.jsx @@ -186,7 +186,7 @@ const Home = ({ isDarkMode }) => { return (
-

Good Morning, {userName}

+

Welcome, {userName}

From 644db1bbd3e9206c0c39ad9c477c1fd4735f864b Mon Sep 17 00:00:00 2001 From: HedwigO Date: Tue, 21 Nov 2023 12:16:54 -0500 Subject: [PATCH 6/8] fix scroll down dark mode --- front-end/src/styles/Event.css | 1 + front-end/src/styles/FriendsPage.css | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/front-end/src/styles/Event.css b/front-end/src/styles/Event.css index aa0a92d..d1a7585 100644 --- a/front-end/src/styles/Event.css +++ b/front-end/src/styles/Event.css @@ -100,4 +100,5 @@ header { .dark-mode .space-to-scroll { @apply bg-gray-700; + height: 0px; } diff --git a/front-end/src/styles/FriendsPage.css b/front-end/src/styles/FriendsPage.css index d14ce8b..98016bb 100644 --- a/front-end/src/styles/FriendsPage.css +++ b/front-end/src/styles/FriendsPage.css @@ -131,7 +131,8 @@ } .dark-mode .space-to-scroll { - height: 60px; + @apply bg-gray-700; + height: 0px; } /* Dark Mode for Add Friends Modal */ From da8c4ba97872bee23a9b638c688bc73bf517d7ad Mon Sep 17 00:00:00 2001 From: HedwigO Date: Tue, 21 Nov 2023 12:25:52 -0500 Subject: [PATCH 7/8] fix paddings and margin for dashboard --- front-end/src/components/Home.jsx | 10 +++++----- front-end/src/styles/Home.css | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/front-end/src/components/Home.jsx b/front-end/src/components/Home.jsx index f889039..239432b 100644 --- a/front-end/src/components/Home.jsx +++ b/front-end/src/components/Home.jsx @@ -164,9 +164,9 @@ const Home = ({ isDarkMode }) => { - /* since spaces are limited, only display 2 event expenses/friends, the user can access the rest by clicking "view more" */ - const friendsPendingPayment = backendData.friends ? backendData.friends.slice(0, 2) : []; - const eventsPending = backupEventsData.events ? backupEventsData.events.slice(0, 2) : []; + /* since spaces are limited, only display 3 event expenses/friends, the user can access the rest by clicking "view more" */ + const friendsPendingPayment = backendData.friends ? backendData.friends.slice(0, 3) : []; + const eventsPending = backupEventsData.events ? backupEventsData.events.slice(0, 3) : []; /* useEffect for fetching name for greeting */ useEffect(() => { @@ -212,7 +212,7 @@ const Home = ({ isDarkMode }) => {
-

Expenses Pending Payment

+

Expenses Summary

    {eventsPending.map(event => (
  • @@ -227,7 +227,7 @@ const Home = ({ isDarkMode }) => { {/* Implement event mapping */}
-

Friends Pending Payment

+

Friends Summary

    {friendsPendingPayment.map((friend) => (
  • diff --git a/front-end/src/styles/Home.css b/front-end/src/styles/Home.css index c580590..40b4a57 100644 --- a/front-end/src/styles/Home.css +++ b/front-end/src/styles/Home.css @@ -1,5 +1,5 @@ .home-container { - @apply p-6 rounded-lg shadow-md bg-white max-w-2xl mx-auto my-8 min-h-[80vh]; + @apply p-6 rounded-lg shadow-md bg-white max-w-4xl mx-auto my-8 min-h-[80vh]; } .greeting h1 { @@ -14,7 +14,7 @@ @apply p-4 rounded-md bg-cyan-100 my-2 flex flex-col cursor-pointer; width: 100%; @apply overflow-auto; - height: 150px; /* if the sections exceed the page, reduce this height */ + height: 170px; /* if the sections exceed the page, reduce this height */ } .box h2 { @@ -44,7 +44,7 @@ } .home-list { - @apply rounded-lg p-4 mt-1; + @apply rounded-lg mt-1; } .home-list2 { @@ -84,7 +84,7 @@ } .small { - @apply mb-1; + @apply mb-1 mt-1; } /* Dark Mode for Home Page */ From cf125f3cf8c90884b7be8321081b95994da8d117 Mon Sep 17 00:00:00 2001 From: HedwigO Date: Sat, 25 Nov 2023 00:04:00 -0800 Subject: [PATCH 8/8] replace Total Spending section with Events Summary section --- back-end/routes/homeRoute.js | 120 ++++--------- front-end/src/components/Home.jsx | 284 ++++++++++++------------------ front-end/src/styles/Home.css | 11 +- 3 files changed, 152 insertions(+), 263 deletions(-) diff --git a/back-end/routes/homeRoute.js b/back-end/routes/homeRoute.js index 7ff09da..e6b1b0e 100644 --- a/back-end/routes/homeRoute.js +++ b/back-end/routes/homeRoute.js @@ -1,99 +1,43 @@ const express = require("express"); const router = express.Router(); -router.get("/home", async (req, res) => { - // assemble an object with the data we want to send - const body = { - id: 1, - name: "LA Road Trip", - expenses: [ - { - id: 1, - name: "Lunch", - amount: 358, - creator: "Jane", - date: "06/16/2023", - }, - { - id: 2, - name: "Flights to LA", - amount: 261, - creator: "Tom", - date: "01/21/2023", - }, - { - id: 3, - name: "Hotels", - amount: 170, - creator: "David", - date: "08/02/2023", - }, +const tripData = { + id: 1, + name: "LA Road Trip", + expenses: [ + { id: 1, name: "Lunch", amount: 358, creator: "Jane", date: "06/16/2023" }, + { id: 2, name: "Flights to LA", amount: 261, creator: "Tom", date: "01/21/2023" }, + { id: 3, name: "Hotels", amount: 170, creator: "David", date: "08/02/2023" }, + { id: 4, name: "Dinner", amount: 120, creator: "David", date: "08/02/2023" }, + { id: 5, name: "Souvenirs", amount: 570, creator: "David", date: "08/02/2023" }, + { id: 6, name: "Gifts", amount: 200, creator: "David", date: "08/02/2023" }, + ], + description: "Road trip with friends", +}; - { - id: 4, - name: "Dinner", - amount: 120, - creator: "David", - date: "08/02/2023", - }, - { - id: 5, - name: "Souvenirs", - amount: 570, - creator: "David", - date: "08/02/2023", - }, - { - id: 6, - name: "Gifts", - amount: 200, - creator: "David", - date: "08/02/2023", - }, - ], - description: "Road trip with friends", - }; - // send the response as JSON to the client - res.json(body); -}); +const userData = { + id: 2, + name: "Jackie", + email: "jlennarde1@chron.com", + avatar: "https://robohash.org/adquiearum.png?size=50x50&set=set1", + friends: [ + { id: 1, name: "Gram" }, + { id: 3, name: "Guglielma" }, + { id: 4, name: "Rayshell" }, + { id: 5, name: "Abram" }, + { id: 6, name: "Tommi" }, + { id: 7, name: "Nicolai" }, + ], +}; -// Hardcoded user data to simulate a database -const userName = { - "id": 2, - "name": "Jackie", - "email": "jlennarde1@chron.com", - "avatar": "https://robohash.org/adquiearum.png?size=50x50&set=set1", - "user": [ - { - "id": 1, - "name": "Gram" - }, - { - "id": 3, - "name": "Guglielma" - }, - { - "id": 4, - "name": "Rayshell" - }, - { - "id": 5, - "name": "Abram" - }, - { - "id": 6, - "name": "Tommi" - }, - { - "id": 7, - "name": "Nicolai" - } - ] -} +// Endpoint to get home data +router.get("/home", async (req, res) => { + res.json(tripData); +}); // Endpoint to get user data with friends router.get('/user', (req, res) => { - res.json(userName); + res.json(userData); }); module.exports = router; diff --git a/front-end/src/components/Home.jsx b/front-end/src/components/Home.jsx index 239432b..5a63e35 100644 --- a/front-end/src/components/Home.jsx +++ b/front-end/src/components/Home.jsx @@ -5,50 +5,87 @@ import axios from "axios"; import { Link } from "react-router-dom"; const Home = ({ isDarkMode }) => { - const [backendData, setBackendData] = useState({ + const [data, setData] = useState({ + userName: "", + totalSpending: 0, expenses: [], friends: [], events: [] }); - const [userName, setUserName] = useState(""); - /* backupData for name in greeting */ - const backupNames = { - "id": 1, - "name": "Bryn", - "email": "btaylot0@booking.com", - "avatar": "https://robohash.org/utetquibusdam.png?size=50x50\u0026set=set1", - "user": [ - { - "id": 5, - "name": "Jdavie", - }, - { - "id": 2, - "name": "Emmie", - } - ] - }; - - const backupData = {"id":1,"name":"Bryn","email":"btaylot0@booking.com","phone":"850-479-2094","avatar":"https://robohash.org/utetquibusdam.png?size=50x50\u0026set=set1","friends":[{"id":5,"name":"Jdavie","email":"jzecchinii0@yahoo.co.jp","phone":"967-156-0272","balance":"$57.06"},{"id":2,"name":"Emmie","email":"esworder1@xinhuanet.com","phone":"832-141-0597","balance":"$60.04"}]}; - - const backupEventsData = { - id: 2, - name: "LA Road Trip", + /* backupData from Expenses, Events, Friends.jsx */ + const backupData = { + userName: "Bryn", + totalSpending: 0, + expenses: [ + { + id: 1, + name: "Lunch", + amount: 358, + creator: "Jane", + date: "06/16/2023", + }, + { + id: 2, + name: "Flights to LA", + amount: 261, + creator: "Tom", + date: "01/21/2023", + }, + { + id: 3, + name: "Hotels", + amount: 170, + creator: "David", + date: "08/02/2023", + }, + ], events: [ - {"id":1, "name":"Lunch", "amount":358, "creator":"Jane", "date":"06/16/2023"}, - {"id":2, "name":"Flights to LA", "amount":261, "creator":"Tom", "date":"01/21/2023"}, - {"id":3, "name":"Hotels", "amount":170, "creator":"David", "date":"08/02/2023"} + { + "id": 1, + "EventName": "Cooro", + "Date": "06/16/2023", + "balance": "$358.00", + "description": "Lunch at local restaurant", + "members": [ + { "names": "Jane" }, + { "names": "John" } + ] + }, + { + "id": 2, + "EventName": "Kobe", + "Date": "01/21/2023", + "balance": "$262.00", + "description": "Flight tickets for LA trip", + "members": [ + { "names": "Tom" }, + { "names": "Lucy" } + ] + }, + { + "id": 3, + "EventName": "Cuiji", + "Date": "08/02/2023", + "balance": "$170.00", + "description": "Accommodation expenses", + "members": [ + { "names": "David" }, + { "names": "Sarah" } + ] + } ], - description: "Road trip with friends", - } - + friends: [ + {"id":2,"name":"Jdavie","email":"jzecchinii0@yahoo.co.jp","phone":"967-156-0272","balance":"$57.06"}, + {"id":4,"name":"Emmie","email":"esworder1@xinhuanet.com","phone":"832-141-0597","balance":"$60.04"}, + {"id":5,"name":"Jason","email":"jsathep@pehisbd.com","phone":"212-121-0437","balance":"$70.41"}] + }; function calculateTotalSpending(expenses) { return expenses.reduce((total, expense) => total + expense.amount, 0); } - const eventsWithTotalExpenses = backendData.events ? backendData.events.map(event => ({ + const eventsWithTotalExpenses = data.events ? data.events.map(event => ({ ...event, totalExpense: calculateTotalSpending(event.expenses || []) })) : []; @@ -60,7 +97,7 @@ const Home = ({ isDarkMode }) => { } else { document.body.classList.remove('body-dark-mode'); } - // if not in dark mode, remove this effect + // if not in dark mode, remove this effect return () => { document.body.classList.remove('body-dark-mode'); }; @@ -68,163 +105,74 @@ const Home = ({ isDarkMode }) => { /* useEffect for fetching total spending expenses */ useEffect(() => { - const fetchHome = async () => { + const fetchData = async () => { try { - const result = await axios.get("http://localhost:3001/home"); - setBackendData(result.data); - } catch (err) { - console.error(err); + // Fetch home data + const homeRes = await axios.get("http://localhost:3001/home"); + const expenses = homeRes.data.expenses || []; + const totalSpending = calculateTotalSpending(expenses); - const backupData = { - id: 2, - name: "LA Road Trip", - expenses: [ - { - id: 1, - name: "Lunch", - amount: 358, - creator: "Jane", - date: "06/16/2023", - }, - { - id: 2, - name: "Flights to LA", - amount: 261, - creator: "Tom", - date: "01/21/2023", - }, - { - id: 3, - name: "Hotels", - amount: 170, - creator: "David", - date: "08/02/2023", - }, - ], - description: "Road trip with friends", - }; + // Fetch events data + const eventsRes = await axios.get("http://localhost:3001/events"); + const events = Array.isArray(eventsRes.data) ? eventsRes.data : []; - setBackendData(backupData); - } - }; + // Fetch friends data + const friendsRes = await axios.get("http://localhost:3001/friends"); + const friends = friendsRes.data.friends || []; - fetchHome(); - }, []); + // Fetch user name + const userRes = await axios.get("http://localhost:3001/user"); + const userName = userRes.data.name || ""; - /* useEffect for fetching events and their expenses */ - useEffect(() => { - const fetchEventsData = async () => { - try { - const eventsResult = await axios.get("http://localhost:3001/events"); - if (Array.isArray(eventsResult.data)) { - setBackendData(prevData => ({ - ...prevData, - events: eventsResult.data, - })); - } else { - // If it's not an array, log the structure to understand what's being returned - console.error('Data fetched is not an array:', eventsResult.data); - throw new Error('Data fetched is not an array.'); - } + setData({ userName, totalSpending, expenses, events, friends }); } catch (error) { - console.error('Error fetching events:', error); - // Use the array within backupEventsData, not the object itself - setBackendData(prevData => ({ - ...prevData, - events: backupEventsData.events, // Ensure this is an array - })); + console.error("Error fetching data:", error); + setData(backupData); // set to backup data in case of error } }; - - fetchEventsData(); - }, []); - - - /* useEffect for fetching friends and their expenses */ - useEffect(() => { - const fetchFriendsData = async () => { - try { - const friendsResult = await axios.get("http://localhost:3001/friends"); - setBackendData(prevData => ({ - ...prevData, - friends: friendsResult.data.friends - })); - } catch (err) { - console.error(err); - setBackendData(prevData => ({ - ...prevData, - friends: backupData.friends - })); - } - }; - - fetchFriendsData(); + fetchData(); }, []); - - /* since spaces are limited, only display 3 event expenses/friends, the user can access the rest by clicking "view more" */ - const friendsPendingPayment = backendData.friends ? backendData.friends.slice(0, 3) : []; - const eventsPending = backupEventsData.events ? backupEventsData.events.slice(0, 3) : []; - - /* useEffect for fetching name for greeting */ - useEffect(() => { - const fetchUserName = async () => { - try { - const result = await axios.get("http://localhost:3001/user"); - setUserName(result.data.name); - } catch (err) { - console.error(err); - setUserName(backupNames.name); - } - }; - - fetchUserName(); - }, []); + const friendsPendingPayment = data.friends ? data.friends.slice(0, 3) : []; + const expensesPending = data.expenses ? data.expenses.slice(0, 3) : []; + const eventsPending = data.events ? data.events.slice(0, 3) : []; return (
    -

    Welcome, {userName}

    +

    Welcome, {data.userName}

    -
    -
    -

    Total Spending:

    -

    ${calculateTotalSpending(backendData.expenses || [])}

    +
    +

    Events Summary

    +
      + {eventsPending.map((event) => ( +
    • +
      +

      {event.EventName}

      +

      {event.Date}

      -
      - {backendData && backendData.expenses && backendData.expenses.length > 0 ? ( -
        - {backendData.expenses.map((expense) => ( -
      • -
        -

        {expense.name}

        -

        ${expense.amount}

        -
        -
      • - ))} -
      - ) : ( -

      No expenses available.

      - )} -
      -
    +
  • + ))} +
+ View All +

Expenses Summary

+ {/*

${calculateTotalSpending(data.expenses || [])}

*/}
    - {eventsPending.map(event => ( -
  • -
    -

    {event.name}

    -

    ${event.amount.toFixed(2)}

    -
    -
  • - ))} -
- View All - {/* Implement event mapping */} + {expensesPending.map(event => ( +
  • +
    +

    {event.name}

    +

    ${event.amount.toFixed(2)}

    +
    +
  • + ))} + + View All

    Friends Summary

    diff --git a/front-end/src/styles/Home.css b/front-end/src/styles/Home.css index 40b4a57..d82aa9d 100644 --- a/front-end/src/styles/Home.css +++ b/front-end/src/styles/Home.css @@ -47,16 +47,13 @@ @apply rounded-lg mt-1; } -.home-list2 { - @apply py-4 border-b border-gray-300 flex justify-between; -} - -.home-expense-text { +.home-expense-text, +.home-expense-amount { @apply text-sm font-semibold; } .home-expense-amount { - @apply text-gray-600; + @apply text-gray-600 flex-1 text-right; } .view-all { @@ -84,7 +81,7 @@ } .small { - @apply mb-1 mt-1; + @apply mb-2 mt-2; } /* Dark Mode for Home Page */