mirror of
https://github.com/gabehf/BudgetBuddy.git
synced 2026-03-07 21:48:14 -08:00
Nav fixes & Error messages
This commit is contained in:
parent
077e515dfb
commit
edf43f30da
21 changed files with 135 additions and 103 deletions
|
|
@ -3,9 +3,9 @@ const nameAlertPlaceholder = document.getElementById('nameAlert')
|
|||
const nameAppendAlert = (message, type) => {
|
||||
const wrapper = document.createElement('div')
|
||||
wrapper.innerHTML = [
|
||||
`<div class="alert alert-${type} alert-dismissible" role="alert">`,
|
||||
`<div className"alert alert-${type} alert-dismissible" role="alert">`,
|
||||
` <div>${message}</div>`,
|
||||
' <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>',
|
||||
' <button type="button" className"btn-close" data-bs-dismiss="alert" aria-label="Close"></button>',
|
||||
'</div>'
|
||||
].join('')
|
||||
|
||||
|
|
@ -24,9 +24,9 @@ const passwordAlertPlaceholder = document.getElementById('passwordAlert')
|
|||
const passwordAppendAlert = (message, type) => {
|
||||
const wrapper = document.createElement('div')
|
||||
wrapper.innerHTML = [
|
||||
`<div class="alert alert-${type} alert-dismissible" role="alert">`,
|
||||
`<div className"alert alert-${type} alert-dismissible" role="alert">`,
|
||||
` <div>${message}</div>`,
|
||||
' <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>',
|
||||
' <button type="button" className"btn-close" data-bs-dismiss="alert" aria-label="Close"></button>',
|
||||
'</div>'
|
||||
].join('')
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import ContactUs from './pages/Contact-Us'
|
|||
import Welcome from './pages/Welcome'
|
||||
import Error from './pages/Error-Page'
|
||||
|
||||
import checkLogin from './utils/utils.js'
|
||||
import {checkLogin} from './utils/utils.js'
|
||||
|
||||
import './styles.css'
|
||||
|
||||
|
|
@ -65,13 +65,13 @@ export default function Main() {
|
|||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className="full-page">
|
||||
<NavBar />
|
||||
{checkLogin() ?
|
||||
<ProSidebarProvider>
|
||||
<div class="main-body">
|
||||
<div className="main-body">
|
||||
<SideNav />
|
||||
<div class="page-display">
|
||||
<div className="page-display elevated">
|
||||
<Layout />
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -28,14 +28,14 @@ const AddExpenseForm = (props) => {
|
|||
|
||||
return (
|
||||
<form onSubmit={onSubmit}>
|
||||
<div class='row alert alert-secondary'>
|
||||
{/* <div class='col-sm col-lg-4'>
|
||||
<form for="name">
|
||||
<div className='row alert alert-secondary'>
|
||||
{/* <div className='col-sm col-lg-4'>
|
||||
<form htmlFor="name">
|
||||
<label >Choose a category:</label>
|
||||
<select>
|
||||
<option required='required'
|
||||
type='text'
|
||||
class='form-control'
|
||||
className='form-control'
|
||||
id='name'
|
||||
value={name}
|
||||
onChange={(event) => setName(event.target.value)}>Rent</option>
|
||||
|
|
@ -43,32 +43,32 @@ const AddExpenseForm = (props) => {
|
|||
</form>
|
||||
</div> */}
|
||||
<h3>Add Expense</h3>
|
||||
<div class='col-sm col-lg-4'>
|
||||
<label for='name'>Name</label>
|
||||
<div className='col-sm col-lg-4'>
|
||||
<label htmlFor='name'>Name</label>
|
||||
<input
|
||||
required='required'
|
||||
type='text'
|
||||
class='form-control'
|
||||
className='form-control'
|
||||
id='name'
|
||||
value={name}
|
||||
onChange={(event) => setName(event.target.value)}
|
||||
></input>
|
||||
|
||||
</div>
|
||||
<div class='col-sm col-lg-4'>
|
||||
<label for='cost'>Cost</label>
|
||||
<div className='col-sm col-lg-4'>
|
||||
<label htmlFor='cost'>Cost</label>
|
||||
<input
|
||||
required='required'
|
||||
type='number'
|
||||
class='form-control'
|
||||
className='form-control'
|
||||
id='cost'
|
||||
value={cost}
|
||||
onChange={(event) => setCost(event.target.value)}
|
||||
/>
|
||||
</div>
|
||||
<div class='row mt-3'>
|
||||
<div class='col-sm'>
|
||||
<button type='submit' class='btn btn-primary'>
|
||||
<div className='row mt-3'>
|
||||
<div className='col-sm'>
|
||||
<button type='submit' className='btn btn-primary'>
|
||||
Save
|
||||
</button>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -27,22 +27,22 @@ const AddExpenseForm = (props) => {
|
|||
|
||||
return (
|
||||
<form onSubmit={onSubmit}>
|
||||
<div class='row'>
|
||||
<div class='col-lg-3'>
|
||||
<label for='cost'>Income</label>
|
||||
<div className='row'>
|
||||
<div className='col-lg-3'>
|
||||
<label htmlFor='cost'>Income</label>
|
||||
<input
|
||||
required='required'
|
||||
type='number'
|
||||
class='form-control'
|
||||
className='form-control'
|
||||
id='cost'
|
||||
value={cost}
|
||||
onChange={(event) => setCost(event.target.value)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class='row mt-3'>
|
||||
<div class='col-sm'>
|
||||
<button type='submit' class='btn btn-primary'>
|
||||
<div className='row mt-3'>
|
||||
<div className='col-sm'>
|
||||
<button type='submit' className='btn btn-primary'>
|
||||
Save
|
||||
</button>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -7,14 +7,14 @@ const EditBudget = (props) => {
|
|||
<input
|
||||
required='required'
|
||||
type='number'
|
||||
class='form-control mr-3'
|
||||
className='form-control mr-3'
|
||||
id='name'
|
||||
value={value}
|
||||
onChange={(event) => setValue(event.target.value)}
|
||||
/>
|
||||
<button
|
||||
type='button'
|
||||
class='btn btn-primary'
|
||||
className='btn btn-primary'
|
||||
onClick={() => props.handleSaveClick(value)}
|
||||
>
|
||||
Save
|
||||
|
|
|
|||
|
|
@ -12,10 +12,10 @@ const ExpenseItem = (props) => {
|
|||
};
|
||||
|
||||
return (
|
||||
<li class='list-group-item d-flex justify-content-between align-items-center'>
|
||||
<li className='list-group-item d-flex justify-content-between align-items-center'>
|
||||
{props.name}
|
||||
<div>
|
||||
<span class='text-primary badge badge-primary badge-pill mr-3'>${props.cost}</span>
|
||||
<span className='text-primary badge badge-primary badge-pill mr-3'>${props.cost}</span>
|
||||
</div>
|
||||
</li>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -22,11 +22,11 @@ const ExpenseList = () => {
|
|||
<>
|
||||
{/* <input
|
||||
type='text'
|
||||
class='form-control mb-2 mr-sm-2'
|
||||
className='form-control mb-2 mr-sm-2'
|
||||
placeholder='Type to search...'
|
||||
onChange={handleChange}
|
||||
/> */}
|
||||
<ul class='list-group mt-3 mb-3'>
|
||||
<ul className='list-group mt-3 mb-3'>
|
||||
{filteredExpenses.map((expense) => (
|
||||
<ExpenseItem
|
||||
id={expense.id}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ const ExpenseTotal = () => {
|
|||
}, 0);
|
||||
|
||||
return (
|
||||
<div class='alert alert-secondary p-4'>
|
||||
<div className='alert alert-secondary p-4'>
|
||||
<img src={logo}></img>
|
||||
<span>This Month's Expenses: ${total}</span>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -4,39 +4,28 @@ import { Toolbar, Typography, Button, IconButton, Link } from "@material-ui/core
|
|||
import AccountCircle from '@mui/icons-material/AccountCircle';
|
||||
import logo from "../assets/BudgetBuddyLogo.png"
|
||||
import "./NavBar.css"
|
||||
import checkLogin from "../utils/utils";
|
||||
import {checkLogin, getFirstName} from "../utils/utils";
|
||||
import NavDropdown from 'react-bootstrap/NavDropdown';
|
||||
|
||||
export default function NavBar() {
|
||||
const [anchorEl, setAnchorEl] = React.useState(null);
|
||||
|
||||
const handleLogin = () => {
|
||||
handleClose();
|
||||
window.location.href='/login';
|
||||
}
|
||||
|
||||
const handleSignup = () => {
|
||||
handleClose();
|
||||
window.location.href='/signup';
|
||||
}
|
||||
|
||||
const handleLogout= () => {
|
||||
handleClose();
|
||||
document.cookie.split(";").forEach(function(c) { document.cookie = c.replace(/^ +/, "").replace(/=.*/, "=;expires=" + new Date().toUTCString() + ";path=/"); });
|
||||
window.location.href='/welcome';
|
||||
}
|
||||
|
||||
const handleMenu = (event) => {
|
||||
setAnchorEl(event.currentTarget);
|
||||
};
|
||||
|
||||
const handleClose = () => {
|
||||
setAnchorEl(null);
|
||||
};
|
||||
|
||||
return (
|
||||
<Toolbar position="sticky" className="bar">
|
||||
<Link href="/" class="nav-brand">
|
||||
<img src={logo} className="logo"/>
|
||||
<Link href="/" className="nav-brand">
|
||||
<img src={logo} className="logo w-100"/>
|
||||
<Typography
|
||||
className="nav-header"
|
||||
variant="h5" >
|
||||
|
|
@ -47,39 +36,17 @@ export default function NavBar() {
|
|||
{checkLogin()
|
||||
? // Logged In
|
||||
<div>
|
||||
<IconButton
|
||||
size="large"
|
||||
aria-label="account of current user"
|
||||
aria-controls="menu-appbar"
|
||||
aria-haspopup="true"
|
||||
onClick={handleMenu}
|
||||
color="inherit" >
|
||||
<AccountCircle />
|
||||
</IconButton>
|
||||
<Menu
|
||||
id="menu-appbar"
|
||||
anchorEl={anchorEl}
|
||||
anchorOrigin={{
|
||||
vertical: 'top',
|
||||
horizontal: 'right',
|
||||
}}
|
||||
keepMounted
|
||||
transformOrigin={{
|
||||
vertical: 'top',
|
||||
horizontal: 'right',
|
||||
}}
|
||||
open={Boolean(anchorEl)}
|
||||
onClose={handleClose} >
|
||||
<MenuItem onClick={handleClose}>Profile</MenuItem>
|
||||
<MenuItem onClick={handleClose}>My account</MenuItem>
|
||||
<MenuItem onClick={handleLogout}>Log Out</MenuItem>
|
||||
</Menu>
|
||||
<NavDropdown title={`Logged in as ${getFirstName()}`}>
|
||||
<NavDropdown.Item>Profile</NavDropdown.Item>
|
||||
<NavDropdown.Item>My account</NavDropdown.Item>
|
||||
<NavDropdown.Item onClick={handleLogout}>Sign Out</NavDropdown.Item>
|
||||
</NavDropdown>
|
||||
</div>
|
||||
: // Logged Out
|
||||
<span style={{display: "flex"}}>
|
||||
<Button onClick={handleLogin}>Login</Button>
|
||||
<span className="mx-0" style={{display: "flex"}}>
|
||||
<Button className="mx-0" onClick={handleLogin}>Login</Button>
|
||||
<p style={{marginTop: "9px"}}>or</p>
|
||||
<Button onClick={handleSignup}>Signup</Button>
|
||||
<Button className="mx-0" onClick={handleSignup}>Signup</Button>
|
||||
</span>
|
||||
}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ const RemainingBudget = () => {
|
|||
const alertType = totalExpenses > budget ? 'alert-danger' : 'alert-success';
|
||||
|
||||
return (
|
||||
<div class={`alert p-4 ${alertType}`}>
|
||||
<div className={`alert p-4 ${alertType}`}>
|
||||
<img src={logo}></img>
|
||||
<span>Budget Remaining: ${budget - totalExpenses}</span>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,3 +1,7 @@
|
|||
.sidebar {
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
.sidebar-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
|
@ -7,4 +11,8 @@
|
|||
|
||||
.sidebar-avatar {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.sidebar-welcome {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
|
@ -5,20 +5,21 @@ import ContactSupportOutlinedIcon from '@mui/icons-material/ContactSupportOutlin
|
|||
import PrivacyTipOutlinedIcon from '@mui/icons-material/PrivacyTipOutlined';
|
||||
import SupervisedUserCircleOutlinedIcon from '@mui/icons-material/SupervisedUserCircleOutlined';
|
||||
import ContactPageOutlinedIcon from '@mui/icons-material/ContactPageOutlined';
|
||||
import LogoutIcon from '@mui/icons-material/Logout';
|
||||
import { Avatar, Typography } from '@material-ui/core';
|
||||
import { Link } from '@material-ui/core';
|
||||
import { Link, Divider } from '@material-ui/core';
|
||||
import './SideNav.css'
|
||||
|
||||
|
||||
export default function SideNav() {
|
||||
return(
|
||||
<Sidebar backgroundColor='transparent'>
|
||||
<Sidebar className="sidebar" backgroundColor='transparent' style={{border:"none"}}>
|
||||
<div className='sidebar-header'>
|
||||
<div className='sidebar-avatar'>
|
||||
<Avatar />
|
||||
</div>
|
||||
<div className='sidebar-text'>
|
||||
<Typography variant='h6'>Welcome, Jacob</Typography>
|
||||
<Typography className='sidebar-welcome' variant='h6'>Welcome, Jacob</Typography>
|
||||
<Typography variant='subtitle2'> Your Budget Overiew</Typography>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -40,21 +41,29 @@ export default function SideNav() {
|
|||
Support
|
||||
</MenuItem>
|
||||
*/}
|
||||
{/*
|
||||
<MenuItem
|
||||
component={<Link href="/privacy" />}
|
||||
icon={<PrivacyTipOutlinedIcon/>}>
|
||||
Privacy
|
||||
</MenuItem>
|
||||
*/}
|
||||
<MenuItem
|
||||
component={<Link href="/about-us" />}
|
||||
icon={<SupervisedUserCircleOutlinedIcon/>}>
|
||||
About Us
|
||||
</MenuItem>
|
||||
{/*
|
||||
<MenuItem
|
||||
component={<Link href="/contact-us" />}
|
||||
icon={<ContactPageOutlinedIcon/>}>
|
||||
Contact Us
|
||||
</MenuItem>
|
||||
*/}
|
||||
<MenuItem
|
||||
icon={<LogoutIcon/>}>
|
||||
Sign Out
|
||||
</MenuItem>
|
||||
</Menu>
|
||||
</Sidebar>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ const ViewBudget = (props) => {
|
|||
<>
|
||||
<img src={logo}></img>
|
||||
<span>Current Balance: ${props.budget}</span>
|
||||
<button type='button' class='btn btn-primary' onClick={props.handleEditClick}>
|
||||
<button type='button' className='btn btn-primary' onClick={props.handleEditClick}>
|
||||
Edit
|
||||
</button>
|
||||
</>
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ const Budget = () => {
|
|||
};
|
||||
|
||||
return (
|
||||
<div class='alert alert-secondary d-flex align-items-center justify-content-between'>
|
||||
<div className='alert alert-secondary d-flex align-items-center justify-content-between'>
|
||||
{isEditing ? (
|
||||
<EditBudget handleSaveClick={handleSaveClick} budget={budget} />
|
||||
) : (
|
||||
|
|
|
|||
|
|
@ -1,4 +1,7 @@
|
|||
|
||||
/* MAKE SURE TO BE SPECIFIC WITH STYLING CUZ THIS CHANGED DIFFERENT SPANS
|
||||
span {
|
||||
float: right;
|
||||
margin-right: 50px;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
|
@ -10,7 +10,7 @@ import Main from './Main.js'
|
|||
function App() {
|
||||
return (
|
||||
<React.StrictMode>
|
||||
<div className="App">
|
||||
<div className="app">
|
||||
<ThemeProvider theme={theme}>
|
||||
<Main/>
|
||||
</ThemeProvider>
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import './Login.css'
|
|||
export default function Login() {
|
||||
const [email, setEmail] = useState('');
|
||||
const [password, setPassword] = useState('');
|
||||
const [errorText, setErrorText] = useState(null);
|
||||
|
||||
function handleSubmit(event) {
|
||||
event.preventDefault();
|
||||
|
|
@ -22,6 +23,7 @@ export default function Login() {
|
|||
.then((data) => {
|
||||
if (data.status != 200) {
|
||||
console.log(data.error);
|
||||
setErrorText(data.error);
|
||||
} else {
|
||||
const session = data.session;
|
||||
document.cookie = `session=${session}; path=/;`
|
||||
|
|
@ -79,6 +81,7 @@ export default function Login() {
|
|||
Submit
|
||||
</button>
|
||||
</div>
|
||||
{errorText && <div className='alert alert-danger p-2 mb-1'>{errorText}</div>}
|
||||
<p className="forgot-password">
|
||||
Don't have an account? <a href="/signup">sign up</a>
|
||||
</p>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import './Login.css'
|
||||
import React, { useState } from 'react'
|
||||
import 'bootstrap/dist/css/bootstrap.css';
|
||||
|
||||
export default function SignUp() {
|
||||
const [firstName, setFirstName] = useState('');
|
||||
|
|
@ -7,6 +8,7 @@ export default function SignUp() {
|
|||
const [name, setName] = useState('');
|
||||
const [email, setEmail] = useState('');
|
||||
const [password, setPassword] = useState('');
|
||||
const [errorText, setErrorText] = useState(null);
|
||||
|
||||
|
||||
function handleSubmit(event) {
|
||||
|
|
@ -29,7 +31,8 @@ export default function SignUp() {
|
|||
.then((response) => response.json())
|
||||
.then((data) => {
|
||||
if (data.status != 200) {
|
||||
console.log(data.error);
|
||||
console.log(data.error);
|
||||
setErrorText(data.error);
|
||||
} else {
|
||||
const session = data.session;
|
||||
document.cookie = `session=${session}; path=/;`
|
||||
|
|
@ -40,6 +43,7 @@ export default function SignUp() {
|
|||
})
|
||||
.catch((error) => {
|
||||
console.error(error); // Log any errors
|
||||
setErrorText(error);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -96,6 +100,7 @@ export default function SignUp() {
|
|||
<button type="submit" className="btn btn-primary mb-3">
|
||||
Sign Up
|
||||
</button>
|
||||
{errorText && <div className='alert alert-danger p-2 mb-1'>{errorText}</div>}
|
||||
</div>
|
||||
<p className="forgot-password text-right">
|
||||
Already registered? <a href="/login">log in</a>
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ export default function Welcome() {
|
|||
<Button className='mx-0 mb-4' variant="outline-success" href="/signup">Get Started</Button>
|
||||
</Col>
|
||||
<Col className='d-flex' md={4}>
|
||||
<Image className='align-self-end' src={budgethero} fluid />
|
||||
<Image className='align-self-end w-100' src={budgethero} fluid />
|
||||
</Col>
|
||||
</Row>
|
||||
</Container>
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ body {
|
|||
sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
|
||||
}
|
||||
|
||||
code {
|
||||
|
|
@ -13,6 +12,12 @@ code {
|
|||
monospace;
|
||||
}
|
||||
|
||||
.app {
|
||||
background-color: #F7F7F2;
|
||||
color: #444444;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.main-body {
|
||||
display: flex;
|
||||
width: 100vw;
|
||||
|
|
@ -20,10 +25,11 @@ code {
|
|||
|
||||
.page-display {
|
||||
margin: 0 40px;
|
||||
border: 2px solid black;
|
||||
margin-bottom: 30px;
|
||||
border-radius: 20px;
|
||||
padding: 20px 30px;
|
||||
width: 100vw;
|
||||
background-color: #FFFFFF;
|
||||
/*display: grid; COMMENTED OUT BY CHRIS FOR PUSH ON WIDGETS, not sure if need for welcome page or not, do not need anymore for widgets
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
grid-template-rows: 125px 250px 100px 100px;
|
||||
|
|
@ -32,6 +38,10 @@ code {
|
|||
box-sizing: border-box; */
|
||||
}
|
||||
|
||||
.elevated {
|
||||
filter: drop-shadow(0px 4px 4px rgba(0, 0, 0, 0.25));
|
||||
}
|
||||
|
||||
.page-display div {
|
||||
padding: 10px;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,39 @@
|
|||
export default function checkLogin() {
|
||||
var cookies = document.cookie.split(';');
|
||||
for (var i = 0; i < cookies.length; i++) {
|
||||
var cookie = cookies[i].trim();
|
||||
if (cookie.indexOf('session=') === 0) {
|
||||
// The "session" cookie exists
|
||||
return true;
|
||||
}
|
||||
export function checkLogin() {
|
||||
var cookies = document.cookie.split(';');
|
||||
for (var i = 0; i < cookies.length; i++) {
|
||||
var cookie = cookies[i].trim();
|
||||
if (cookie.indexOf('session=') === 0) {
|
||||
// The "session" cookie exists
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// The "session" cookie doesn't exist
|
||||
return false;
|
||||
}
|
||||
|
||||
function getSessionKey() {
|
||||
var cookies = document.cookie.split(';');
|
||||
for (let i = 0; i < cookies.length; i++) {
|
||||
const cookie = cookies[i].trim(); // Remove any leading or trailing whitespace
|
||||
if (cookie.startsWith('session=')) {
|
||||
console.log(cookie.substring('session='.length, cookie.length));
|
||||
return cookie.substring('session='.length, cookie.length); // Extract the value of the cookie
|
||||
}
|
||||
// The "session" cookie doesn't exist
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
export function getFirstName() {
|
||||
fetch('http://127.0.0.1:3030/userinfo', {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'x-session-key' : "b36efa01-7824-4f61-a274-63131b58d8fe",
|
||||
}
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
const name = data.name;
|
||||
return name; // Return firstname
|
||||
})
|
||||
.catch(error => console.error(error));
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue