Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Controllers/ExpenseController.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ function getAll($idUser)
$db = new MySqlDatabase();
$mysql = $db->connect();

$sql = 'SELECT * FROM expenses WHERE idUser=?';
$sql = 'SELECT * FROM expenses WHERE idUser=? ORDER BY date DESC';
$stmt = $mysql->prepare($sql);

if (!$stmt) {
Expand Down Expand Up @@ -91,7 +91,7 @@ function delete()
{
}

function update()
function update($obj, $uid)
{
}

Expand Down
28 changes: 27 additions & 1 deletion Controllers/RevenueController.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
include_once __DIR__ . '/../Interfaces/Controller.inter.php';
include_once __DIR__ . '/../Models/MySqlDatabase.class.php';
include_once __DIR__ . '/../Models/Revenue.class.php';
include_once __DIR__ . '/../Utils/Constants.php';

class RevenueController implements Controller {

Expand Down Expand Up @@ -59,7 +60,32 @@ function create($transaction) {

function delete() {}

function update() {}
function update($obj, $uid) {}

function delete_all() {}

function sumAmount($idUser, $type)
{
$db = new MySqlDatabase();
$mysql = $db->connect();

$subquery = $type == TODAY ? 'DATE(date) = CURDATE()' : 'DATE_FORMAT(date, "%Y-%m") = DATE_FORMAT(NOW(), "%Y-%m")';
$sql = 'SELECT IFNULL(SUM(amount),0) AS total FROM revenues WHERE ' . $subquery . ' AND idUser=?;';
$stmt = $mysql->prepare($sql);

if (!$stmt) {
return null;
} else {
$stmt->bind_param('s', $idUser);
$stmt->execute();
$result = $stmt->get_result();

if ($row = $result->fetch_assoc()) {
return $row['total'];
} else {
return 0;
}
}
$db->disconnect();
}
}
21 changes: 20 additions & 1 deletion Controllers/UserController.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,26 @@ function create($user) {

function delete() {}

function update() {}
function update($user, $uidUser) {
$db = new MySqlDatabase();
$mysql = $db->connect();

$sql = 'UPDATE users SET uidUser=?, emailUser=?, pwdUser=? WHERE uidUser=?';
$stmt = $mysql->prepare($sql);

if (!$stmt) {
return 1064;
}
else {
$hashPassword = password_hash($user->password, PASSWORD_DEFAULT);
$stmt->bind_param('ssss', $user->username, $user->email, $hashPassword, $uidUser);
$stmt->execute();

return $stmt->errno;
}

$db->disconnect();
}

function delete_all() {}
}
2 changes: 1 addition & 1 deletion Interfaces/Controller.inter.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
function get($id);
function create($obj);
function delete();
function update();
function update($obj, $uid);
function delete_all();

}
File renamed without changes.
File renamed without changes.
File renamed without changes.
74 changes: 74 additions & 0 deletions Public/includes/profile.inc.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<?php
session_start();
include_once __DIR__ . '/../../Controllers/UserController.php';
include_once __DIR__ . '/../../Models/User.class.php';
include_once __DIR__ . '/../../Utils/Constants.php';

if (isset($_POST['profile-submit'])) {
$username = $_POST["username"];
$email = $_POST["email"];
$password = $_POST["password"];
$passwordRepeat = $_POST["password-repeat"];

// User input check
if (empty($username) || empty($email) || empty($password) || empty($passwordRepeat)) {

header("Location: /profile?error=emptyfields&uid=$username&mail=$email");
exit();
}
else if (!filter_var($email, FILTER_VALIDATE_EMAIL) && !preg_match("/^[a-zA-Z0-9]*$/", $username)) {

header("Location: /profile?error=invalidmailuid");
exit();
}
else if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {

header("Location: /profile?error=invalidmail&uid=$username");
exit();
}
else if (!preg_match("/^[a-zA-Z0-9]*$/", $username)) {

header("Location: /profile?error=invaliduid&mail=$email");
exit();
}
else if (!preg_match('/^(?=.*\d)(?=.*[A-Z])(?=.*[a-z])[a-zA-Z0-9]{8,}$/', $password)) {

header("Location: /profile?error=passwordmalformed&uid=$username&mail=$email");
exit();
}
else if ($password !== $passwordRepeat) {

header("Location: /profile?error=passwordcheck&uid=$username&mail=$email");
exit();
}
else {
// Check if user already exists
$user_obj = new User(null, $username, $email, $password);
$user_controller = new UserController();

$result = $user_controller->update($user_obj, $_SESSION['userUid']);
if ($result === SUCCESS) {
$_SESSION['userUid'] = $_POST["userUid"] = $username;
header("Location: /profile?edit=success");
exit();
}
else if ($result === ER_DUP_ENTRY) {
//User taken
header("Location: /profile?error=userTaken&mail=$email");
exit();
}
else if ($result === ER_PARSE_ERROR) {
header("Location: /profile?error=invalidsql");
exit();
}
else {
throw new Exception($result);
//header("Location: /profile?error=invalid");
exit();
}
}
}
else {
header("Location: /profile");
exit();
}
50 changes: 50 additions & 0 deletions Public/styles/profile.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
budget-card {
margin: 0 25px;
}

ul {
padding: 0;
}

.list {
display: grid;
grid-template-columns: 1fr 1fr;
}

.category {
text-align: left;
padding: 10px;
color: var(--secondary-color);
}

.value {
text-align: right;
padding: 10px;
color: var(--primary-dark-color);
}

#save,
#edit,
#cancel {
background-color: var(--primary-color);
padding: 8px 45px;
border-radius: 5px;
margin: 10px;
display: inline;
}

#cancel {
background-color: var(--text-body);
}

input {
border: none;
}

*:focus {
outline: none;
}

.hidden {
display: none;
}
39 changes: 24 additions & 15 deletions Public/views/dashboard.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
include_once __DIR__ . '/../../Controllers/RevenueController.php';

$expense_controller = new ExpenseController();
$revenue_controller = new RevenueController();
$transactions = $expense_controller->getAll($_SESSION['userId']);
$chartData = $expense_controller->spending_breakdown($_SESSION['userId']);
?>
Expand Down Expand Up @@ -36,32 +37,25 @@
<div class="container">
<budget-card card header="Quick Summary">
<div slot="body">
<budget-item no-border value="<?php echo $expense_controller->sumAmount($_SESSION['userId'], 0); ?>">Total Spent Today</budget-item>
<budget-item no-border value="<?php echo $expense_controller->sumAmount($_SESSION['userId'], 1); ?>">Total Spent in <?php echo date('F'); ?></budget-item>
<budget-item no-border type="0" class="revenue-summary" value="<?php echo $revenue_controller->sumAmount($_SESSION['userId'], 0); ?>">Earned Today</budget-item>
<budget-item type="1" value="<?php echo $expense_controller->sumAmount($_SESSION['userId'], 0); ?>">Spent Today</budget-item>
<budget-item no-border type="0" class="revenue-summary" value="<?php echo $revenue_controller->sumAmount($_SESSION['userId'], 1); ?>"><?php echo date('F'); ?> Earnings</budget-item>
<budget-item no-border type="1" value="<?php echo $expense_controller->sumAmount($_SESSION['userId'], 1); ?>"><?php echo date('F'); ?> Spendings </budget-item>
</div>
</budget-card>

<budget-card href='/transactions' header="Recent Transactions" type='View Transactions'>
<div slot="body">
<budget-card href='/trends' header="Latest <?php echo date('F'); ?> Trends" type="View Trends">
<div class="chart" slot="body">
<?php
if ($transactions) {
foreach (array_splice($transactions, 0, 5) as $item) {
$date = date("M d", strtotime($item->date));
echo "<budget-item date=\"{$date}\" category=\"{$item->category}\" value=\"{$item->amount}\">{$item->merchant}</budget-item>";
}
if (!empty($chartData)) {
echo '<canvas id="spending-breakdown" height=150></canvas>';
} else {
echo "<p>No recent transactions</p>";
}
?>
</div>
</budget-card>

<budget-card href='/trends' header="Latest <?php echo date('F'); ?> Trends" type="View Trends">
<div class="chart" slot="body">
<canvas id="spending-breakdown" height=150></canvas>
</div>
</budget-card>

<script>
Chart.defaults.global.legend.labels.usePointStyle = true;
data = {
Expand Down Expand Up @@ -92,6 +86,21 @@
options: options
});
</script>

<budget-card href='/transactions' header="Recent Transactions" type='View Transactions'>
<div slot="body">
<?php
if ($transactions) {
foreach (array_splice($transactions, 0, 5) as $item) {
$date = date("M d", strtotime($item->date));
echo "<budget-item type=\"1\" date=\"{$date}\" category=\"{$item->category}\" value=\"{$item->amount}\">{$item->merchant}</budget-item>";
}
} else {
echo "<p>No recent transactions</p>";
}
?>
</div>
</budget-card>
</div>
</div>
<fab-button>
Expand Down
2 changes: 1 addition & 1 deletion Public/views/header.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
// User logged in
echo '<ul class="menu">
<label id="close">&#10006;</label>
<a class="nav-link" href="/dashboard"><img src=\'../media/profile.svg\' width=30 height=35/>Profile</a>
<a class="nav-link" href="/profile"><img src=\'../media/profile.svg\' width=30 height=35/>Profile</a>
<a class="nav-link" href="/dashboard"><img src=\'../media/dashboard.svg\' width=30 height=35/>Dashboard</a>
<a class="nav-link" href="/transactions"><img src=\'../media/transactions.svg\' width=30 height=35/>Transactions</a>
<a class="nav-link" href="/trends"><img src=\'../media/trend.svg\' width=30 height=35/>Trends</a>
Expand Down
88 changes: 88 additions & 0 deletions Public/views/profile.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
<?php
session_start();
?>
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<link rel="preload" href="../fonts/regular.otf" as="font" type="font/otf" crossorigin>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="icon" href="data:,">
<link type="text/css" rel="stylesheet" href="../styles/styles.css">
<link type="text/css" rel="stylesheet" href="../styles/profile.css">
<script src="../web-components/budget-card.js"></script>
</head>

<body>
<div class="content">
<?php
require './header.php';
include_once __DIR__ . '/../../Controllers/UserController.php';

$uid = $_SESSION['userUid'];
$user_controller = new UserController();
$user = $user_controller->get($uid);
?>
<budget-card card header="<span class='heading'>My Profile </span>">
<div slot="body">
<?php
$errorMapping = [
'userTaken' => 'User is taken!',
'invalidsql' => 'Oops! An error occured!',
'invaliduid' => 'Invalid username!',
'invalimail' => 'Invalid email!',
'invalimailuid' => 'Invalid email!',
'emptyfields' => 'Some fields were left empty!',
'passwordmalformed' => 'Password needs 1 uppercase, 1 lowercase, and 1 digit!',
'passwordcheck' => 'Passwords don\'t match!',
'' => ''
];
if (isset($_GET['error'])) {
$errorMapping[$_GET['error']];

echo '<p class="error">' . $errorMapping[$_GET["error"]] . '</p>';
}
?>
<form action="../includes/profile.inc.php" method="post">
<div class="list"><span class="category">Username:</span><input class="value" type="text" name="username" value="<?php echo $user->username; ?>" readonly></div>
<div class="list"><span class="category">Email:</span><input class="value" type="email" name="email" value="<?php echo $user->email; ?>" readonly></div>
<div class="list"><span class="category">Password:</span><input class="value" type="password" name="password" placeholder="&#9679;&#9679;&#9679;&#9679;&#9679;" readonly></div>
<div class="list hidden" id="repeat-password"><span class="category">Confirm Password:</span><input class="value" type="password" name="password-repeat" placeholder="&#9679;&#9679;&#9679;&#9679;&#9679;" readonly></div>
<input type="hidden" id="cancel" value="Cancel"> </input>
<input type="hidden" id="save" value="Save" name="profile-submit"> </input>
<input type="button" id="edit" value="Edit"> </input>
</form>
</div>
</budget-card>

<script>
document.querySelector('#edit').addEventListener('click', function() {
document.getElementById('edit').type = 'hidden';
document.getElementById('save').type = 'submit';
document.getElementById('cancel').type = 'button';

var inputs = document.querySelectorAll('input.value');
inputs.forEach(input => input.readOnly = false);
inputs[0].focus();
document.querySelector('#repeat-password').classList.remove('hidden');
})

document.querySelector('#cancel').addEventListener('click', function() {
document.getElementById('edit').type = 'button';
document.getElementById('save').type = 'hidden';
document.getElementById('cancel').type = 'hidden';
document.querySelector('#repeat-password').classList.add('hidden');

var inputs = document.querySelectorAll('input.value');
inputs[0].value = "<?php echo $user->username; ?>";
inputs[1].value = "<?php echo $user->email; ?>";
})
</script>
</div>
<?php
require './footer.php';
?>
</body>

</html>
Loading