mirror of
https://github.com/Nezumi-2711/typescript-training.git
synced 2026-09-22 13:48:29 +00:00
Add common service and base class
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
<!DOCTYPE html>
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
export const DATABASE_URL =
|
||||
'https://javascript-training-81f7a-default-rtdb.asia-southeast1.firebasedatabase.app';
|
||||
export const TIME_OUT_SEC = 3;
|
||||
|
||||
export enum BTN_CONTENT {
|
||||
GOT_IT = 'Got it!',
|
||||
OK = 'Ok',
|
||||
}
|
||||
|
||||
export const LOCAL_STORAGE = {
|
||||
ACCESS_TOKEN: 'accessToken',
|
||||
};
|
||||
|
||||
export enum TYPE_TOAST {
|
||||
success = 'success',
|
||||
error = 'error',
|
||||
}
|
||||
export enum MARK_ICON {
|
||||
success = 'check',
|
||||
error = 'error',
|
||||
}
|
||||
|
||||
export const REGEX = {
|
||||
PASSWORD:
|
||||
/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$/,
|
||||
EMAIL:
|
||||
/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|.(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/,
|
||||
};
|
||||
@@ -0,0 +1,31 @@
|
||||
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_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!';
|
||||
|
||||
export const ADD_WALLET_SUCCESS = 'Add wallet success!';
|
||||
|
||||
export const DEFAULT_MESSAGE = 'Press OK to continue!';
|
||||
|
||||
export const ADD_TRANSACTION_SUCCESS = 'Add success!';
|
||||
|
||||
export const UPDATE_TRANSACTION_SUCCESS = 'Update success!';
|
||||
|
||||
export const REGISTER_SUCCESS = 'Register Success';
|
||||
|
||||
export const REQUIRED_MESSAGE = (field) => `The ${field} is required!`;
|
||||
|
||||
export const INVALID_EMAIL_FORMAT = `The email is not correct!`;
|
||||
@@ -0,0 +1,69 @@
|
||||
import * as MESSAGE from '../constants/message';
|
||||
import { TIME_OUT_SEC, REGEX } from '../constants/config';
|
||||
import FirebaseService from '../services/firebaseService';
|
||||
|
||||
/**
|
||||
* Validate password
|
||||
* @param {string} password Password input
|
||||
* @returns {boolean} Return true if validate password success, otherwise return false
|
||||
*/
|
||||
export const isValidPassword = (password: string): boolean => {
|
||||
return REGEX.PASSWORD.test(password);
|
||||
};
|
||||
|
||||
export const isValidateEmail = (email: string): RegExpMatchArray | null => {
|
||||
return String(email).toLowerCase().match(REGEX.EMAIL);
|
||||
};
|
||||
|
||||
export const compare2Password = (
|
||||
password: string,
|
||||
passwordConfirm: string,
|
||||
): boolean => {
|
||||
return password === passwordConfirm;
|
||||
};
|
||||
|
||||
/**
|
||||
* A waiting function with s second
|
||||
* @param {number} s The time will be waiting
|
||||
* @returns {Promise} A Promise will be only reject after s second
|
||||
*/
|
||||
export const timeout = (s: number): Promise<string> => {
|
||||
return new Promise((_, reject) => {
|
||||
setTimeout(() => {
|
||||
FirebaseService.disconnect();
|
||||
reject(MESSAGE.TIME_OUT_ERROR);
|
||||
}, s * 1000);
|
||||
});
|
||||
};
|
||||
|
||||
export const createIdUser = (): number => {
|
||||
return new Date().getTime();
|
||||
};
|
||||
|
||||
/**
|
||||
* A function waiting the action need to be perform and throw error after s second.
|
||||
* @param {Function} action The action need to be perform.
|
||||
* @returns { Object || Error } Return the any object from Firebase or Error
|
||||
*/
|
||||
export const timeOutConnect = async (
|
||||
action: Promise<object>,
|
||||
): Promise<string | object> => {
|
||||
const result: object | string = await Promise.race([
|
||||
action,
|
||||
timeout(TIME_OUT_SEC),
|
||||
]);
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
export const renderRequiredText = (field: string, element: Element) => {
|
||||
const markup: string = `
|
||||
<p class="error-text">${MESSAGE.REQUIRED_MESSAGE(field)}</p>
|
||||
`;
|
||||
|
||||
element.insertAdjacentHTML('afterend', markup);
|
||||
};
|
||||
|
||||
export const redirectToLoginPage = () => {
|
||||
window.location.replace('/login');
|
||||
};
|
||||
@@ -0,0 +1,104 @@
|
||||
import {
|
||||
convertDataObjectToModel,
|
||||
convertModelToDataObject,
|
||||
timeOutConnect,
|
||||
} from '../helpers/helpers';
|
||||
import FirebaseService from './firebaseService';
|
||||
|
||||
export default class CommonService {
|
||||
constructor() {
|
||||
this.defaultPath = '/';
|
||||
this.firebaseService = FirebaseService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect to Firebase Databse
|
||||
*/
|
||||
connectToDb() {
|
||||
this.firebaseService.reconnect();
|
||||
}
|
||||
|
||||
async getDataFromProp(property, value, path = this.defaultPath) {
|
||||
this.connectToDb();
|
||||
const data = this.firebaseService.getDataFromProp(path, property, value);
|
||||
const result = await timeOutConnect(data);
|
||||
|
||||
if (result.id && result.data) {
|
||||
return convertDataObjectToModel(result);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save data on database
|
||||
* @param {*} data The data wants to save on database
|
||||
* @param {string} path The path of database
|
||||
*/
|
||||
async save(model) {
|
||||
this.connectToDb();
|
||||
const results = convertModelToDataObject(model);
|
||||
|
||||
const saveData = this.firebaseService.save(
|
||||
results.data,
|
||||
this.defaultPath + results.id,
|
||||
);
|
||||
|
||||
await timeOutConnect(saveData);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} id The string of data object
|
||||
* @param {string} path The path of database
|
||||
* @returns {Object || null} Return the object if has, otherwise return null
|
||||
*/
|
||||
async getDataFromId(id, path = this.defaultPath) {
|
||||
this.connectToDb();
|
||||
const result = await this.firebaseService.getDataFromId(id, path);
|
||||
const data = await timeOutConnect(result);
|
||||
|
||||
if (data) return data;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
async getAllDataFromPath(path = this.defaultPath) {
|
||||
this.connectToDb();
|
||||
|
||||
const results = await timeOutConnect(
|
||||
this.firebaseService.getAllDataFromPath(path),
|
||||
);
|
||||
|
||||
if (results) {
|
||||
// Convert format object
|
||||
return results.map((data) => {
|
||||
return convertDataObjectToModel(data);
|
||||
});
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
async getListDataFromProp(property, value, path = this.defaultPath) {
|
||||
this.connectToDb();
|
||||
|
||||
const results = await timeOutConnect(
|
||||
this.firebaseService.getListDataFromProp(path, property, value),
|
||||
);
|
||||
if (results) {
|
||||
// Convert format object
|
||||
|
||||
return results.map((data) => {
|
||||
return convertDataObjectToModel(data);
|
||||
});
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
async deleteData(id, path = this.defaultPath) {
|
||||
this.connectToDb();
|
||||
await timeOutConnect(this.firebaseService.delete(id, path));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,163 @@
|
||||
import { FirebaseApp, initializeApp } from 'firebase/app';
|
||||
import {
|
||||
getDatabase,
|
||||
ref,
|
||||
set,
|
||||
goOffline,
|
||||
goOnline,
|
||||
onValue,
|
||||
remove,
|
||||
Database,
|
||||
} from 'firebase/database';
|
||||
import { DATABASE_URL } from '../constants/config';
|
||||
|
||||
class FirebaseService {
|
||||
private app: FirebaseApp;
|
||||
private db: Database;
|
||||
|
||||
constructor() {
|
||||
const firebaseConfig = {
|
||||
databaseURL: DATABASE_URL,
|
||||
};
|
||||
this.app = initializeApp(firebaseConfig);
|
||||
this.db = getDatabase(this.app);
|
||||
}
|
||||
|
||||
/**
|
||||
* Save data in database
|
||||
* @param {Object} data The object need to save into database
|
||||
* @param {string} path The path of database need to be save
|
||||
* @returns {Promise} Return the resolves when write to database completed
|
||||
*/
|
||||
save(data: object, path: string): Promise<any> {
|
||||
return set(ref(this.db, path), data);
|
||||
}
|
||||
|
||||
delete(id: string, path: string) {
|
||||
return remove(ref(this.db, path + id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Disconnect to database
|
||||
*/
|
||||
disconnect() {
|
||||
goOffline(this.db);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reconnect to database
|
||||
*/
|
||||
reconnect() {
|
||||
goOnline(this.db);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find id of value by property in database
|
||||
* @param {string} path The path of database to be found
|
||||
* @param {string} property The property of the value need to be found
|
||||
* @param {value} value The value to compare in database
|
||||
* @returns {Promise} Return the resolve when find completed
|
||||
*/
|
||||
getDataFromProp(path: string, property: string, value: object): Promise<any> {
|
||||
return new Promise((resolve) => {
|
||||
onValue(
|
||||
ref(this.db, path),
|
||||
(snapshot) => {
|
||||
let id: string | null = null;
|
||||
let data: object | null = null;
|
||||
|
||||
// snapshot is a type of data by Firebase define
|
||||
snapshot.forEach((childSnapshot) => {
|
||||
const dataTemp = childSnapshot.val();
|
||||
|
||||
if (dataTemp[property] === value) {
|
||||
id = childSnapshot.key;
|
||||
data = dataTemp;
|
||||
}
|
||||
});
|
||||
resolve({ id, data });
|
||||
},
|
||||
{
|
||||
onlyOnce: true,
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get data object from Id
|
||||
* @param {string} id The id of data object
|
||||
* @param {string} path The path of data save in database
|
||||
* @returns {Promise} Return new Promise
|
||||
*/
|
||||
getDataFromId(id: string, path: string): Promise<any> {
|
||||
return new Promise((resolve) => {
|
||||
onValue(
|
||||
ref(this.db, path + id),
|
||||
(snapshot) => {
|
||||
resolve(snapshot.val());
|
||||
},
|
||||
{
|
||||
onlyOnce: true,
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
getAllDataFromPath(path) {
|
||||
return new Promise((resolve) => {
|
||||
onValue(
|
||||
ref(this.db, path),
|
||||
(snapshot) => {
|
||||
const listData: object[] = [];
|
||||
|
||||
// snapshot is a type of data by Firebase define
|
||||
snapshot.forEach((childSnapshot) => {
|
||||
let id: string | null = null;
|
||||
let data: object | null = null;
|
||||
|
||||
id = childSnapshot.key;
|
||||
data = childSnapshot.val();
|
||||
|
||||
listData.push({ id, data });
|
||||
});
|
||||
resolve(listData);
|
||||
},
|
||||
{
|
||||
onlyOnce: true,
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
getListDataFromProp(path: string, property: string, value: object) {
|
||||
return new Promise((resolve) => {
|
||||
onValue(
|
||||
ref(this.db, path),
|
||||
(snapshot) => {
|
||||
let id: string;
|
||||
let data: object;
|
||||
const listData: object[] = [];
|
||||
|
||||
// snapshot is a type of data by Firebase define
|
||||
snapshot.forEach((childSnapshot) => {
|
||||
const dataTemp = childSnapshot.val();
|
||||
|
||||
if (dataTemp[property] === value) {
|
||||
id = childSnapshot.key;
|
||||
data = dataTemp;
|
||||
|
||||
listData.push({ id, data });
|
||||
}
|
||||
});
|
||||
resolve(listData);
|
||||
},
|
||||
{
|
||||
onlyOnce: true,
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export default new FirebaseService();
|
||||
@@ -0,0 +1 @@
|
||||
export default class Service {}
|
||||
@@ -0,0 +1,25 @@
|
||||
class LocalStorageService {
|
||||
private localStorage: Storage;
|
||||
|
||||
constructor() {
|
||||
this.localStorage = localStorage;
|
||||
}
|
||||
|
||||
add(key: string, value: string) {
|
||||
this.localStorage.setItem(key, value);
|
||||
}
|
||||
|
||||
get(key: string) {
|
||||
return this.localStorage.getItem(key);
|
||||
}
|
||||
|
||||
remove(key: string) {
|
||||
this.localStorage.removeItem(key);
|
||||
}
|
||||
|
||||
clear() {
|
||||
this.localStorage.clear();
|
||||
}
|
||||
}
|
||||
|
||||
export default new LocalStorageService();
|
||||
Reference in New Issue
Block a user