Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prettifying frontend #47

Merged
merged 11 commits into from
Apr 15, 2024
122 changes: 60 additions & 62 deletions backend-lambda/OAuthProcessing/index.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -11,46 +11,50 @@ 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 = {
method: 'GET',
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;
Expand All @@ -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}`;
};
10 changes: 3 additions & 7 deletions frontend/src/App.css
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
14 changes: 9 additions & 5 deletions frontend/src/pages/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import ManualVehicleHistory from "./maintenance-history/ManualVehicleHistory";
import AddVehicle from "./garage/AddVehicle";
import {Settings} from "./Settings";
import {useState} from "react";
import Footer from "./Footer";

const ProtectedRoute = () => {
const authenticated = localStorage.getItem('token') !== null;
Expand All @@ -21,24 +22,27 @@ function App() {

return (
<Router>
<div>
<div className="d-flex flex-column min-vh-100">
<NavBar />
<Routes>
<Route path= "/" element={<Login />} />
<Route path="/" element={<Login />} />
<Route path="/login" element={<Login />} />
<Route element={<ProtectedRoute />}>
<Route path="/garage" element={<Garage info={garageInfo} setInfo={setGarageInfo} />} />
<Route path="/garage/add" element={<AddVehicle />} />
<Route path="/garage/vehicle-info/:vehicle/*" element={<VehicleInfo configId={configId} setConfig={setConfigId}/>} />
<Route path="/garage/vehicle-history/:vehicle/*" element={<VehicleHistory configId={configId} setConfig={setConfigId}/>} />
<Route path="/garage/vehicle-info/:vehicle/*" element={<VehicleInfo configId={configId} setConfig={setConfigId} />} />
<Route path="/garage/vehicle-history/:vehicle/*" element={<VehicleHistory configId={configId} setConfig={setConfigId} />} />
<Route path="/garage/vehicle-history/upload" element={<UploadVehicleHistory />} />
<Route path="/garage/vehicle-history/manual" element={<ManualVehicleHistory />} />
<Route path="/settings" element={<Settings />} />
</Route>
</Routes>
<div className="mt-auto">
<Footer />
</div>
</div>
</Router>
)
);
}

export default App;
15 changes: 15 additions & 0 deletions frontend/src/pages/Footer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import React from 'react';
import { Container } from 'react-bootstrap';

function Footer() {
return (
<footer className="footer mt-auto py-3 bg-light">
<Container className="text-center">
<span className="text-muted">© 2024 drivelineapp.xyz | </span>
<a href="https://github.com/dheffer/PredictiveVehicleMaintenanceSystem/blob/main/privacy-policy.md" target="_blank" rel="noopener noreferrer">Privacy Policy</a>
</Container>
</footer>
);
}

export default Footer;
3 changes: 1 addition & 2 deletions frontend/src/pages/Login.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,7 @@ export const Login = () => {
<img src="/logo.png" alt="Logo" id="driveline-diamond-logo" />
<h1>Welcome to <span className="drive">Drive</span><span className="line">line</span></h1>
<p id="intro-text">Your personalized tool to help keep your vehicle in top condition.</p>
<Button variant="primary" id="get-started-button" onClick={handleLogin} className="mt-4">Sign in with Google</Button>
{error && <div className="mt-3"><Alert variant="danger">{error}</Alert></div>}
<Button variant="primary" id="get-started-button" onClick={handleLogin} className="mt-4" style={{ backgroundColor: '#644A77', borderColor: '#644A77' }}>Sign in with Google</Button> {error && <div className="mt-3"><Alert variant="danger">{error}</Alert></div>}
</Container>
</div>
);
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/pages/NavBar.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ function NavBar() {
<Nav className="ms-auto">
<Nav.Link>
<Settings greeting={user ? user : 'Sign in'} />
<GearFill className="ml-2" />

</Nav.Link>
</Nav>
</Container>
Expand Down
15 changes: 13 additions & 2 deletions frontend/src/pages/Settings.js
Original file line number Diff line number Diff line change
@@ -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);
Expand All @@ -26,7 +27,17 @@ export const Settings = (props) => {
return (
<div>
{/*<Button variant="primary" onClick={handleShow}>Settings</Button>*/}
<Nav.Link onClick={handleShow} className={".align-items-center"} >{props.greeting}</Nav.Link>

<Nav.Link onClick={handleShow} className="align-items-center">
<Row>
<Col lg="auto">
{props.greeting}
</Col>
<Col>
<GearFill className=".pe-2" />
</Col>
</Row>
</Nav.Link>
<Offcanvas show={show} onHide={handleShow} placement="end">
<Offcanvas.Header closeButton>
<Offcanvas.Title>Settings</Offcanvas.Title>
Expand Down
18 changes: 11 additions & 7 deletions frontend/src/pages/garage/AddVehicle.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import React, { useEffect, useState } from "react";
import { Button, Form, Container, Row, Col } from 'react-bootstrap';
import '../../App.css';
import {useNavigate} from "react-router-dom";

function AddVehicle() {

const [refreshData, setRefreshData] = useState(false);
Expand Down Expand Up @@ -61,21 +62,21 @@ function AddVehicle() {
}, []);

const handleChange = async (e) => {
const {name, value} = e.target;
const { name, value } = e.target;
setSelectedVehicle(prevSelectedVehicle => ({
...prevSelectedVehicle,
[name]: value
}));

if (name === 'year') {
getDropdownValues('makes', value);
setDropdownValues(prev => ({...prev, models: [], engines: [], transmissions: []}));
setDropdownValues(prev => ({ ...prev, models: [], engines: [], transmissions: [] }));
} else if (name === 'make') {
getDropdownValues('models', selectedVehicle.year, value);
setDropdownValues(prev => ({...prev, engines: [], transmissions: []}));
setDropdownValues(prev => ({ ...prev, engines: [], transmissions: [] }));
} else if (name === 'model') {
getDropdownValues('engines', selectedVehicle.year, selectedVehicle.make, value);
setDropdownValues(prev => ({...prev, transmissions: []}));
setDropdownValues(prev => ({ ...prev, transmissions: [] }));
} else if (name === 'engine') {
getDropdownValues('transmissions', selectedVehicle.year, selectedVehicle.make, selectedVehicle.model, value);
}
Expand Down Expand Up @@ -250,9 +251,12 @@ function AddVehicle() {
)}

<div className="text-center mt-4">
<Button className="btn btn-primary" onClick={handleSelectAndAddVehicle}
disabled={!selectedVehicle.transmission || vehicleAdded}>Select and Add
Vehicle</Button>
<Button
style={{backgroundColor: '#644A77', borderColor: '#644A77'}}
onClick={handleSelectAndAddVehicle}
disabled={!selectedVehicle.transmission || vehicleAdded}>
Add Vehicle
</Button>
</div>
{vehicleAdded && <div className="alert alert-success mt-4" role="alert">
Vehicle has been added successfully!
Expand Down
12 changes: 8 additions & 4 deletions frontend/src/pages/garage/Garage.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ function Garage(props) {
}, []);

useEffect(() => {

const myHeaders = new Headers();
myHeaders.append("Authorization", "Bearer " + localStorage.getItem('token'));

Expand Down Expand Up @@ -68,12 +67,17 @@ function Garage(props) {

return (
<Container className="mt-5">
<Row className="mb-4 justify-content-between align-items-center">
<Row className="mb-3">
<Col>
<h2 className="d-inline-block mr-4" onClick={()=> navigate('/garage')} style={{ cursor: 'pointer', color: '#644A77', fontWeight: 'bold' }}>
<h2 onClick={() => navigate('/garage')}
style={{cursor: 'pointer', color: '#644A77', fontWeight: 'bold'}}>
{user} Garage
</h2>
<Link to="/garage/add" className="btn btn-primary" style={{verticalAlign: 'baseline', marginLeft: '10px'}}>
</Col>
</Row>
<Row className="mb-3">
<Col className="text-start">
<Link to="/garage/add" className="btn btn-primary" style={{ backgroundColor: '#8c7498', borderColor: '#8c7498' }}>
Add New Vehicle
</Link>
</Col>
Expand Down
10 changes: 5 additions & 5 deletions frontend/src/pages/garage/RemoveVehicle.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,23 +39,23 @@ function RemoveVehicle(props) {

return (
<>
<Button onClick={handleShow}>Remove</Button>
<Button variant="secondary" onClick={handleShow}>Remove</Button>
<Modal show={show} onHide={handleClose}>
<Modal.Dialog>
<Modal.Header closeButton>
<Modal.Title>Are you sure you want to delete?</Modal.Title>
</Modal.Header>
<Modal.Body className={'text-justify-center'}>
<Alert key={'danger'} variant={'danger'} className={'text-justify'}>Deletion is irreversible.</Alert>
<Alert key={'danger'} variant={'danger'} className={'text-justify'}>Removing this vehicle will also result in the loss of any maintenance history associated with it.</Alert>
</Modal.Body>
<Modal.Footer className={'mx-auto'}>
<Button variant="secondary" onClick={handleClose}>No, take me back.</Button>
<Button variant="primary" onClick={handleDelete}>Yes, I am sure.</Button>
<Button variant="secondary" onClick={handleClose}>No, take me back</Button>
<Button variant={"danger"} onClick={handleDelete}>Remove vehicle</Button>
</Modal.Footer>
</Modal.Dialog>
</Modal>
</>
)
}

export default RemoveVehicle;
export default RemoveVehicle;
4 changes: 2 additions & 2 deletions frontend/src/pages/garage/Vehicle.js
Original file line number Diff line number Diff line change
Expand Up @@ -141,9 +141,9 @@ function Vehicle(props) {
<Card.Title className={'d-flex justify-content-center'}>{v.configurations.year} {v.configurations.make} {v.configurations.model}</Card.Title>
<Card.Text className="d-flex justify-content-around">
<Link to={`/garage/vehicle-info/${v.configurations.config_id}`} state={{configId: v.configurations.config_id}}>
<Button className={"btn btn-primary"}>View Info</Button>
<Button style={{ backgroundColor: '#8c7498', borderColor: '#8c7498' }}>View Info</Button>
</Link>
<RemoveVehicle configId={v.configurations.config_id}/>
<RemoveVehicle configId={v.configurations.config_id} />
</Card.Text>
<Card.Footer className="d-flex justify-content-around">
<div className="d-flex flex-column align-items-center">
Expand Down
Loading
Loading