mirror of
https://github.com/Nezumi-2711/javascript-training.git
synced 2026-09-22 13:38:43 +00:00
Merge branch from feat/refactor-code
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
import Controller from './controllers/controller';
|
import Controller from './controllers/index';
|
||||||
import Service from './services/service';
|
import Service from './services/index';
|
||||||
import View from './views/view';
|
import View from './views/index';
|
||||||
import 'regenerator-runtime/runtime';
|
import 'regenerator-runtime/runtime';
|
||||||
import 'core-js/stable';
|
import 'core-js/stable';
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
export const DATABASE_URL =
|
export const DATABASE_URL =
|
||||||
'https://javascript-training-81f7a-default-rtdb.asia-southeast1.firebasedatabase.app';
|
'https://javascript-training-81f7a-default-rtdb.asia-southeast1.firebasedatabase.app';
|
||||||
export const TIME_OUT_SEC = 3;
|
export const TIME_OUT_SEC = 3;
|
||||||
export const REGEX_PASSWORD =
|
|
||||||
/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$/;
|
|
||||||
|
|||||||
@@ -1,36 +0,0 @@
|
|||||||
export const MESSAGE = {
|
|
||||||
PASSWORD_NOT_MATCH: 'Password not match! Please try again!',
|
|
||||||
PASSWORD_NOT_STRONG:
|
|
||||||
'Password must at least one uppercase, one lowercase letter, one number and one special character!',
|
|
||||||
ERROR_MESSAGE_DEFAULT: 'Something went wrong!',
|
|
||||||
TIME_OUT_ERROR: 'Connection time out! Please try again!',
|
|
||||||
ERROR_CREDENTIAL: {
|
|
||||||
title: 'Error Credential',
|
|
||||||
message: 'Email or password not match! Please try again!',
|
|
||||||
},
|
|
||||||
DEFAULT_TITLE_ERROR_POPUP: 'Error',
|
|
||||||
USER_EXIST_ERROR: 'User is exists! Please try another email!',
|
|
||||||
WELCOME: {
|
|
||||||
title: 'Login Successful!',
|
|
||||||
message: 'Welcome to Money Lover!',
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
export const URL = {
|
|
||||||
LOGIN: 'login',
|
|
||||||
REGISTER: 'register',
|
|
||||||
HOME: '',
|
|
||||||
};
|
|
||||||
|
|
||||||
export const BTN_CONTENT = {
|
|
||||||
GOT_IT: 'Got it!',
|
|
||||||
OK: 'Ok',
|
|
||||||
};
|
|
||||||
|
|
||||||
export const LOCAL_STORAGE = {
|
|
||||||
ACCESS_TOKEN: 'accessToken',
|
|
||||||
IS_FIRST_LOGIN: 'isFirstLogin',
|
|
||||||
};
|
|
||||||
|
|
||||||
export const TYPE_POPUP = { success: 'success', error: 'error' };
|
|
||||||
export const MARK_ICON = { success: 'check', error: 'error' };
|
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
export const PASSWORD_NOT_MATCH = 'Password not match! Please try again!';
|
||||||
|
|
||||||
|
export const PASSWORD_NOT_STRONG =
|
||||||
|
'Password must at least one uppercase, one lowercase letter, one number and one special character!';
|
||||||
|
|
||||||
|
export const ERROR_MESSAGE_DEFAULT = 'Something went wrong!';
|
||||||
|
|
||||||
|
export const TIME_OUT_ERROR = 'Connection time out! Please try again!';
|
||||||
|
|
||||||
|
export const ERROR_CREDENTIAL = {
|
||||||
|
title: 'Error Credential',
|
||||||
|
message: 'Email or password not match! Please try again!',
|
||||||
|
};
|
||||||
|
|
||||||
|
export const DEFAULT_TITLE_ERROR_TOAST = 'Error';
|
||||||
|
|
||||||
|
export const USER_EXIST_ERROR = 'User is exists! Please try another email!';
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
export const URL = {
|
||||||
|
LOGIN: 'login',
|
||||||
|
REGISTER: 'register',
|
||||||
|
HOME: '',
|
||||||
|
};
|
||||||
|
|
||||||
|
export const BTN_CONTENT = {
|
||||||
|
GOT_IT: 'Got it!',
|
||||||
|
OK: 'Ok',
|
||||||
|
};
|
||||||
|
|
||||||
|
export const LOCAL_STORAGE = {
|
||||||
|
ACCESS_TOKEN: 'accessToken',
|
||||||
|
};
|
||||||
|
|
||||||
|
export const TYPE_TOAST = { success: 'success', error: 'error' };
|
||||||
|
export const MARK_ICON = { success: 'check', error: 'error' };
|
||||||
|
|
||||||
|
export const REGEX_PASSWORD =
|
||||||
|
/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$/;
|
||||||
@@ -4,13 +4,13 @@ export default class LoginController {
|
|||||||
this.loginView = view.loginView;
|
this.loginView = view.loginView;
|
||||||
}
|
}
|
||||||
|
|
||||||
handlerValidateUser(email, password) {
|
handlerLoginUser(email, password) {
|
||||||
return this.service.userService.validateUser(email, password);
|
return this.service.userService.loginUser(email, password);
|
||||||
}
|
}
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
if (this.loginView) {
|
if (this.loginView) {
|
||||||
this.loginView.addHandlerForm(this.handlerValidateUser.bind(this));
|
this.loginView.addHandlerForm(this.handlerLoginUser.bind(this));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ export default class RegisterController {
|
|||||||
this.service = service;
|
this.service = service;
|
||||||
}
|
}
|
||||||
|
|
||||||
hanlderCheckUserExist(email) {
|
handlerCheckUserExist(email) {
|
||||||
return this.service.userService.checkUserExist(email);
|
return this.service.userService.checkUserExist(email);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -15,7 +15,7 @@ export default class RegisterController {
|
|||||||
init() {
|
init() {
|
||||||
if (this.registerView) {
|
if (this.registerView) {
|
||||||
this.registerView.addHandlerForm(
|
this.registerView.addHandlerForm(
|
||||||
this.hanlderCheckUserExist.bind(this),
|
this.handlerCheckUserExist.bind(this),
|
||||||
this.handlerSaveUser.bind(this),
|
this.handlerSaveUser.bind(this),
|
||||||
);
|
);
|
||||||
this.registerView.addHandlerInputFormChange();
|
this.registerView.addHandlerInputFormChange();
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { MESSAGE } from '../constants/constant';
|
import * as MESSAGE from '../constants/message';
|
||||||
import { REGEX_PASSWORD, TIME_OUT_SEC } from '../constants/config';
|
import { TIME_OUT_SEC } from '../constants/config';
|
||||||
import FirebaseService from '../services/firebaseService';
|
import FirebaseService from '../services/firebaseService';
|
||||||
|
import { REGEX_PASSWORD } from '../constants/variable';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validate password
|
* Validate password
|
||||||
@@ -70,6 +71,7 @@ export const getSubdirectoryURL = () => {
|
|||||||
|
|
||||||
const subDirectory = parts[3]; // Get subdirectory url only
|
const subDirectory = parts[3]; // Get subdirectory url only
|
||||||
|
|
||||||
|
// Remove query behind subDirectory
|
||||||
const index = subDirectory.indexOf('?');
|
const index = subDirectory.indexOf('?');
|
||||||
if (index !== -1) {
|
if (index !== -1) {
|
||||||
return subDirectory.substring(0, index);
|
return subDirectory.substring(0, index);
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { LOCAL_STORAGE } from '../constants/constant';
|
import { LOCAL_STORAGE } from '../constants/variable';
|
||||||
import { createToken } from '../helpers/helpers';
|
import { createToken } from '../helpers/helpers';
|
||||||
import CommonService from './commonService';
|
import CommonService from './commonService';
|
||||||
import LocalStorageService from './localStorageService';
|
import LocalStorageService from './localStorageService';
|
||||||
@@ -54,7 +54,7 @@ export default class UserService extends CommonService {
|
|||||||
* @param {*} password The password user input
|
* @param {*} password The password user input
|
||||||
* @returns {boolean} Return true if match info on database, otherwise return false
|
* @returns {boolean} Return true if match info on database, otherwise return false
|
||||||
*/
|
*/
|
||||||
async validateUser(email, password) {
|
async loginUser(email, password) {
|
||||||
const user = await this.getUserByEmail(email);
|
const user = await this.getUserByEmail(email);
|
||||||
|
|
||||||
// Check password
|
// Check password
|
||||||
|
|||||||
@@ -1,15 +1,13 @@
|
|||||||
import CommonView from './commonView';
|
import CommonView from './commonView';
|
||||||
import * as CONSTANT from '../constants/constant';
|
import * as MESSAGE from '../constants/message';
|
||||||
import { validatePassword } from '../helpers/helpers';
|
import { validatePassword } from '../helpers/helpers';
|
||||||
|
|
||||||
export default class CommonLoginRegisterView extends CommonView {
|
export default class CommonLoginRegisterView extends CommonView {
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
this.handleEventBtnPopupAndOverlay();
|
|
||||||
|
|
||||||
this.parentElement = document.querySelector('.form');
|
this.parentElement = document.querySelector('.form');
|
||||||
this.messageDefault = CONSTANT.MESSAGE.ERROR_MESSAGE_DEFAULT;
|
this.messageDefault = MESSAGE.ERROR_MESSAGE_DEFAULT;
|
||||||
this.inputPassword = document.querySelector('input[name="password"]');
|
this.inputPassword = document.querySelector('input[name="password"]');
|
||||||
this.inputPasswordConfirm = document.querySelector(
|
this.inputPasswordConfirm = document.querySelector(
|
||||||
'input[name="password_confirm"]',
|
'input[name="password_confirm"]',
|
||||||
@@ -26,17 +24,17 @@ export default class CommonLoginRegisterView extends CommonView {
|
|||||||
if (validatePassword(account.passwordConfirm)) {
|
if (validatePassword(account.passwordConfirm)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
this.showError(CONSTANT.MESSAGE.PASSWORD_NOT_STRONG);
|
this.showError(MESSAGE.PASSWORD_NOT_STRONG);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
this.showError(CONSTANT.MESSAGE.PASSWORD_NOT_MATCH);
|
this.showError(MESSAGE.PASSWORD_NOT_MATCH);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show or hide style error input password
|
* Show or hide style error input password
|
||||||
*/
|
*/
|
||||||
toogleErrorStyleInputPass() {
|
toggleErrorStyleInputPass() {
|
||||||
this.inputPassword.classList.toggle('error-input');
|
this.inputPassword.classList.toggle('error-input');
|
||||||
this.inputPasswordConfirm.classList.toggle('error-input');
|
this.inputPasswordConfirm.classList.toggle('error-input');
|
||||||
}
|
}
|
||||||
@@ -51,7 +49,7 @@ export default class CommonLoginRegisterView extends CommonView {
|
|||||||
// If have error message on page, remove it with style error input password
|
// If have error message on page, remove it with style error input password
|
||||||
if (this.errorMessageEl) {
|
if (this.errorMessageEl) {
|
||||||
this.errorMessageEl.remove();
|
this.errorMessageEl.remove();
|
||||||
this.toogleErrorStyleInputPass();
|
this.toggleErrorStyleInputPass();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,7 +68,11 @@ export default class CommonLoginRegisterView extends CommonView {
|
|||||||
*/
|
*/
|
||||||
showError(message) {
|
showError(message) {
|
||||||
this.renderError(message);
|
this.renderError(message);
|
||||||
this.toogleErrorStyleInputPass();
|
this.toggleErrorStyleInputPass();
|
||||||
|
}
|
||||||
|
|
||||||
|
toggleDialog() {
|
||||||
|
this.dialog.classList.toggle('active');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -86,16 +88,4 @@ export default class CommonLoginRegisterView extends CommonView {
|
|||||||
.querySelector('.form__title')
|
.querySelector('.form__title')
|
||||||
.insertAdjacentHTML('afterend', markup);
|
.insertAdjacentHTML('afterend', markup);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Add event listener for popup and overlay
|
|
||||||
*/
|
|
||||||
handleEventBtnPopupAndOverlay() {
|
|
||||||
this.popupBtn.addEventListener('click', this.tooglePopupForm.bind(this));
|
|
||||||
this.overlay.addEventListener('click', this.toogleDialog.bind(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
toogleDialog() {
|
|
||||||
this.dialog.classList.toggle('active');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,93 +1,106 @@
|
|||||||
import { MARK_ICON, TYPE_POPUP } from '../constants/constant';
|
import { MARK_ICON, TYPE_TOAST } from '../constants/variable';
|
||||||
|
|
||||||
export default class CommonView {
|
export default class CommonView {
|
||||||
constructor() {
|
constructor() {
|
||||||
this.overlayMarkup = '<div class="overlay"></div>';
|
this.initToast();
|
||||||
|
this.initElementToast();
|
||||||
this.initPopup();
|
|
||||||
this.initElementPopup();
|
|
||||||
this.initLoader();
|
this.initLoader();
|
||||||
|
this.handleEventToast();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implement popup in site
|
* Implement toast in site
|
||||||
*/
|
*/
|
||||||
initPopup() {
|
initToast() {
|
||||||
this.rootElement = document.querySelector('body');
|
this.rootElement = document.querySelector('body');
|
||||||
|
|
||||||
const markup = `
|
const markup = `
|
||||||
${this.overlayMarkup}
|
<dialog class="dialog">
|
||||||
<div class="modal-box">
|
<div class="toast">
|
||||||
<div class="mark"></div>
|
<div class="mark"></div>
|
||||||
<h2 class="modal-box__title"></h2>
|
<h2 class="toast__title"></h2>
|
||||||
<p class="modal-box__message"></p>
|
<p class="toast__message"></p>
|
||||||
|
<button class="toast__redirect-btn">OK</button>
|
||||||
<button class="modal-box__redirect-btn"></button>
|
|
||||||
</div>
|
</div>
|
||||||
|
</dialog>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
this.rootElement.insertAdjacentHTML('afterbegin', markup);
|
this.rootElement.insertAdjacentHTML('afterbegin', markup);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Assgign element in popup to property
|
* Assign element in toast to property
|
||||||
*/
|
*/
|
||||||
initElementPopup() {
|
initElementToast() {
|
||||||
this.modalBox = document.querySelector('.modal-box');
|
this.toastDialog = document.querySelector('.dialog');
|
||||||
this.popupIcon = document.querySelector('.mark');
|
this.toast = document.querySelector('.toast');
|
||||||
this.popupBtn = document.querySelector('.modal-box__redirect-btn');
|
this.toastIcon = document.querySelector('.mark');
|
||||||
this.popupTitle = document.querySelector('.modal-box__title');
|
this.toastBtn = document.querySelector('.toast__redirect-btn');
|
||||||
this.popupContent = document.querySelector('.modal-box__message');
|
this.toastTitle = document.querySelector('.toast__title');
|
||||||
this.overlay = document.querySelector('.overlay');
|
this.toastContent = document.querySelector('.toast__message');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show or hide loader screen
|
* Show or hide loader screen
|
||||||
*/
|
*/
|
||||||
toogleLoaderSpinner() {
|
toggleLoaderSpinner() {
|
||||||
this.spinner.classList.toggle('hidden');
|
this.spinner.classList.toggle('hidden');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show or hide popup
|
* Add toast content
|
||||||
|
* @param {TYPE_TOAST} typeToast Type of the toast
|
||||||
|
* @param {string} title Title of toast
|
||||||
|
* @param {string} content Content of toast
|
||||||
|
* @param {string} btnContent Content of button
|
||||||
*/
|
*/
|
||||||
tooglePopupForm() {
|
initToastContent(typeToast, title, content, btnContent) {
|
||||||
this.overlay.classList.toggle('active');
|
// Remove old typeToast class if haved
|
||||||
this.modalBox.classList.toggle('active');
|
this.toast.classList.forEach((classItem) =>
|
||||||
|
classItem === TYPE_TOAST.success || classItem === TYPE_TOAST.error
|
||||||
|
? this.toast.classList.remove(classItem)
|
||||||
|
: '',
|
||||||
|
);
|
||||||
|
|
||||||
|
// Remove old icon toast if haved
|
||||||
|
this.toastIcon.classList.forEach((classItem) =>
|
||||||
|
classItem === MARK_ICON.success || classItem === MARK_ICON.error
|
||||||
|
? this.toastIcon.classList.remove(classItem)
|
||||||
|
: '',
|
||||||
|
);
|
||||||
|
|
||||||
|
// Init content toast
|
||||||
|
this.toast.classList.add(
|
||||||
|
typeToast === TYPE_TOAST.success ? TYPE_TOAST.success : TYPE_TOAST.error,
|
||||||
|
);
|
||||||
|
this.toastIcon.classList.add(
|
||||||
|
typeToast === TYPE_TOAST.success ? MARK_ICON.success : MARK_ICON.error,
|
||||||
|
);
|
||||||
|
this.toastTitle.textContent = title;
|
||||||
|
this.toastContent.textContent = content;
|
||||||
|
this.toastBtn.textContent = btnContent;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add popup content
|
* Add event listener for toast
|
||||||
* @param {TYPE_POPUP} typePopup Type of the popup
|
|
||||||
* @param {string} title Title of popup
|
|
||||||
* @param {string} content Content of popup
|
|
||||||
* @param {string} btnContent Content of button
|
|
||||||
*/
|
*/
|
||||||
initPopupContent(typePopup, title, content, btnContent) {
|
handleEventToast() {
|
||||||
// Remove old typePopup class if haved
|
this.toastBtn.addEventListener('click', () => {
|
||||||
this.modalBox.classList.forEach((classItem) =>
|
this.toastDialog.close();
|
||||||
classItem === TYPE_POPUP.success || classItem === TYPE_POPUP.error
|
});
|
||||||
? this.modalBox.classList.remove(classItem)
|
|
||||||
: '',
|
|
||||||
);
|
|
||||||
|
|
||||||
// Remove old icon popup if haved
|
// Add event close dialog when click outside
|
||||||
this.popupIcon.classList.forEach((classItem) =>
|
this.toastDialog.addEventListener('click', (e) => {
|
||||||
classItem === MARK_ICON.success || classItem === MARK_ICON.error
|
const dialogDimensions = this.toastDialog.getBoundingClientRect();
|
||||||
? this.popupIcon.classList.remove(classItem)
|
if (
|
||||||
: '',
|
e.clientX < dialogDimensions.left ||
|
||||||
);
|
e.clientX > dialogDimensions.right ||
|
||||||
|
e.clientY < dialogDimensions.top ||
|
||||||
// Init content popup
|
e.clientY > dialogDimensions.bottom
|
||||||
this.modalBox.classList.add(
|
) {
|
||||||
typePopup === TYPE_POPUP.success ? TYPE_POPUP.success : TYPE_POPUP.error,
|
this.toastDialog.close();
|
||||||
);
|
}
|
||||||
this.popupIcon.classList.add(
|
});
|
||||||
typePopup === TYPE_POPUP.success ? MARK_ICON.success : MARK_ICON.error,
|
|
||||||
);
|
|
||||||
this.popupTitle.textContent = title;
|
|
||||||
this.popupContent.textContent = content;
|
|
||||||
this.popupBtn.textContent = btnContent;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { TYPE_POPUP, MESSAGE, BTN_CONTENT } from '../constants/constant';
|
import { TYPE_TOAST, BTN_CONTENT } from '../constants/variable';
|
||||||
|
import * as MESSAGE from '../constants/message';
|
||||||
import CommonView from './commonView';
|
import CommonView from './commonView';
|
||||||
import Wallet from '../models/wallet';
|
import Wallet from '../models/wallet';
|
||||||
|
|
||||||
@@ -10,19 +11,15 @@ export default class HomeView extends CommonView {
|
|||||||
this.allContent = document.querySelectorAll('.app__content-item');
|
this.allContent = document.querySelectorAll('.app__content-item');
|
||||||
this.addTransactionBtn = document.getElementById('addTransaction');
|
this.addTransactionBtn = document.getElementById('addTransaction');
|
||||||
this.addBudgetBtn = document.getElementById('addBudget');
|
this.addBudgetBtn = document.getElementById('addBudget');
|
||||||
this.overlay = document.querySelector('.overlay');
|
|
||||||
this.darkOverlay = document.querySelector('.dark-overlay');
|
|
||||||
this.dialog = document.querySelectorAll('.dialog');
|
|
||||||
this.saveBtn = document.querySelectorAll('.form__save-btn');
|
this.saveBtn = document.querySelectorAll('.form__save-btn');
|
||||||
|
this.dialogs = document.querySelectorAll('.dialog');
|
||||||
this.cancelBtn = document.querySelectorAll('.form__cancel-btn');
|
this.cancelBtn = document.querySelectorAll('.form__cancel-btn');
|
||||||
this.categoryField = document.getElementById('selectCategory');
|
this.categoryField = document.getElementById('selectCategory');
|
||||||
this.closeIcon = document.querySelector('.close-icon');
|
this.closeIcon = document.querySelector('.close-icon');
|
||||||
|
|
||||||
this.budgetForm = document.getElementById('budgetForm');
|
this.budgetDialog = document.getElementById('budgetDialog');
|
||||||
this.transactionForm = document.getElementById('transactionForm');
|
this.transactionDialog = document.getElementById('transactionDialog');
|
||||||
this.categoryForm = document.getElementById('categoryForm');
|
this.categoryDialog = document.getElementById('categoryDialog');
|
||||||
this.walletForm = document.getElementById('walletForm');
|
|
||||||
|
|
||||||
this.walletDialog = document.getElementById('walletDialog');
|
this.walletDialog = document.getElementById('walletDialog');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -38,11 +35,7 @@ export default class HomeView extends CommonView {
|
|||||||
// Check user's wallet if have or not
|
// Check user's wallet if have or not
|
||||||
if (!walletExist) {
|
if (!walletExist) {
|
||||||
// Show add wallet dialog
|
// Show add wallet dialog
|
||||||
this.walletDialog.classList.add('active');
|
this.walletDialog.showModal();
|
||||||
// If overlay is not exist on page
|
|
||||||
if (!this.overlay.classList.contains('active')) {
|
|
||||||
this.toggleActiveOverlay();
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
this.loadEvent();
|
this.loadEvent();
|
||||||
}
|
}
|
||||||
@@ -50,7 +43,7 @@ export default class HomeView extends CommonView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
addHandlerSubmitWalletForm(saveWallet) {
|
addHandlerSubmitWalletForm(saveWallet) {
|
||||||
this.walletForm.addEventListener('submit', (e) => {
|
this.walletDialog.addEventListener('submit', (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
this.submitWalletForm(saveWallet);
|
this.submitWalletForm(saveWallet);
|
||||||
@@ -68,16 +61,16 @@ export default class HomeView extends CommonView {
|
|||||||
await saveWallet(wallet);
|
await saveWallet(wallet);
|
||||||
|
|
||||||
this.hideDialog();
|
this.hideDialog();
|
||||||
this.showSuccessPopup('Add wallet success', 'Click ok to continue!');
|
this.showSuccessToast('Add wallet success', 'Click ok to continue!');
|
||||||
this.loadEvent();
|
this.loadEvent();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// Show popup error
|
// Show toast error
|
||||||
this.initErrorPopup(error);
|
this.initErrorToast(error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
addHandlerInputChangeWalletForm() {
|
addHandlerInputChangeWalletForm() {
|
||||||
this.walletForm.addEventListener('input', (e) => {
|
this.walletDialog.addEventListener('input', (e) => {
|
||||||
const bodyDialog = e.target.closest('.dialog__body');
|
const bodyDialog = e.target.closest('.dialog__body');
|
||||||
this.validateWalletForm(bodyDialog);
|
this.validateWalletForm(bodyDialog);
|
||||||
});
|
});
|
||||||
@@ -95,28 +88,27 @@ export default class HomeView extends CommonView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
showSuccessPopup(title, message) {
|
showSuccessToast(title, message) {
|
||||||
const typePopup = TYPE_POPUP.success;
|
const typeToast = TYPE_TOAST.success;
|
||||||
const btnContent = BTN_CONTENT.OK;
|
const btnContent = BTN_CONTENT.OK;
|
||||||
|
|
||||||
this.initPopupContent(typePopup, title, message, btnContent);
|
this.initToastContent(typeToast, title, message, btnContent);
|
||||||
|
|
||||||
// Show popup
|
this.dialogToast.showModal();
|
||||||
this.tooglePopupForm();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implement error popup in site
|
* Implement error toast in site
|
||||||
* @param {string} content The content will show in error popup
|
* @param {string} content The content will show in error toast
|
||||||
*/
|
*/
|
||||||
initErrorPopup(error) {
|
initErrorToast(error) {
|
||||||
const title = error.title ? error.title : MESSAGE.DEFAULT_TITLE_ERROR_POPUP;
|
const title = error.title ? error.title : MESSAGE.DEFAULT_TITLE_ERROR_TOAST;
|
||||||
const content = error.message ? error.message : error;
|
const content = error.message ? error.message : error;
|
||||||
|
|
||||||
this.initPopupContent(TYPE_POPUP.error, title, content, BTN_CONTENT.GOT_IT);
|
this.initToastContent(TYPE_TOAST.error, title, content, BTN_CONTENT.GOT_IT);
|
||||||
|
|
||||||
// Show popup
|
// Show toast
|
||||||
this.tooglePopupForm();
|
this.toggleToastForm();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------- HANDLER EVENT ------------------------------- */
|
/* ------------------------------- HANDLER EVENT ------------------------------- */
|
||||||
@@ -149,66 +141,38 @@ export default class HomeView extends CommonView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
addCommonEventPage() {
|
addCommonEventPage() {
|
||||||
|
// Add event close dialog when click outside
|
||||||
|
this.dialogs.forEach((dialog) => {
|
||||||
|
dialog.addEventListener('click', (e) => {
|
||||||
|
const dialogDimensions = dialog.getBoundingClientRect();
|
||||||
|
if (
|
||||||
|
e.clientX < dialogDimensions.left ||
|
||||||
|
e.clientX > dialogDimensions.right ||
|
||||||
|
e.clientY < dialogDimensions.top ||
|
||||||
|
e.clientY > dialogDimensions.bottom
|
||||||
|
) {
|
||||||
|
dialog.close();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
this.addTransactionBtn.addEventListener('click', () => {
|
this.addTransactionBtn.addEventListener('click', () => {
|
||||||
this.transactionForm.classList.add('active');
|
this.transactionDialog.showModal();
|
||||||
this.toggleActiveOverlay();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
this.addBudgetBtn.addEventListener('click', () => {
|
this.addBudgetBtn.addEventListener('click', () => {
|
||||||
this.budgetForm.classList.add('active');
|
this.budgetDialog.showModal();
|
||||||
this.toggleActiveOverlay();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
this.cancelBtn.forEach((item) => {
|
|
||||||
item.addEventListener('click', () => {
|
|
||||||
this.hideDialog();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
this.overlay.addEventListener('click', () => {
|
|
||||||
this.hideDialog();
|
|
||||||
});
|
|
||||||
|
|
||||||
this.popupBtn.addEventListener('click', this.tooglePopupForm.bind(this));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
addEventSelectCategoryDialog() {
|
addEventSelectCategoryDialog() {
|
||||||
this.categoryField.addEventListener('click', () => {
|
this.categoryField.addEventListener('click', () => {
|
||||||
this.categoryForm.classList.add('active');
|
this.categoryDialog.showModal();
|
||||||
this.toggleDarkOverlayActive();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
this.closeIcon.addEventListener(
|
this.closeIcon.addEventListener('click', () => {
|
||||||
'click',
|
this.categoryDialog.close();
|
||||||
this.hideSelectCategoryForm.bind(this),
|
|
||||||
);
|
|
||||||
|
|
||||||
this.darkOverlay.addEventListener(
|
|
||||||
'click',
|
|
||||||
this.hideSelectCategoryForm.bind(this),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
hideSelectCategoryForm() {
|
|
||||||
this.categoryForm.classList.remove('active');
|
|
||||||
this.toggleDarkOverlayActive();
|
|
||||||
}
|
|
||||||
|
|
||||||
toggleDarkOverlayActive() {
|
|
||||||
this.darkOverlay.classList.toggle('active');
|
|
||||||
}
|
|
||||||
|
|
||||||
hideDialog() {
|
|
||||||
this.dialog.forEach((item) => {
|
|
||||||
if (item.classList.contains('active')) {
|
|
||||||
item.classList.remove('active');
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
this.toggleActiveOverlay();
|
|
||||||
}
|
|
||||||
|
|
||||||
toggleActiveOverlay() {
|
|
||||||
this.overlay.classList.toggle('active');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
removeActiveTab() {
|
removeActiveTab() {
|
||||||
@@ -216,4 +180,12 @@ export default class HomeView extends CommonView {
|
|||||||
tab.classList.remove('active');
|
tab.classList.remove('active');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
toggleDialog() {
|
||||||
|
this.dialog.forEach((item) => {
|
||||||
|
if (item.classList.contains('active')) {
|
||||||
|
item.classList.remove('active');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
import RegisterView from './registerView';
|
import RegisterView from './registerView';
|
||||||
import LoginView from './loginView';
|
import LoginView from './loginView';
|
||||||
import { getSubdirectoryURL } from '../helpers/helpers';
|
import { getSubdirectoryURL } from '../helpers/helpers';
|
||||||
import { URL } from '../constants/constant';
|
import { URL } from '../constants/variable';
|
||||||
import HomeView from './homeView';
|
import HomeView from './homeView';
|
||||||
|
|
||||||
export default class View {
|
export default class View {
|
||||||
@@ -1,12 +1,13 @@
|
|||||||
import CommonLoginRegisterView from './commonLoginRegisterView';
|
import CommonLoginRegisterView from './commonLoginRegisterView';
|
||||||
import { MESSAGE, TYPE_POPUP, BTN_CONTENT } from '../constants/constant';
|
import { TYPE_TOAST, BTN_CONTENT } from '../constants/variable';
|
||||||
|
import * as MESSAGE from '../constants/message';
|
||||||
|
|
||||||
export default class LoginView extends CommonLoginRegisterView {
|
export default class LoginView extends CommonLoginRegisterView {
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
this.parentElement = document.querySelector('.form');
|
this.parentElement = document.querySelector('.form');
|
||||||
this.dialog = document.querySelector('.modal-box');
|
this.dialog = document.querySelector('.toast');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -24,17 +25,17 @@ export default class LoginView extends CommonLoginRegisterView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implement error popup in site
|
* Implement error toast in site
|
||||||
* @param {string} content The content will show in error popup
|
* @param {string} content The content will show in error toast
|
||||||
*/
|
*/
|
||||||
initErrorPopup(error) {
|
initErrorToast(error) {
|
||||||
const title = error.title ? error.title : MESSAGE.DEFAULT_TITLE_ERROR_POPUP;
|
const title = error.title ? error.title : MESSAGE.DEFAULT_TITLE_ERROR_TOAST;
|
||||||
const content = error.message ? error.message : error;
|
const content = error.message ? error.message : error;
|
||||||
|
|
||||||
this.initPopupContent(TYPE_POPUP.error, title, content, BTN_CONTENT.GOT_IT);
|
this.initToastContent(TYPE_TOAST.error, title, content, BTN_CONTENT.GOT_IT);
|
||||||
|
|
||||||
// Show popup
|
// Show toast
|
||||||
this.tooglePopupForm();
|
this.toastDialog.showModal();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -51,17 +52,18 @@ export default class LoginView extends CommonLoginRegisterView {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* The action when submit form
|
* The action when submit form
|
||||||
* @param {Function} validateUser The function need to be set event
|
* @param {Function} loginUser The function need to be set event
|
||||||
|
* * @param {event} event The event target
|
||||||
*/
|
*/
|
||||||
async submitForm(validateUser, event) {
|
async submitForm(loginUser, event) {
|
||||||
try {
|
try {
|
||||||
// Load spinner
|
// Load spinner
|
||||||
this.toogleLoaderSpinner();
|
this.toggleLoaderSpinner();
|
||||||
|
|
||||||
// Get data from form
|
// Get data from form
|
||||||
const userInput = this.getDataFromForm(event);
|
const userInput = this.getDataFromForm(event);
|
||||||
// Check user exist
|
// Check user exist
|
||||||
const results = await validateUser(userInput.email, userInput.password);
|
const results = await loginUser(userInput.email, userInput.password);
|
||||||
|
|
||||||
if (results) {
|
if (results) {
|
||||||
window.location.replace('/');
|
window.location.replace('/');
|
||||||
@@ -70,10 +72,10 @@ export default class LoginView extends CommonLoginRegisterView {
|
|||||||
}
|
}
|
||||||
throw MESSAGE.ERROR_CREDENTIAL;
|
throw MESSAGE.ERROR_CREDENTIAL;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// Show popup error
|
// Show toast error
|
||||||
this.initErrorPopup(error);
|
this.initErrorToast(error);
|
||||||
}
|
}
|
||||||
// Close spinner
|
// Close spinner
|
||||||
this.toogleLoaderSpinner();
|
this.toggleLoaderSpinner();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { TYPE_POPUP, MESSAGE, BTN_CONTENT } from '../constants/constant';
|
import { TYPE_TOAST, BTN_CONTENT } from '../constants/variable';
|
||||||
|
import * as MESSAGE from '../constants/message';
|
||||||
import CommonLoginRegisterView from './commonLoginRegisterView';
|
import CommonLoginRegisterView from './commonLoginRegisterView';
|
||||||
import User from '../models/user';
|
import User from '../models/user';
|
||||||
|
|
||||||
@@ -6,7 +7,7 @@ export default class RegisterView extends CommonLoginRegisterView {
|
|||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
this.dialog = document.querySelector('.modal-box');
|
this.dialog = document.querySelector('.toast');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -32,32 +33,32 @@ export default class RegisterView extends CommonLoginRegisterView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implement register success popup in site
|
* Implement register success toast in site
|
||||||
*/
|
*/
|
||||||
showRegisterSuccessPopup() {
|
showRegisterSuccessToast() {
|
||||||
const typePopup = TYPE_POPUP.success;
|
const typeToast = TYPE_TOAST.success;
|
||||||
const title = 'Register Commpleted';
|
const title = 'Register Commpleted';
|
||||||
const content = 'Please login to continue!';
|
const content = 'Please login to continue!';
|
||||||
const btnContent = 'OK';
|
const btnContent = 'OK';
|
||||||
|
|
||||||
this.initPopupContent(typePopup, title, content, btnContent);
|
this.initToastContent(typeToast, title, content, btnContent);
|
||||||
|
|
||||||
// Show popup
|
// Show toast
|
||||||
this.tooglePopupForm();
|
this.toastDialog.showModal();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implement error popup in site
|
* Implement error toast in site
|
||||||
* @param {string} content The content will show in error popup
|
* @param {string} content The content will show in error toast
|
||||||
*/
|
*/
|
||||||
initErrorPopup(error) {
|
initErrorToast(error) {
|
||||||
const title = error.title ? error.title : MESSAGE.DEFAULT_TITLE_ERROR_POPUP;
|
const title = error.title ? error.title : MESSAGE.DEFAULT_TITLE_ERROR_TOAST;
|
||||||
const content = error.message ? error.message : error;
|
const content = error.message ? error.message : error;
|
||||||
|
|
||||||
this.initPopupContent(TYPE_POPUP.error, title, content, BTN_CONTENT.OK);
|
this.initToastContent(TYPE_TOAST.error, title, content, BTN_CONTENT.OK);
|
||||||
|
|
||||||
// Show popup
|
// Show toast
|
||||||
this.tooglePopupForm();
|
this.toastDialog.showModal();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -75,7 +76,7 @@ export default class RegisterView extends CommonLoginRegisterView {
|
|||||||
async submitForm(checkExistUser, saveUser) {
|
async submitForm(checkExistUser, saveUser) {
|
||||||
try {
|
try {
|
||||||
// Load spinner
|
// Load spinner
|
||||||
this.toogleLoaderSpinner();
|
this.toggleLoaderSpinner();
|
||||||
|
|
||||||
// Get data from form
|
// Get data from form
|
||||||
const user = this.getDataFromForm();
|
const user = this.getDataFromForm();
|
||||||
@@ -88,16 +89,16 @@ export default class RegisterView extends CommonLoginRegisterView {
|
|||||||
throw Error(MESSAGE.USER_EXIST_ERROR);
|
throw Error(MESSAGE.USER_EXIST_ERROR);
|
||||||
} else {
|
} else {
|
||||||
await saveUser(user);
|
await saveUser(user);
|
||||||
// Show popup success
|
// Show toast success
|
||||||
this.showRegisterSuccessPopup();
|
this.showRegisterSuccessToast();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// Show popup error
|
// Show toast error
|
||||||
this.initErrorPopup(error);
|
this.initErrorToast(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close spinner
|
// Close spinner
|
||||||
this.toogleLoaderSpinner();
|
this.toggleLoaderSpinner();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,16 +8,16 @@
|
|||||||
<title>Money Lover Web</title>
|
<title>Money Lover Web</title>
|
||||||
</head>
|
</head>
|
||||||
<body class="home-page">
|
<body class="home-page">
|
||||||
<div class="dark-overlay"></div>
|
<dialog class="dialog">
|
||||||
<!-- <div class="modal-box success active">
|
<div class="toast success">
|
||||||
<div class="mark check"></div>
|
<div class="mark check"></div>
|
||||||
<h2 class="modal-box__title">Login Success!</h2>
|
<h2 class="toast__title">Login Success!</h2>
|
||||||
<p class="modal-box__message">Welcome to Money Lover!</p>
|
<p class="toast__message">Welcome to Money Lover!</p>
|
||||||
|
<button class="toast__redirect-btn">OK</button>
|
||||||
<button class="modal-box__redirect-btn">OK</button>
|
</div>
|
||||||
</div> -->
|
</dialog>
|
||||||
<!-- Add a wallet form -->
|
<!-- Add a wallet form -->
|
||||||
<div class="dialog" id="walletDialog">
|
<dialog class="dialog" id="walletDialog">
|
||||||
<div class="dialog__add-wallet">
|
<div class="dialog__add-wallet">
|
||||||
<!-- Dialog header -->
|
<!-- Dialog header -->
|
||||||
<div class="dialog__header">
|
<div class="dialog__header">
|
||||||
@@ -62,10 +62,10 @@
|
|||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</dialog>
|
||||||
<!-- End form -->
|
<!-- End form -->
|
||||||
<!-- Add budget form -->
|
<!-- Add budget form -->
|
||||||
<div class="dialog" id="budgetForm">
|
<dialog class="dialog" id="budgetDialog">
|
||||||
<div class="dialog__add-budget">
|
<div class="dialog__add-budget">
|
||||||
<!-- Header -->
|
<!-- Header -->
|
||||||
<div class="dialog__header">
|
<div class="dialog__header">
|
||||||
@@ -102,16 +102,18 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="form__action">
|
<div class="form__action">
|
||||||
<button type="button" class="form__cancel-btn">CANCEL</button>
|
<button formmethod="dialog" class="form__cancel-btn">
|
||||||
|
CANCEL
|
||||||
|
</button>
|
||||||
<button type="submit" class="form__save-btn">SAVE</button>
|
<button type="submit" class="form__save-btn">SAVE</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</dialog>
|
||||||
<!-- End form -->
|
<!-- End form -->
|
||||||
<!-- Add, edit, delete transaction form -->
|
<!-- Add, edit, delete transaction form -->
|
||||||
<div class="dialog" id="transactionForm">
|
<dialog class="dialog" id="transactionDialog">
|
||||||
<div class="dialog__add-transaction">
|
<div class="dialog__add-transaction">
|
||||||
<!-- Header-->
|
<!-- Header-->
|
||||||
<div class="dialog__header">
|
<div class="dialog__header">
|
||||||
@@ -160,20 +162,22 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="form__action">
|
<div class="form__action">
|
||||||
<button type="button" class="form__cancel-btn">CANCEL</button>
|
<button formmethod="dialog" class="form__cancel-btn">
|
||||||
|
CANCEL
|
||||||
|
</button>
|
||||||
<button type="submit" class="form__save-btn">SAVE</button>
|
<button type="submit" class="form__save-btn">SAVE</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</dialog>
|
||||||
<!-- End form -->
|
<!-- End form -->
|
||||||
<!-- Select category form -->
|
<!-- Select category form -->
|
||||||
<div class="dialog" id="categoryForm">
|
<dialog class="dialog" id="categoryDialog">
|
||||||
<div class="dialog__select-category">
|
<div class="dialog__select-category">
|
||||||
<div class="dialog__header">
|
<div class="dialog__header">
|
||||||
<div class="dialog__title-container">
|
<div class="dialog__title-container">
|
||||||
<div class="close-icon"></div>
|
<div formmethod="dialog" class="close-icon"></div>
|
||||||
<div class="dialog__title">Select category</div>
|
<div class="dialog__title">Select category</div>
|
||||||
</div>
|
</div>
|
||||||
<form class="form">
|
<form class="form">
|
||||||
@@ -268,7 +272,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</dialog>
|
||||||
<!-- End form -->
|
<!-- End form -->
|
||||||
<!-- Start header -->
|
<!-- Start header -->
|
||||||
<header class="header">
|
<header class="header">
|
||||||
@@ -410,89 +414,5 @@
|
|||||||
</div>
|
</div>
|
||||||
<!-- All scripts below is use for test purpose! -->
|
<!-- All scripts below is use for test purpose! -->
|
||||||
<script type="module" src="../js/main.js"></script>
|
<script type="module" src="../js/main.js"></script>
|
||||||
<!-- <script>
|
|
||||||
// Handle event when click on tabs
|
|
||||||
const tabs = document.querySelectorAll('.app__tab-item');
|
|
||||||
const all_content = document.querySelectorAll('.app__content-item');
|
|
||||||
|
|
||||||
tabs.forEach((tab, index) => {
|
|
||||||
tab.addEventListener('click', (e) => {
|
|
||||||
tabs.forEach((tab) => {
|
|
||||||
tab.classList.remove('active');
|
|
||||||
});
|
|
||||||
tab.classList.add('active');
|
|
||||||
|
|
||||||
const line = document.querySelector('.app__line');
|
|
||||||
line.style.width = e.target.offsetWidth + 'px';
|
|
||||||
line.style.left = e.target.offsetLeft + 'px';
|
|
||||||
|
|
||||||
all_content.forEach((content) => {
|
|
||||||
content.classList.remove('active');
|
|
||||||
});
|
|
||||||
all_content[index].classList.add('active');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// Add event
|
|
||||||
const addTransactionBtn = document.getElementById('addTransaction');
|
|
||||||
const addBudgetBtn = document.getElementById('addBudget');
|
|
||||||
const overlay = document.querySelector('.overlay');
|
|
||||||
const darkOverlay = document.querySelector('.dark-overlay');
|
|
||||||
const dialog = document.querySelectorAll('.dialog');
|
|
||||||
const cancelBtn = document.querySelectorAll('.form__cancel-btn');
|
|
||||||
const categoryField = document.getElementById('selectCategory');
|
|
||||||
const closeIcon = document.querySelector('.close-icon');
|
|
||||||
|
|
||||||
const budgetForm = document.getElementById('budgetForm');
|
|
||||||
const transactionForm = document.getElementById('transactionForm');
|
|
||||||
const categoryForm = document.getElementById('categoryForm');
|
|
||||||
|
|
||||||
overlay.addEventListener('click', () => {
|
|
||||||
overlay.classList.toggle('active');
|
|
||||||
|
|
||||||
dialog.forEach((item) => {
|
|
||||||
if (item.classList.contains('active')) {
|
|
||||||
item.classList.remove('active');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
addTransactionBtn.addEventListener('click', () => {
|
|
||||||
transactionForm.classList.toggle('active');
|
|
||||||
overlay.classList.toggle('active');
|
|
||||||
});
|
|
||||||
|
|
||||||
addBudgetBtn.addEventListener('click', () => {
|
|
||||||
budgetForm.classList.toggle('active');
|
|
||||||
overlay.classList.toggle('active');
|
|
||||||
});
|
|
||||||
|
|
||||||
cancelBtn.forEach((item) => {
|
|
||||||
item.addEventListener('click', () => {
|
|
||||||
overlay.classList.toggle('active');
|
|
||||||
|
|
||||||
dialog.forEach((item) => {
|
|
||||||
if (item.classList.contains('active')) {
|
|
||||||
item.classList.remove('active');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
categoryField.addEventListener('click', () => {
|
|
||||||
categoryForm.classList.add('active');
|
|
||||||
darkOverlay.classList.add('active');
|
|
||||||
});
|
|
||||||
|
|
||||||
closeIcon.addEventListener('click', () => {
|
|
||||||
categoryForm.classList.remove('active');
|
|
||||||
darkOverlay.classList.remove('active');
|
|
||||||
});
|
|
||||||
|
|
||||||
darkOverlay.addEventListener('click', () => {
|
|
||||||
darkOverlay.classList.remove('active');
|
|
||||||
categoryForm.classList.remove('active');
|
|
||||||
});
|
|
||||||
</script> -->
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<link rel="shortcut icon" href="../assets/images/favicon.ico" />
|
||||||
<link rel="stylesheet" href="../styles/_main.scss" />
|
<link rel="stylesheet" href="../styles/_main.scss" />
|
||||||
<title>Login - Money Lover</title>
|
<title>Login - Money Lover</title>
|
||||||
</head>
|
</head>
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<link rel="shortcut icon" href="../assets/images/favicon.ico" />
|
||||||
<link rel="stylesheet" href="../styles/_main.scss" />
|
<link rel="stylesheet" href="../styles/_main.scss" />
|
||||||
<title>Register - Money Lover</title>
|
<title>Register - Money Lover</title>
|
||||||
</head>
|
</head>
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
@import './components/dialog';
|
@import './components/dialog';
|
||||||
@import './components/icons';
|
@import './components/icons';
|
||||||
@import './components/loader';
|
@import './components/loader';
|
||||||
@import './components/popup-form';
|
@import './components/toast-form';
|
||||||
|
|
||||||
// Layouts
|
// Layouts
|
||||||
@import './layouts/header';
|
@import './layouts/header';
|
||||||
|
|||||||
@@ -1,14 +1,9 @@
|
|||||||
.dialog {
|
.dialog {
|
||||||
@extend %d-absolute, %rounded-sm;
|
@extend %rounded-sm;
|
||||||
|
|
||||||
left: 50%;
|
border: none;
|
||||||
top: 32%;
|
|
||||||
transform: translate(-50%, -50%) scale(1);
|
|
||||||
background-color: $white;
|
background-color: $white;
|
||||||
z-index: $zindex-lv-2;
|
padding: none;
|
||||||
|
|
||||||
opacity: 0;
|
|
||||||
pointer-events: none;
|
|
||||||
transition: all 0.3s ease;
|
transition: all 0.3s ease;
|
||||||
|
|
||||||
&__title {
|
&__title {
|
||||||
@@ -17,7 +12,17 @@
|
|||||||
line-height: 20px;
|
line-height: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.active {
|
&::backdrop {
|
||||||
@extend %active;
|
background-color: rgba($color: #000000, $alpha: 0.2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Login page
|
||||||
|
.login-page,
|
||||||
|
.register-page {
|
||||||
|
.dialog {
|
||||||
|
@extend %rounded;
|
||||||
|
|
||||||
|
padding: 0px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-19
@@ -1,19 +1,8 @@
|
|||||||
.modal-box {
|
.toast {
|
||||||
@extend %d-flex;
|
@extend %d-flex;
|
||||||
@extend %d-absolute;
|
|
||||||
@include flex-layout($direction: column, $align: center, $gap: 30px);
|
@include flex-layout($direction: column, $align: center, $gap: 30px);
|
||||||
|
|
||||||
left: 50%;
|
|
||||||
top: 50%;
|
|
||||||
transform: translate(-50%, -50%) scale(1);
|
|
||||||
box-shadow: 0 5px 10px rgba(0, 0, 0, 0.1);
|
|
||||||
z-index: $zindex-lv-2;
|
|
||||||
padding: 40px 50px;
|
padding: 40px 50px;
|
||||||
border-radius: 10px;
|
|
||||||
background-color: $white;
|
|
||||||
opacity: 0;
|
|
||||||
pointer-events: none;
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
|
|
||||||
&__title {
|
&__title {
|
||||||
font-size: $fs-2x-lg;
|
font-size: $fs-2x-lg;
|
||||||
@@ -32,17 +21,12 @@
|
|||||||
padding: 15px 30px;
|
padding: 15px 30px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.active {
|
|
||||||
opacity: 1;
|
|
||||||
pointer-events: auto;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.success .modal-box__redirect-btn {
|
.success .toast__redirect-btn {
|
||||||
background-color: $light-primary-color;
|
background-color: $light-primary-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
.error .modal-box__redirect-btn {
|
.error .toast__redirect-btn {
|
||||||
background-color: $dark-error-color;
|
background-color: $dark-error-color;
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user