diff --git a/javascript-practice/src/js/app.js b/javascript-practice/src/js/app.js new file mode 100644 index 0000000..6c68c70 --- /dev/null +++ b/javascript-practice/src/js/app.js @@ -0,0 +1,15 @@ +import Controller from './controllers/controller'; +import Service from './services/service'; +import View from './views/view'; +import 'regenerator-runtime/runtime'; +import 'core-js/stable'; + +export default class App { + constructor() { + this.controller = new Controller(new Service(), new View()); + } + + start() { + this.controller.registerController.init(); + } +} diff --git a/javascript-practice/src/js/controller.js b/javascript-practice/src/js/controller.js deleted file mode 100644 index e69de29..0000000 diff --git a/javascript-practice/src/js/controllers/controller.js b/javascript-practice/src/js/controllers/controller.js new file mode 100644 index 0000000..e360b3c --- /dev/null +++ b/javascript-practice/src/js/controllers/controller.js @@ -0,0 +1,7 @@ +import RegisterController from './registerController'; + +export default class Controller { + constructor(service, view) { + this.registerController = new RegisterController(service, view); + } +} diff --git a/javascript-practice/src/js/controllers/registerController.js b/javascript-practice/src/js/controllers/registerController.js new file mode 100644 index 0000000..7fa6f8c --- /dev/null +++ b/javascript-practice/src/js/controllers/registerController.js @@ -0,0 +1,46 @@ +export default class RegisterController { + constructor(service, view) { + this.view = view; + this.service = service; + } + + async controlRegister() { + try { + // Load spinner + this.view.registerView.toogleLoaderSpinner(); + + // Get data from form + const user = this.view.registerView.getDataFromForm(); + + // Save user + if (user) { + // Check user exist + const userExist = await this.service.userService.checkExistUserByEmail( + user.email, + ); + if (userExist) { + throw Error('User is exists! Please try another email!'); + } else { + await this.service.userService.saveUser(user); + // Show popup success + this.view.registerView.initRegisterSuccessPopup(); + this.view.registerView.tooglePopupForm(); + } + } + } catch (error) { + // Show popup error + this.view.registerView.initErrorPopup(error); + this.view.registerView.tooglePopupForm(); + } + + // Close spinner + this.view.registerView.toogleLoaderSpinner(); + } + + init() { + if (this.view.registerView.registerForm !== null) { + this.view.registerView.addHandlerForm(this.controlRegister.bind(this)); + this.view.registerView.addHandlerInputFormChange(); + } + } +} diff --git a/javascript-practice/src/js/main.js b/javascript-practice/src/js/main.js new file mode 100644 index 0000000..626a1f8 --- /dev/null +++ b/javascript-practice/src/js/main.js @@ -0,0 +1,7 @@ +import App from './app'; + +// Sure that scripts called after DOM loaded +document.addEventListener('DOMContentLoaded', () => { + const myApp = new App(); + myApp.start(); +}); diff --git a/javascript-practice/src/js/views/commonLoginRegisterView.js b/javascript-practice/src/js/views/commonLoginRegisterView.js new file mode 100644 index 0000000..46d1ad8 --- /dev/null +++ b/javascript-practice/src/js/views/commonLoginRegisterView.js @@ -0,0 +1,117 @@ +import CommonView from './commonView'; +import * as CONSTANT from '../constants/constant'; +import { validatePassword } from '../helpers/helpers'; + +export default class CommonLoginRegisterView extends CommonView { + constructor() { + super(); + + this.parentElement = document.querySelector('.form'); + this.messageDefault = CONSTANT.MESSAGE.ERROR_MESSAGE_DEFAULT; + this.inputField = document.querySelectorAll('.form__input'); + } + + /** + * Validate user input data + * @param {Object} account The account object with email, password, passwordConfirm field + * @returns {boolean} Return true if validate success and return false if validate not success + */ + validateForm(account) { + if (account.password === account.passwordConfirm) { + if (validatePassword(account.passwordConfirm)) { + return true; + } + this.showError(CONSTANT.MESSAGE.PASSWORD_NOT_STRONG); + return false; + } + this.showError(CONSTANT.MESSAGE.PASSWORD_NOT_MATCH); + return false; + } + + /** + * Add event listener for form input + * @param {Function} handler The function need to be set event + */ + addHandlerForm(handler) { + this.parentElement.addEventListener('submit', (e) => { + e.preventDefault(); + this.clearErrorMessage(); + handler(); + }); + } + + /** + * Show error style input password + */ + changeToStyleErrorInputPassword() { + // Index = 1 because it should skip email input field + for (let index = 1; index < this.inputField.length; index += 1) { + this.inputField[index].style.background = '#ffc3c3'; + this.inputField[index].style.borderColor = '#ce1414'; + } + } + + /** + * Clear error style input password + */ + clearStyleErrorInputPassword() { + for (let index = 1; index < this.inputField.length; index += 1) { + this.inputField[index].style.background = '#f5f5f5'; + this.inputField[index].style.borderColor = '#f5f5f5'; + } + } + + /** + * Reassign again to check error message element haved on page or not + */ + reassignVariableErrorMessage() { + this.errorMessage = document.querySelector('.form__error-message'); + } + + /** + * Clear error message at form + */ + clearErrorMessage() { + this.reassignVariableErrorMessage(); + + // If have error message on page, remove it + if (this.errorMessage) { + this.errorMessage.remove(); + this.clearStyleErrorInputPassword(); + } + } + + /** + * Add event listener for input field at form + */ + addHandlerInputFormChange() { + this.parentElement.addEventListener('input', () => { + this.clearErrorMessage(); + }); + } + + /** + * Show error message with error style input password. + * @param {string} message The error message you want show in form. + */ + showError(message) { + this.renderError(message); + this.changeToStyleErrorInputPassword(); + } + + /** + * Show error message in form + * @param {*} message The message will show in form + */ + renderError(message) { + const markup = ` +
+ `; + + document + .querySelector('.form__title') + .insertAdjacentHTML('afterend', markup); + } +} diff --git a/javascript-practice/src/js/views/registerView.js b/javascript-practice/src/js/views/registerView.js index aa0576e..4a311a0 100644 --- a/javascript-practice/src/js/views/registerView.js +++ b/javascript-practice/src/js/views/registerView.js @@ -1,21 +1,17 @@ -import { validatePassword } from '../helpers/helpers'; -import * as CONSTANT from '../constants/constant'; -import CommonView from './commonView'; +import { TYPE_POPUP } from '../constants/constant'; +import CommonLoginRegisterView from './commonLoginRegisterView'; import User from '../models/userModel'; -export default class RegisterView extends CommonView { +export default class RegisterView extends CommonLoginRegisterView { constructor() { super(); - this.parentElement = document.querySelector('.form'); - this.inputField = document.querySelectorAll('.form__input'); - - this.messageDefault = CONSTANT.MESSAGE.ERROR_MESSAGE_DEFAULT; + this.registerForm = document.getElementById('registerForm'); } /** * Get data from user input - * @returns {Object || null} Return user object or null + * @returns {Object || null} Return object or null */ getDataFromForm() { const { registerForm } = document.forms; @@ -33,99 +29,11 @@ export default class RegisterView extends CommonView { return null; } - /** - * Validate user input data - * @param {Object} account The account object with email, password, passwordConfirm field - * @returns {boolean} Return true if validate success and return false if validate not success - */ - validateForm(account) { - if (account.password === account.passwordConfirm) { - if (validatePassword(account.passwordConfirm)) { - return true; - } - this.showError(CONSTANT.MESSAGE.PASSWORD_NOT_STRONG); - return false; - } - this.showError(CONSTANT.MESSAGE.PASSWORD_NOT_MATCH); - return false; - } - - /** - * Add event listener for form input - * @param {Function} handler The function need to be set event - */ - addHandlerForm(handler) { - this.parentElement.addEventListener('submit', (e) => { - e.preventDefault(); - this.clearErrorMessage(); - handler(); - }); - } - - /** - * Show error style input password - */ - changeToStyleErrorInputPassword() { - // Index = 1 because it should skip email input field - for (let index = 1; index < this.inputField.length; index += 1) { - this.inputField[index].style.background = '#ffc3c3'; - this.inputField[index].style.borderColor = '#ce1414'; - } - } - - /** - * Clear error style input password - */ - clearStyleErrorInputPassword() { - for (let index = 1; index < this.inputField.length; index += 1) { - this.inputField[index].style.background = '#f5f5f5'; - this.inputField[index].style.borderColor = '#f5f5f5'; - } - } - - /** - * Reassign again to check error message element haved on page or not - */ - reassignVariableErrorMessage() { - this.errorMessage = document.querySelector('.form__error-message'); - } - - /** - * Clear error message at form - */ - clearErrorMessage() { - this.reassignVariableErrorMessage(); - - // If have error message on page, remove it - if (this.errorMessage) { - this.errorMessage.remove(); - this.clearStyleErrorInputPassword(); - } - } - - /** - * Add event listener for input field at form - */ - addHandlerInputFormChange() { - this.parentElement.addEventListener('input', () => { - this.clearErrorMessage(); - }); - } - - /** - * Show error message with error style input password. - * @param {string} message The error message you want show in form. - */ - showError(message) { - this.renderError(message); - this.changeToStyleErrorInputPassword(); - } - /** * Implement register success popup in site */ initRegisterSuccessPopup() { - const typePopup = CONSTANT.TYPE_POPUP.success; + const typePopup = TYPE_POPUP.success; const title = 'Register Commpleted'; const content = 'Please login to continue!'; const btnContent = 'OK'; @@ -138,26 +46,10 @@ export default class RegisterView extends CommonView { * @param {string} content The content will show in error popup */ initErrorPopup(content) { - const typePopup = CONSTANT.TYPE_POPUP.error; + const typePopup = TYPE_POPUP.error; const title = 'Error'; const btnContent = 'Got it!'; this.initPopupContent(typePopup, title, content, btnContent); } - - /** - * Show error message in form - * @param {*} message The message will show in form - */ - renderError(message) { - const markup = ` - - `; - - document - .querySelector('.form__title') - .insertAdjacentHTML('afterend', markup); - } } diff --git a/javascript-practice/src/pages/register.html b/javascript-practice/src/pages/register.html index ec6c9a5..7a729f1 100644 --- a/javascript-practice/src/pages/register.html +++ b/javascript-practice/src/pages/register.html @@ -55,6 +55,6 @@ - +