From 6e243bdf236b6b2465a5aacb17aed8a08f5e2332 Mon Sep 17 00:00:00 2001 From: Loi Phan Date: Mon, 11 Sep 2023 14:02:05 +0700 Subject: [PATCH 1/4] Change naming function --- javascript-practice/src/js/helpers/helpers.js | 16 ++++++++++++---- javascript-practice/src/js/views/view.js | 4 ++-- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/javascript-practice/src/js/helpers/helpers.js b/javascript-practice/src/js/helpers/helpers.js index 5f58efc..5c5596e 100644 --- a/javascript-practice/src/js/helpers/helpers.js +++ b/javascript-practice/src/js/helpers/helpers.js @@ -63,10 +63,18 @@ export const convertDataObjectToModel = (data) => { return { id, ...object.data }; }; -export const getURL = () => { +export const getSubdirectoryURL = () => { const url = window.location.href; - const parts = url.split('/'); - const lastPart = parts.pop(); // Lấy phần tử cuối cùng trong mảng - return lastPart; + const parts = url.split('/'); // Results: ['http:', '', 'example.com', ''] + + const subDirectory = parts[3]; // Get subdirectory url only + + // Remove query behind subDirectory + const index = subDirectory.indexOf('?'); + if (index !== -1) { + return subDirectory.substring(0, index); + } + + return subDirectory; }; diff --git a/javascript-practice/src/js/views/view.js b/javascript-practice/src/js/views/view.js index e9e04d5..d98bd38 100644 --- a/javascript-practice/src/js/views/view.js +++ b/javascript-practice/src/js/views/view.js @@ -1,11 +1,11 @@ import RegisterView from './registerView'; import LoginView from './loginView'; -import { getURL } from '../helpers/helpers'; +import { getSubdirectoryURL } from '../helpers/helpers'; import { URL } from '../constants/constant'; export default class View { constructor() { - switch (getURL()) { + switch (getSubdirectoryURL()) { case URL.LOGIN: this.loginView = new LoginView(); break; From 0912441c3f024ac34760d5a2b5dfc1d6c4816a47 Mon Sep 17 00:00:00 2001 From: Loi Phan Date: Mon, 11 Sep 2023 16:25:00 +0700 Subject: [PATCH 2/4] Implement dialog element into project --- .../src/js/constants/constant.js | 4 +- .../src/js/views/commonLoginRegisterView.js | 10 +- .../src/js/views/commonView.js | 130 ++++++++---------- javascript-practice/src/js/views/homeView.js | 86 +++++------- javascript-practice/src/js/views/loginView.js | 26 ++-- .../src/js/views/registerView.js | 42 +++--- javascript-practice/src/pages/index.html | 42 +++--- .../src/styles/components/_dialog.scss | 13 +- .../src/styles/components/_popup-form.scss | 22 +-- 9 files changed, 166 insertions(+), 209 deletions(-) diff --git a/javascript-practice/src/js/constants/constant.js b/javascript-practice/src/js/constants/constant.js index 3397fc0..da22de9 100644 --- a/javascript-practice/src/js/constants/constant.js +++ b/javascript-practice/src/js/constants/constant.js @@ -8,7 +8,7 @@ export const MESSAGE = { title: 'Error Credential', message: 'Email or password not match! Please try again!', }, - DEFAULT_TITLE_ERROR_POPUP: 'Error', + DEFAULT_TITLE_ERROR_TOAST: 'Error', USER_EXIST_ERROR: 'User is exists! Please try another email!', }; @@ -27,5 +27,5 @@ export const LOCAL_STORAGE = { ACCESS_TOKEN: 'accessToken', }; -export const TYPE_POPUP = { success: 'success', error: 'error' }; +export const TYPE_TOAST = { success: 'success', error: 'error' }; export const MARK_ICON = { success: 'check', error: 'error' }; diff --git a/javascript-practice/src/js/views/commonLoginRegisterView.js b/javascript-practice/src/js/views/commonLoginRegisterView.js index 1e5dcf3..d7c0b88 100644 --- a/javascript-practice/src/js/views/commonLoginRegisterView.js +++ b/javascript-practice/src/js/views/commonLoginRegisterView.js @@ -34,7 +34,7 @@ export default class CommonLoginRegisterView extends CommonView { /** * Show or hide style error input password */ - toogleErrorStyleInputPass() { + toggleErrorStyleInputPass() { this.inputPassword.classList.toggle('error-input'); this.inputPasswordConfirm.classList.toggle('error-input'); } @@ -49,7 +49,7 @@ export default class CommonLoginRegisterView extends CommonView { // If have error message on page, remove it with style error input password if (this.errorMessageEl) { this.errorMessageEl.remove(); - this.toogleErrorStyleInputPass(); + this.toggleErrorStyleInputPass(); } } @@ -68,7 +68,11 @@ export default class CommonLoginRegisterView extends CommonView { */ showError(message) { this.renderError(message); - this.toogleErrorStyleInputPass(); + this.toggleErrorStyleInputPass(); + } + + toggleDialog() { + this.dialog.classList.toggle('active'); } /** diff --git a/javascript-practice/src/js/views/commonView.js b/javascript-practice/src/js/views/commonView.js index 933b6fb..bd92974 100644 --- a/javascript-practice/src/js/views/commonView.js +++ b/javascript-practice/src/js/views/commonView.js @@ -1,116 +1,106 @@ -import { MARK_ICON, TYPE_POPUP } from '../constants/constant'; +import { MARK_ICON, TYPE_TOAST } from '../constants/constant'; export default class CommonView { constructor() { - this.overlayMarkup = '
'; - - this.initPopup(); - this.initElementPopup(); + this.initToast(); + this.initElementToast(); this.initLoader(); - this.handleEventBtnPopupAndOverlay(); + this.handleEventToast(); } /** - * Implement popup in site + * Implement toast in site */ - initPopup() { + initToast() { this.rootElement = document.querySelector('body'); const markup = ` - ${this.overlayMarkup} - + +
+
+

+

+ +
+
`; this.rootElement.insertAdjacentHTML('afterbegin', markup); } /** - * Assgign element in popup to property + * Assign element in toast to property */ - initElementPopup() { - this.modalBox = document.querySelector('.modal-box'); - this.popupIcon = document.querySelector('.mark'); - this.popupBtn = document.querySelector('.modal-box__redirect-btn'); - this.popupTitle = document.querySelector('.modal-box__title'); - this.popupContent = document.querySelector('.modal-box__message'); - this.overlay = document.querySelector('.overlay'); + initElementToast() { + this.toastDialog = document.querySelector('.dialog'); + this.toast = document.querySelector('.toast'); + this.toastIcon = document.querySelector('.mark'); + this.toastBtn = document.querySelector('.toast__redirect-btn'); + this.toastTitle = document.querySelector('.toast__title'); + this.toastContent = document.querySelector('.toast__message'); } /** * Show or hide loader screen */ - toogleLoaderSpinner() { + toggleLoaderSpinner() { this.spinner.classList.toggle('hidden'); } /** - * Show or hide popup - */ - tooglePopupForm() { - this.overlay.classList.toggle('active'); - this.modalBox.classList.toggle('active'); - } - - /** - * Add popup content - * @param {TYPE_POPUP} typePopup Type of the popup - * @param {string} title Title of popup - * @param {string} content Content of 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 */ - initPopupContent(typePopup, title, content, btnContent) { - // Remove old typePopup class if haved - this.modalBox.classList.forEach((classItem) => - classItem === TYPE_POPUP.success || classItem === TYPE_POPUP.error - ? this.modalBox.classList.remove(classItem) + initToastContent(typeToast, title, content, btnContent) { + // Remove old typeToast class if haved + this.toast.classList.forEach((classItem) => + classItem === TYPE_TOAST.success || classItem === TYPE_TOAST.error + ? this.toast.classList.remove(classItem) : '', ); - // Remove old icon popup if haved - this.popupIcon.classList.forEach((classItem) => + // Remove old icon toast if haved + this.toastIcon.classList.forEach((classItem) => classItem === MARK_ICON.success || classItem === MARK_ICON.error - ? this.popupIcon.classList.remove(classItem) + ? this.toastIcon.classList.remove(classItem) : '', ); - // Init content popup - this.modalBox.classList.add( - typePopup === TYPE_POPUP.success ? TYPE_POPUP.success : TYPE_POPUP.error, + // Init content toast + this.toast.classList.add( + typeToast === TYPE_TOAST.success ? TYPE_TOAST.success : TYPE_TOAST.error, ); - this.popupIcon.classList.add( - typePopup === TYPE_POPUP.success ? MARK_ICON.success : MARK_ICON.error, + this.toastIcon.classList.add( + typeToast === TYPE_TOAST.success ? MARK_ICON.success : MARK_ICON.error, ); - this.popupTitle.textContent = title; - this.popupContent.textContent = content; - this.popupBtn.textContent = btnContent; + this.toastTitle.textContent = title; + this.toastContent.textContent = content; + this.toastBtn.textContent = btnContent; } /** - * Add event listener for popup and overlay + * Add event listener for toast */ - handleEventBtnPopupAndOverlay() { - this.popupBtn.addEventListener('click', this.tooglePopupForm.bind(this)); - this.overlay.addEventListener('click', this.toogleDialog.bind(this)); - } + handleEventToast() { + this.toastBtn.addEventListener('click', () => { + this.toastDialog.close(); + }); - toogleDialog() { - this.overlay.classList.toggle('active'); - if (this.dialog.length) { - // If it have more dialog - this.dialog.forEach((item) => { - if (item.classList.contains('active')) { - item.classList.remove('active'); - } - }); - } else { - this.dialog.classList.toggle('active'); - } + // Add event close dialog when click outside + this.toastDialog.addEventListener('click', (e) => { + const dialogDimensions = this.toastDialog.getBoundingClientRect(); + if ( + e.clientX < dialogDimensions.left || + e.clientX > dialogDimensions.right || + e.clientY < dialogDimensions.top || + e.clientY > dialogDimensions.bottom + ) { + this.toastDialog.close(); + } + }); } /** diff --git a/javascript-practice/src/js/views/homeView.js b/javascript-practice/src/js/views/homeView.js index 4a0636c..08f7637 100644 --- a/javascript-practice/src/js/views/homeView.js +++ b/javascript-practice/src/js/views/homeView.js @@ -8,16 +8,14 @@ export default class HomeView extends CommonView { this.allContent = document.querySelectorAll('.app__content-item'); this.addTransactionBtn = document.getElementById('addTransaction'); this.addBudgetBtn = document.getElementById('addBudget'); - this.overlay = document.querySelector('.overlay'); - this.darkOverlay = document.querySelector('.dark-overlay'); - this.dialog = document.querySelectorAll('.dialog'); + this.dialogs = document.querySelectorAll('.dialog'); this.cancelBtn = document.querySelectorAll('.form__cancel-btn'); this.categoryField = document.getElementById('selectCategory'); this.closeIcon = document.querySelector('.close-icon'); - this.budgetForm = document.getElementById('budgetForm'); - this.transactionForm = document.getElementById('transactionForm'); - this.categoryForm = document.getElementById('categoryForm'); + this.budgetDialog = document.getElementById('budgetDialog'); + this.transactionDialog = document.getElementById('transactionDialog'); + this.categoryDialog = document.getElementById('categoryDialog'); } /** @@ -42,69 +40,51 @@ export default class HomeView extends CommonView { } addCommonEventPage() { - this.addTransactionBtn.addEventListener('click', () => { - this.transactionForm.classList.add('active'); - this.toggleActiveOverlay(); - }); - - this.addBudgetBtn.addEventListener('click', () => { - this.budgetForm.classList.add('active'); - this.toggleActiveOverlay(); - }); - - this.cancelBtn.forEach((item) => { - item.addEventListener('click', () => { - this.hideDialog(); - this.toggleActiveOverlay(); + // 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.overlay.addEventListener('click', () => { - this.hideDialog(); + this.addTransactionBtn.addEventListener('click', () => { + this.transactionDialog.showModal(); + }); + + this.addBudgetBtn.addEventListener('click', () => { + this.budgetDialog.showModal(); }); } addEventSelectCategoryDialog() { this.categoryField.addEventListener('click', () => { - this.categoryForm.classList.add('active'); - this.toggleDarkOverlayActive(); + this.categoryDialog.showModal(); }); - this.closeIcon.addEventListener( - 'click', - 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.closeIcon.addEventListener('click', () => { + this.categoryDialog.close(); }); } - toggleActiveOverlay() { - this.overlay.classList.toggle('active'); - } - removeActiveTab() { this.tabs.forEach((tab) => { tab.classList.remove('active'); }); } + + toggleDialog() { + this.dialog.forEach((item) => { + if (item.classList.contains('active')) { + item.classList.remove('active'); + } + }); + } } diff --git a/javascript-practice/src/js/views/loginView.js b/javascript-practice/src/js/views/loginView.js index c325955..d296f44 100644 --- a/javascript-practice/src/js/views/loginView.js +++ b/javascript-practice/src/js/views/loginView.js @@ -1,12 +1,12 @@ import CommonLoginRegisterView from './commonLoginRegisterView'; -import { MESSAGE, TYPE_POPUP, BTN_CONTENT } from '../constants/constant'; +import { MESSAGE, TYPE_TOAST, BTN_CONTENT } from '../constants/constant'; export default class LoginView extends CommonLoginRegisterView { constructor() { super(); this.parentElement = document.querySelector('.form'); - this.dialog = document.querySelector('.modal-box'); + this.dialog = document.querySelector('.toast'); } /** @@ -24,17 +24,17 @@ export default class LoginView extends CommonLoginRegisterView { } /** - * Implement error popup in site - * @param {string} content The content will show in error popup + * Implement error toast in site + * @param {string} content The content will show in error toast */ - initErrorPopup(error) { - const title = error.title ? error.title : MESSAGE.DEFAULT_TITLE_ERROR_POPUP; + initErrorToast(error) { + const title = error.title ? error.title : MESSAGE.DEFAULT_TITLE_ERROR_TOAST; 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 - this.tooglePopupForm(); + // Show toast + this.toastDialog.showModal(); } /** @@ -56,7 +56,7 @@ export default class LoginView extends CommonLoginRegisterView { async submitForm(validateUser, event) { try { // Load spinner - this.toogleLoaderSpinner(); + this.toggleLoaderSpinner(); // Get data from form const userInput = this.getDataFromForm(event); @@ -70,10 +70,10 @@ export default class LoginView extends CommonLoginRegisterView { } throw MESSAGE.ERROR_CREDENTIAL; } catch (error) { - // Show popup error - this.initErrorPopup(error); + // Show toast error + this.initErrorToast(error); } // Close spinner - this.toogleLoaderSpinner(); + this.toggleLoaderSpinner(); } } diff --git a/javascript-practice/src/js/views/registerView.js b/javascript-practice/src/js/views/registerView.js index f7a4aed..08c34ee 100644 --- a/javascript-practice/src/js/views/registerView.js +++ b/javascript-practice/src/js/views/registerView.js @@ -1,4 +1,4 @@ -import { TYPE_POPUP, MESSAGE, BTN_CONTENT } from '../constants/constant'; +import { TYPE_TOAST, MESSAGE, BTN_CONTENT } from '../constants/constant'; import CommonLoginRegisterView from './commonLoginRegisterView'; import User from '../models/user'; @@ -6,7 +6,7 @@ export default class RegisterView extends CommonLoginRegisterView { constructor() { super(); - this.dialog = document.querySelector('.modal-box'); + this.dialog = document.querySelector('.toast'); } /** @@ -32,32 +32,32 @@ export default class RegisterView extends CommonLoginRegisterView { } /** - * Implement register success popup in site + * Implement register success toast in site */ - showRegisterSuccessPopup() { - const typePopup = TYPE_POPUP.success; + showRegisterSuccessToast() { + const typeToast = TYPE_TOAST.success; const title = 'Register Commpleted'; const content = 'Please login to continue!'; const btnContent = 'OK'; - this.initPopupContent(typePopup, title, content, btnContent); + this.initToastContent(typeToast, title, content, btnContent); - // Show popup - this.tooglePopupForm(); + // Show toast + this.toastDialog.showModal(); } /** - * Implement error popup in site - * @param {string} content The content will show in error popup + * Implement error toast in site + * @param {string} content The content will show in error toast */ - initErrorPopup(error) { - const title = error.title ? error.title : MESSAGE.DEFAULT_TITLE_ERROR_POPUP; + initErrorToast(error) { + const title = error.title ? error.title : MESSAGE.DEFAULT_TITLE_ERROR_TOAST; 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 - this.tooglePopupForm(); + // Show toast + this.toastDialog.showModal(); } /** @@ -75,7 +75,7 @@ export default class RegisterView extends CommonLoginRegisterView { async submitForm(checkExistUser, saveUser) { try { // Load spinner - this.toogleLoaderSpinner(); + this.toggleLoaderSpinner(); // Get data from form const user = this.getDataFromForm(); @@ -88,16 +88,16 @@ export default class RegisterView extends CommonLoginRegisterView { throw Error(MESSAGE.USER_EXIST_ERROR); } else { await saveUser(user); - // Show popup success - this.showRegisterSuccessPopup(); + // Show toast success + this.showRegisterSuccessToast(); } } } catch (error) { - // Show popup error - this.initErrorPopup(error); + // Show toast error + this.initErrorToast(error); } // Close spinner - this.toogleLoaderSpinner(); + this.toggleLoaderSpinner(); } } diff --git a/javascript-practice/src/pages/index.html b/javascript-practice/src/pages/index.html index 1457d43..8d07d2e 100644 --- a/javascript-practice/src/pages/index.html +++ b/javascript-practice/src/pages/index.html @@ -8,16 +8,16 @@ Money Lover Web -
- + +
+
+

Login Success!

+

Welcome to Money Lover!

+ +
+
-
+
@@ -55,10 +55,10 @@
-
+ -
+
@@ -95,16 +95,18 @@ />
- +
- + -
+
@@ -153,20 +155,22 @@ />
- +
- + -
+
-
+
Select category
@@ -261,7 +265,7 @@
- +
diff --git a/javascript-practice/src/styles/components/_dialog.scss b/javascript-practice/src/styles/components/_dialog.scss index 5edd09e..bb7115b 100644 --- a/javascript-practice/src/styles/components/_dialog.scss +++ b/javascript-practice/src/styles/components/_dialog.scss @@ -1,14 +1,9 @@ .dialog { - @extend %d-absolute, %rounded-sm; + @extend %rounded-sm; - left: 50%; - top: 32%; - transform: translate(-50%, -50%) scale(1); + border: none; background-color: $white; - z-index: $zindex-lv-2; - opacity: 0; - pointer-events: none; transition: all 0.3s ease; &__title { @@ -17,7 +12,7 @@ line-height: 20px; } - &.active { - @extend %active; + &::backdrop { + background-color: rgba($color: #000000, $alpha: 0.2); } } diff --git a/javascript-practice/src/styles/components/_popup-form.scss b/javascript-practice/src/styles/components/_popup-form.scss index 0617043..60ff0dd 100644 --- a/javascript-practice/src/styles/components/_popup-form.scss +++ b/javascript-practice/src/styles/components/_popup-form.scss @@ -1,19 +1,8 @@ -.modal-box { +.toast { @extend %d-flex; - @extend %d-absolute; @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; - border-radius: 10px; - background-color: $white; - opacity: 0; - pointer-events: none; - transition: all 0.3s ease; &__title { font-size: $fs-2x-lg; @@ -32,17 +21,12 @@ padding: 15px 30px; cursor: pointer; } - - &.active { - opacity: 1; - pointer-events: auto; - } } -.success .modal-box__redirect-btn { +.success .toast__redirect-btn { background-color: $light-primary-color; } -.error .modal-box__redirect-btn { +.error .toast__redirect-btn { background-color: $dark-error-color; } From 50f4051badd63de61d96b69612e8d4c482f15c93 Mon Sep 17 00:00:00 2001 From: Loi Phan Date: Mon, 11 Sep 2023 17:18:29 +0700 Subject: [PATCH 3/4] Fix typo and refactor code --- javascript-practice/src/js/app.js | 6 ++-- .../src/js/constants/config.js | 2 -- .../src/js/constants/constant.js | 31 ------------------- .../src/js/constants/message.js | 17 ++++++++++ .../src/js/constants/variable.js | 20 ++++++++++++ .../controllers/{controller.js => index.js} | 0 .../src/js/controllers/loginController.js | 6 ++-- .../src/js/controllers/registerController.js | 4 +-- javascript-practice/src/js/helpers/helpers.js | 5 +-- .../src/js/services/{service.js => index.js} | 0 .../src/js/services/userService.js | 4 +-- .../src/js/views/commonLoginRegisterView.js | 8 ++--- .../src/js/views/commonView.js | 2 +- .../src/js/views/{view.js => index.js} | 2 +- javascript-practice/src/js/views/loginView.js | 10 +++--- .../src/js/views/registerView.js | 3 +- .../src/styles/components/_dialog.scss | 12 ++++++- 17 files changed, 75 insertions(+), 57 deletions(-) delete mode 100644 javascript-practice/src/js/constants/constant.js create mode 100644 javascript-practice/src/js/constants/message.js create mode 100644 javascript-practice/src/js/constants/variable.js rename javascript-practice/src/js/controllers/{controller.js => index.js} (100%) rename javascript-practice/src/js/services/{service.js => index.js} (100%) rename javascript-practice/src/js/views/{view.js => index.js} (92%) diff --git a/javascript-practice/src/js/app.js b/javascript-practice/src/js/app.js index 80e6a3e..5f951bf 100644 --- a/javascript-practice/src/js/app.js +++ b/javascript-practice/src/js/app.js @@ -1,6 +1,6 @@ -import Controller from './controllers/controller'; -import Service from './services/service'; -import View from './views/view'; +import Controller from './controllers/index'; +import Service from './services/index'; +import View from './views/index'; import 'regenerator-runtime/runtime'; import 'core-js/stable'; diff --git a/javascript-practice/src/js/constants/config.js b/javascript-practice/src/js/constants/config.js index 8a88e89..4950d70 100644 --- a/javascript-practice/src/js/constants/config.js +++ b/javascript-practice/src/js/constants/config.js @@ -1,5 +1,3 @@ export const DATABASE_URL = 'https://javascript-training-81f7a-default-rtdb.asia-southeast1.firebasedatabase.app'; export const TIME_OUT_SEC = 3; -export const REGEX_PASSWORD = - /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$/; diff --git a/javascript-practice/src/js/constants/constant.js b/javascript-practice/src/js/constants/constant.js deleted file mode 100644 index da22de9..0000000 --- a/javascript-practice/src/js/constants/constant.js +++ /dev/null @@ -1,31 +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_TOAST: 'Error', - USER_EXIST_ERROR: 'User is exists! Please try another email!', -}; - -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' }; diff --git a/javascript-practice/src/js/constants/message.js b/javascript-practice/src/js/constants/message.js new file mode 100644 index 0000000..b0e7995 --- /dev/null +++ b/javascript-practice/src/js/constants/message.js @@ -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!'; diff --git a/javascript-practice/src/js/constants/variable.js b/javascript-practice/src/js/constants/variable.js new file mode 100644 index 0000000..423aaef --- /dev/null +++ b/javascript-practice/src/js/constants/variable.js @@ -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,}$/; diff --git a/javascript-practice/src/js/controllers/controller.js b/javascript-practice/src/js/controllers/index.js similarity index 100% rename from javascript-practice/src/js/controllers/controller.js rename to javascript-practice/src/js/controllers/index.js diff --git a/javascript-practice/src/js/controllers/loginController.js b/javascript-practice/src/js/controllers/loginController.js index 59b3d4c..12a1117 100644 --- a/javascript-practice/src/js/controllers/loginController.js +++ b/javascript-practice/src/js/controllers/loginController.js @@ -4,13 +4,13 @@ export default class LoginController { this.loginView = view.loginView; } - handlerValidateUser(email, password) { - return this.service.userService.validateUser(email, password); + handlerLoginUser(email, password) { + return this.service.userService.loginUser(email, password); } init() { if (this.loginView) { - this.loginView.addHandlerForm(this.handlerValidateUser.bind(this)); + this.loginView.addHandlerForm(this.handlerLoginUser.bind(this)); } } } diff --git a/javascript-practice/src/js/controllers/registerController.js b/javascript-practice/src/js/controllers/registerController.js index ea7ee41..0722299 100644 --- a/javascript-practice/src/js/controllers/registerController.js +++ b/javascript-practice/src/js/controllers/registerController.js @@ -4,7 +4,7 @@ export default class RegisterController { this.service = service; } - hanlderCheckUserExist(email) { + handlerCheckUserExist(email) { return this.service.userService.checkUserExist(email); } @@ -15,7 +15,7 @@ export default class RegisterController { init() { if (this.registerView) { this.registerView.addHandlerForm( - this.hanlderCheckUserExist.bind(this), + this.handlerCheckUserExist.bind(this), this.handlerSaveUser.bind(this), ); this.registerView.addHandlerInputFormChange(); diff --git a/javascript-practice/src/js/helpers/helpers.js b/javascript-practice/src/js/helpers/helpers.js index 5c5596e..46c44fe 100644 --- a/javascript-practice/src/js/helpers/helpers.js +++ b/javascript-practice/src/js/helpers/helpers.js @@ -1,6 +1,7 @@ -import { MESSAGE } from '../constants/constant'; -import { REGEX_PASSWORD, TIME_OUT_SEC } from '../constants/config'; +import * as MESSAGE from '../constants/message'; +import { TIME_OUT_SEC } from '../constants/config'; import FirebaseService from '../services/firebaseService'; +import { REGEX_PASSWORD } from '../constants/variable'; /** * Validate password diff --git a/javascript-practice/src/js/services/service.js b/javascript-practice/src/js/services/index.js similarity index 100% rename from javascript-practice/src/js/services/service.js rename to javascript-practice/src/js/services/index.js diff --git a/javascript-practice/src/js/services/userService.js b/javascript-practice/src/js/services/userService.js index 9821641..511d7ba 100644 --- a/javascript-practice/src/js/services/userService.js +++ b/javascript-practice/src/js/services/userService.js @@ -1,4 +1,4 @@ -import { LOCAL_STORAGE } from '../constants/constant'; +import { LOCAL_STORAGE } from '../constants/variable'; import { createToken } from '../helpers/helpers'; import CommonService from './commonService'; import LocalStorageService from './localStorageService'; @@ -54,7 +54,7 @@ export default class UserService extends CommonService { * @param {*} password The password user input * @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); // Check password diff --git a/javascript-practice/src/js/views/commonLoginRegisterView.js b/javascript-practice/src/js/views/commonLoginRegisterView.js index d7c0b88..5003978 100644 --- a/javascript-practice/src/js/views/commonLoginRegisterView.js +++ b/javascript-practice/src/js/views/commonLoginRegisterView.js @@ -1,5 +1,5 @@ import CommonView from './commonView'; -import * as CONSTANT from '../constants/constant'; +import * as MESSAGE from '../constants/message'; import { validatePassword } from '../helpers/helpers'; export default class CommonLoginRegisterView extends CommonView { @@ -7,7 +7,7 @@ export default class CommonLoginRegisterView extends CommonView { super(); 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.inputPasswordConfirm = document.querySelector( 'input[name="password_confirm"]', @@ -24,10 +24,10 @@ export default class CommonLoginRegisterView extends CommonView { if (validatePassword(account.passwordConfirm)) { return true; } - this.showError(CONSTANT.MESSAGE.PASSWORD_NOT_STRONG); + this.showError(MESSAGE.PASSWORD_NOT_STRONG); return false; } - this.showError(CONSTANT.MESSAGE.PASSWORD_NOT_MATCH); + this.showError(MESSAGE.PASSWORD_NOT_MATCH); return false; } diff --git a/javascript-practice/src/js/views/commonView.js b/javascript-practice/src/js/views/commonView.js index bd92974..636c55c 100644 --- a/javascript-practice/src/js/views/commonView.js +++ b/javascript-practice/src/js/views/commonView.js @@ -1,4 +1,4 @@ -import { MARK_ICON, TYPE_TOAST } from '../constants/constant'; +import { MARK_ICON, TYPE_TOAST } from '../constants/variable'; export default class CommonView { constructor() { diff --git a/javascript-practice/src/js/views/view.js b/javascript-practice/src/js/views/index.js similarity index 92% rename from javascript-practice/src/js/views/view.js rename to javascript-practice/src/js/views/index.js index 684b193..a2f11d2 100644 --- a/javascript-practice/src/js/views/view.js +++ b/javascript-practice/src/js/views/index.js @@ -1,7 +1,7 @@ import RegisterView from './registerView'; import LoginView from './loginView'; import { getSubdirectoryURL } from '../helpers/helpers'; -import { URL } from '../constants/constant'; +import { URL } from '../constants/variable'; import HomeView from './homeView'; export default class View { diff --git a/javascript-practice/src/js/views/loginView.js b/javascript-practice/src/js/views/loginView.js index d296f44..3fe4d49 100644 --- a/javascript-practice/src/js/views/loginView.js +++ b/javascript-practice/src/js/views/loginView.js @@ -1,5 +1,6 @@ import CommonLoginRegisterView from './commonLoginRegisterView'; -import { MESSAGE, TYPE_TOAST, 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 { constructor() { @@ -51,9 +52,10 @@ export default class LoginView extends CommonLoginRegisterView { /** * 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 { // Load spinner this.toggleLoaderSpinner(); @@ -61,7 +63,7 @@ export default class LoginView extends CommonLoginRegisterView { // Get data from form const userInput = this.getDataFromForm(event); // Check user exist - const results = await validateUser(userInput.email, userInput.password); + const results = await loginUser(userInput.email, userInput.password); if (results) { window.location.replace('/'); diff --git a/javascript-practice/src/js/views/registerView.js b/javascript-practice/src/js/views/registerView.js index 08c34ee..cea6bcc 100644 --- a/javascript-practice/src/js/views/registerView.js +++ b/javascript-practice/src/js/views/registerView.js @@ -1,4 +1,5 @@ -import { TYPE_TOAST, 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 User from '../models/user'; diff --git a/javascript-practice/src/styles/components/_dialog.scss b/javascript-practice/src/styles/components/_dialog.scss index bb7115b..fa741f0 100644 --- a/javascript-practice/src/styles/components/_dialog.scss +++ b/javascript-practice/src/styles/components/_dialog.scss @@ -3,7 +3,7 @@ border: none; background-color: $white; - + padding: none; transition: all 0.3s ease; &__title { @@ -16,3 +16,13 @@ background-color: rgba($color: #000000, $alpha: 0.2); } } + +// Login page +.login-page, +.register-page { + .dialog { + @extend %rounded; + + padding: 0px; + } +} From dd27c381dd60ce2869fbf8f2053ed73a997874f7 Mon Sep 17 00:00:00 2001 From: Loi Phan Date: Mon, 11 Sep 2023 17:20:07 +0700 Subject: [PATCH 4/4] Add icon for login and register page --- javascript-practice/src/pages/login.html | 1 + javascript-practice/src/pages/register.html | 1 + 2 files changed, 2 insertions(+) diff --git a/javascript-practice/src/pages/login.html b/javascript-practice/src/pages/login.html index fe79d78..e759d46 100644 --- a/javascript-practice/src/pages/login.html +++ b/javascript-practice/src/pages/login.html @@ -3,6 +3,7 @@ + Login - Money Lover diff --git a/javascript-practice/src/pages/register.html b/javascript-practice/src/pages/register.html index b0bc1ca..cc41c7f 100644 --- a/javascript-practice/src/pages/register.html +++ b/javascript-practice/src/pages/register.html @@ -3,6 +3,7 @@ + Register - Money Lover