Merge pull request #9 from Nez27/feat/fix-comments

Refactor and optimized code
This commit is contained in:
Loi Phan
2023-10-03 16:56:33 +07:00
committed by GitHub
28 changed files with 443 additions and 364 deletions
+1 -1
View File
@@ -250,7 +250,7 @@
<div class="app__tabs">
<button class="app__tab-item active">SUMMARY</button>
<button class="app__tab-item">TRANSACTION DETAILS</button>
<div class="app__line left"></div>
<div class="app__line"></div>
</div>
<!-- Start content app -->
<div class="app__contents">
@@ -104,6 +104,8 @@
&__line {
position: absolute;
top: 66px;
left: 152px;
width: 116px;
height: 2px;
background-color: $primary-color;
border-radius: 10px;
@@ -11,14 +11,15 @@ export const LOCAL_STORAGE = {
ACCESS_TOKEN: 'accessToken',
};
export enum TypeToast {
success = 'success',
error = 'error',
}
export enum MarkIcon {
success = 'success',
error = 'error',
}
export const TypeToast = {
success: 'success',
error: 'error',
};
export const MarkIcon = {
success: 'success',
error: 'error',
};
export const REGEX = {
PASSWORD:
@@ -1,3 +1,17 @@
export const PASSWORD_NOT_MATCH = 'Password not match!';
export const PASSWORD_NOT_STRONG =
'Password must at least one uppercase, one lowercase letter, one number and one special character!';
export const ERROR_CREDENTIAL = {
title: 'Error Credential',
message: 'Email or password not match! Please try again!',
};
export const INVALID_EMAIL_FORMAT = `The email is not correct!`;
export const REQUIRED_MESSAGE = (field: string) => `The ${field} is required!`;
export const ERROR_MESSAGE_DEFAULT = ['Something went wrong!'];
export const TIME_OUT_ERROR = 'Connection time out! Please try again!';
@@ -1,13 +0,0 @@
export const PASSWORD_NOT_MATCH = 'Password not match!';
export const PASSWORD_NOT_STRONG =
'Password must at least one uppercase, one lowercase letter, one number and one special character!';
export const ERROR_CREDENTIAL = {
title: 'Error Credential',
message: 'Email or password not match! Please try again!',
};
export const INVALID_EMAIL_FORMAT = `The email is not correct!`;
export const REQUIRED_MESSAGE = (field: string) => `The ${field} is required!`;
@@ -1,10 +1,10 @@
import HomeView from 'views/home/homeView';
import Transform from '../helpers/transform';
import Service from 'services';
import View from 'views';
import Wallet from 'models/wallet';
import Transaction from 'models/transaction';
import Category from 'models/category';
import { IHomeFunc } from 'global/types';
export default class HomeController {
public homeView: HomeView | null = null;
@@ -47,16 +47,17 @@ export default class HomeController {
init() {
if (this.homeView) {
this.homeView.initFunction(
this.handlerGetInfoUserLogin.bind(this),
this.handlerGetWalletByIdUser.bind(this),
this.handlerGetAllCategory.bind(this),
this.handlerGetAllTransactions.bind(this),
this.handlerSaveWallet.bind(this),
this.handlerSaveTransaction.bind(this),
this.handlerDeleteTransaction.bind(this),
new Transform(),
);
const func: IHomeFunc = {
getInfoUserLogin: this.handlerGetInfoUserLogin.bind(this),
getWalletByIdUser: this.handlerGetWalletByIdUser.bind(this),
getAllCategory: this.handlerGetAllCategory.bind(this),
getAllTransactions: this.handlerGetAllTransactions.bind(this),
saveWallet: this.handlerSaveWallet.bind(this),
saveTransaction: this.handlerSaveTransaction.bind(this),
deleteTransaction: this.handlerDeleteTransaction.bind(this),
};
this.homeView.initFunction(func);
this.homeView.loadPage();
+50 -8
View File
@@ -19,11 +19,13 @@ export class DataObject<T> {
}
}
export interface TError {
export interface IError {
title: string;
message: string;
}
export type TError = string | IError;
export class CustomError extends Error {
constructor(
public title: string,
@@ -33,13 +35,6 @@ export class CustomError extends Error {
}
}
export type TSignal = {
[key: string]: {
name: string;
handler: (value: Data) => void;
};
};
export interface Data {
wallet?: Wallet;
listTransactions?: Transaction[];
@@ -54,3 +49,50 @@ export interface ItemTransaction {
note: string;
amount: number;
}
export type Nullable<T> = T | null;
export type PromiseVoid = () => Promise<void>;
export type VoidFunc = () => void;
export type PromiseOrNull<T> = () => Promise<T | null>;
export interface IHomeFunc {
getInfoUserLogin?: PromiseOrNull<User>;
getWalletByIdUser?: (idUser: string) => Promise<Wallet | null>;
getAllCategory?: PromiseOrNull<Category[]>;
getAllTransactions?: (idUser: string) => Promise<Transaction[] | null>;
saveWallet?: (wallet: Wallet) => Promise<void>;
saveTransaction?: (transaction: Transaction) => Promise<void>;
deleteTransaction?: (idTransaction: string) => Promise<void>;
}
export interface IBudgetViewFunc {
showErrorToast: (error: TError) => void;
showSuccessToast: (title: string, message: string) => void;
toggleLoaderSpinner: VoidFunc;
saveTransaction: Nullable<(transaction: Transaction) => Promise<void>>;
loadTransactionData: PromiseVoid;
updateAmountWallet: PromiseVoid;
loadData: PromiseVoid;
}
export interface ITransactionViewFunc {
toggleLoaderSpinner: VoidFunc;
deleteTransaction: (idTransaction: string) => Promise<void>;
loadTransactionData: PromiseVoid;
updateAmountWallet: PromiseVoid;
loadData: PromiseVoid;
showSuccessToast: (title: string, message: string) => void;
showErrorToast: (error: TError) => void;
saveTransaction: (transaction: Transaction) => Promise<void>;
}
export interface IWalletViewFunc {
toggleLoaderSpinner: () => void;
saveWallet: ((wallet: Wallet) => Promise<void>) | null;
saveTransaction: ((transaction: Transaction) => Promise<void>) | null;
loadTransactionData: () => Promise<void>;
loadData: () => Promise<void>;
loadEvent: () => void;
showSuccessToast: (title: string, message: string) => void;
showErrorToast: (error: TError) => void;
}
@@ -1,4 +1,4 @@
import { TIME_OUT_ERROR } from '../constants/messages/dialog';
import { TIME_OUT_ERROR } from '../constants/messages';
import { TIME_OUT_SEC } from '../constants/config';
import FirebaseService from '../services/firebaseService';
@@ -1,12 +1,25 @@
import { TSignal, Data } from 'global/types';
import { Data } from 'global/types';
type TSignal = {
[key: string]: {
name: string;
handler: (value: Data) => void;
};
};
export default class EventDataTrigger {
private static _instance: EventDataTrigger;
export default class Transform {
public signal: TSignal;
constructor() {
this.signal = {};
}
public static get Instance() {
return this._instance || (this._instance = new this());
}
onSendSignal(fromClass: string, value: Data) {
Object.keys(this.signal).forEach((key) => {
const item = this.signal[key as keyof TSignal];
+2 -2
View File
@@ -1,8 +1,8 @@
export const redirectToLoginPage = (): void => {
export const redirectToLoginPage = () => {
window.location.replace('/login');
};
export const getSubdirectoryURL = () => {
export const getSubdirectoryURL = (): string => {
const url = window.location.href;
const parts = url.split('/'); // Results: ['http:', '', 'example.com', '']
const subDirectory = parts[3]; // Get subdirectory url only
@@ -1,5 +1,5 @@
import { REGEX } from '../constants/config';
import { REQUIRED_MESSAGE } from '../constants/messages/form';
import { REQUIRED_MESSAGE } from '../constants/messages';
/**
* Validate password
@@ -21,7 +21,7 @@ export const compare2Password = (
return password === passwordConfirm;
};
export const renderRequiredText = (field: string, element: Element): void => {
export const renderRequiredText = (field: string, element: Element) => {
const markup: string = `
<p class="error-text">${REQUIRED_MESSAGE(field)}</p>
`;
@@ -1,11 +1,9 @@
export default class Category {
readonly id: string;
url: string;
name: string;
constructor(id: string, url: string, name: string) {
constructor(
public id: string,
public url: string,
public name: string,
) {
this.id = id;
this.url = url;
this.name = name;
+7 -10
View File
@@ -1,16 +1,13 @@
import { generateId } from '../helpers/data';
export default class User {
id: string;
email: string;
password: string;
accessToken: string;
constructor(email: string, password: string, accessToken?: string) {
this.id = generateId();
constructor(
public id: string,
public email: string,
public password: string,
public accessToken?: string,
) {
this.id = id ? id : generateId();
this.email = email;
this.password = password || '';
this.accessToken = accessToken || '';
+6 -15
View File
@@ -1,23 +1,14 @@
import { generateId } from '../helpers/data';
export default class Wallet {
id: string;
walletName: string;
inflow: number;
outflow: number;
idUser: string;
constructor(
walletName: string,
inflow: number,
outflow: number,
idUser: string,
public id: string,
public walletName: string,
public inflow: number,
public outflow: number,
public idUser: string,
) {
this.id = generateId();
this.id = id ? id : generateId();
this.walletName = walletName;
this.inflow = inflow;
this.outflow = outflow;
@@ -5,7 +5,7 @@ class LocalStorageService {
this.localStorage = localStorage;
}
add(key: string, value: string): void {
add(key: string, value: string) {
this.localStorage.setItem(key, value);
}
@@ -13,11 +13,11 @@ class LocalStorageService {
return this.localStorage.getItem(key);
}
remove(key: string): void {
remove(key: string) {
this.localStorage.removeItem(key);
}
clear(): void {
clear() {
this.localStorage.clear();
}
}
@@ -28,7 +28,7 @@ export default class TransactionService extends CommonService<Transaction> {
return results || null;
}
async deleteTransaction(idTransaction: string) {
async deleteTransaction(idTransaction: string): Promise<void> {
await this.deleteData(idTransaction);
}
}
@@ -1,27 +1,28 @@
import CommonView from './commonView';
import { ERROR_MESSAGE_DEFAULT } from '../constants/messages/dialog';
import {
INVALID_EMAIL_FORMAT,
PASSWORD_NOT_MATCH,
PASSWORD_NOT_STRONG,
} from 'constants/messages/form';
ERROR_MESSAGE_DEFAULT,
} from 'constants/messages';
import {
compare2Password,
isValidPassword,
isValidateEmail,
renderRequiredText,
} from '../helpers/validatorForm';
import { Nullable } from 'global/types';
export default class AuthenticationView extends CommonView {
public formEl: HTMLBodyElement | null;
public formEl: Nullable<HTMLBodyElement>;
public emailEl: HTMLBodyElement | null;
public emailEl: Nullable<HTMLBodyElement>;
public messageDefault: string[];
public inputPasswordEl: HTMLBodyElement | null;
public inputPasswordEl: Nullable<HTMLBodyElement>;
public inputPasswordConfirmEl: HTMLBodyElement | null;
public inputPasswordConfirmEl: Nullable<HTMLBodyElement>;
public listError: string[];
@@ -70,7 +71,7 @@ export default class AuthenticationView extends CommonView {
return false;
}
validatePasswordConfirm(password: string, passwordConfirm: string) {
validatePasswordConfirm(password: string, passwordConfirm: string): boolean {
if (passwordConfirm) {
if (!compare2Password(password, passwordConfirm)) {
this.listError.push(PASSWORD_NOT_MATCH);
@@ -120,7 +121,7 @@ export default class AuthenticationView extends CommonView {
/**
* Add event listener for input field at form
*/
addHandlerInputFormChange(): void {
addHandlerInputFormChange() {
if (this.formEl)
this.formEl.addEventListener('input', () => {
this.clearErrorMessage();
@@ -131,7 +132,7 @@ export default class AuthenticationView extends CommonView {
* Show error message with error style input password.
* @param {string} message The error message you want show in form.
*/
showError(message: string[]): void {
showError(message: string[]) {
this.renderError(message);
}
@@ -139,7 +140,7 @@ export default class AuthenticationView extends CommonView {
* Show error message in form
* @param {string} message The message will show in form
*/
renderError(messages = this.messageDefault): void {
renderError(messages = this.messageDefault) {
if (messages.length > 0) {
const messageItemMarkup = messages
.map((message) => `<li>${message}</li>`)
+17 -13
View File
@@ -1,17 +1,18 @@
import { Nullable } from 'global/types';
import { MarkIcon, TypeToast } from '../constants/config';
export default class CommonView {
public toastDialog: HTMLDialogElement | null = null;
public toastDialog: Nullable<HTMLDialogElement> = null;
public toastIcon: HTMLBodyElement | null = null;
public toastIcon: Nullable<HTMLBodyElement> = null;
public toastBtn: HTMLBodyElement | null = null;
public toastBtn: Nullable<HTMLBodyElement> = null;
public toastTitle: HTMLBodyElement | null = null;
public toastTitle: Nullable<HTMLBodyElement> = null;
public toastContent: HTMLBodyElement | null = null;
public toastContent: Nullable<HTMLBodyElement> = null;
public spinner: HTMLBodyElement | null = null;
public spinner: Nullable<HTMLBodyElement> = null;
constructor() {
this.toastDialog = document.querySelector('.dialog .toast');
@@ -22,7 +23,7 @@ export default class CommonView {
/**
* Implement toast in site
*/
initToast(): void {
initToast() {
const markup = `
<dialog class="dialog">
<div class="toast">
@@ -61,7 +62,7 @@ export default class CommonView {
/**
* Show or hide loader screen
*/
toggleLoaderSpinner(): void {
toggleLoaderSpinner() {
if (this.spinner) this.spinner.classList.toggle('hidden');
}
@@ -77,18 +78,21 @@ export default class CommonView {
title: string,
content: string,
btnContent: string,
): void {
) {
// Remove old typeToast class if haved
Object.keys(TypeToast).forEach((key) => {
CommonView.removeClassElement(
TypeToast[key as TypeToast],
TypeToast[key as keyof typeof TypeToast],
this.toastDialog as HTMLBodyElement | null,
);
});
// Remove old icon toast if haved
Object.keys(MarkIcon).forEach((key) => {
CommonView.removeClassElement(MarkIcon[key as MarkIcon], this.toastIcon);
CommonView.removeClassElement(
MarkIcon[key as keyof typeof MarkIcon],
this.toastIcon,
);
});
// Init content toast
@@ -111,7 +115,7 @@ export default class CommonView {
}
}
static removeClassElement(classEl: string, el: HTMLBodyElement | null): void {
static removeClassElement(classEl: string, el: HTMLBodyElement | null) {
if (el && el.classList.contains(classEl)) {
el.classList.remove(classEl);
}
@@ -120,7 +124,7 @@ export default class CommonView {
/**
* Add event listener for toast
*/
handleEventToast(): void {
handleEventToast() {
if (this.toastBtn) {
this.toastBtn.addEventListener('click', () => {
if (this.toastDialog) this.toastDialog.close();
@@ -1,39 +1,43 @@
import Transaction from '../../models/transaction';
import { renderRequiredText } from '../../helpers/validatorForm';
import { Data, TError } from 'global/types';
import Transform from 'helpers/transform';
import EventDataTrigger from 'helpers/evDataTrigger';
import Wallet from 'models/wallet';
import User from 'models/user';
import { DEFAULT_CATEGORY } from 'constants/config';
import { ADD_TRANSACTION_SUCCESS, DEFAULT_MESSAGE } from 'constants/messages';
import {
ADD_TRANSACTION_SUCCESS,
DEFAULT_MESSAGE,
} from 'constants/messages/dialog';
IBudgetViewFunc,
Data,
Nullable,
PromiseVoid,
TError,
VoidFunc,
} from 'global/types';
export default class BudgetView {
budgetDialog: HTMLDialogElement | null = null;
budgetDialog: Nullable<HTMLDialogElement> = null;
addBudgetBtn: HTMLElement | null = null;
addBudgetBtn: Nullable<HTMLElement> = null;
transform: Transform | null = null;
evDataTrigger: Nullable<EventDataTrigger> = null;
toggleLoaderSpinner: (() => void) | null = null;
toggleLoaderSpinner: Nullable<VoidFunc> = null;
saveTransaction: ((transaction: Transaction) => Promise<void>) | null = null;
saveTransaction: Nullable<(transaction: Transaction) => Promise<void>> = null;
loadTransactionData: (() => Promise<void>) | null = null;
loadTransactionData: Nullable<PromiseVoid> = null;
updateAmountWallet: (() => Promise<void>) | null = null;
updateAmountWallet: Nullable<PromiseVoid> = null;
loadData: (() => Promise<void>) | null = null;
loadData: Nullable<PromiseVoid> = null;
showSuccessToast: ((title: string, message: string) => void) | null = null;
showSuccessToast: Nullable<(title: string, message: string) => void> = null;
showErrorToast: ((error: string | TError) => void) | null = null;
showErrorToast: Nullable<(error: TError) => void> = null;
wallet: Wallet | null = null;
wallet: Nullable<Wallet> = null;
user: User | null = null;
user: Nullable<User> = null;
constructor() {
this.budgetDialog = document.getElementById(
@@ -44,34 +48,26 @@ export default class BudgetView {
this.handlerEventBudgetView();
}
initFunction(
showErrorToast: (error: string | TError) => void,
showSuccessToast: (title: string, message: string) => void,
toggleLoaderSpinner: () => void,
saveTransaction: ((transaction: Transaction) => Promise<void>) | null,
loadTransactionData: () => Promise<void>,
updateAmountWallet: () => Promise<void>,
loadData: () => Promise<void>,
transform: Transform | null,
) {
this.showErrorToast = showErrorToast;
this.showSuccessToast = showSuccessToast;
this.toggleLoaderSpinner = toggleLoaderSpinner;
this.saveTransaction = saveTransaction;
this.loadTransactionData = loadTransactionData;
this.updateAmountWallet = updateAmountWallet;
this.loadData = loadData;
this.transform = transform;
initFunction(func: IBudgetViewFunc) {
this.showErrorToast = func.showErrorToast;
this.showSuccessToast = func.showSuccessToast;
this.toggleLoaderSpinner = func.toggleLoaderSpinner;
this.saveTransaction = func.saveTransaction;
this.loadTransactionData = func.loadTransactionData;
this.updateAmountWallet = func.updateAmountWallet;
this.loadData = func.loadData;
this.evDataTrigger = EventDataTrigger.Instance;
}
subscribe() {
this.transform!.create('budgetView', this.updateData.bind(this));
this.evDataTrigger!.create('budgetView', this.updateData.bind(this));
}
sendData() {
const data = { wallet: this.wallet! };
this.transform!.onSendSignal('budgetView', data);
this.evDataTrigger!.onSendSignal('budgetView', data);
}
updateData(data: Data) {
@@ -110,7 +106,7 @@ export default class BudgetView {
});
}
async submitBudgetForm() {
async submitBudgetForm(): Promise<void> {
try {
const form = document.getElementById('formAddBudget') as HTMLFormElement;
const formAddBudget = new FormData(form);
@@ -149,11 +145,11 @@ export default class BudgetView {
(<HTMLFormElement>document.getElementById('formAddBudget')!).reset();
}
} catch (error) {
this.showErrorToast!(error as string | TError);
this.showErrorToast!(error as TError);
}
}
validateBudgetForm(date: string, amount: number) {
validateBudgetForm(date: string, amount: number): boolean {
const inputFieldEl =
this.budgetDialog!.querySelectorAll('.form__input-field');
@@ -1,20 +1,20 @@
import Transform from 'helpers/transform';
import EventDataTrigger from 'helpers/evDataTrigger';
import { REMOVE_CATEGORY } from '../../constants/config';
import Category from 'models/category';
import { Data } from 'global/types';
import { Data, Nullable, PromiseOrNull } from 'global/types';
export default class CategoryView {
categoryDialog: HTMLDialogElement | null = null;
categoryDialog: Nullable<HTMLDialogElement> = null;
categoryField: HTMLElement | null = null;
categoryField: Nullable<HTMLElement> = null;
closeIcon: HTMLElement | null = null;
closeIcon: Nullable<HTMLElement> = null;
getAllCategory: (() => Promise<Category[] | null>) | null = null;
getAllCategory: Nullable<PromiseOrNull<Category[]>> = null;
transform: Transform | null = null;
evDataTrigger: Nullable<EventDataTrigger> = null;
listCategory: Category[] | null = null;
listCategory: Nullable<Category[]> = null;
categorySelected: string;
@@ -32,17 +32,17 @@ export default class CategoryView {
}
initFunction(
getAllCategory: () => Promise<Category[] | null>,
transform: Transform,
getAllCategory: PromiseOrNull<Category[]>,
evDataTrigger: EventDataTrigger,
) {
this.getAllCategory = getAllCategory;
this.transform = transform;
this.evDataTrigger = evDataTrigger;
}
sendData() {
const data: Data = { listCategories: this.listCategory! };
this.transform!.onSendSignal('categoryView', data);
this.evDataTrigger!.onSendSignal('categoryView', data);
}
handlerEventCategoryDialog() {
@@ -57,7 +57,7 @@ export default class CategoryView {
* Load category data
* @param {function} getAllCategory Get all category function
*/
async loadCategory() {
async loadCategory(): Promise<void> {
if (!this.listCategory) {
this.listCategory = await this.getAllCategory!();
@@ -4,11 +4,20 @@ import { clearAccessToken, formatNumber } from '../../helpers/data';
import WalletView from './walletView';
import Wallet from 'models/wallet';
import Transform from 'helpers/transform';
import EventDataTrigger from 'helpers/evDataTrigger';
import Transaction from 'models/transaction';
import User from 'models/user';
import { Data, TError } from 'global/types';
import { DEFAULT_TITLE_ERROR_TOAST } from 'constants/messages/dialog';
import {
Data,
IBudgetViewFunc,
IHomeFunc,
ITransactionViewFunc,
IWalletViewFunc,
Nullable,
PromiseOrNull,
TError,
} from 'global/types';
import { DEFAULT_TITLE_ERROR_TOAST } from 'constants/messages';
import { redirectToLoginPage } from 'helpers/url';
import Category from 'models/category';
import CategoryView from './categoryView';
@@ -41,31 +50,32 @@ export default class HomeView extends CommonView {
amountInputs: NodeListOf<Element>;
user: User | null = null;
user: Nullable<User> = null;
wallet: Wallet | null = null;
wallet: Nullable<Wallet> = null;
listTransactions: Transaction[] | null = null;
listTransactions: Transaction[] = [];
transactionDetails: TransactionDetail[] = [];
getInfoUserLogin: (() => Promise<User | null>) | null = null;
getInfoUserLogin: Nullable<PromiseOrNull<User>> = null;
getWalletByIdUser: ((idUser: string) => Promise<Wallet | null>) | null = null;
getWalletByIdUser: Nullable<(idUser: string) => Promise<Wallet | null>> =
null;
getAllCategory: (() => Promise<Category[] | null>) | null = null;
getAllCategory: Nullable<() => Promise<Category[] | null>> = null;
getAllTransactions:
| ((idUser: string) => Promise<Transaction[] | null>)
| null = null;
getAllTransactions: Nullable<
(idUser: string) => Promise<Transaction[] | null>
> = null;
deleteTransaction: ((idTransaction: string) => Promise<void>) | null = null;
deleteTransaction: Nullable<(idTransaction: string) => Promise<void>> = null;
saveWallet: ((wallet: Wallet) => Promise<void>) | null = null;
saveWallet: Nullable<(wallet: Wallet) => Promise<void>> = null;
saveTransaction: ((transaction: Transaction) => Promise<void>) | null = null;
saveTransaction: Nullable<(transaction: Transaction) => Promise<void>> = null;
transform: Transform | null = null;
evDataTrigger: Nullable<EventDataTrigger> = null;
constructor() {
super();
@@ -89,25 +99,17 @@ export default class HomeView extends CommonView {
this.handleEventToast();
}
initFunction(
getInfoUserLogin: () => Promise<User | null>,
getWalletByIdUser: (idUser: string) => Promise<Wallet | null>,
getAllCategory: () => Promise<Category[] | null>,
getAllTransactions: (idUser: string) => Promise<Transaction[] | null>,
saveWallet: (wallet: Wallet) => Promise<void>,
saveTransaction: (transaction: Transaction) => Promise<void>,
deleteTransaction: (idTransaction: string) => Promise<void>,
transform: Transform,
) {
this.getInfoUserLogin = getInfoUserLogin;
this.getWalletByIdUser = getWalletByIdUser;
this.getAllCategory = getAllCategory;
this.getAllTransactions = getAllTransactions;
this.saveWallet = saveWallet;
this.saveTransaction = saveTransaction;
this.deleteTransaction = deleteTransaction;
// ----------------------- Init function ----------------------- //
initFunction(func: IHomeFunc) {
this.getInfoUserLogin = func.getInfoUserLogin || null;
this.getWalletByIdUser = func.getWalletByIdUser || null;
this.getAllCategory = func.getAllCategory || null;
this.getAllTransactions = func.getAllTransactions || null;
this.saveWallet = func.saveWallet || null;
this.saveTransaction = func.saveTransaction || null;
this.deleteTransaction = func.deleteTransaction || null;
this.transform = transform;
this.evDataTrigger = EventDataTrigger.Instance;
// Init function for child view
this.initWalletViewFunction();
@@ -119,57 +121,61 @@ export default class HomeView extends CommonView {
}
initTransactionViewFunction() {
this.transactionView.initFunction(
this.toggleLoaderSpinner.bind(this),
this.deleteTransaction!,
this.loadTransactionData.bind(this),
this.updateAmountWallet.bind(this),
this.loadData.bind(this),
this.showSuccessToast.bind(this),
this.showErrorToast.bind(this),
this.saveTransaction!,
this.transform,
);
const func: ITransactionViewFunc = {
toggleLoaderSpinner: this.toggleLoaderSpinner.bind(this),
deleteTransaction: this.deleteTransaction!,
loadTransactionData: this.loadTransactionData.bind(this),
updateAmountWallet: this.updateAmountWallet.bind(this),
loadData: this.loadData.bind(this),
showSuccessToast: this.showSuccessToast.bind(this),
showErrorToast: this.showErrorToast.bind(this),
saveTransaction: this.saveTransaction!,
};
this.transactionView.initFunction(func);
}
initBudgetViewFunction() {
this.budgetView.initFunction(
this.showErrorToast.bind(this),
this.showSuccessToast.bind(this),
this.toggleLoaderSpinner.bind(this),
this.saveTransaction!.bind(this),
this.loadTransactionData.bind(this),
this.updateAmountWallet.bind(this),
this.loadData.bind(this),
this.transform,
);
const func: IBudgetViewFunc = {
showErrorToast: this.showErrorToast.bind(this),
showSuccessToast: this.showSuccessToast.bind(this),
toggleLoaderSpinner: this.toggleLoaderSpinner.bind(this),
saveTransaction: this.saveTransaction!.bind(this),
loadTransactionData: this.loadTransactionData.bind(this),
updateAmountWallet: this.updateAmountWallet.bind(this),
loadData: this.loadData.bind(this),
};
this.budgetView.initFunction(func);
}
initCategoryViewFunction() {
this.categoryView.initFunction(this.getAllCategory!, this.transform!);
this.categoryView.initFunction(this.getAllCategory!, this.evDataTrigger!);
}
initSummaryTabViewFunction() {
this.summaryTabView.initFunction(this.transform!);
this.summaryTabView.initFunction(this.evDataTrigger!);
}
initTransactionTabViewFunction() {
this.transactionTabView.initFunction(this.transform!);
this.transactionTabView.initFunction(this.evDataTrigger!);
}
initWalletViewFunction() {
this.walletView.initFunction(
this.transform,
this.toggleLoaderSpinner.bind(this),
this.saveWallet,
this.saveTransaction,
this.loadTransactionData.bind(this),
this.loadData.bind(this),
this.loadEvent.bind(this),
this.showSuccessToast.bind(this),
this.showErrorToast.bind(this),
);
const func: IWalletViewFunc = {
toggleLoaderSpinner: this.toggleLoaderSpinner.bind(this),
saveWallet: this.saveWallet,
saveTransaction: this.saveTransaction,
loadTransactionData: this.loadTransactionData.bind(this),
loadData: this.loadData.bind(this),
loadEvent: this.loadEvent.bind(this),
showSuccessToast: this.showSuccessToast.bind(this),
showErrorToast: this.showErrorToast.bind(this),
};
this.walletView.initFunction(func);
}
// ----------------------- End ----------------------- //
subscribeListenerData() {
this.subscribe();
@@ -180,7 +186,7 @@ export default class HomeView extends CommonView {
this.walletView.subscribe();
}
async loadData() {
async loadData(): Promise<void> {
// Send data to other class
this.sendData();
@@ -195,7 +201,7 @@ export default class HomeView extends CommonView {
await this.updateAmountWallet();
}
async loadPage() {
async loadPage(): Promise<void> {
this.toggleLoaderSpinner();
const user = await this.getInfoUserLogin!();
@@ -229,7 +235,7 @@ export default class HomeView extends CommonView {
// ---------------------LOAD DATA---------------------//
subscribe() {
this.transform!.create('homeView', this.updateData.bind(this));
this.evDataTrigger!.create('homeView', this.updateData.bind(this));
}
sendData() {
@@ -239,7 +245,7 @@ export default class HomeView extends CommonView {
user: this.user!,
};
this.transform!.onSendSignal('homeView', data);
this.evDataTrigger!.onSendSignal('homeView', data);
}
updateData(data: Data) {
@@ -251,7 +257,7 @@ export default class HomeView extends CommonView {
/**
* Load wallet user
*/
async loadWalletUser() {
async loadWalletUser(): Promise<void> {
const wallet = this.wallet
? this.wallet
: await this.getWalletByIdUser!(this.user!.id);
@@ -273,13 +279,15 @@ export default class HomeView extends CommonView {
this.saveWallet!(this.wallet!);
}
async loadTransactionData() {
this.listTransactions = await this.getAllTransactions!(this.wallet!.idUser);
async loadTransactionData(): Promise<void> {
const data = await this.getAllTransactions!(this.wallet!.idUser);
if (data) this.listTransactions = data;
this.sendData();
}
async updateAmountWallet() {
async updateAmountWallet(): Promise<void> {
let inflow = 0;
let outflow = 0;
// Init data first
@@ -315,7 +323,7 @@ export default class HomeView extends CommonView {
* Implement error toast in site
* @param {string} content The content will show in error toast
*/
showErrorToast(error: TError | string): void {
showErrorToast(error: TError) {
const title =
typeof error === 'object' && error.title
? error.title
@@ -1,25 +1,25 @@
import Transform from 'helpers/transform';
import EventDataTrigger from 'helpers/evDataTrigger';
import { formatNumber } from '../../helpers/data';
import { Data } from 'global/types';
import { Data, Nullable } from 'global/types';
import Wallet from 'models/wallet';
import Transaction from 'models/transaction';
import Category from 'models/category';
export default class SummaryTabView {
transform: Transform | null = null;
evDataTrigger: Nullable<EventDataTrigger> = null;
wallet: Wallet | null = null;
wallet: Nullable<Wallet> = null;
listTransactions: Transaction[] = [];
listCategories: Category[] = [];
initFunction(transform: Transform) {
this.transform = transform;
initFunction(evDataTrigger: EventDataTrigger) {
this.evDataTrigger = evDataTrigger;
}
subscribe() {
this.transform!.create('summaryTabView', this.updateData.bind(this));
this.evDataTrigger!.create('summaryTabView', this.updateData.bind(this));
}
updateData(data: Data) {
@@ -1,4 +1,4 @@
import Transform from 'helpers/transform';
import EventDataTrigger from 'helpers/evDataTrigger';
import {
createTransactionDetailObject,
getAllCategoryNameInTransactions,
@@ -6,7 +6,7 @@ import {
} from '../../helpers/data';
import { formatNumber } from '../../helpers/data';
import TransactionView from './transactionView';
import { Data } from 'global/types';
import { Data, Nullable } from 'global/types';
import Wallet from 'models/wallet';
import Transaction from 'models/transaction';
import Category from 'models/category';
@@ -15,9 +15,9 @@ import TransactionDetail from 'models/transactionDetail';
export default class TransactionTabView {
transactionView: TransactionView;
transform: Transform | null = null;
evDataTrigger: Nullable<EventDataTrigger> = null;
wallet: Wallet | null = null;
wallet: Nullable<Wallet> = null;
listTransactions: Transaction[] = [];
@@ -30,12 +30,15 @@ export default class TransactionTabView {
this.addEventTransactionItem();
}
initFunction(transform: Transform) {
this.transform = transform;
initFunction(evDataTrigger: EventDataTrigger) {
this.evDataTrigger = evDataTrigger;
}
subscribe() {
this.transform!.create('transactionTabView', this.updateData.bind(this));
this.evDataTrigger!.create(
'transactionTabView',
this.updateData.bind(this),
);
}
updateData(data: Data) {
@@ -46,7 +49,7 @@ export default class TransactionTabView {
if (data.listCategories) this.listCategories = data.listCategories;
}
async loadTransactionTab() {
async loadTransactionTab(): Promise<void> {
// Load category
// Init data first
this.transactionDetails = this.loadTransactionDetailsData();
@@ -100,7 +103,7 @@ export default class TransactionTabView {
}
// eslint-disable-next-line class-methods-use-this
transactionDetailMarkup(transactionDetail: TransactionDetail) {
transactionDetailMarkup(transactionDetail: TransactionDetail): string {
const itemTransaction = () => {
const listMarkup: string[] = [];
@@ -1,19 +1,26 @@
import Transaction from 'models/transaction';
import defaultCategoryIcon from '../../../assets/images/question-icon.svg';
import CategoryView from './categoryView';
import Transform from 'helpers/transform';
import { Data, TError } from 'global/types';
import EventDataTrigger from 'helpers/evDataTrigger';
import {
Data,
ITransactionViewFunc,
Nullable,
PromiseVoid,
TError,
VoidFunc,
} from 'global/types';
import Wallet from 'models/wallet';
import Category from 'models/category';
import {
ADD_TRANSACTION_SUCCESS,
DEFAULT_MESSAGE,
UPDATE_TRANSACTION_SUCCESS,
} from 'constants/messages/dialog';
} from 'constants/messages';
import { renderRequiredText } from 'helpers/validatorForm';
export default class TransactionView {
wallet: Wallet | null = null;
wallet: Nullable<Wallet> = null;
listTransactions: Transaction[] = [];
@@ -21,29 +28,29 @@ export default class TransactionView {
categoryView: CategoryView;
addTransactionBtn: HTMLElement | null = null;
addTransactionBtn: Nullable<HTMLElement> = null;
transactionDialog: HTMLDialogElement | null = null;
transactionDialog: Nullable<HTMLDialogElement> = null;
transactionForm: HTMLFormElement | null = null;
transactionForm: Nullable<HTMLFormElement> = null;
toggleLoaderSpinner: (() => void) | null = null;
toggleLoaderSpinner: Nullable<VoidFunc> = null;
deleteTransaction: ((idTransaction: string) => Promise<void>) | null = null;
deleteTransaction: Nullable<(idTransaction: string) => Promise<void>> = null;
loadTransactionData: (() => Promise<void>) | null = null;
loadTransactionData: Nullable<PromiseVoid> = null;
updateAmountWallet: (() => Promise<void>) | null = null;
updateAmountWallet: Nullable<PromiseVoid> = null;
loadData: (() => Promise<void>) | null = null;
loadData: Nullable<PromiseVoid> = null;
showSuccessToast: ((title: string, message: string) => void) | null = null;
showErrorToast: ((error: string | TError) => void) | null = null;
showErrorToast: ((error: TError) => void) | null = null;
saveTransaction: ((transaction: Transaction) => Promise<void>) | null = null;
saveTransaction: Nullable<(transaction: Transaction) => Promise<void>> = null;
transform: Transform | null = null;
evDataTrigger: EventDataTrigger | null = null;
constructor(categoryView: CategoryView) {
this.addTransactionBtn = document.getElementById('addTransaction');
@@ -59,30 +66,21 @@ export default class TransactionView {
this.categoryView = categoryView;
}
initFunction(
toggleLoaderSpinner: () => void,
deleteTransaction: (idTransaction: string) => Promise<void>,
loadTransactionData: () => Promise<void>,
updateAmountWallet: () => Promise<void>,
loadData: () => Promise<void>,
showSuccessToast: (title: string, message: string) => void,
showErrorToast: (error: string | TError) => void,
saveTransaction: (transaction: Transaction) => Promise<void>,
transform: Transform | null,
) {
this.toggleLoaderSpinner = toggleLoaderSpinner;
this.deleteTransaction = deleteTransaction;
this.loadTransactionData = loadTransactionData;
this.updateAmountWallet = updateAmountWallet;
this.loadData = loadData;
this.showSuccessToast = showSuccessToast;
this.showErrorToast = showErrorToast;
this.saveTransaction = saveTransaction;
this.transform = transform;
initFunction(func: ITransactionViewFunc) {
this.toggleLoaderSpinner = func.toggleLoaderSpinner;
this.deleteTransaction = func.deleteTransaction;
this.loadTransactionData = func.loadTransactionData;
this.updateAmountWallet = func.updateAmountWallet;
this.loadData = func.loadData;
this.showSuccessToast = func.showSuccessToast;
this.showErrorToast = func.showErrorToast;
this.saveTransaction = func.saveTransaction;
this.evDataTrigger = EventDataTrigger.Instance;
}
subscribe() {
this.transform!.create('transactionView', this.updateData.bind(this));
this.evDataTrigger!.create('transactionView', this.updateData.bind(this));
}
sendData() {
@@ -91,7 +89,7 @@ export default class TransactionView {
listTransactions: this.listTransactions!,
};
this.transform!.onSendSignal('transactionView', data);
this.evDataTrigger!.onSendSignal('transactionView', data);
}
updateData(data: Data) {
@@ -174,7 +172,7 @@ export default class TransactionView {
this.showSuccessToast!('Delete success!', DEFAULT_MESSAGE);
} catch (error) {
this.showErrorToast!(error as string | TError);
this.showErrorToast!(error as TError);
}
this.toggleLoaderSpinner!();
}
@@ -253,7 +251,7 @@ export default class TransactionView {
deleteBtn.classList.toggle('hide', !showDeleteBtn());
}
async submitTransactionDialog() {
async submitTransactionDialog(): Promise<void> {
try {
const dateEl = <HTMLDataElement>(
this.transactionForm!.querySelector("[name='selected_date']")
@@ -308,12 +306,16 @@ export default class TransactionView {
this.clearInputTransactionForm();
}
} catch (error) {
this.showErrorToast!(error as string | TError);
this.showErrorToast!(error as TError);
this.toggleLoaderSpinner!();
}
}
validateTransactionForm(date: string, categoryName: string, amount: number) {
validateTransactionForm(
date: string,
categoryName: string,
amount: number,
): boolean {
const inputFieldEls =
this.transactionDialog!.querySelectorAll('.form__input-field');
@@ -1,32 +1,39 @@
import Transaction from '../../models/transaction';
import Wallet from '../../models/wallet';
import { renderRequiredText } from '../../helpers/validatorForm';
import Transform from 'helpers/transform';
import { Data, TError } from 'global/types';
import EventDataTrigger from 'helpers/evDataTrigger';
import {
Data,
IWalletViewFunc,
Nullable,
PromiseVoid,
TError,
VoidFunc,
} from 'global/types';
import User from 'models/user';
import { FIRST_ADD_WALLET_NOTE } from 'constants/defaultVariable';
import { ADD_WALLET_SUCCESS, DEFAULT_MESSAGE } from 'constants/messages/dialog';
import { ADD_WALLET_SUCCESS, DEFAULT_MESSAGE } from 'constants/messages';
export default class WalletView {
walletDialog: HTMLDialogElement | null = null;
walletDialog: Nullable<HTMLDialogElement> = null;
transform: Transform | null = null;
evDataTrigger: Nullable<EventDataTrigger> = null;
toggleLoaderSpinner: (() => void) | null = null;
toggleLoaderSpinner: Nullable<VoidFunc> = null;
saveWallet: ((wallet: Wallet) => Promise<void>) | null = null;
saveWallet: Nullable<(wallet: Wallet) => Promise<void>> = null;
saveTransaction: ((transaction: Transaction) => Promise<void>) | null = null;
saveTransaction: Nullable<(transaction: Transaction) => Promise<void>> = null;
loadTransactionData: (() => Promise<void>) | null = null;
loadTransactionData: Nullable<PromiseVoid> = null;
loadData: (() => Promise<void>) | null = null;
loadData: Nullable<PromiseVoid> = null;
loadEvent: (() => void) | null = null;
loadEvent: Nullable<VoidFunc> = null;
showSuccessToast: ((title: string, message: string) => void) | null = null;
showErrorToast: ((error: string | TError) => void) | null = null;
showErrorToast: ((error: TError) => void) | null = null;
user: User | null = null;
@@ -40,30 +47,21 @@ export default class WalletView {
this.addHandlerEventWalletForm();
}
initFunction(
transform: Transform | null,
toggleLoaderSpinner: () => void,
saveWallet: ((wallet: Wallet) => Promise<void>) | null,
saveTransaction: ((transaction: Transaction) => Promise<void>) | null,
loadTransactionData: () => Promise<void>,
loadData: () => Promise<void>,
loadEvent: () => void,
showSuccessToast: (title: string, message: string) => void,
showErrorToast: (error: string | TError) => void,
) {
this.transform = transform;
this.toggleLoaderSpinner = toggleLoaderSpinner;
this.saveWallet = saveWallet;
this.saveTransaction = saveTransaction;
this.loadTransactionData = loadTransactionData;
this.loadData = loadData;
this.loadEvent = loadEvent;
this.showSuccessToast = showSuccessToast;
this.showErrorToast = showErrorToast;
initFunction(func: IWalletViewFunc) {
this.toggleLoaderSpinner = func.toggleLoaderSpinner;
this.saveWallet = func.saveWallet;
this.saveTransaction = func.saveTransaction;
this.loadTransactionData = func.loadTransactionData;
this.loadData = func.loadData;
this.loadEvent = func.loadEvent;
this.showSuccessToast = func.showSuccessToast;
this.showErrorToast = func.showErrorToast;
this.evDataTrigger = EventDataTrigger.Instance;
}
subscribe() {
this.transform!.create('walletView', this.updateData.bind(this));
this.evDataTrigger!.create('walletView', this.updateData.bind(this));
}
sendData() {
@@ -72,7 +70,7 @@ export default class WalletView {
user: this.user!,
};
this.transform!.onSendSignal('walletView', data);
this.evDataTrigger!.onSendSignal('walletView', data);
}
updateData(data: Data) {
@@ -116,7 +114,7 @@ export default class WalletView {
});
}
async submitWalletForm() {
async submitWalletForm(): Promise<void> {
try {
// Wallet info
const form = document.getElementById('walletForm') as HTMLFormElement;
@@ -128,7 +126,7 @@ export default class WalletView {
this.walletDialog!.close();
this.toggleLoaderSpinner!();
const wallet = new Wallet(walletName, +amount, 0, this.user!.id);
const wallet = new Wallet('', walletName, +amount, 0, this.user!.id);
this.wallet = wallet;
this.sendData();
@@ -156,12 +154,12 @@ export default class WalletView {
}
} catch (error) {
// Show toast error
this.showErrorToast!(error as string | TError);
this.showErrorToast!(error as TError);
this.toggleLoaderSpinner!();
}
}
validateWalletDialog(walletName: string, amount: number) {
validateWalletDialog(walletName: string, amount: number): boolean {
const inputFieldEls =
this.walletDialog!.querySelectorAll('.form__input-field');
+4 -3
View File
@@ -3,13 +3,14 @@ import LoginView from './loginView';
import RegisterView from './registerView';
import { URL } from 'constants/config';
import HomeView from './home/homeView';
import { Nullable } from 'global/types';
export default class View {
public registerView: RegisterView | null = null;
public registerView: Nullable<RegisterView> = null;
public loginView: LoginView | null = null;
public loginView: Nullable<LoginView> = null;
public homeView: HomeView | null = null;
public homeView: Nullable<HomeView> = null;
constructor() {
switch (getSubdirectoryURL()) {
+10 -8
View File
@@ -1,10 +1,12 @@
import AuthenticationView from './authenticationView';
import { TypeToast, BTN_CONTENT } from '../constants/config';
import User from 'models/user';
import { DEFAULT_TITLE_ERROR_TOAST } from 'constants/messages/dialog';
import { CustomError, TError } from 'global/types';
import {
DEFAULT_TITLE_ERROR_TOAST,
ERROR_CREDENTIAL,
} from 'constants/messages';
import { CustomError, Nullable, PromiseOrNull, TError } from 'global/types';
import { redirectToLoginPage } from 'helpers/url';
import { ERROR_CREDENTIAL } from 'constants/messages/form';
export default class LoginView extends AuthenticationView {
constructor() {
@@ -15,7 +17,7 @@ export default class LoginView extends AuthenticationView {
this.handleEventToast();
}
async loadPage(getInfoUserLogin: () => Promise<User | null>) {
async loadPage(getInfoUserLogin: PromiseOrNull<User>) {
this.toggleLoaderSpinner();
const user = await getInfoUserLogin();
if (user) {
@@ -28,7 +30,7 @@ export default class LoginView extends AuthenticationView {
* Implement error toast in site
* @param {string} content The content will show in error toast
*/
initErrorToast(error: TError | string): void {
initErrorToast(error: TError) {
const title =
typeof error === 'object' && error.title
? error.title
@@ -90,7 +92,7 @@ export default class LoginView extends AuthenticationView {
}
} catch (error) {
// Show toast error
this.initErrorToast(error as string | TError);
this.initErrorToast(error as TError);
}
// Close spinner
this.toggleLoaderSpinner();
@@ -100,7 +102,7 @@ export default class LoginView extends AuthenticationView {
* Get data from user input
* @returns {Object || null} Return object or null
*/
validateForm(event: Event): User | null {
validateForm(event: Event): Nullable<User> {
if (event.target) {
const formData = new FormData(event.target as HTMLFormElement);
const email = formData.get('email') as string;
@@ -116,7 +118,7 @@ export default class LoginView extends AuthenticationView {
this.emailEl.classList.toggle('error-input', !emailValid);
this.inputPasswordEl.classList.toggle('error-input', !passwordValid);
if (emailValid && passwordValid) {
return new User(email, password);
return new User('', email, password);
}
}
}
@@ -7,8 +7,14 @@ import {
DEFAULT_TITLE_ERROR_TOAST,
REGISTER_SUCCESS,
USER_EXIST_ERROR,
} from 'constants/messages/dialog';
import { TError } from 'global/types';
} from 'constants/messages';
import { Nullable, PromiseOrNull, TError } from 'global/types';
interface UserInput {
email: string;
password: string;
passwordConfirm: string;
}
export default class RegisterView extends AuthenticationView {
constructor() {
@@ -21,7 +27,7 @@ export default class RegisterView extends AuthenticationView {
this.toastBtn = document.querySelector('.toast__redirect-btn');
}
async loadPage(getInfoUserLogin: () => Promise<User | null>) {
async loadPage(getInfoUserLogin: PromiseOrNull<User>) {
this.toggleLoaderSpinner();
const user = await getInfoUserLogin();
@@ -37,20 +43,36 @@ export default class RegisterView extends AuthenticationView {
* Get data from user input
* @returns {Object || null} Return object or null
*/
validateForm(): User | null {
getUserFromForm(): Nullable<User> {
const form = document.getElementById('registerForm') as HTMLFormElement;
const formData = new FormData(form);
const email = formData.get('email') as string;
const password = formData.get('password') as string;
const passwordConfirm = formData.get('password_confirm') as string;
// Validate user input
this.listError = []; // Reset list error
const emailValid = this.validateEmail(email);
const passwordValid = this.validatePassword(password);
const passwordConfirmValid = this.validatePasswordConfirm(
const userInput: UserInput = {
email,
password,
passwordConfirm,
};
const result = this.validateForm(userInput);
if (result) {
return new User('', email, password);
}
return null;
}
validateForm(userInput: UserInput): boolean {
// Validate user input
this.listError = []; // Reset list error
const emailValid = this.validateEmail(userInput.email);
const passwordValid = this.validatePassword(userInput.password);
const passwordConfirmValid = this.validatePasswordConfirm(
userInput.password,
userInput.passwordConfirm,
);
// Show error style
@@ -63,13 +85,9 @@ export default class RegisterView extends AuthenticationView {
);
}
if (emailValid && passwordValid && passwordConfirmValid) {
return new User(email, password);
}
this.showError(this.listError);
return null;
return emailValid && passwordValid && passwordConfirmValid;
}
/**
@@ -95,7 +113,7 @@ export default class RegisterView extends AuthenticationView {
* Implement error toast in site
* @param {string} content The content will show in error toast
*/
initErrorToast(error: TError | string): void {
initErrorToast(error: TError) {
const title =
typeof error === 'object' && error.title
? error.title
@@ -126,10 +144,10 @@ export default class RegisterView extends AuthenticationView {
saveUser: (user: User) => Promise<void>,
) {
if (this.formEl) {
this.formEl.addEventListener('submit', (e) => {
this.formEl.addEventListener('submit', async (e) => {
e.preventDefault();
this.clearErrorMessage();
this.submitForm(checkExistUser, saveUser);
await this.submitForm(checkExistUser, saveUser);
});
}
}
@@ -137,13 +155,13 @@ export default class RegisterView extends AuthenticationView {
async submitForm(
checkExistUser: (email: string) => Promise<boolean>,
saveUser: (user: User) => Promise<void>,
) {
): Promise<void> {
try {
// Load spinner
this.toggleLoaderSpinner();
// Get validate form
const user = this.validateForm();
const user = this.getUserFromForm();
// Save user
if (user) {
@@ -166,7 +184,7 @@ export default class RegisterView extends AuthenticationView {
}
} catch (error) {
// Show toast error
this.initErrorToast(error as string | TError);
this.initErrorToast(error as TError);
}
// Close spinner