From dae4caf14d825f25a8e8537d78605a40f7295d2e Mon Sep 17 00:00:00 2001 From: ntuff Date: Sun, 14 Apr 2024 18:57:58 -0230 Subject: [PATCH 1/6] Revising Maintenance History page layout, converting to react-bootstrap --- frontend/src/App.css | 10 +- frontend/src/pages/garage/AddVehicle.js | 20 +- frontend/src/pages/garage/Garage.js | 27 +- frontend/src/pages/garage/RemoveVehicle.js | 6 +- frontend/src/pages/garage/Vehicle.js | 10 +- .../ManualVehicleHistory.js | 19 +- .../pages/maintenance-history/UploadNavbar.js | 1 - frontend/src/pages/vehicle/VehicleHistory.js | 237 ++++++++++-------- frontend/src/pages/vehicle/VehicleInfo.js | 26 +- 9 files changed, 205 insertions(+), 151 deletions(-) diff --git a/frontend/src/App.css b/frontend/src/App.css index 6801192..df150ad 100644 --- a/frontend/src/App.css +++ b/frontend/src/App.css @@ -175,15 +175,11 @@ body, .navbar-nav .nav-link, .navbar-text { height: 100%; } -button, .btn { - background-color: #8c7498 !important; - border-color: #8c7498 !important; - color: white !important; -} + .custom-button-primary, .custom-button-success { - background-color: #2872a7 !important; - border-color: #2872a7 !important; + background-color: #8c7498 !important; + border-color: #8c7498 !important; color: white !important; } diff --git a/frontend/src/pages/garage/AddVehicle.js b/frontend/src/pages/garage/AddVehicle.js index 51a0d4a..6005df0 100644 --- a/frontend/src/pages/garage/AddVehicle.js +++ b/frontend/src/pages/garage/AddVehicle.js @@ -161,7 +161,7 @@ function AddVehicle() {
- Year + Year {dropdownValues.years.map((year, index) => ( @@ -172,7 +172,7 @@ function AddVehicle() { {selectedVehicle.year && ( - Make + Make {dropdownValues.makes.map((make, index) => ( @@ -184,7 +184,7 @@ function AddVehicle() { {selectedVehicle.make && ( - Model + Model {dropdownValues.models.map((model, index) => ( @@ -196,7 +196,7 @@ function AddVehicle() { {selectedVehicle.model && ( - Engine + Engine {dropdownValues.engines.map((engine, index) => ( @@ -208,8 +208,9 @@ function AddVehicle() { {selectedVehicle.engine && ( - Transmission - + Transmission + {dropdownValues.transmissions.map((transmission, index) => ( @@ -219,7 +220,12 @@ function AddVehicle() { )}
- +
{vehicleAdded &&
Vehicle has been added successfully! diff --git a/frontend/src/pages/garage/Garage.js b/frontend/src/pages/garage/Garage.js index ae8cfbd..7e6980b 100644 --- a/frontend/src/pages/garage/Garage.js +++ b/frontend/src/pages/garage/Garage.js @@ -62,26 +62,24 @@ function Garage(props) { }, [refreshData]); const updateOdometer = async (configID, email) => { - try{ + try { const response = await fetch("/api/update-odometer", { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ - vehicle_config_ids : configID, + vehicle_config_ids: configID, email: email, //odometer: odometer }) }); - if(response.ok){ + if (response.ok) { setRefreshData(!refreshData); - } - else{ + } else { console.error("Failed to update Odometer"); } - } - catch (error){ + } catch (error) { console.error("Catch Failed to update Odometer"); } } @@ -90,12 +88,17 @@ function Garage(props) { return ( - + -

navigate('/garage')} style={{ cursor: 'pointer', color: '#644A77', fontWeight: 'bold' }}> +

navigate('/garage')} + style={{cursor: 'pointer', color: '#644A77', fontWeight: 'bold'}}> {user} Garage

- + +
+ + + Add New Vehicle @@ -103,7 +106,7 @@ function Garage(props) { {props.info ? props.info.map((vehicle, index) => ( - + )) : !loading && No vehicles found.} @@ -111,4 +114,4 @@ function Garage(props) { ); } -export default Garage; \ No newline at end of file + export default Garage; \ No newline at end of file diff --git a/frontend/src/pages/garage/RemoveVehicle.js b/frontend/src/pages/garage/RemoveVehicle.js index 4fccca7..80987a3 100644 --- a/frontend/src/pages/garage/RemoveVehicle.js +++ b/frontend/src/pages/garage/RemoveVehicle.js @@ -39,7 +39,7 @@ function RemoveVehicle(props) { return ( <> - + @@ -50,7 +50,7 @@ function RemoveVehicle(props) { - + @@ -58,4 +58,4 @@ function RemoveVehicle(props) { ) } -export default RemoveVehicle; \ No newline at end of file + export default RemoveVehicle; \ No newline at end of file diff --git a/frontend/src/pages/garage/Vehicle.js b/frontend/src/pages/garage/Vehicle.js index b82fde7..8b0bf90 100644 --- a/frontend/src/pages/garage/Vehicle.js +++ b/frontend/src/pages/garage/Vehicle.js @@ -31,7 +31,7 @@ function Vehicle(props) { } const v = props.vehicle; - + const handleUpdateOdometer = () => { console.log("Updating odometer"); console.log(v.configurations.config_id+ "= config"); @@ -72,7 +72,7 @@ function Vehicle(props) { const reading = odometerReading.find(vehicle => vehicle.config_id === config); return reading ? reading.odometer : -9999; } - + const getPicture = (config) => { const reading = odometerReading.find(vehicle => vehicle.config_id === config); return reading ? reading.picture_url : "https://cdn.dealerk.it/cars/placeholder/placeholder-800.png"; @@ -120,9 +120,9 @@ function Vehicle(props) { {v.configurations.year} {v.configurations.make} {v.configurations.model} - + - +
@@ -143,7 +143,7 @@ function Vehicle(props) { onChange={e => setPictureUrl(e.target.value)} /> - + diff --git a/frontend/src/pages/maintenance-history/ManualVehicleHistory.js b/frontend/src/pages/maintenance-history/ManualVehicleHistory.js index bc28c27..d0bb7c8 100644 --- a/frontend/src/pages/maintenance-history/ManualVehicleHistory.js +++ b/frontend/src/pages/maintenance-history/ManualVehicleHistory.js @@ -46,11 +46,11 @@ function ManualVehicleHistory(props) { return ( <> - + - Manual Maintenance History + Add Maintenance Information @@ -60,10 +60,15 @@ function ManualVehicleHistory(props) { Type - - - - + + + + + + + + + @@ -79,7 +84,7 @@ function ManualVehicleHistory(props) { - Service + Part diff --git a/frontend/src/pages/maintenance-history/UploadNavbar.js b/frontend/src/pages/maintenance-history/UploadNavbar.js index 66b3031..ceadb2e 100644 --- a/frontend/src/pages/maintenance-history/UploadNavbar.js +++ b/frontend/src/pages/maintenance-history/UploadNavbar.js @@ -12,7 +12,6 @@ function UploadNavbar(props) {
e.preventDefault()}> -
diff --git a/frontend/src/pages/vehicle/VehicleHistory.js b/frontend/src/pages/vehicle/VehicleHistory.js index 0ab89a6..1637475 100644 --- a/frontend/src/pages/vehicle/VehicleHistory.js +++ b/frontend/src/pages/vehicle/VehicleHistory.js @@ -1,12 +1,11 @@ -import {Routes, Route, useLocation} from "react-router-dom"; -import VehicleNavbar from "./VehicleNavbar"; +import { useLocation, useNavigate } from "react-router-dom"; import UploadNavbar from "../maintenance-history/UploadNavbar"; -import {useEffect, useRef, useState} from "react"; -import Button from "react-bootstrap/Button"; -import Modal from "react-bootstrap/Modal"; -import {Alert, Col, Form, InputGroup, Row} from "react-bootstrap"; +import { useEffect, useRef, useState } from "react"; +import { Button, Modal, Alert, Form, InputGroup, Container, Row, Col, Table } from "react-bootstrap"; +import ManualVehicleHistory from "../maintenance-history/ManualVehicleHistory"; function VehicleHistory(props) { + const navigate = useNavigate(); const location = useLocation(); const { configId } = location.state; @@ -14,6 +13,35 @@ function VehicleHistory(props) { const [refreshData, setRefreshData] = useState(false); const [maintenance, setMaintenance] = useState(null); + const [vehicleInfo, setVehicleInfo] = useState(null); + const [user, setUser] = useState("Loading..."); + + useEffect(() => { + const fetchUser = async () => { + try { + const token = localStorage.getItem('token'); + if (token) { + const response = await fetch('/api/user', { + headers: { + 'Authorization': `Bearer ${token}` + } + }); + if (response.ok) { + const data = await response.json(); + const firstName = data.name.split(' ')[0]; + setUser(`${firstName}'s`); + } else { + console.error("User not found"); + setUser("User's"); + } + } + } catch (error) { + console.error(error); + setUser("User's"); + } + }; + fetchUser(); + }, []); useEffect(() => { const myHeaders = new Headers(); @@ -22,97 +50,108 @@ function VehicleHistory(props) { headers: myHeaders, redirect: 'follow' }; - fetch('/api/get-vehicle-history?configId='+configId, reqOptions) - .then( (res) => { + fetch(`/api/get-vehicle-info?configId=${configId}`, reqOptions) + .then((res) => { + if (!res.ok) { + throw new Error('Network response was not ok'); + } + return res.json(); + }) + .then((info) => { + setVehicleInfo(info); + }) + .catch((error) => { + console.error('There has been a problem with your fetch operation:', error); + }); + fetch(`/api/get-vehicle-history?configId=${configId}`, reqOptions) + .then((res) => { if (!res.ok) { throw new Error('Network response was not ok'); } return res.json(); }) - .then( (maintenance) => { - setMaintenance(maintenance[0]); + .then((maintenanceData) => { + setMaintenance(maintenanceData[0]); setLoading(false); }) - .catch( (error) => { + .catch((error) => { console.error('There has been a problem with your fetch operation:', error); }); - }, []); + }, [refreshData]); return ( -
- - - - - - -
-
-
-
-
-
- - -

Maintenance History

- - - - - -
+ + +

+ navigate('/garage')} style={{ cursor: 'pointer', color: '#644A77', fontWeight: 'bold' }}> + {user} Garage + + {' > '} + {vehicleInfo ? ( + navigate(`/garage/vehicle-info/${configId}`, {state: {configId}})} + style={{ cursor: 'pointer', color: '#644A77', fontWeight: 'bold' }}> + {vehicleInfo.year} {vehicleInfo.make} {vehicleInfo.model} + + ) : ( + Loading Vehicle Info... + )} + {' > '} Maintenance History +

+
-
-
-
-
-
-
- - - - - - - - + + + + + +
- TypeDateServiceCost + +
+ + + + + + + + + + + {maintenance != null ? + maintenance.completed_maintenance.map((service, index) => ( + + + + + + - - - { - maintenance != null ? - maintenance.completed_maintenance.map((service, index) => { - return ( - - - - - - - - - ) - }) : - - } - -
ActionPartCostDateEdit/Remove
{service.type}{service.maintenance}${parseFloat(service.cost).toFixed(2)}{service.date} + + + + +
{service.type}{service.date}{service.maintenance}{service.cost}
No maintenance history!
-
-
-
-
-
-
-
+ )) : No maintenance history! + } + + + + + ); } function UpdateMaintenanceHistory(props) { - - const [loading, setLoading] = useState(true); - const [refreshData, setRefreshData] = useState(false); - const [show, setShow] = useState(false); const handleClose = () => setShow(false); const handleShow = () => setShow(true); @@ -142,12 +181,11 @@ function UpdateMaintenanceHistory(props) { redirect: 'follow' }; - fetch("/api/update-maintenance-history?configId="+props.configId, reqOptions) - .then((res) => - res.json()) + fetch(`/api/update-maintenance-history?configId=${props.configId}`, reqOptions) + .then((res) => res.json()) .then((result) => { console.log(result); - setRefreshData(!refreshData); + props.setRefreshData(!props.refreshData); }) .catch((error) => console.error(error)); handleClose(); @@ -155,7 +193,7 @@ function UpdateMaintenanceHistory(props) { return ( <> - + @@ -170,10 +208,15 @@ function UpdateMaintenanceHistory(props) { Type - - - - + + + + + + + + + @@ -202,7 +245,6 @@ function UpdateMaintenanceHistory(props) { - @@ -217,14 +259,10 @@ function UpdateMaintenanceHistory(props) { } function DeleteMaintenanceHistory(props) { - const [loading, setLoading] = useState(true); - const [refreshData, setRefreshData] = useState(false); - const [show, setShow] = useState(false); const handleClose = () => setShow(false); const handleShow = () => setShow(true); - const handleDelete = (e) => { e.preventDefault(); const myHeaders = new Headers(); @@ -244,10 +282,11 @@ function DeleteMaintenanceHistory(props) { redirect: "follow" }; - fetch("/api/delete-maintenance-history?configId="+props.configId, reqOptions) + fetch(`/api/delete-maintenance-history?configId=${props.configId}`, reqOptions) .then((response) => response.text()) .then((result) => { - setRefreshData(!refreshData); + console.log(result); + props.setRefreshData(!props.refreshData); }) .catch((error) => console.error(error)); @@ -256,7 +295,7 @@ function DeleteMaintenanceHistory(props) { return ( <> - + @@ -272,7 +311,7 @@ function DeleteMaintenanceHistory(props) { - ) + ); } -export default VehicleHistory \ No newline at end of file +export default VehicleHistory; diff --git a/frontend/src/pages/vehicle/VehicleInfo.js b/frontend/src/pages/vehicle/VehicleInfo.js index 35a3bf6..60dcfcb 100644 --- a/frontend/src/pages/vehicle/VehicleInfo.js +++ b/frontend/src/pages/vehicle/VehicleInfo.js @@ -148,11 +148,13 @@ function VehicleInfo() { -

navigate('/garage')} - style={{cursor: 'pointer', color: '#644A77', fontWeight: 'bold'}}> +

+ navigate('/garage')} + style={{cursor: 'pointer', color: '#644A77', fontWeight: 'bold'}}> {user} Garage - > - {info ? ` ${info.year} ${info.make} ${info.model}` : ' Loading Vehicle Info...'} + + + {' >'}{info ? ` ${info.year} ${info.make} ${info.model}` : ' Loading Vehicle Info...'}

@@ -160,7 +162,8 @@ function VehicleInfo() { @@ -168,8 +171,7 @@ function VehicleInfo() { - Vehicle - Specifications + Vehicle Specifications {info ? ( <> @@ -199,7 +201,10 @@ function VehicleInfo() {
- +
@@ -208,8 +213,9 @@ function VehicleInfo() { {upcomingMaintenance && ( - Upcoming - Maintenance Procedures | Due at: {upcomingMaintenance} miles + + Upcoming Maintenance Procedures | Due at: {upcomingMaintenance} miles + {maintenance && maintenance.tasks.length > 0 ? ( From 0c0c74bcd46a13fc0a6fd9c556fa97bd262c371b Mon Sep 17 00:00:00 2001 From: ntuff Date: Mon, 15 Apr 2024 04:40:36 -0230 Subject: [PATCH 2/6] Added footer w/ privacy policy, styling improvements --- frontend/src/pages/App.js | 14 +- frontend/src/pages/Footer.js | 15 ++ frontend/src/pages/Login.js | 3 +- frontend/src/pages/garage/Garage.js | 2 +- frontend/src/pages/garage/RemoveVehicle.js | 8 +- frontend/src/pages/vehicle/VehicleHistory.js | 152 ++++++++++--------- 6 files changed, 114 insertions(+), 80 deletions(-) create mode 100644 frontend/src/pages/Footer.js diff --git a/frontend/src/pages/App.js b/frontend/src/pages/App.js index 954e047..aeb1cef 100644 --- a/frontend/src/pages/App.js +++ b/frontend/src/pages/App.js @@ -10,6 +10,7 @@ import AddVehicle from "./garage/AddVehicle"; import RemoveVehicle from "./garage/RemoveVehicle"; import {Settings} from "./Settings"; import {useState} from "react"; +import Footer from "./Footer"; const ProtectedRoute = () => { const authenticated = localStorage.getItem('token') !== null; @@ -22,24 +23,27 @@ function App() { return ( -
+
- } /> + } /> } /> }> } /> } /> - } /> - } /> + } /> + } /> } /> } /> } /> +
+
+
- ) + ); } export default App; \ No newline at end of file diff --git a/frontend/src/pages/Footer.js b/frontend/src/pages/Footer.js new file mode 100644 index 0000000..f463b12 --- /dev/null +++ b/frontend/src/pages/Footer.js @@ -0,0 +1,15 @@ +import React from 'react'; +import { Container } from 'react-bootstrap'; + +function Footer() { + return ( + + ); +} + +export default Footer; diff --git a/frontend/src/pages/Login.js b/frontend/src/pages/Login.js index c5a0947..56aacfa 100644 --- a/frontend/src/pages/Login.js +++ b/frontend/src/pages/Login.js @@ -48,8 +48,7 @@ export const Login = () => {

Welcome to Driveline

Your personalized tool to help keep your vehicle in top condition.

- - {error &&
{error}
} + {error &&
{error}
}
); diff --git a/frontend/src/pages/garage/Garage.js b/frontend/src/pages/garage/Garage.js index 67809c0..f188a5d 100644 --- a/frontend/src/pages/garage/Garage.js +++ b/frontend/src/pages/garage/Garage.js @@ -86,7 +86,7 @@ function Garage(props) { {props.info ? props.info.map((vehicle, index) => (
- + )) : !loading && No vehicles found.} diff --git a/frontend/src/pages/garage/RemoveVehicle.js b/frontend/src/pages/garage/RemoveVehicle.js index 3a82254..54742a3 100644 --- a/frontend/src/pages/garage/RemoveVehicle.js +++ b/frontend/src/pages/garage/RemoveVehicle.js @@ -39,18 +39,18 @@ function RemoveVehicle(props) { return ( <> - + Are you sure you want to delete? - Deletion is irreversible. + Removing this vehicle will also result in the loss of any maintenance history associated with it. - - + + diff --git a/frontend/src/pages/vehicle/VehicleHistory.js b/frontend/src/pages/vehicle/VehicleHistory.js index a258ce8..0d5e873 100644 --- a/frontend/src/pages/vehicle/VehicleHistory.js +++ b/frontend/src/pages/vehicle/VehicleHistory.js @@ -1,8 +1,8 @@ -import {Routes, Route, useLocation} from "react-router-dom"; +import {Routes, Route, useLocation, useNavigate} from "react-router-dom"; import VehicleNavbar from "./VehicleNavbar"; import UploadNavbar from "../maintenance-history/UploadNavbar"; import { useEffect, useRef, useState } from "react"; -import { Button, Modal, Alert, Form, InputGroup, Container, Row, Col, Table } from "react-bootstrap"; +import { Button, Modal, Alert, Form, InputGroup, Container, Row, Col, Table, Card } from "react-bootstrap"; import ManualVehicleHistory from "../maintenance-history/ManualVehicleHistory"; function VehicleHistory(props) { @@ -84,71 +84,88 @@ function VehicleHistory(props) { }, [refreshData]); return ( - - -

- navigate('/garage')} style={{ cursor: 'pointer', color: '#644A77', fontWeight: 'bold' }}> - {user} Garage - - {' > '} - {vehicleInfo ? ( - navigate(`/garage/vehicle-info/${configId}`, {state: {configId}})} + + +

+

+ navigate('/garage')} style={{ cursor: 'pointer', color: '#644A77', fontWeight: 'bold' }}> - {vehicleInfo.year} {vehicleInfo.make} {vehicleInfo.model} - - ) : ( - Loading Vehicle Info... - )} - {' > '} Maintenance History -

+ {user} Garage + + {' > '} + {vehicleInfo ? ( + navigate(`/garage/vehicle-info/${configId}`, {state: {configId}})} + style={{ cursor: 'pointer', color: '#644A77', fontWeight: 'bold' }}> + {vehicleInfo.year} {vehicleInfo.make} {vehicleInfo.model} + + ) : ( + Loading Vehicle Info... + )} + {' > '} Maintenance History + + - - -
- - - - - - - - - - - {maintenance != null ? - maintenance.completed_maintenance.map((service, index) => ( - - - - - - + + + + Detailed Maintenance Records + + +
ActionPartCostDateEdit/Remove
{service.type}{service.maintenance}${parseFloat(service.cost).toFixed(2)}{service.date} - - - - -
+ + + + + + + - )) : - } - -
ActionPartCostDate
No maintenance history!
+ + + {maintenance && maintenance.completed_maintenance.map((service, index) => ( + + {service.type} + {service.maintenance} + ${parseFloat(service.cost).toFixed(2)} + {service.date} + + + {/* Adding a span with horizontal padding */} + + + + + ))} + + + +
+
@@ -159,6 +176,7 @@ function UpdateMaintenanceHistory(props) { const [show, setShow] = useState(false); const handleClose = () => setShow(false); const handleShow = () => setShow(true); + const [refreshData, setRefreshData] = useState(false); const typeText = useRef(); const dateText = useRef(); @@ -274,14 +292,12 @@ function DeleteMaintenanceHistory(props) { const myHeaders = new Headers(); myHeaders.append("Content-Type", "application/json"); myHeaders.append("Authorization", "Bearer " + localStorage.getItem('token')); - const raw = JSON.stringify({ "type": props.maintenanceInfo.type, "date": props.maintenanceInfo.date, "maintenance": props.maintenanceInfo.maintenance, "cost": props.maintenanceInfo.cost }); - const reqOptions = { method: "DELETE", headers: myHeaders, @@ -292,8 +308,8 @@ function DeleteMaintenanceHistory(props) { fetch(`/api/delete-maintenance-history?configId=${props.configId}`, reqOptions) .then((response) => response.text()) .then((result) => { - setRefreshData(!refreshData); - window.location.reload(); + console.log(result); + props.setRefreshData(!props.refreshData); }) .catch((error) => console.error(error)); @@ -302,23 +318,23 @@ function DeleteMaintenanceHistory(props) { return ( <> - + Are you sure you want to delete? - Deletion is irreversible. + Once an entry is deleted it cannot be restored. - - + + - ); + ) } -export default VehicleHistory; +export default VehicleHistory \ No newline at end of file From 52820d21adf2e16db0c6bbc586a7668d9ba2a39d Mon Sep 17 00:00:00 2001 From: brandon Date: Mon, 15 Apr 2024 15:52:15 -0230 Subject: [PATCH 3/6] #mino --- backend-lambda/OAuthProcessing/index.mjs | 122 +++++++++++----------- frontend/src/pages/garage/Garage.js | 60 ++++++----- frontend/src/pages/vehicle/VehicleInfo.js | 2 +- 3 files changed, 92 insertions(+), 92 deletions(-) diff --git a/backend-lambda/OAuthProcessing/index.mjs b/backend-lambda/OAuthProcessing/index.mjs index 9c0935d..cbf6b64 100644 --- a/backend-lambda/OAuthProcessing/index.mjs +++ b/backend-lambda/OAuthProcessing/index.mjs @@ -11,12 +11,12 @@ export const handler = async (event, context) => { process.env.CLIENT_SECRET, process.env.OAUTH_CALLBACK_URL ); - const { code } = event['queryStringParameters']; - const { tokens } = await oauthClient.getToken(code); + const {code} = event['queryStringParameters']; + const {tokens} = await oauthClient.getToken(code); const url = getAccessAndBearerTokenUrl(tokens.access_token); const myHeaders = new Headers(); - const bearerToken = "Bearer "+tokens.id_token; + const bearerToken = "Bearer " + tokens.id_token; myHeaders.append("Authorization", bearerToken); const reqOptions = { @@ -24,33 +24,37 @@ export const handler = async (event, context) => { headers: myHeaders, redirect: 'follow' }; - return await fetch(url, reqOptions) - .then(response => response.json()) - .then(res => { - let user = updateOrCreateUserFromOAuth(res); - console.log("RES " + JSON.stringify(res)); - const payload = { - name: res.name, - email: res.email + + try { + let response = await fetch(url, reqOptions); + console.log(response) + let res = await response.json(); + console.log(res) + await updateOrCreateUserFromOAuth(res); + const payload = { + name: res.name, + email: res.email + } + console.log("PAYLOAD " + JSON.stringify(payload)); + const token = jwt.sign( payload, JWTSecret, {expiresIn: '2d'} ); + console.log("TOKEN " + token); + console.log("VERIFY " + jwt.verify(token, JWTSecret)); + console.log("DECODE " + jwt.decode(token, JWTSecret).name + " " + jwt.decode(token, JWTSecret).email); + + return { + statusCode: 302, + headers: { + "Location": `${process.env.APP_URL}/login?token=${token}` } - console.log("PAYLOAD " + JSON.stringify(payload)); - const token = jwt.sign( payload, JWTSecret, {expiresIn: '2d'} ); - console.log("TOKEN " + token); - console.log("VERIFY " + jwt.verify(token, JWTSecret)); - console.log("DECODE " + jwt.decode(token, JWTSecret).name + " " + jwt.decode(token, JWTSecret).email); - return { - statusCode: 302, - headers: { - "Location": `${process.env.APP_URL}/login?token=${token}` - } - }; - }).catch(err => { - return { - statusCode: 500, - body: JSON.stringify({ message: `Internal Server Error: ${err.message}` }) - }; - }); -}; + }; + } catch (err) { + return { + statusCode: 500, + body: err.message + }; + + } +} const updateOrCreateUserFromOAuth = async (user) => { const uri = process.env.MONGO_URI; @@ -65,42 +69,36 @@ const updateOrCreateUserFromOAuth = async (user) => { const { name, email } = user; console.log("UPDATE OR CREATE FROM OAUTH -- NAME & EMAIL " + name + " " + email) - return client.connect() - .then(async () => { - const database = client.db("vehicleDB"); - const users = database.collection("users"); - const existingUser = await users.findOne({email}) - if( existingUser ) { - console.log("User exists") - const result = await users.findOneAndUpdate({email}, - { $set: {name, email}}, - { returnDocument: "after"} - ); - console.log("Result: ", result.value.name + " " + result.value.email) - return { - statusCode: 200, - body: JSON.stringify(result.value) - }; - } - else { - console.log("User does not exist") - const result = await users.insertOne( {email, name}); - console.log("Result: ", result.value.name + " " + result.value.email) - return { - statusCode: 200, - body: JSON.stringify(result.value) - }; - } - }).catch(err => { - return { - statusCode: 500, - body: JSON.stringify({ message: `Internal Server Error: ${err.message}` }) - }; - }).finally(() => client.close()); -}; + try { + await client.connect(); + const database = client.db("vehicleDB"); + const users = database.collection("users"); + const existingUser = await users.findOne({email}); + if (existingUser) { + console.log("User exists") + await users.findOneAndUpdate({email}, + {$set: {name, email}}, + {returnDocument: "after"} + ); + console.log("UPDATED USER") + } else { + console.log("User does not exist") + await users.insertOne({email, name}); + console.log("NEW USER ADDED") + + } + } + catch (e) { + console.log(e.message); + } + finally{ + console.log("FINISHED") + await client.close(); + } +} const getAccessAndBearerTokenUrl = (access_token) => { return `https://www.googleapis.com/oauth2/v1/userinfo?alt=json&access_token=${access_token}`; }; \ No newline at end of file diff --git a/frontend/src/pages/garage/Garage.js b/frontend/src/pages/garage/Garage.js index 2e8d51b..59a81da 100644 --- a/frontend/src/pages/garage/Garage.js +++ b/frontend/src/pages/garage/Garage.js @@ -11,34 +11,6 @@ function Garage(props) { const navigate = useNavigate(); const [refreshData, setRefreshData] = useState(false); - - useEffect(() => { - const fetchUser = async () => { - try { - const token = localStorage.getItem('token'); - if (token) { - const response = await fetch('/api/user', { - headers: { - 'Authorization': `Bearer ${token}` - } - }); - if (response.ok) { - const { data } = await response.json(); - const firstName = data.name.split(' ')[0]; - setUser(`${firstName}'s`); - } else { - console.error("User not found"); - setUser("User's"); - } - } - } catch (error) { - console.error(error); - setUser("User's"); - } - }; - fetchUser(); - }, []); - useEffect(() => { const myHeaders = new Headers(); @@ -66,12 +38,42 @@ function Garage(props) { }); }, [refreshData]); + useEffect(() => { + fetchUser(); + }, []); + + const fetchUser = async () => { + try { + const token = localStorage.getItem('token'); + if (token) { + const response = await fetch('/api/user', { + headers: { + 'Authorization': `Bearer ${token}` + } + }); + if (response.ok) { + const data = await response.json(); + console.log(data); + const firstName = data.name.split(' ')[0]; + console.log(firstName) + setUser(`${firstName}'s`); + } else { + console.error("User not found"); + setUser("User's"); + } + } + } catch (error) { + console.error(error); + setUser("User's"); + } + }; + return (

navigate('/garage')} style={{ cursor: 'pointer', color: '#644A77', fontWeight: 'bold' }}> - User Garage + ${user} Garage

Add New Vehicle diff --git a/frontend/src/pages/vehicle/VehicleInfo.js b/frontend/src/pages/vehicle/VehicleInfo.js index 7cc5c9c..78034b4 100644 --- a/frontend/src/pages/vehicle/VehicleInfo.js +++ b/frontend/src/pages/vehicle/VehicleInfo.js @@ -182,7 +182,7 @@ function VehicleInfo() { style={{cursor: 'pointer', color: '#644A77', fontWeight: 'bold'}}> {user} Garage > - {info ? ` ${info.year} ${info.make} ${info.model}` : ' Loading Vehicle Info...'} + {info ? ` ${info.message.year} ${info.message.make} ${info.message.model}` : ' Loading Vehicle Info...'} From dd3198b7afac54941090eb0606000900474e3c2e Mon Sep 17 00:00:00 2001 From: brandon Date: Mon, 15 Apr 2024 15:55:21 -0230 Subject: [PATCH 4/6] #minor All lambdas working --- frontend/src/pages/vehicle/VehicleInfo.js | 1 - 1 file changed, 1 deletion(-) diff --git a/frontend/src/pages/vehicle/VehicleInfo.js b/frontend/src/pages/vehicle/VehicleInfo.js index 78034b4..fd6e37f 100644 --- a/frontend/src/pages/vehicle/VehicleInfo.js +++ b/frontend/src/pages/vehicle/VehicleInfo.js @@ -173,7 +173,6 @@ function VehicleInfo() { }); } - return ( From 1faa1eb808ba9b6797d29c26171407e09fe61515 Mon Sep 17 00:00:00 2001 From: ntuff Date: Mon, 15 Apr 2024 16:02:03 -0230 Subject: [PATCH 5/6] Frontend improvements --- frontend/src/pages/vehicle/VehicleHistory.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/frontend/src/pages/vehicle/VehicleHistory.js b/frontend/src/pages/vehicle/VehicleHistory.js index c12c710..0d5e873 100644 --- a/frontend/src/pages/vehicle/VehicleHistory.js +++ b/frontend/src/pages/vehicle/VehicleHistory.js @@ -53,8 +53,8 @@ function VehicleHistory(props) { headers: myHeaders, redirect: 'follow' }; - fetch('/api/get-vehicle-history?config_id='+configId, reqOptions) - .then( (res) => { + fetch(`/api/get-vehicle-info?configId=${configId}`, reqOptions) + .then((res) => { if (!res.ok) { throw new Error('Network response was not ok'); } @@ -81,7 +81,7 @@ function VehicleHistory(props) { .catch((error) => { console.error('There has been a problem with your fetch operation:', error); }); - }, []); + }, [refreshData]); return ( @@ -204,8 +204,8 @@ function UpdateMaintenanceHistory(props) { redirect: 'follow' }; - fetch("/api/update-maintenance-history?config_id="+props.configId, reqOptions) - .then((res) => res.text()) + fetch(`/api/update-maintenance-history?configId=${props.configId}`, reqOptions) + .then((res) => res.json()) .then((result) => { console.log(result); setRefreshData(!refreshData); @@ -305,7 +305,7 @@ function DeleteMaintenanceHistory(props) { redirect: "follow" }; - fetch("/api/delete-maintenance-history?config_id="+props.configId, reqOptions) + fetch(`/api/delete-maintenance-history?configId=${props.configId}`, reqOptions) .then((response) => response.text()) .then((result) => { console.log(result); From 0324662ed16318aaa34a2cac5cdc499bb4413ca6 Mon Sep 17 00:00:00 2001 From: ntuff Date: Mon, 15 Apr 2024 16:40:49 -0230 Subject: [PATCH 6/6] Fixed sign-in button and nav bar icon --- frontend/src/pages/NavBar.js | 2 +- frontend/src/pages/Settings.js | 15 +++++++++++++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/frontend/src/pages/NavBar.js b/frontend/src/pages/NavBar.js index 7df7c0f..dc6ae64 100644 --- a/frontend/src/pages/NavBar.js +++ b/frontend/src/pages/NavBar.js @@ -47,7 +47,7 @@ function NavBar() { diff --git a/frontend/src/pages/Settings.js b/frontend/src/pages/Settings.js index c3bcd12..9973700 100644 --- a/frontend/src/pages/Settings.js +++ b/frontend/src/pages/Settings.js @@ -1,8 +1,9 @@ import React, { useState } from 'react'; import Button from 'react-bootstrap/Button'; import Offcanvas from 'react-bootstrap/Offcanvas'; -import {Nav} from "react-bootstrap"; +import {Col, Nav, Row} from "react-bootstrap"; import { useNavigate } from 'react-router-dom'; +import {GearFill} from "react-bootstrap-icons"; export const Settings = (props) => { const [darkMode, setDarkMode] = useState(false); @@ -26,7 +27,17 @@ export const Settings = (props) => { return (
{/**/} - {props.greeting} + + + + + {props.greeting} + + + + + + Settings