mirror of
https://github.com/Nezumi-2711/javascript-training.git
synced 2026-09-22 20:01:31 +00:00
Implement show transactions tab
This commit is contained in:
@@ -28,30 +28,30 @@ export default class HomeController {
|
||||
return this.service.categoryService.getAllCategory();
|
||||
}
|
||||
|
||||
handlerGetAllTransactions(idUser) {
|
||||
return this.service.transactionService.getListTransactionByIdUser(idUser);
|
||||
}
|
||||
|
||||
init() {
|
||||
if (this.homeView) {
|
||||
this.homeView.addHandlerEventWalletForm(
|
||||
this.handlerSaveWallet.bind(this),
|
||||
);
|
||||
|
||||
this.homeView.loadPage(
|
||||
this.homeView.initFunction(
|
||||
this.handlerGetInfoUserLogin.bind(this),
|
||||
this.handlerCheckWalletValid.bind(this),
|
||||
this.handlerGetWalletUser.bind(this),
|
||||
this.handlerGetAllCategory.bind(this),
|
||||
);
|
||||
|
||||
this.homeView.addHandlerEventBudgetForm(
|
||||
this.handlerSaveTransaction.bind(this),
|
||||
this.handlerGetAllTransactions.bind(this),
|
||||
this.handlerSaveWallet.bind(this),
|
||||
this.handlerSaveTransaction.bind(this),
|
||||
);
|
||||
this.homeView.addHandlerEventWalletForm();
|
||||
|
||||
this.homeView.loadPage();
|
||||
|
||||
this.homeView.addHandlerEventBudgetForm();
|
||||
|
||||
this.homeView.handlerEventCategoryDialog();
|
||||
|
||||
this.homeView.handlerEventTransactionDialog(
|
||||
this.handlerSaveTransaction.bind(this),
|
||||
this.handlerSaveWallet.bind(this),
|
||||
);
|
||||
this.homeView.handlerEventTransactionDialog();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,3 +92,64 @@ export const changeDateFormat = (oldFormatDate) => {
|
||||
|
||||
return `${day}, ${date}, ${month}, ${year}`;
|
||||
};
|
||||
|
||||
export const createTransactionDetailObject = (category, transactions) => {
|
||||
const totalTransaction = transactions.length;
|
||||
const totalAmount = () => {
|
||||
let amount = 0;
|
||||
|
||||
transactions.forEach((transaction) => {
|
||||
amount += transaction.amount;
|
||||
});
|
||||
|
||||
return amount;
|
||||
};
|
||||
const listTransaction = () => {
|
||||
const results = [];
|
||||
|
||||
transactions.forEach((transaction) => {
|
||||
const dateParts = transaction.date.split(','); // ['Monday', '14', 'September', '2023']
|
||||
const day = dateParts[1];
|
||||
const fullDateString = `${dateParts[0]}, ${dateParts[2]} ${dateParts[3]}`;
|
||||
const tempData = {
|
||||
id: transaction.id,
|
||||
day,
|
||||
fullDateString,
|
||||
note: transaction.note,
|
||||
amount: transaction.amount,
|
||||
};
|
||||
|
||||
results.push(tempData);
|
||||
});
|
||||
|
||||
results.sort((a, b) => parseInt(b.id, 10) - parseInt(a.id, 10));
|
||||
|
||||
return results;
|
||||
};
|
||||
|
||||
return {
|
||||
categoryName: category.name,
|
||||
url: category.url,
|
||||
totalTransaction,
|
||||
totalAmount: totalAmount(),
|
||||
transactions: listTransaction(),
|
||||
};
|
||||
};
|
||||
|
||||
export const getAllCategoryNameInTransactions = (transactions) => {
|
||||
const categoryName = new Set();
|
||||
|
||||
transactions.forEach((transaction) =>
|
||||
categoryName.add(transaction.categoryName),
|
||||
);
|
||||
|
||||
return Array.from(categoryName);
|
||||
};
|
||||
|
||||
export const getAllTransactionByCategoryName = (categoryName, transactions) => {
|
||||
const results = transactions.filter((transaction) => {
|
||||
return transaction.categoryName === categoryName;
|
||||
});
|
||||
|
||||
return results;
|
||||
};
|
||||
|
||||
@@ -4,7 +4,13 @@ import * as MESSAGE from '../constants/message';
|
||||
import CommonView from './commonView';
|
||||
import Wallet from '../models/wallet';
|
||||
import Transaction from '../models/transaction';
|
||||
import { changeDateFormat, formatNumber } from '../helpers/helpers';
|
||||
import {
|
||||
changeDateFormat,
|
||||
createTransactionDetailObject,
|
||||
formatNumber,
|
||||
getAllCategoryNameInTransactions,
|
||||
getAllTransactionByCategoryName,
|
||||
} from '../helpers/helpers';
|
||||
import defaultCategoryIcon from '../../assets/images/question-icon.svg';
|
||||
|
||||
export default class HomeView extends CommonView {
|
||||
@@ -30,24 +36,35 @@ export default class HomeView extends CommonView {
|
||||
this.walletDialog = document.getElementById('walletDialog');
|
||||
}
|
||||
|
||||
async loadPage(
|
||||
initFunction(
|
||||
getInfoUserLogin,
|
||||
isValidWallet,
|
||||
getWalletByIdUser,
|
||||
getAllCategory,
|
||||
getAllTransactions,
|
||||
saveWallet,
|
||||
saveTransaction,
|
||||
) {
|
||||
// Init function
|
||||
this.getInfoUserLogin = getInfoUserLogin;
|
||||
this.isValidWallet = isValidWallet;
|
||||
this.getWalletByIdUser = getWalletByIdUser;
|
||||
this.getAllCategory = getAllCategory;
|
||||
this.getAllTransactions = getAllTransactions;
|
||||
this.saveWallet = saveWallet;
|
||||
this.saveTransaction = saveTransaction;
|
||||
}
|
||||
|
||||
async loadPage() {
|
||||
// Init function
|
||||
|
||||
this.toggleLoaderSpinner();
|
||||
const user = await getInfoUserLogin();
|
||||
const user = await this.getInfoUserLogin();
|
||||
|
||||
if (!user) {
|
||||
window.location.replace('/login');
|
||||
} else {
|
||||
this.user = user;
|
||||
const wallet = await isValidWallet(user.id);
|
||||
const wallet = await this.isValidWallet(user.id);
|
||||
|
||||
// Check user's wallet if have or not
|
||||
if (!wallet) {
|
||||
@@ -67,8 +84,10 @@ export default class HomeView extends CommonView {
|
||||
|
||||
async loadData() {
|
||||
await this.loadWalletUser();
|
||||
await this.loadTransactionData();
|
||||
await this.loadCategory(this.getAllCategory);
|
||||
this.loadSummaryTab();
|
||||
this.loadTransactionTab();
|
||||
}
|
||||
|
||||
// ---------------------LOAD DATA---------------------//
|
||||
@@ -130,13 +149,134 @@ export default class HomeView extends CommonView {
|
||||
)}`;
|
||||
}
|
||||
|
||||
async loadTransactionData() {
|
||||
this.listTransactions = await this.getAllTransactions(this.wallet.idUser);
|
||||
}
|
||||
|
||||
async loadTransactionTab() {
|
||||
// Init data first
|
||||
const transactionDetails = this.loadTransactionDetailsData();
|
||||
const transactionEl = document.querySelector('.transaction');
|
||||
const listTransactionDetailEl =
|
||||
transactionEl.querySelector('.transaction__list');
|
||||
|
||||
const markup = [];
|
||||
|
||||
if (transactionDetails) {
|
||||
transactionDetails.forEach((transactionDetail) => {
|
||||
markup.push(this.transactionDetailMarkup(transactionDetail));
|
||||
});
|
||||
}
|
||||
|
||||
listTransactionDetailEl.innerHTML = '';
|
||||
listTransactionDetailEl.insertAdjacentHTML('afterbegin', markup.join('\n'));
|
||||
}
|
||||
|
||||
loadTransactionDetailsData() {
|
||||
// Get all category user have in transactions
|
||||
const listCategoryInTransaction = getAllCategoryNameInTransactions(
|
||||
this.listTransactions,
|
||||
);
|
||||
|
||||
// Create transactions details object
|
||||
const tempList = [];
|
||||
|
||||
listCategoryInTransaction.forEach((categoryName) => {
|
||||
// Get category object from list category has been loaded.
|
||||
const category = this.listCategory.filter(
|
||||
(item) => item.name === categoryName,
|
||||
);
|
||||
|
||||
const transactions = getAllTransactionByCategoryName(
|
||||
categoryName,
|
||||
this.listTransactions,
|
||||
);
|
||||
|
||||
tempList.push(
|
||||
createTransactionDetailObject(
|
||||
Object.assign({}, ...category),
|
||||
transactions,
|
||||
),
|
||||
);
|
||||
});
|
||||
|
||||
tempList.sort(
|
||||
(a, b) =>
|
||||
parseInt(b.transactions[0].id, 10) - parseInt(a.transactions[0].id, 10),
|
||||
);
|
||||
|
||||
return tempList;
|
||||
}
|
||||
|
||||
transactionDetailMarkup(transactionDetail) {
|
||||
const transactionTimeMarkup = () => {
|
||||
const listMarkup = [];
|
||||
transactionDetail.transactions.forEach((transaction) => {
|
||||
const markup = `
|
||||
<div class="transaction__time">
|
||||
<div class="transaction__details">
|
||||
<p class="transaction__day">${transaction.day}</p>
|
||||
<div class="transaction__time-details">
|
||||
<p class="transaction__date-time">
|
||||
${transaction.fullDateString}
|
||||
</p>
|
||||
<p class="transaction__note">${
|
||||
transaction.note === '' ? 'None' : transaction.note
|
||||
}</p>
|
||||
</div>
|
||||
</div>
|
||||
<p class="transaction__${
|
||||
transaction.amount >= 0 ? 'income' : 'outcome'
|
||||
}">${transaction.amount >= 0 ? '+' : '-'}$ ${formatNumber(
|
||||
Math.abs(transaction.amount),
|
||||
)}</p>
|
||||
</div>
|
||||
`;
|
||||
|
||||
listMarkup.push(markup);
|
||||
});
|
||||
|
||||
return listMarkup.join('\n');
|
||||
};
|
||||
|
||||
return `
|
||||
<div class="transaction__item">
|
||||
<div class="transaction__category">
|
||||
<div class="transaction__category-infor">
|
||||
<div class="transaction__category-icon-container">
|
||||
<img
|
||||
class="icon-category"
|
||||
src="${transactionDetail.url}"
|
||||
alt="Transportation icon category"
|
||||
/>
|
||||
</div>
|
||||
<div class="transaction__category-content">
|
||||
<p class="transaction__category-name">
|
||||
${transactionDetail.categoryName}
|
||||
</p>
|
||||
<p class="transaction__total">${
|
||||
transactionDetail.totalTransaction
|
||||
} Transactions</p>
|
||||
</div>
|
||||
</div>
|
||||
<p class="transaction__category-total">${
|
||||
transactionDetail.totalAmount >= 0 ? '+' : '-'
|
||||
}$ ${formatNumber(Math.abs(transactionDetail.totalAmount))}</p>
|
||||
</div>
|
||||
<div class="transaction__line"></div>
|
||||
<!-- Transaction time item -->
|
||||
${transactionTimeMarkup()}
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
// ---------------------END---------------------//
|
||||
|
||||
// ---------------------TRANSACTION DIALOG---------------------//
|
||||
handlerEventTransactionDialog(saveTransaction, saveWallet) {
|
||||
handlerEventTransactionDialog() {
|
||||
this.transactionDialog.addEventListener('submit', (e) => {
|
||||
e.preventDefault();
|
||||
this.submitTransactionDialog(saveTransaction, saveWallet);
|
||||
this.submitTransactionDialog();
|
||||
});
|
||||
|
||||
this.transactionDialog.addEventListener('input', () => {
|
||||
@@ -157,7 +297,7 @@ export default class HomeView extends CommonView {
|
||||
});
|
||||
}
|
||||
|
||||
async submitTransactionDialog(saveTransaction, saveWallet) {
|
||||
async submitTransactionDialog() {
|
||||
this.toggleLoaderSpinner();
|
||||
this.transactionDialog.close();
|
||||
|
||||
@@ -171,16 +311,16 @@ export default class HomeView extends CommonView {
|
||||
const note = transactionForm.querySelector("[name='note']");
|
||||
const transaction = new Transaction({
|
||||
categoryName: categoryName.value,
|
||||
date: date.value,
|
||||
date: changeDateFormat(date.value),
|
||||
amount: -+amount.value,
|
||||
note: note.value,
|
||||
idUser: this.wallet.idUser,
|
||||
});
|
||||
|
||||
await saveTransaction(transaction);
|
||||
await this.saveTransaction(transaction);
|
||||
|
||||
// Update wallet info
|
||||
this.updateAmountWallet(-+amount.value, saveWallet);
|
||||
this.updateAmountWallet(-+amount.value, this.saveWallet);
|
||||
|
||||
this.showSuccessToast(
|
||||
MESSAGE.ADD_TRANSACTION_SUCCESS,
|
||||
@@ -268,11 +408,11 @@ export default class HomeView extends CommonView {
|
||||
// ---------------------END DIALOG---------------------//
|
||||
|
||||
// ---------------------ADD BUDGET DIALOG---------------------//
|
||||
addHandlerEventBudgetForm(saveTransaction, saveWallet) {
|
||||
addHandlerEventBudgetForm() {
|
||||
this.budgetDialog.addEventListener('submit', (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
this.submitBudgetForm(saveTransaction, saveWallet);
|
||||
this.submitBudgetForm();
|
||||
});
|
||||
|
||||
this.budgetDialog.addEventListener('input', (e) => {
|
||||
@@ -281,7 +421,7 @@ export default class HomeView extends CommonView {
|
||||
});
|
||||
}
|
||||
|
||||
async submitBudgetForm(saveTransaction, saveWallet) {
|
||||
async submitBudgetForm() {
|
||||
try {
|
||||
this.toggleLoaderSpinner(); // Enable loader spinner
|
||||
this.budgetDialog.close(); // Close dialog
|
||||
@@ -300,9 +440,9 @@ export default class HomeView extends CommonView {
|
||||
idUser: this.wallet.idUser,
|
||||
});
|
||||
|
||||
await saveTransaction(transaction);
|
||||
await this.saveTransaction(transaction);
|
||||
|
||||
await this.updateAmountWallet(+amount, saveWallet); // Update wallet
|
||||
await this.updateAmountWallet(+amount, this.saveWallet); // Update wallet
|
||||
|
||||
this.loadData();
|
||||
|
||||
@@ -335,11 +475,11 @@ export default class HomeView extends CommonView {
|
||||
// ---------------------END DIALOG---------------------//
|
||||
|
||||
// ---------------------WALLET DIALOG--------------------- //
|
||||
addHandlerEventWalletForm(saveWallet) {
|
||||
addHandlerEventWalletForm() {
|
||||
this.walletDialog.addEventListener('submit', (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
this.submitWalletForm(saveWallet);
|
||||
this.submitWalletForm();
|
||||
});
|
||||
|
||||
this.walletDialog.addEventListener('input', (e) => {
|
||||
@@ -348,7 +488,7 @@ export default class HomeView extends CommonView {
|
||||
});
|
||||
}
|
||||
|
||||
async submitWalletForm(saveWallet) {
|
||||
async submitWalletForm() {
|
||||
this.walletDialog.close();
|
||||
this.toggleLoaderSpinner();
|
||||
|
||||
@@ -365,7 +505,7 @@ export default class HomeView extends CommonView {
|
||||
inflow: +amount,
|
||||
});
|
||||
|
||||
await saveWallet(wallet);
|
||||
await this.saveWallet(wallet);
|
||||
|
||||
this.showSuccessToast(
|
||||
MESSAGE.ADD_WALLET_SUCCESS,
|
||||
|
||||
@@ -251,93 +251,21 @@
|
||||
<div class="summary">
|
||||
<div class="inflow">
|
||||
<p class="inflow__text">Inflow</p>
|
||||
<p class="inflow__text--income">+$ 500,000,000.00</p>
|
||||
<p class="inflow__text--income">+$ 0.00</p>
|
||||
</div>
|
||||
<div class="outflow">
|
||||
<p class="outflow__text">Outflow</p>
|
||||
<p class="outflow__text--outcome">-$ 100,000.00</p>
|
||||
<p class="outflow__text--outcome">$ 0.00</p>
|
||||
</div>
|
||||
<div class="summary__line"></div>
|
||||
<p class="summary__total">+$ 499,900,000.00</p>
|
||||
<p class="summary__total">+$ 0.00</p>
|
||||
</div>
|
||||
<!-- End content summary -->
|
||||
</div>
|
||||
<div class="app__content-item">
|
||||
<!-- Start content transaction -->
|
||||
<div class="transaction">
|
||||
<div class="transaction__list">
|
||||
<!-- Transaction item -->
|
||||
<!-- Outcome transaction -->
|
||||
<div class="transaction__item">
|
||||
<div class="transaction__category">
|
||||
<div class="transaction__category-infor">
|
||||
<div class="transaction__category-icon-container">
|
||||
<img
|
||||
src="../assets/images/ic_category_transport.png.png"
|
||||
alt="Transportation icon category"
|
||||
/>
|
||||
</div>
|
||||
<div class="transaction__category-content">
|
||||
<p class="transaction__category-name">
|
||||
Transportation
|
||||
</p>
|
||||
<p class="transaction__total">1 Transactions</p>
|
||||
</div>
|
||||
</div>
|
||||
<p class="transaction__category-total">-$ 100,000.00</p>
|
||||
</div>
|
||||
<div class="transaction__line"></div>
|
||||
<!-- Transaction time item -->
|
||||
<div class="transaction__time">
|
||||
<div class="transaction__details">
|
||||
<p class="transaction__day">18</p>
|
||||
<div class="transaction__time-details">
|
||||
<p class="transaction__date-time">
|
||||
Friday, August 2023
|
||||
</p>
|
||||
<p class="transaction__note">Test Note</p>
|
||||
</div>
|
||||
</div>
|
||||
<p class="transaction__outcome">-$ 100,000.00</p>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Income transaction -->
|
||||
<div class="transaction__item">
|
||||
<div class="transaction__category">
|
||||
<div class="transaction__category-infor">
|
||||
<div class="transaction__category-icon-container">
|
||||
<img
|
||||
src="../assets/images/ic_category_other_income.png.png"
|
||||
alt="Transportation icon category"
|
||||
/>
|
||||
</div>
|
||||
<div class="transaction__category-content">
|
||||
<p class="transaction__category-name">
|
||||
Transportation
|
||||
</p>
|
||||
<p class="transaction__total">1 Transactions</p>
|
||||
</div>
|
||||
</div>
|
||||
<p class="transaction__category-total">
|
||||
+$ 500,000,000.00
|
||||
</p>
|
||||
</div>
|
||||
<div class="transaction__line"></div>
|
||||
<!-- Transaction time item -->
|
||||
<div class="transaction__time">
|
||||
<div class="transaction__details">
|
||||
<p class="transaction__day">18</p>
|
||||
<div class="transaction__time-details">
|
||||
<p class="transaction__date-time">
|
||||
Friday, August 2023
|
||||
</p>
|
||||
<p class="transaction__note">Initial Balance</p>
|
||||
</div>
|
||||
</div>
|
||||
<p class="transaction__income">+$ 500,000,000.00</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="transaction__list"></div>
|
||||
</div>
|
||||
<!-- End content transaction -->
|
||||
</div>
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
.background {
|
||||
height: 100vh;
|
||||
background: $gray;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.wrapper {
|
||||
|
||||
Reference in New Issue
Block a user