Skip to content

SOLUTION: ISSUE-4 #70

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
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
275 changes: 275 additions & 0 deletions app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,275 @@

const storageKey = 'savedAccount';
let state = Object.freeze({
account: null
});
const routes = {
'/login': {
templateId: 'login',
title: 'Login - Bank App'
},
'/dashboard': {
templateId: 'dashboard',
title: 'Dashboard - Bank App',
init: refresh
},
'/credits': {
templateId: 'credits',
title: 'Credits - Bank App'
},
};

function navigate(path) {
window.history.pushState({}, path, path);
updateRoute();
}

function updateRoute() {
const path = window.location.pathname;
const route = routes[path];

if (!route) {
return navigate('/dashboard');
}

const template = document.getElementById(route.templateId);
const view = template ? template.content.cloneNode(true) : null;
const app = document.getElementById('app');

if (app && view) {
app.innerHTML = '';
app.appendChild(view);
document.title = route.title;
}

if (typeof route.init === 'function') {
route.init();
}
}


function onLinkClick(event) {
event.preventDefault();
navigate(event.target.href);
}


function updateElement(id, textOrNode) {
const element = document.getElementById(id);
if (!element) {
console.warn(`Element with id '${id}' not found.`);
return;
}
element.textContent = '';
element.append(textOrNode);
}

// Register a new user
async function register() {
const registerForm = document.getElementById('registerForm');
const formData = new FormData(registerForm);
const jsonData = JSON.stringify(Object.fromEntries(formData));
const result = await createAccount(jsonData);

if (result.error) {
return updateElement('registerError', result.error);
}

updateState('account', result);
navigate('/dashboard');
}

// API call to create an account
async function createAccount(account) {
try {
const response = await fetch('//localhost:5000/api/accounts', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: account
});
return await response.json();
} catch (error) {
return { error: error.message || 'Unknown error' };
}
}

// Login existing user
async function login() {
const loginForm = document.getElementById('loginForm');
const user = loginForm.user.value;
const data = await getAccount(user);

if (data.error) {
return updateElement('loginError', data.error);
}

updateState('account', data);
navigate('/dashboard');
}

// Fetch account data from API
async function getAccount(user) {
try {
const response = await fetch(`//localhost:5000/api/accounts/${encodeURIComponent(user)}`);
return await response.json();
} catch (error) {
return { error: error.message || 'Unknown error' };
}
}


function updateDashboard() {
if (!state.account) return navigate('/login');

updateElement('description', state.account.description);
updateElement('balance', state.account.balance.toFixed(2));
updateElement('currency', state.account.currency);

if (!state.account.transactions || state.account.transactions.length === 0) {
console.warn("No transactions found!");
return;
}

const transactionsTable = document.getElementById('transactions');
if (!transactionsTable) {
console.error("Transactions table not found!");
return;
}

transactionsTable.innerHTML = '';

for (const transaction of state.account.transactions) {
transactionsTable.appendChild(createTransactionRow(transaction));
}
}

// Refresh the dashboard data
async function refresh() {
await updateAccountData();
if (typeof updateDashboard === "function") {
updateDashboard();
} else {
console.warn("updateDashboard is not defined!");
}
}

function createTransactionRow(transaction) {
const tr = document.createElement('tr');

const dateTd = document.createElement('td');
dateTd.textContent = transaction.date;

const objectTd = document.createElement('td');
objectTd.textContent = transaction.object;

const amountTd = document.createElement('td');
amountTd.textContent = transaction.amount.toFixed(2);

tr.appendChild(dateTd);
tr.appendChild(objectTd);
tr.appendChild(amountTd);

return tr;
}

function updateState(property, newData) {
state = Object.freeze({
...state,
[property]: newData
});

if (property === 'account' && newData) {
localStorage.setItem(storageKey, newData.user); // Only username
} else if (property === 'account' && !newData) {
localStorage.removeItem(storageKey);
}
}
function logout() {
updateState('account', null);
navigate('/login');
}

// Initialize
async function init() {
const savedUser = localStorage.getItem(storageKey);
if (savedUser) {
const data = await getAccount(savedUser);
if (!data.error) {
updateState('account', data);
}
}

window.onpopstate = () => updateRoute();
updateRoute();
}

init();

// Fetch latest account data
async function updateAccountData() {
const account = state.account;
if (!account) {
return logout();
}

const data = await getAccount(account.user);
if (data.error) {
return logout();
}

updateState('account', data);
}

// Show transaction dialog
function showTransactionDialog() {
const dialog = document.getElementById('transactionDialog');
if (dialog) {
dialog.showModal();
} else {
console.warn("Transaction dialog not found.");
}
}

function closeTransactionDialog() {
const dialog = document.getElementById('transactionDialog');
if (dialog) {
dialog.close();
}
}
async function submitTransaction(event) {
event.preventDefault();

const form = document.getElementById('transactionForm');
const formData = new FormData(form);
const transactionData = Object.fromEntries(formData);
transactionData.amount = parseFloat(transactionData.amount);

const user = state.account?.user;
if (!user) {
console.error("User not found in state!");
return;
}

const response = await fetch(`//localhost:5000/api/accounts/${encodeURIComponent(user)}/transactions`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(transactionData),
});

if (!response.ok) {
console.error(`Transaction failed: ${response.status}`);
return;
}

closeTransactionDialog();
await refresh();
}
document.addEventListener("DOMContentLoaded", function () {
const transactionForm = document.getElementById("transactionForm");

if (transactionForm) {
transactionForm.addEventListener("submit", submitTransaction);
} else {
console.error("Transaction form not found!");
}
});
Binary file added login.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading