mirror of
https://github.com/Nezumi-2711/javascript-training.git
synced 2026-09-22 13:38:43 +00:00
Implement edit and delete transaction
This commit is contained in:
@@ -34,6 +34,10 @@ export default class HomeController {
|
|||||||
return this.service.transactionService.getListTransactionByIdUser(idUser);
|
return this.service.transactionService.getListTransactionByIdUser(idUser);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handlerDeleteTransaction(idTransaction) {
|
||||||
|
return this.service.transactionService.deleteTransaction(idTransaction);
|
||||||
|
}
|
||||||
|
|
||||||
static handlerClearAccessToken() {
|
static handlerClearAccessToken() {
|
||||||
UserService.clearAccessToken();
|
UserService.clearAccessToken();
|
||||||
}
|
}
|
||||||
@@ -49,6 +53,7 @@ export default class HomeController {
|
|||||||
this.handlerSaveWallet.bind(this),
|
this.handlerSaveWallet.bind(this),
|
||||||
this.handlerSaveTransaction.bind(this),
|
this.handlerSaveTransaction.bind(this),
|
||||||
HomeController.handlerClearAccessToken.bind(this),
|
HomeController.handlerClearAccessToken.bind(this),
|
||||||
|
this.handlerDeleteTransaction.bind(this),
|
||||||
);
|
);
|
||||||
this.homeView.addHandlerEventWalletForm();
|
this.homeView.addHandlerEventWalletForm();
|
||||||
|
|
||||||
|
|||||||
@@ -108,7 +108,7 @@ export const createTransactionDetailObject = (category, transactions) => {
|
|||||||
const results = [];
|
const results = [];
|
||||||
|
|
||||||
transactions.forEach((transaction) => {
|
transactions.forEach((transaction) => {
|
||||||
const dateParts = transaction.date.split(','); // ['Monday', '14', 'September', '2023']
|
const dateParts = changeDateFormat(transaction.date).split(','); // ['Monday', '14', 'September', '2023']
|
||||||
const day = dateParts[1];
|
const day = dateParts[1];
|
||||||
const fullDateString = `${dateParts[0]}, ${dateParts[2]} ${dateParts[3]}`;
|
const fullDateString = `${dateParts[0]}, ${dateParts[2]} ${dateParts[3]}`;
|
||||||
const tempData = {
|
const tempData = {
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
export default class Transaction {
|
export default class Transaction {
|
||||||
constructor({
|
constructor({
|
||||||
id = Transaction.createIdTransactions(),
|
id = '',
|
||||||
categoryName = '',
|
categoryName = '',
|
||||||
date = '',
|
date = '',
|
||||||
note = '',
|
note = '',
|
||||||
amount = 0,
|
amount = 0,
|
||||||
idUser,
|
idUser,
|
||||||
}) {
|
}) {
|
||||||
this.id = id;
|
this.id = id === '' ? Transaction.createIdTransactions() : id;
|
||||||
this.categoryName = categoryName;
|
this.categoryName = categoryName;
|
||||||
this.date = date;
|
this.date = date;
|
||||||
this.note = note;
|
this.note = note;
|
||||||
|
|||||||
@@ -102,4 +102,8 @@ export default class CommonService {
|
|||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async deleteData(id, path = this.defaultPath) {
|
||||||
|
await timeOutConnect(this.firebaseService.delete(id, path));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import {
|
|||||||
goOffline,
|
goOffline,
|
||||||
goOnline,
|
goOnline,
|
||||||
onValue,
|
onValue,
|
||||||
|
remove,
|
||||||
} from 'firebase/database';
|
} from 'firebase/database';
|
||||||
import { DATABASE_URL } from '../constants/config';
|
import { DATABASE_URL } from '../constants/config';
|
||||||
|
|
||||||
@@ -28,6 +29,12 @@ class FirebaseService {
|
|||||||
return set(ref(this.db, path), data);
|
return set(ref(this.db, path), data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
delete(id, path) {
|
||||||
|
const dbRef = ref(this.db, `${path}${id}/`);
|
||||||
|
|
||||||
|
return remove(dbRef);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Disconnect to database
|
* Disconnect to database
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -28,4 +28,8 @@ export default class TransactionService extends CommonService {
|
|||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async deleteTransaction(idTransaction) {
|
||||||
|
await this.deleteData(idTransaction);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import CommonView from './commonView';
|
|||||||
import Wallet from '../models/wallet';
|
import Wallet from '../models/wallet';
|
||||||
import Transaction from '../models/transaction';
|
import Transaction from '../models/transaction';
|
||||||
import {
|
import {
|
||||||
changeDateFormat,
|
|
||||||
createTransactionDetailObject,
|
createTransactionDetailObject,
|
||||||
formatNumber,
|
formatNumber,
|
||||||
getAllCategoryNameInTransactions,
|
getAllCategoryNameInTransactions,
|
||||||
@@ -34,6 +33,8 @@ export default class HomeView extends CommonView {
|
|||||||
this.transactionDialog = document.getElementById('transactionDialog');
|
this.transactionDialog = document.getElementById('transactionDialog');
|
||||||
this.categoryDialog = document.getElementById('categoryDialog');
|
this.categoryDialog = document.getElementById('categoryDialog');
|
||||||
this.walletDialog = document.getElementById('walletDialog');
|
this.walletDialog = document.getElementById('walletDialog');
|
||||||
|
|
||||||
|
this.transactionForm = document.getElementById('formAddTransaction');
|
||||||
}
|
}
|
||||||
|
|
||||||
initFunction(
|
initFunction(
|
||||||
@@ -45,6 +46,7 @@ export default class HomeView extends CommonView {
|
|||||||
saveWallet,
|
saveWallet,
|
||||||
saveTransaction,
|
saveTransaction,
|
||||||
clearAccessToken,
|
clearAccessToken,
|
||||||
|
deleteTransaction,
|
||||||
) {
|
) {
|
||||||
this.getInfoUserLogin = getInfoUserLogin;
|
this.getInfoUserLogin = getInfoUserLogin;
|
||||||
this.isValidWallet = isValidWallet;
|
this.isValidWallet = isValidWallet;
|
||||||
@@ -54,6 +56,7 @@ export default class HomeView extends CommonView {
|
|||||||
this.saveWallet = saveWallet;
|
this.saveWallet = saveWallet;
|
||||||
this.saveTransaction = saveTransaction;
|
this.saveTransaction = saveTransaction;
|
||||||
this.clearAccessToken = clearAccessToken;
|
this.clearAccessToken = clearAccessToken;
|
||||||
|
this.deleteTransaction = deleteTransaction;
|
||||||
}
|
}
|
||||||
|
|
||||||
async loadPage() {
|
async loadPage() {
|
||||||
@@ -74,11 +77,11 @@ export default class HomeView extends CommonView {
|
|||||||
// Show add wallet dialog
|
// Show add wallet dialog
|
||||||
this.walletDialog.showModal();
|
this.walletDialog.showModal();
|
||||||
} else {
|
} else {
|
||||||
|
// Init data
|
||||||
|
await this.loadData();
|
||||||
|
|
||||||
// Load event page
|
// Load event page
|
||||||
this.loadEvent();
|
this.loadEvent();
|
||||||
|
|
||||||
// Init data
|
|
||||||
this.loadData();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -216,7 +219,7 @@ export default class HomeView extends CommonView {
|
|||||||
const listMarkup = [];
|
const listMarkup = [];
|
||||||
transactionDetail.transactions.forEach((transaction) => {
|
transactionDetail.transactions.forEach((transaction) => {
|
||||||
const markup = `
|
const markup = `
|
||||||
<div class="transaction__time">
|
<div class="transaction__time" data-id=${transaction.id}>
|
||||||
<div class="transaction__details">
|
<div class="transaction__details">
|
||||||
<p class="transaction__day">${transaction.day}</p>
|
<p class="transaction__day">${transaction.day}</p>
|
||||||
<div class="transaction__time-details">
|
<div class="transaction__time-details">
|
||||||
@@ -298,6 +301,54 @@ export default class HomeView extends CommonView {
|
|||||||
dateInput && categoryName && amountInput >= 1,
|
dateInput && categoryName && amountInput >= 1,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const deleteTransactionBtn =
|
||||||
|
this.transactionDialog.querySelector('.form__delete-btn');
|
||||||
|
|
||||||
|
deleteTransactionBtn.addEventListener('click', async () => {
|
||||||
|
const idEl = this.transactionDialog.querySelector(
|
||||||
|
"[name='id_transaction']",
|
||||||
|
);
|
||||||
|
|
||||||
|
if (idEl.value) {
|
||||||
|
this.transactionDialog.close();
|
||||||
|
this.toggleLoaderSpinner();
|
||||||
|
await this.deleteTransaction(idEl.value);
|
||||||
|
this.toggleLoaderSpinner();
|
||||||
|
this.showSuccessToast('Delete success!', MESSAGE.DEFAULT_MESSAGE);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
initDataTransactionDialog(idTransaction) {
|
||||||
|
const transactionArr = this.listTransactions.filter(
|
||||||
|
(obj) => obj.id === idTransaction,
|
||||||
|
);
|
||||||
|
const transaction = Object.assign({}, ...transactionArr);
|
||||||
|
const categoryArr = this.listCategory.filter(
|
||||||
|
(obj) => obj.name === transaction.categoryName,
|
||||||
|
);
|
||||||
|
const category = Object.assign({}, ...categoryArr);
|
||||||
|
|
||||||
|
const idEl = this.transactionDialog.querySelector(
|
||||||
|
"[name='id_transaction']",
|
||||||
|
);
|
||||||
|
const dateEl = this.transactionDialog.querySelector(
|
||||||
|
"[name='selected_date']",
|
||||||
|
);
|
||||||
|
const categoryEl = this.transactionDialog.querySelector(
|
||||||
|
"[name='category_name']",
|
||||||
|
);
|
||||||
|
const amountEl = this.transactionDialog.querySelector("[name='amount']");
|
||||||
|
const noteEl = this.transactionDialog.querySelector("[name='note']");
|
||||||
|
const iconEl = this.transactionDialog.querySelector('.category-icon');
|
||||||
|
|
||||||
|
idEl.value = transaction.id;
|
||||||
|
dateEl.value = transaction.date;
|
||||||
|
categoryEl.value = transaction.categoryName;
|
||||||
|
amountEl.value = Math.abs(transaction.amount);
|
||||||
|
noteEl.value = transaction.note;
|
||||||
|
iconEl.src = category.url;
|
||||||
}
|
}
|
||||||
|
|
||||||
async submitTransactionDialog() {
|
async submitTransactionDialog() {
|
||||||
@@ -305,32 +356,37 @@ export default class HomeView extends CommonView {
|
|||||||
this.transactionDialog.close();
|
this.transactionDialog.close();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const transactionForm = document.getElementById('formAddTransaction');
|
const dateEl = this.transactionForm.querySelector(
|
||||||
const date = transactionForm.querySelector("[name='selected_date']");
|
"[name='selected_date']",
|
||||||
const categoryName = transactionForm.querySelector(
|
);
|
||||||
|
const categoryNameEl = this.transactionForm.querySelector(
|
||||||
"[name='category_name']",
|
"[name='category_name']",
|
||||||
);
|
);
|
||||||
const amount = transactionForm.querySelector("[name='amount']");
|
const amountEl = this.transactionForm.querySelector("[name='amount']");
|
||||||
const note = transactionForm.querySelector("[name='note']");
|
const noteEl = this.transactionForm.querySelector("[name='note']");
|
||||||
|
const idEl = this.transactionForm.querySelector(
|
||||||
|
"[name='id_transaction']",
|
||||||
|
);
|
||||||
const transaction = new Transaction({
|
const transaction = new Transaction({
|
||||||
categoryName: categoryName.value,
|
id: idEl.value,
|
||||||
date: changeDateFormat(date.value),
|
categoryName: categoryNameEl.value,
|
||||||
amount: -+amount.value,
|
date: dateEl.value,
|
||||||
note: note.value,
|
amount: -+amountEl.value,
|
||||||
|
note: noteEl.value,
|
||||||
idUser: this.wallet.idUser,
|
idUser: this.wallet.idUser,
|
||||||
});
|
});
|
||||||
|
|
||||||
await this.saveTransaction(transaction);
|
await this.saveTransaction(transaction);
|
||||||
|
|
||||||
// Update wallet info
|
// Update wallet info
|
||||||
this.updateAmountWallet(-+amount.value, this.saveWallet);
|
this.updateAmountWallet(-+amountEl.value, this.saveWallet);
|
||||||
|
|
||||||
this.showSuccessToast(
|
this.showSuccessToast(
|
||||||
MESSAGE.ADD_TRANSACTION_SUCCESS,
|
MESSAGE.ADD_TRANSACTION_SUCCESS,
|
||||||
MESSAGE.DEFAULT_MESSAGE,
|
MESSAGE.DEFAULT_MESSAGE,
|
||||||
);
|
);
|
||||||
|
|
||||||
this.clearInputTransactionForm(transactionForm);
|
this.clearInputTransactionForm(this.transactionForm);
|
||||||
|
|
||||||
// Reload data
|
// Reload data
|
||||||
this.loadData();
|
this.loadData();
|
||||||
@@ -341,8 +397,8 @@ export default class HomeView extends CommonView {
|
|||||||
this.toggleLoaderSpinner();
|
this.toggleLoaderSpinner();
|
||||||
}
|
}
|
||||||
|
|
||||||
clearInputTransactionForm(transactionForm) {
|
clearInputTransactionForm() {
|
||||||
const categoryIcon = transactionForm.querySelector('.category-icon');
|
const categoryIcon = this.transactionForm.querySelector('.category-icon');
|
||||||
|
|
||||||
categoryIcon.src = defaultCategoryIcon;
|
categoryIcon.src = defaultCategoryIcon;
|
||||||
|
|
||||||
@@ -350,7 +406,7 @@ export default class HomeView extends CommonView {
|
|||||||
|
|
||||||
this.renderCategoryItem(this.keySearchCategory);
|
this.renderCategoryItem(this.keySearchCategory);
|
||||||
|
|
||||||
transactionForm.reset();
|
this.transactionForm.reset();
|
||||||
}
|
}
|
||||||
// ---------------------END DIALOG---------------------//
|
// ---------------------END DIALOG---------------------//
|
||||||
|
|
||||||
@@ -437,7 +493,7 @@ export default class HomeView extends CommonView {
|
|||||||
|
|
||||||
const transaction = new Transaction({
|
const transaction = new Transaction({
|
||||||
categoryName: DEFAULT_CATEGORY.INCOME,
|
categoryName: DEFAULT_CATEGORY.INCOME,
|
||||||
date: changeDateFormat(date),
|
date,
|
||||||
amount: +amount,
|
amount: +amount,
|
||||||
note,
|
note,
|
||||||
idUser: this.wallet.idUser,
|
idUser: this.wallet.idUser,
|
||||||
@@ -568,6 +624,7 @@ export default class HomeView extends CommonView {
|
|||||||
this.addCommonEventPage();
|
this.addCommonEventPage();
|
||||||
this.handlerTabsTransfer();
|
this.handlerTabsTransfer();
|
||||||
this.addEventSelectCategoryDialog();
|
this.addEventSelectCategoryDialog();
|
||||||
|
this.addEventTransactionItem();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -644,14 +701,31 @@ export default class HomeView extends CommonView {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
showTransactionDialog(editMode = false) {
|
showTransactionDialog(idTransaction = null) {
|
||||||
const deleteBtn = this.transactionDialog.querySelector('.form__delete-btn');
|
this.clearInputTransactionForm();
|
||||||
|
|
||||||
deleteBtn.classList.toggle('hide', !editMode);
|
const deleteBtn = this.transactionDialog.querySelector('.form__delete-btn');
|
||||||
|
deleteBtn.classList.toggle('hide', !idTransaction);
|
||||||
|
|
||||||
|
if (idTransaction) this.initDataTransactionDialog(idTransaction);
|
||||||
|
|
||||||
this.transactionDialog.showModal();
|
this.transactionDialog.showModal();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
addEventTransactionItem() {
|
||||||
|
const transactionItemEl = document.querySelectorAll('.transaction__item');
|
||||||
|
if (transactionItemEl) {
|
||||||
|
transactionItemEl.forEach((item) => {
|
||||||
|
item.addEventListener('click', (e) => {
|
||||||
|
const transactionTime = e.target.closest('.transaction__time');
|
||||||
|
const idTransaction = transactionTime.dataset.id;
|
||||||
|
|
||||||
|
this.showTransactionDialog(idTransaction);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
addEventSelectCategoryDialog() {
|
addEventSelectCategoryDialog() {
|
||||||
const categoryListEl = document.querySelector('.list-category');
|
const categoryListEl = document.querySelector('.list-category');
|
||||||
const categoryIconEl = this.categoryField.querySelector('.category-icon');
|
const categoryIconEl = this.categoryField.querySelector('.category-icon');
|
||||||
|
|||||||
@@ -114,6 +114,7 @@
|
|||||||
<!-- Body -->
|
<!-- Body -->
|
||||||
<div class="dialog__body">
|
<div class="dialog__body">
|
||||||
<form class="form" id="formAddTransaction">
|
<form class="form" id="formAddTransaction">
|
||||||
|
<input type="text" name="id_transaction" hidden />
|
||||||
<div class="form__date-category-amount-input">
|
<div class="form__date-category-amount-input">
|
||||||
<div class="form__input-field">
|
<div class="form__input-field">
|
||||||
<p class="form__label">Date</p>
|
<p class="form__label">Date</p>
|
||||||
|
|||||||
@@ -263,6 +263,11 @@
|
|||||||
@include flex-layout($justify: space-between, $align: center);
|
@include flex-layout($justify: space-between, $align: center);
|
||||||
|
|
||||||
padding: 16px;
|
padding: 16px;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: $hover-light-primary-color;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&__details {
|
&__details {
|
||||||
|
|||||||
Reference in New Issue
Block a user