Merge branch 'main' of https://github.com/jacobmveber-01839764/BudgetBuddy
BIN
build/BudgetBuddyLogo.ico
Normal file
|
After Width: | Height: | Size: 226 KiB |
23
build/asset-manifest.json
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"files": {
|
||||
"main.css": "/static/css/main.a647f1f7.css",
|
||||
"main.js": "/static/js/main.205e7457.js",
|
||||
"static/js/496.f12dc038.chunk.js": "/static/js/496.f12dc038.chunk.js",
|
||||
"static/media/budgethero1.png": "/static/media/budgethero1.ef97d4454cc11d5d60d0.png",
|
||||
"static/media/umass_lowell.jpeg": "/static/media/umass_lowell.adff7eaefc5d0aa6343d.jpeg",
|
||||
"static/media/expenses_logo.png": "/static/media/expenses_logo.f24db1454b6c041fade7.png",
|
||||
"static/media/money2.png": "/static/media/money2.4e0a9f8da499f5fe72a1.png",
|
||||
"static/media/money1.png": "/static/media/money1.900d2433a99d49f20ade.png",
|
||||
"static/media/river_hawk.png": "/static/media/river_hawk.175d1b2ee8b8ae31ab50.png",
|
||||
"static/media/money3.png": "/static/media/money3.8859e70f73221654d7ed.png",
|
||||
"static/media/BudgetBuddyLogo.png": "/static/media/BudgetBuddyLogo.8e4cd296c3a372956bf4.png",
|
||||
"index.html": "/index.html",
|
||||
"main.a647f1f7.css.map": "/static/css/main.a647f1f7.css.map",
|
||||
"main.205e7457.js.map": "/static/js/main.205e7457.js.map",
|
||||
"496.f12dc038.chunk.js.map": "/static/js/496.f12dc038.chunk.js.map"
|
||||
},
|
||||
"entrypoints": [
|
||||
"static/css/main.a647f1f7.css",
|
||||
"static/js/main.205e7457.js"
|
||||
]
|
||||
}
|
||||
15
build/manifest.json
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"short_name": "React App",
|
||||
"name": "Create React App Sample",
|
||||
"icons": [
|
||||
{
|
||||
"src": "favicon.ico",
|
||||
"sizes": "64x64 32x32 24x24 16x16",
|
||||
"type": "image/x-icon"
|
||||
}
|
||||
],
|
||||
"start_url": ".",
|
||||
"display": "standalone",
|
||||
"theme_color": "#000000",
|
||||
"background_color": "#ffffff"
|
||||
}
|
||||
3
build/robots.txt
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
# https://www.robotstxt.org/robotstxt.html
|
||||
User-agent: *
|
||||
Disallow:
|
||||
13
build/static/css/main.a647f1f7.css
Normal file
1
build/static/css/main.a647f1f7.css.map
Normal file
2
build/static/js/496.f12dc038.chunk.js
Normal file
1
build/static/js/496.f12dc038.chunk.js.map
Normal file
3
build/static/js/main.205e7457.js
Normal file
122
build/static/js/main.205e7457.js.LICENSE.txt
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
/*!
|
||||
Copyright (c) 2018 Jed Watson.
|
||||
Licensed under the MIT License (MIT), see
|
||||
http://jedwatson.github.io/classnames
|
||||
*/
|
||||
|
||||
/*!
|
||||
*
|
||||
* Copyright 2009-2017 Kris Kowal under the terms of the MIT
|
||||
* license found at https://github.com/kriskowal/q/blob/v1/LICENSE
|
||||
*
|
||||
* With parts by Tyler Close
|
||||
* Copyright 2007-2009 Tyler Close under the terms of the MIT X license found
|
||||
* at http://www.opensource.org/licenses/mit-license.html
|
||||
* Forked at ref_send.js version: 2009-05-11
|
||||
*
|
||||
* With parts by Mark Miller
|
||||
* Copyright (C) 2011 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @kurkle/color v0.3.2
|
||||
* https://github.com/kurkle/color#readme
|
||||
* (c) 2023 Jukka Kurkela
|
||||
* Released under the MIT License
|
||||
*/
|
||||
|
||||
/*!
|
||||
* Chart.js v4.2.1
|
||||
* https://www.chartjs.org
|
||||
* (c) 2023 Chart.js Contributors
|
||||
* Released under the MIT License
|
||||
*/
|
||||
|
||||
/*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */
|
||||
|
||||
/**
|
||||
* @license React
|
||||
* react-dom.production.min.js
|
||||
*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @license React
|
||||
* react-jsx-runtime.production.min.js
|
||||
*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @license React
|
||||
* react.production.min.js
|
||||
*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @license React
|
||||
* scheduler.production.min.js
|
||||
*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @mui/styled-engine v5.12.0
|
||||
*
|
||||
* @license MIT
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
/**
|
||||
* A better abstraction over CSS.
|
||||
*
|
||||
* @copyright Oleg Isonen (Slobodskoi) / Isonen 2014-present
|
||||
* @website https://github.com/cssinjs/jss
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
/** @license React v16.13.1
|
||||
* react-is.production.min.js
|
||||
*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
/** @license React v17.0.2
|
||||
* react-is.production.min.js
|
||||
*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
1
build/static/js/main.205e7457.js.map
Normal file
BIN
build/static/media/BudgetBuddyLogo.8e4cd296c3a372956bf4.png
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
build/static/media/budgethero1.ef97d4454cc11d5d60d0.png
Normal file
|
After Width: | Height: | Size: 483 KiB |
BIN
build/static/media/expenses_logo.f24db1454b6c041fade7.png
Normal file
|
After Width: | Height: | Size: 334 KiB |
BIN
build/static/media/money1.900d2433a99d49f20ade.png
Normal file
|
After Width: | Height: | Size: 120 KiB |
BIN
build/static/media/money2.4e0a9f8da499f5fe72a1.png
Normal file
|
After Width: | Height: | Size: 121 KiB |
BIN
build/static/media/money3.8859e70f73221654d7ed.png
Normal file
|
After Width: | Height: | Size: 76 KiB |
BIN
build/static/media/river_hawk.175d1b2ee8b8ae31ab50.png
Normal file
|
After Width: | Height: | Size: 80 KiB |
BIN
build/static/media/umass_lowell.adff7eaefc5d0aa6343d.jpeg
Normal file
|
After Width: | Height: | Size: 441 KiB |
|
|
@ -1,14 +1,14 @@
|
|||
import React, { useContext, useState, useEffect } from 'react';
|
||||
import ExpenseItem from './ExpenseItem';
|
||||
import { AppContext } from '../context/AppContext';
|
||||
|
||||
|
||||
import './css/ExpenseList.css'
|
||||
|
||||
const ExpenseList = () => {
|
||||
const [whole, setWhole] = useState('');
|
||||
const [decimal, setDecimal] = useState('');
|
||||
const [transaction, setTransactions] = useState('');
|
||||
const [category, setCategories] = useState('');
|
||||
const [time, setTime] = useState('');
|
||||
|
||||
function getSessionKey() {
|
||||
var cookies = document.cookie.split(';');
|
||||
|
|
@ -68,13 +68,41 @@ const ExpenseList = () => {
|
|||
}
|
||||
}
|
||||
|
||||
async function buildTable(data1, data2){
|
||||
async function getDate() {
|
||||
try {
|
||||
const response = await fetch('https://api.bb.gabefarrell.com/w/transactions/recent', {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'x-session-key': getSessionKey(),
|
||||
},
|
||||
});
|
||||
const data = await response.json();
|
||||
const timestamp = data.transactions.map((item)=>item.timestamp);
|
||||
let dateFormat = [];
|
||||
let date, month, day;
|
||||
for (let i = 0; i < timestamp.length; i++) {
|
||||
date = new Date(timestamp[i]);
|
||||
month = date.getMonth();
|
||||
day = date.getDay();
|
||||
console.log(month, day);
|
||||
dateFormat.push(month + '/' + day);
|
||||
}
|
||||
//let dateFormat = new Date(timestamp[0]);
|
||||
// console.log(date);
|
||||
return dateFormat;
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
|
||||
async function buildTable(data1, data2, data3){
|
||||
var table = document.getElementById('myTable')
|
||||
|
||||
for (var i = 0; i < data1.length; i++){
|
||||
var row = `<tr>
|
||||
<td>${data1[i]}</td>
|
||||
<td>${data2[i]}</td>
|
||||
<td>$${data2[i]}</td>
|
||||
|
||||
</tr>`
|
||||
table.innerHTML += row
|
||||
|
||||
|
|
@ -82,17 +110,18 @@ const ExpenseList = () => {
|
|||
}
|
||||
}
|
||||
|
||||
buildTable(category, transaction);
|
||||
buildTable(category, transaction, time);
|
||||
|
||||
async function fetchTransactions() {
|
||||
const categories = await getTransactionsCategory();
|
||||
const transaction_balance = await getTransactionsBalance();
|
||||
const date = await getDate();
|
||||
|
||||
|
||||
|
||||
setCategories(categories);
|
||||
setTransactions(transaction_balance);
|
||||
|
||||
setTime(date);
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
|
|
|
|||
|
|
@ -23,10 +23,10 @@ const ExpenseTotal = () => {
|
|||
}, [])
|
||||
|
||||
return (
|
||||
<div className='widget p-4'>
|
||||
{//<img src={logo} className='expenseTotalIcon'></img>
|
||||
}
|
||||
<span className='widgetText'>This Month's Expenses: ${expense}</span>
|
||||
<div>
|
||||
<h5 class="textttt">This Month's Expenses:</h5>
|
||||
<img src={logo} class="imageee"></img>
|
||||
<h1 class="displayyyy">${expense}</h1>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -29,25 +29,19 @@ const LoanCalculator = () => {
|
|||
<h4 className="mb-0">Loan Calculator</h4>
|
||||
|
||||
<form onSubmit={(event) => event.preventDefault()}>
|
||||
<div className="row align-items-center">
|
||||
<div className="col mb-3">
|
||||
<FormInputGroup text="Loan Amount $" placeholder="Enter the value of the loan" value={loanAmount} onInput={(event) => setLoanAmount(event.target.value)}/>
|
||||
<FormInputGroup text="Interest Rate %" placeholder="Enter interest rate of the loan" value={interestRate} onInput={(event) => setInterestRate(event.target.value)}/>
|
||||
<FormInputGroup text="Loan Duration in Years" placeholder="Enter the duration of the loan in years" value={loanDuration} onInput={(event) => setLoanDuration(event.target.value)}/>
|
||||
</div>
|
||||
<div className="col">
|
||||
<h5 className="alert alert-info fw-bold mt-3">
|
||||
Monthly Payment: ${monthlyPayment.toFixed(2)}
|
||||
<h6 className="mt-4">Principal Paid: ${loanAmount}</h6>
|
||||
<h6>Interest Paid: ${interestPaid.toFixed(2)}</h6>
|
||||
</h5>
|
||||
</div>
|
||||
</div>
|
||||
<FormInputGroup text="Loan Amount $" placeholder="" value={loanAmount} onInput={(event) => setLoanAmount(event.target.value)}/>
|
||||
<FormInputGroup text="Interest Rate %" placeholder="" value={interestRate} onInput={(event) => setInterestRate(event.target.value)}/>
|
||||
<FormInputGroup text="Loan Duration in Years" placeholder="" value={loanDuration} onInput={(event) => setLoanDuration(event.target.value)}/>
|
||||
|
||||
<button type="submit" className="btn btn-primary btn-lg w-100 center" onClick={calculateMonthlyPayment}>Calculate</button>
|
||||
<h4 className="alert alert-info fw-bold">
|
||||
Monthly Payment: ${monthlyPayment.toFixed(2)}
|
||||
<h5 className="mt-4">Principal Paid: ${loanAmount}</h5>
|
||||
<h5>Interest Paid: ${interestPaid.toFixed(2)}</h5>
|
||||
</h4>
|
||||
<button type="submit" className="btn btn-primary btn-lg w-100 mt-3 center" onClick={calculateMonthlyPayment}>Calculate</button>
|
||||
</form>
|
||||
</div>
|
||||
)
|
||||
};
|
||||
|
||||
export default LoanCalculator;
|
||||
export default LoanCalculator;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import React, {useState, useEffect} from 'react';
|
||||
import './css/ViewBudget.css'
|
||||
import logo from './widget_logos/current_balance_logo.png';
|
||||
import './css/Remaining.css'
|
||||
import logo from './widget_logos/budget_logo.png';
|
||||
|
||||
export default function Remaining() {
|
||||
const [budget, setBudget] = useState('');
|
||||
|
|
@ -107,7 +107,10 @@ export default function Remaining() {
|
|||
{/* <img src={logo}></img>
|
||||
<span>Current Balance: ${data}</span> */}
|
||||
{/* <button onClick={apiGet()}> TEST</button> */}
|
||||
<h1>{budget}</h1>
|
||||
<h5 class="text">Budget Remaining</h5>
|
||||
|
||||
|
||||
<img src={logo} class="image"></img><h1 class="display">${budget}</h1>
|
||||
<form id="form" onSubmit={handleSubmit}>
|
||||
<input
|
||||
type = "text"
|
||||
|
|
|
|||
|
|
@ -110,7 +110,9 @@ export default function FetchAPI() {
|
|||
{/* <img src={logo}></img>
|
||||
<span>Current Balance: ${data}</span> */}
|
||||
{/* <button onClick={apiGet()}> TEST</button> */}
|
||||
<h1>{balance}</h1>
|
||||
<h5 class="text">Current Balance</h5>
|
||||
<img src={logo} class="imagee"></img>
|
||||
<h1 class="displayy">${balance}</h1>
|
||||
<form id="form" onSubmit={handleSubmit}>
|
||||
<input
|
||||
type = "text"
|
||||
|
|
|
|||
6
src/components/css/ExpenseList.css
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
td {
|
||||
padding-top: 8px;
|
||||
padding-bottom: 8px;
|
||||
padding-left: 50px;
|
||||
border: 1px solid;
|
||||
}
|
||||
|
|
@ -1,4 +1,16 @@
|
|||
.widgetText {
|
||||
padding-left: 1em;
|
||||
color: #333;
|
||||
.imageee {
|
||||
margin-top: 50px;
|
||||
margin-left: 20px;
|
||||
max-width: 50px;
|
||||
}
|
||||
|
||||
.displayyyy {
|
||||
margin-top: 50px;
|
||||
margin-left: 120px;
|
||||
float: right;
|
||||
}
|
||||
|
||||
.textttt {
|
||||
position: fixed;
|
||||
top: 10px;
|
||||
}
|
||||
|
|
@ -1,3 +1,14 @@
|
|||
img {
|
||||
width: 50px;
|
||||
.image {
|
||||
margin-top: 50px;
|
||||
margin-left: 20px;
|
||||
width: 70px;
|
||||
}
|
||||
|
||||
.display {
|
||||
margin-top: 50px;
|
||||
}
|
||||
|
||||
.text {
|
||||
position: fixed;
|
||||
top: 10px;
|
||||
}
|
||||
|
|
@ -1,7 +1,14 @@
|
|||
|
||||
/* MAKE SURE TO BE SPECIFIC WITH STYLING CUZ THIS CHANGED DIFFERENT SPANS
|
||||
span {
|
||||
float: right;
|
||||
margin-right: 50px;
|
||||
.imagee {
|
||||
margin-top: 50px;
|
||||
margin-left: 20px;
|
||||
width: 50px;
|
||||
}
|
||||
*/
|
||||
|
||||
.displayy {
|
||||
margin-top: 50px;
|
||||
}
|
||||
|
||||
.text {
|
||||
position: fixed;
|
||||
top: 10px;
|
||||
}
|
||||
|
|
@ -1,13 +1,115 @@
|
|||
export default function Settings() {
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { getName, getEmail, getSessionKey, handleLogout } from "../utils/utils";
|
||||
|
||||
const Settings = () => {
|
||||
const [currentName, setCurrentName] = useState('');
|
||||
const [firstName, setFirstName] = useState('');
|
||||
const [lastName, setLastName] = useState('');
|
||||
const [newName, setNewName] = useState('');
|
||||
const [currentPassword, setCurrentPassword] = useState('');
|
||||
const [newPassword, setNewPassword] = useState('');
|
||||
const [email, setEmail] = useState('');
|
||||
const [deleteAccount, setDeleteAccount] = useState('');
|
||||
|
||||
useEffect(() => {
|
||||
async function fetchName() {
|
||||
const currentName = await getName();
|
||||
setCurrentName(currentName);
|
||||
}
|
||||
fetchName();
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
async function fetchEmail() {
|
||||
const email = await getEmail();
|
||||
setEmail(email);
|
||||
}
|
||||
fetchEmail();
|
||||
}, []);
|
||||
|
||||
// javascript for the updated username and password alerts
|
||||
const handleNameClick = () => {
|
||||
const alert = '<div class="alert alert-success alert-dismissible" role="alert">Name updated successfully!<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button></div>';
|
||||
document.getElementById('nameAlert').innerHTML = alert;
|
||||
const handleNameChange = (event) => {
|
||||
event.preventDefault();
|
||||
|
||||
const name = `${firstName} ${lastName}`;
|
||||
setNewName(name);
|
||||
|
||||
const formData = new FormData();
|
||||
formData.append('name', name);
|
||||
|
||||
fetch(`https://api.bb.gabefarrell.com/auth/changename?name=${name}`, {
|
||||
method: 'POST',
|
||||
body: formData,
|
||||
headers: {
|
||||
'x-session-key': getSessionKey(),
|
||||
},
|
||||
})
|
||||
.then(response => {
|
||||
if(response.ok) {
|
||||
alert('Name updated successfully!');
|
||||
window.location.reload();
|
||||
}
|
||||
else {
|
||||
alert('Name update failed!');
|
||||
window.location.reload();
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const handlePasswordClick = () => {
|
||||
const alert = '<div class="alert alert-success alert-dismissible" role="alert">Name updated successfully!<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button></div>';
|
||||
document.getElementById('passwordAlert').innerHTML = alert;
|
||||
const handlePasswordChange = (event) => {
|
||||
event.preventDefault();
|
||||
|
||||
const oldP = `${currentPassword}`;
|
||||
const newP = `${newPassword}`
|
||||
|
||||
const formData = new FormData();
|
||||
formData.append('old', oldP);
|
||||
formData.append('new', newP);
|
||||
|
||||
fetch(`https://api.bb.gabefarrell.com/auth/changepassword?old=${oldP}&new=${newP}`, {
|
||||
method: 'POST',
|
||||
body: formData,
|
||||
headers: {
|
||||
'x-session-key': getSessionKey(),
|
||||
},
|
||||
})
|
||||
.then(response => {
|
||||
if(response.ok) {
|
||||
alert('Password updated successfully!');
|
||||
window.location.reload();
|
||||
}
|
||||
else {
|
||||
alert('Password update failed! Make sure you have entered your current password correctly');
|
||||
window.location.reload();
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const handleDeleteAccount = (event) => {
|
||||
event.preventDefault();
|
||||
|
||||
const password = `${deleteAccount}`;
|
||||
|
||||
const formData = new FormData();
|
||||
formData.append('password', password);
|
||||
|
||||
fetch(`https://api.bb.gabefarrell.com/auth/deleteaccount?password=${password}`, {
|
||||
method: 'POST',
|
||||
body: formData,
|
||||
headers: {
|
||||
'x-session-key': getSessionKey(),
|
||||
},
|
||||
})
|
||||
.then(response => {
|
||||
if(response.ok) {
|
||||
alert('Account deleted successfully!');
|
||||
handleLogout();
|
||||
}
|
||||
else {
|
||||
alert('Account could not be delete. Make sure you have entered your current password correctly');
|
||||
window.location.reload();
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
(() => {
|
||||
|
|
@ -16,10 +118,10 @@ export default function Settings() {
|
|||
|
||||
// Loop over them and prevent submission
|
||||
Array.from(forms).forEach(form => {
|
||||
form.addEventListener('click', event => {
|
||||
form.addEventListener('submit', event => {
|
||||
if (!form.checkValidity()) {
|
||||
event.preventDefault()
|
||||
event.stopPropagation()
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
}
|
||||
|
||||
form.classList.add('was-validated')
|
||||
|
|
@ -28,98 +130,117 @@ export default function Settings() {
|
|||
})()
|
||||
|
||||
// toggle between light mode and dark mode
|
||||
const toggleDarkMode = () => {
|
||||
/*const toggleDarkMode = () => {
|
||||
if (document.documentElement.getAttribute('data-bs-theme') === 'dark') {
|
||||
document.documentElement.setAttribute('data-bs-theme','light')
|
||||
}
|
||||
else {
|
||||
document.documentElement.setAttribute('data-bs-theme','dark')
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
// JSX: Javascript XML
|
||||
return (
|
||||
<>
|
||||
<div className="container overflow-auto">
|
||||
<h4 className="mt-4 mb-4">Profile Settings</h4>
|
||||
|
||||
<h5 className="mb-4">Email and Name</h5>
|
||||
<form className="needs-validation" noValidate>
|
||||
<form className="needs-validation" onSubmit={handleNameChange} noValidate>
|
||||
<div className="row mb-3">
|
||||
<label htmlFor="staticEmail" className="col-2 col-form-label">Email</label>
|
||||
<div className="col-4">
|
||||
<input type="text" readOnly className="form-control-plaintext" id="staticEmail" value="daniel_quinonezrosario@student.uml.edu" />
|
||||
</div>
|
||||
</div>
|
||||
<div className="row mb-3">
|
||||
<label htmlFor="currentName" className="col-2 col-form-label">Current Name</label>
|
||||
<div className="col-4">
|
||||
<input type="text" readOnly className="form-control-plaintext" id="currentName" value="Daniel" />
|
||||
</div>
|
||||
</div>
|
||||
<div className="row mb-3">
|
||||
<label htmlFor="newName" className="col-2 col-form-label">New Name</label>
|
||||
<div className="col-4">
|
||||
<input type="text" className="form-control" id="newName" required />
|
||||
<div className="invalid-feedback">
|
||||
Please enter a new name
|
||||
<label htmlFor="staticEmail" className="col-2 col-form-label">Email</label>
|
||||
<div className="col-4">
|
||||
<input type="text" readOnly className="form-control-plaintext" id="staticEmail" value={email}/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="row mb-3">
|
||||
<label htmlFor="currentName" className="col-2 col-form-label">Current Name</label>
|
||||
<div className="col-4">
|
||||
<input type="text" readOnly className="form-control-plaintext" id="currentName" value={currentName}/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="row mb-3">
|
||||
<label htmlFor="newFirstName" className="col-2 col-form-label">New First Name</label>
|
||||
<div className="col-4">
|
||||
<input type="text" className="form-control" id="newFirstName" placeholder="Please enter a new first name" value={firstName} onChange={(event) => setFirstName(event.target.value)} required/>
|
||||
<div className="invalid-feedback">
|
||||
Please enter a new first name
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="row mb-3">
|
||||
<label htmlFor="newLastName" className="col-2 col-form-label">New Last Name</label>
|
||||
<div className="col-4">
|
||||
<input type="text" className="form-control" id="newLastName" placeholder="Please enter a new last name" value={lastName} onChange={(event) => setLastName(event.target.value)} required />
|
||||
<div className="invalid-feedback">
|
||||
Please enter a new last name
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="nameAlert"></div>
|
||||
<div>
|
||||
<button type="button" className="btn btn-primary mb-5" id="newNameButton" onClick={handleNameClick}>Change Name</button>
|
||||
<button type="submit" className="btn btn-primary mb-5" id="newNameButton">Change Name</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<h5 className="mb-4">Password</h5>
|
||||
<form className="needs-validation" noValidate>
|
||||
<form className="needs-validation" onSubmit={handlePasswordChange} noValidate>
|
||||
<div className="row mb-3">
|
||||
<label htmlFor="currentPassword" className="col-2 col-form-label">Current Password</label>
|
||||
<div className="col-4">
|
||||
<input type="password" className="form-control" id="currentPassword" minLength="8" required />
|
||||
<div className="invalid-feedback">
|
||||
Please enter your current password
|
||||
<label htmlFor="currentPassword" className="col-2 col-form-label">Current Password</label>
|
||||
<div className="col-4">
|
||||
<input type="password" className="form-control" id="currentPassword" placeholder="Please enter your current password" minLength="8" value={currentPassword} onChange={(event) => setCurrentPassword(event.target.value)} required />
|
||||
<div className="invalid-feedback">
|
||||
Please enter your current password
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="row mb-3">
|
||||
<label htmlFor="newPassword" className="col-2 col-form-label">New Password</label>
|
||||
<div className="col-4">
|
||||
<input type="password" className="form-control" id="newPassword" minLength="8" required />
|
||||
<div className="invalid-feedback">
|
||||
Please enter a new password
|
||||
<br />
|
||||
Your new password must be at least 8 characters long
|
||||
<label htmlFor="newPassword" className="col-2 col-form-label">New Password</label>
|
||||
<div className="col-4">
|
||||
<input type="password" className="form-control" id="newPassword" placeholder="Please enter a new password" minLength="8" value={newPassword} onChange={(event) => setNewPassword(event.target.value)} required />
|
||||
<div className="invalid-feedback">
|
||||
Please enter a new password
|
||||
<br/>
|
||||
Your new password must be at least 8 characters long
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="passwordAlert"></div>
|
||||
<div>
|
||||
<button type="button" className="btn btn-primary mb-5" id="newPasswordButton" onClick={handlePasswordClick}>Change Password</button>
|
||||
<button type="submit" className="btn btn-primary mb-5" id="newPasswordButton">Change Password</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<h4 className="mb-4">Dark Mode</h4>
|
||||
{/*<h4 className="mb-4">Dark Mode</h4>
|
||||
|
||||
<div className="form-check form-switch mb-5">
|
||||
<input className="form-check-input" type="checkbox" id="darkModeCheckbox" onClick={toggleDarkMode}/>
|
||||
<label className="form-check-label" htmlFor="darkModeCheckbox">Enable Dark Mode</label>
|
||||
</div>
|
||||
|
||||
{/*<h4 className="mb-4">Account Settings</h4>
|
||||
|
||||
<div className="mb-4">
|
||||
<button type="button" className="btn btn-danger">Delete Account</button>
|
||||
<br />
|
||||
<div className="mt-2">
|
||||
CAUTION: This will delete your account. All account and profile data
|
||||
will be completely erased.
|
||||
</div>
|
||||
</div>*/}
|
||||
|
||||
<h4 className="mb-4">Account Settings</h4>
|
||||
|
||||
<h5 className="mb-4">Delete Your Account</h5>
|
||||
<form className="needs-validation" onSubmit={handleDeleteAccount} noValidate>
|
||||
<div className="row mb-3">
|
||||
<label htmlFor="deleteAccount" className="col-2 col-form-label">Current Password</label>
|
||||
<div className="col-4">
|
||||
<input type="password" className="form-control" id="deleteAccount" placeholder="Please enter your current password" minLength="8" value={deleteAccount} onChange={(event) => setDeleteAccount(event.target.value)} required />
|
||||
<div className="invalid-feedback">
|
||||
Please enter your current password in order to delete your account
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<button type="submit" className="btn btn-danger" id="deleteAccountButton">Delete Account</button>
|
||||
</div>
|
||||
<div className="mt-2 mb-5 fw-bold">
|
||||
CAUTION: This will delete your account. All account and profile data
|
||||
will be completely erased.
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
export default Settings;
|
||||
|
|
@ -35,6 +35,22 @@ export async function getName() {
|
|||
}
|
||||
}
|
||||
|
||||
export async function getEmail() {
|
||||
try {
|
||||
const response = await fetch('https://api.bb.gabefarrell.com/userinfo', {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'x-session-key': getSessionKey(),
|
||||
},
|
||||
});
|
||||
const data = await response.json();
|
||||
const email = data.email;
|
||||
return email;
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
|
||||
export function handleLogout() {
|
||||
document.cookie.split(";").forEach(function(c) { document.cookie = c.replace(/^ +/, "").replace(/=.*/, "=;expires=" + new Date().toUTCString() + ";path=/"); });
|
||||
window.location.href='/welcome';
|
||||
|
|
|
|||