feat: setup apps
|
@ -24,4 +24,6 @@ dist-ssr
|
|||
*.sw?
|
||||
|
||||
.env
|
||||
yarn.lock
|
||||
yarn.lock
|
||||
tsconfig.app.tsbuildinfo
|
||||
tsconfig.node.tsbuildinfo
|
|
@ -22,6 +22,7 @@ export default tseslint.config(
|
|||
'react-refresh/only-export-components': ['warn', { allowConstantExport: true }],
|
||||
'@typescript-eslint/no-explicit-any': 'off',
|
||||
'@typescript-eslint/no-duplicate-enum-values': 'off',
|
||||
'@typescript-eslint/no-unused-expressions': 'warn',
|
||||
},
|
||||
},
|
||||
);
|
||||
|
|
|
@ -22,19 +22,23 @@
|
|||
"react-dom": "^18.3.1",
|
||||
"react-icons": "^5.3.0",
|
||||
"react-intl": "^6.7.0",
|
||||
"react-router-dom": "^6.26.2",
|
||||
"recoil": "^0.7.7"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^9.9.0",
|
||||
"@types/crypto-js": "^4.2.2",
|
||||
"@types/lodash": "^4.17.9",
|
||||
"@types/node": "^22.7.4",
|
||||
"@types/react": "^18.3.3",
|
||||
"@types/react-dom": "^18.3.0",
|
||||
"@vitejs/plugin-react-swc": "^3.5.0",
|
||||
"autoprefixer": "^10.4.20",
|
||||
"eslint": "^9.9.0",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
"eslint-plugin-prettier": "^5.2.1",
|
||||
"eslint-plugin-react-hooks": "^5.1.0-rc.0",
|
||||
"eslint-plugin-react-refresh": "^0.4.9",
|
||||
"eslint-plugin-react-refresh": "^0.4.12",
|
||||
"globals": "^15.9.0",
|
||||
"less": "^4.2.0",
|
||||
"postcss": "^8.4.47",
|
||||
|
@ -917,6 +921,18 @@
|
|||
"node": ">=14"
|
||||
}
|
||||
},
|
||||
"node_modules/@pkgr/core": {
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.1.tgz",
|
||||
"integrity": "sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": "^12.20.0 || ^14.18.0 || >=16.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/unts"
|
||||
}
|
||||
},
|
||||
"node_modules/@rc-component/async-validator": {
|
||||
"version": "5.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@rc-component/async-validator/-/async-validator-5.0.4.tgz",
|
||||
|
@ -1057,6 +1073,14 @@
|
|||
"react-dom": ">=16.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@remix-run/router": {
|
||||
"version": "1.19.2",
|
||||
"resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.19.2.tgz",
|
||||
"integrity": "sha512-baiMx18+IMuD1yyvOGaHM9QrVUPGGG0jC+z+IPHnRJWUAUvaKuWKyE8gjDj2rzv3sz9zOGoRSPgeBVHRhZnBlA==",
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@rollup/rollup-android-arm-eabi": {
|
||||
"version": "4.23.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.23.0.tgz",
|
||||
|
@ -1511,6 +1535,15 @@
|
|||
"integrity": "sha512-w9iWudx1XWOHW5lQRS9iKpK/XuRhnN+0T7HvdCCd802FYkT1AMTnxndJHGrNJwRoRHkslGr4S29tjm1cT7x/7w==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "22.7.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.4.tgz",
|
||||
"integrity": "sha512-y+NPi1rFzDs1NdQHHToqeiX2TIS79SWEAw9GYhkkx8bD0ChpfqC+n2j5OXOCpzfojBEBt6DnEnnG9MY0zk1XLg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"undici-types": "~6.19.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/prop-types": {
|
||||
"version": "15.7.13",
|
||||
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.13.tgz",
|
||||
|
@ -2516,6 +2549,48 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-config-prettier": {
|
||||
"version": "9.1.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz",
|
||||
"integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"eslint-config-prettier": "bin/cli.js"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"eslint": ">=7.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-plugin-prettier": {
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.2.1.tgz",
|
||||
"integrity": "sha512-gH3iR3g4JfF+yYPaJYkN7jEl9QbweL/YfkoRlNnuIEHEz1vHVlCmWOS+eGGiRuzHQXdJFCOTxRgvju9b8VUmrw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"prettier-linter-helpers": "^1.0.0",
|
||||
"synckit": "^0.9.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.18.0 || >=16.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/eslint-plugin-prettier"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/eslint": ">=8.0.0",
|
||||
"eslint": ">=8.0.0",
|
||||
"eslint-config-prettier": "*",
|
||||
"prettier": ">=3.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/eslint": {
|
||||
"optional": true
|
||||
},
|
||||
"eslint-config-prettier": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-plugin-react-hooks": {
|
||||
"version": "5.1.0-rc-fb9a90fa48-20240614",
|
||||
"resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.1.0-rc-fb9a90fa48-20240614.tgz",
|
||||
|
@ -2630,6 +2705,12 @@
|
|||
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/fast-diff": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz",
|
||||
"integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/fast-glob": {
|
||||
"version": "3.3.2",
|
||||
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz",
|
||||
|
@ -3827,6 +3908,18 @@
|
|||
"url": "https://github.com/prettier/prettier?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/prettier-linter-helpers": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz",
|
||||
"integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"fast-diff": "^1.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/prop-types": {
|
||||
"version": "15.8.1",
|
||||
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
|
||||
|
@ -4517,6 +4610,36 @@
|
|||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
||||
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
|
||||
},
|
||||
"node_modules/react-router": {
|
||||
"version": "6.26.2",
|
||||
"resolved": "https://registry.npmjs.org/react-router/-/react-router-6.26.2.tgz",
|
||||
"integrity": "sha512-tvN1iuT03kHgOFnLPfLJ8V95eijteveqdOSk+srqfePtQvqCExB8eHOYnlilbOcyJyKnYkr1vJvf7YqotAJu1A==",
|
||||
"dependencies": {
|
||||
"@remix-run/router": "1.19.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.8"
|
||||
}
|
||||
},
|
||||
"node_modules/react-router-dom": {
|
||||
"version": "6.26.2",
|
||||
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.26.2.tgz",
|
||||
"integrity": "sha512-z7YkaEW0Dy35T3/QKPYB1LjMK2R1fxnHO8kWpUMTBdfVzZrWOiY9a7CtN8HqdWtDUWd5FY6Dl8HFsqVwH4uOtQ==",
|
||||
"dependencies": {
|
||||
"@remix-run/router": "1.19.2",
|
||||
"react-router": "6.26.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.8",
|
||||
"react-dom": ">=16.8"
|
||||
}
|
||||
},
|
||||
"node_modules/read-cache": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
|
||||
|
@ -4927,6 +5050,22 @@
|
|||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/synckit": {
|
||||
"version": "0.9.1",
|
||||
"resolved": "https://registry.npmjs.org/synckit/-/synckit-0.9.1.tgz",
|
||||
"integrity": "sha512-7gr8p9TQP6RAHusBOSLs46F4564ZrjV8xFmw5zCmgmhGUcw2hxsShhJ6CEiHQMgPDwAQ1fWHPM0ypc4RMAig4A==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@pkgr/core": "^0.1.0",
|
||||
"tslib": "^2.6.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.18.0 || >=16.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/unts"
|
||||
}
|
||||
},
|
||||
"node_modules/tailwindcss": {
|
||||
"version": "3.4.13",
|
||||
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.13.tgz",
|
||||
|
@ -5100,6 +5239,12 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"node_modules/undici-types": {
|
||||
"version": "6.19.8",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz",
|
||||
"integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/update-browserslist-db": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz",
|
||||
|
|
|
@ -24,19 +24,23 @@
|
|||
"react-dom": "^18.3.1",
|
||||
"react-icons": "^5.3.0",
|
||||
"react-intl": "^6.7.0",
|
||||
"react-router-dom": "^6.26.2",
|
||||
"recoil": "^0.7.7"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^9.9.0",
|
||||
"@types/crypto-js": "^4.2.2",
|
||||
"@types/lodash": "^4.17.9",
|
||||
"@types/node": "^22.7.4",
|
||||
"@types/react": "^18.3.3",
|
||||
"@types/react-dom": "^18.3.0",
|
||||
"@vitejs/plugin-react-swc": "^3.5.0",
|
||||
"autoprefixer": "^10.4.20",
|
||||
"eslint": "^9.9.0",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
"eslint-plugin-prettier": "^5.2.1",
|
||||
"eslint-plugin-react-hooks": "^5.1.0-rc.0",
|
||||
"eslint-plugin-react-refresh": "^0.4.9",
|
||||
"eslint-plugin-react-refresh": "^0.4.12",
|
||||
"globals": "^15.9.0",
|
||||
"less": "^4.2.0",
|
||||
"postcss": "^8.4.47",
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
import { LocalStorageService } from './local-storage.services';
|
||||
import {
|
||||
LS_DEFAULT_URL,
|
||||
LS_ACTIVE_ACCOUNT,
|
||||
IDB_T_NAME__USER_DATA,
|
||||
IDB_T_NAME__ACCESS_TOKEN,
|
||||
IDB_T_NAME__PRIVILEGE,
|
||||
} from './storage.key';
|
||||
import { IndexedDbService } from './indexed-db.services';
|
||||
import { appConfig } from './indexed-db.init';
|
||||
|
||||
// LOCAL STORAGE NO NEED PROMISE FOR CALL
|
||||
export const StorageActiveAccount = new LocalStorageService(LS_ACTIVE_ACCOUNT);
|
||||
export const StorageDefaultURL = new LocalStorageService(LS_DEFAULT_URL);
|
||||
|
||||
// LOCAL STORAGE NEED PROMISE FOR CALL
|
||||
export const StorageUserData = new IndexedDbService(appConfig, IDB_T_NAME__USER_DATA);
|
||||
export const StorageAccessToken = new IndexedDbService(appConfig, IDB_T_NAME__ACCESS_TOKEN);
|
||||
export const StoragePrivilege = new IndexedDbService(appConfig, IDB_T_NAME__PRIVILEGE);
|
|
@ -0,0 +1,27 @@
|
|||
import { openDB } from 'idb';
|
||||
import { IDB_NAME, IDB_T_NAME__ACCESS_TOKEN, IDB_T_NAME__USER_DATA, IDB_T_NAME__PRIVILEGE } from './storage.key';
|
||||
|
||||
export const appConfig = openDB(IDB_NAME, 3, {
|
||||
upgrade(db) {
|
||||
if (!db.objectStoreNames.contains(IDB_T_NAME__ACCESS_TOKEN)) {
|
||||
db.createObjectStore(IDB_T_NAME__ACCESS_TOKEN, {
|
||||
keyPath: 'id',
|
||||
autoIncrement: false,
|
||||
});
|
||||
}
|
||||
|
||||
if (!db.objectStoreNames.contains(IDB_T_NAME__USER_DATA)) {
|
||||
db.createObjectStore(IDB_T_NAME__USER_DATA, {
|
||||
keyPath: 'id',
|
||||
autoIncrement: false,
|
||||
});
|
||||
}
|
||||
|
||||
if (!db.objectStoreNames.contains(IDB_T_NAME__PRIVILEGE)) {
|
||||
db.createObjectStore(IDB_T_NAME__PRIVILEGE, {
|
||||
keyPath: 'id',
|
||||
autoIncrement: false,
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
|
@ -0,0 +1,92 @@
|
|||
import { DBSchema, IDBPDatabase } from 'idb';
|
||||
import { IIndexedDbService } from './storage.interface';
|
||||
import { decryptData, encryptData } from '@pos/base';
|
||||
import { StorageActiveAccount } from './index';
|
||||
|
||||
export type IndexedDbValueEntity = any;
|
||||
|
||||
export class IndexedDbService implements IIndexedDbService<IndexedDbValueEntity> {
|
||||
dbPromise: IDBPDatabase<DBSchema> | any;
|
||||
dbTableName: string | any;
|
||||
|
||||
constructor(dbPromise: IDBPDatabase<DBSchema> | any, dbTableName: string | any) {
|
||||
this.dbPromise = dbPromise;
|
||||
this.dbTableName = dbTableName;
|
||||
}
|
||||
|
||||
async create(payload: IndexedDbValueEntity): Promise<void> {
|
||||
const id = StorageActiveAccount.get();
|
||||
const dataIsExist = await this.get();
|
||||
if (!dataIsExist && id) {
|
||||
const d = encryptData(JSON.stringify(payload));
|
||||
const item = { id, d };
|
||||
|
||||
const db = await this.dbPromise;
|
||||
const tx = db?.transaction(this.dbTableName, 'readwrite');
|
||||
const store = tx?.objectStore(this.dbTableName);
|
||||
|
||||
await store?.add(item);
|
||||
} else {
|
||||
this.update(payload);
|
||||
}
|
||||
}
|
||||
|
||||
async get(): Promise<IndexedDbValueEntity> {
|
||||
const id = StorageActiveAccount.get();
|
||||
if (!id) return undefined;
|
||||
|
||||
const db = await this.dbPromise;
|
||||
const tx = db.transaction(this.dbTableName, 'readwrite');
|
||||
const store = tx.objectStore(this.dbTableName);
|
||||
const result = await store.get(id);
|
||||
|
||||
if (!result) return undefined;
|
||||
|
||||
const d = JSON.parse(decryptData(result.d));
|
||||
return d;
|
||||
}
|
||||
|
||||
async getAll(): Promise<IndexedDbValueEntity> {
|
||||
const db = await this.dbPromise;
|
||||
const tx = db.transaction(this.dbTableName, 'readwrite');
|
||||
const store = tx.objectStore(this.dbTableName);
|
||||
const result = await store.getAll();
|
||||
|
||||
if (!result) return undefined;
|
||||
|
||||
const newResult = result.map((item: any) => {
|
||||
return {
|
||||
...item,
|
||||
d: JSON.parse(decryptData(item.d)),
|
||||
};
|
||||
});
|
||||
|
||||
return newResult;
|
||||
}
|
||||
|
||||
async update(payload: IndexedDbValueEntity): Promise<void> {
|
||||
const id = StorageActiveAccount.get();
|
||||
|
||||
if (id) {
|
||||
const d = encryptData(JSON.stringify(payload));
|
||||
const item = { id, d };
|
||||
|
||||
const db = await this.dbPromise;
|
||||
const tx = db.transaction(this.dbTableName, 'readwrite');
|
||||
const store = tx.objectStore(this.dbTableName);
|
||||
|
||||
await store.put(item);
|
||||
}
|
||||
}
|
||||
|
||||
async delete(): Promise<void> {
|
||||
const id = StorageActiveAccount.get();
|
||||
|
||||
if (id) {
|
||||
const db = await this.dbPromise;
|
||||
const tx = db.transaction(this.dbTableName, 'readwrite');
|
||||
const store = tx.objectStore(this.dbTableName);
|
||||
await store.delete(id);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
import { decryptData, encryptData } from '@pos/base';
|
||||
import { ILocalStorageStorage, LSSetItemEntity } from './storage.interface';
|
||||
|
||||
export class LocalStorageService implements ILocalStorageStorage {
|
||||
storageKey?: string;
|
||||
constructor(storageKey?: string) {
|
||||
this.storageKey = storageKey;
|
||||
}
|
||||
|
||||
create(payload: LSSetItemEntity): void {
|
||||
const keyData = this.storageKey ?? payload.key;
|
||||
if (keyData && payload.value) {
|
||||
const value = encryptData(JSON.stringify(payload.value));
|
||||
localStorage.setItem(keyData, value);
|
||||
}
|
||||
}
|
||||
|
||||
get(key?: string): string | null | undefined {
|
||||
const keyData = this.storageKey ?? key;
|
||||
if (keyData) {
|
||||
const value = localStorage.getItem(keyData);
|
||||
if (value) return JSON.parse(decryptData(value));
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
delete(key?: string): void {
|
||||
const keyData = this.storageKey ?? key;
|
||||
if (keyData) localStorage.removeItem(keyData);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
export interface IIndexedDbService<E> {
|
||||
create(payload: E): Promise<void>;
|
||||
get(): Promise<E>;
|
||||
getAll(): Promise<E[]>;
|
||||
update(payload: E): Promise<void>;
|
||||
delete(): Promise<void>;
|
||||
}
|
||||
|
||||
export interface LSSetItemEntity {
|
||||
key?: string;
|
||||
value: string;
|
||||
}
|
||||
|
||||
export interface ILocalStorageStorage {
|
||||
create(payload: LSSetItemEntity): void;
|
||||
get(key: string): string | null | undefined;
|
||||
delete(key: string): void;
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
export const IDB_NAME = 'pos__gen__conf';
|
||||
export const IDB_T_NAME__USER_DATA = 'pos__Wl9Yf85G';
|
||||
export const IDB_T_NAME__ACCESS_TOKEN = 'pos__vRtgHurGCD';
|
||||
export const IDB_T_NAME__PRIVILEGE = 'pos__AzyMJGe21c';
|
||||
|
||||
export const LS_ACTIVE_ACCOUNT = 'pos__acc__log';
|
||||
export const LS_DEFAULT_URL = 'pros__deft_u';
|
|
@ -0,0 +1,544 @@
|
|||
import { IBaseDataServicesRepository } from '../../domain/repositories';
|
||||
import {
|
||||
DataServicesConstructorEntity,
|
||||
ResponseEntity,
|
||||
ApiURLEntity,
|
||||
RequestMethodEntity,
|
||||
ManagerParamsEntity,
|
||||
BaseEntity,
|
||||
} from '../../domain/entities';
|
||||
|
||||
import { DEFAULT_METHOD, REQUEST_ACTION } from '../../infrastructure/constants';
|
||||
import axios, { AxiosResponse } from 'axios';
|
||||
|
||||
export abstract class BaseRemoteDataServices<E extends BaseEntity = BaseEntity> implements IBaseDataServicesRepository {
|
||||
protected baseUrl?: string;
|
||||
protected URLs: ApiURLEntity;
|
||||
protected methods: RequestMethodEntity;
|
||||
protected moduleKey: string | undefined;
|
||||
|
||||
constructor(params: DataServicesConstructorEntity) {
|
||||
const moduleKeyEncrypt = params.moduleKey;
|
||||
|
||||
this.moduleKey = moduleKeyEncrypt;
|
||||
|
||||
this.baseUrl = params.baseUrl;
|
||||
this.URLs = {
|
||||
...(this.makeDefaultURL(params.apiUrl ?? '') ?? {}),
|
||||
...(params.urls ?? {}),
|
||||
};
|
||||
this.methods = {
|
||||
...(DEFAULT_METHOD ?? {}),
|
||||
...(params.requestMethods ?? {}),
|
||||
};
|
||||
}
|
||||
|
||||
protected makeApiUrl(variable = {} as any, url = '' as string): string {
|
||||
return url
|
||||
.split('/')
|
||||
.map((item: string) => {
|
||||
if (item.includes(':')) return variable[item.slice(1)];
|
||||
return item;
|
||||
})
|
||||
.join('/');
|
||||
}
|
||||
|
||||
protected makeIds(payload: E[]): string[] {
|
||||
const ids: string[] = [];
|
||||
for (const entity of payload) {
|
||||
if (entity.id) ids.push(entity.id.toString());
|
||||
}
|
||||
return ids;
|
||||
}
|
||||
|
||||
protected makeId(payload: E): string {
|
||||
if (payload.id) return payload.id;
|
||||
return '';
|
||||
}
|
||||
|
||||
protected makeHeader(action: string) {
|
||||
return {
|
||||
'ex-model-key': this.moduleKey,
|
||||
'ex-model-action': action,
|
||||
};
|
||||
}
|
||||
|
||||
protected makeDefaultURL(apiUrl: string): ApiURLEntity {
|
||||
return {
|
||||
getManyUrl: `${apiUrl}`,
|
||||
getOneUrl: `${apiUrl}/:id`,
|
||||
createUrl: `${apiUrl}`,
|
||||
editUrl: `${apiUrl}/:id`,
|
||||
|
||||
deleteUrl: `${apiUrl}/:id`,
|
||||
batchDeleteUrl: `${apiUrl}/batch-delete`,
|
||||
|
||||
activateUrl: `${apiUrl}/:id/active`,
|
||||
batchActivateUrl: `${apiUrl}/batch-active`,
|
||||
|
||||
deactivateUrl: `${apiUrl}/:id/inactive`,
|
||||
batchDeactivateUrl: `${apiUrl}/batch-inactive`,
|
||||
|
||||
confirmProcessDataUrl: `${apiUrl}/:id/confirm`,
|
||||
batchConfirmProcessDataUrl: `${apiUrl}/batch-confirm`,
|
||||
|
||||
cancelProcessDataUrl: `${apiUrl}/:id/cancel`,
|
||||
batchCancelProcessDataUrl: `${apiUrl}/batch-cancel`,
|
||||
|
||||
confirmProcessTransactionUrl: `${apiUrl}/:id/confirm-data`,
|
||||
batchConfirmProcessTransactionUrl: `${apiUrl}/batch-confirm-data`,
|
||||
|
||||
cancelProcessTransactionUrl: `${apiUrl}/:id/cancel`,
|
||||
batchCancelProcessTransactionUrl: `${apiUrl}/batch-cancel`,
|
||||
|
||||
rollbackProcessTransactionUrl: `${apiUrl}/:id/confirm-rollback`,
|
||||
batchRollbackProcessTransactionUrl: `${apiUrl}/batch-confirm-rollback`,
|
||||
|
||||
holdProcessTransactionUrl: `${apiUrl}/:id/confirm-hold`,
|
||||
batchHoldProcessTransactionUrl: `${apiUrl}/batch-confirm-hold`,
|
||||
};
|
||||
}
|
||||
|
||||
//custom request
|
||||
async handleCustomRequest(manager: ManagerParamsEntity): Promise<void> {
|
||||
try {
|
||||
const response: AxiosResponse = await axios.request({
|
||||
...(manager.config ?? {}),
|
||||
baseURL: this.baseUrl,
|
||||
params: {
|
||||
...(manager?.config?.params ?? {}),
|
||||
},
|
||||
});
|
||||
|
||||
if (manager.onSuccess) manager.onSuccess(response as ResponseEntity);
|
||||
} catch (error) {
|
||||
if (manager.onFailed) manager.onFailed(error as ResponseEntity);
|
||||
}
|
||||
}
|
||||
|
||||
async handleGetOne(manager: ManagerParamsEntity): Promise<void> {
|
||||
try {
|
||||
const response: AxiosResponse = await axios.request({
|
||||
baseURL: this.baseUrl,
|
||||
url: this.makeApiUrl(manager.variableURL, this.URLs.getOneUrl),
|
||||
method: this.methods.getOneMethod,
|
||||
...(manager.config ?? {}),
|
||||
headers: this.makeHeader(REQUEST_ACTION.VIEW),
|
||||
});
|
||||
|
||||
if (manager.onSuccess) manager.onSuccess(response as ResponseEntity);
|
||||
} catch (error) {
|
||||
if (manager.onFailed) manager.onFailed(error as ResponseEntity);
|
||||
}
|
||||
}
|
||||
|
||||
async handleGetMany(manager: ManagerParamsEntity): Promise<void> {
|
||||
try {
|
||||
const response: AxiosResponse = await axios.request({
|
||||
baseURL: this.baseUrl,
|
||||
url: this.makeApiUrl(manager.variableURL, this.URLs.getManyUrl),
|
||||
method: this.methods.getManyMethod,
|
||||
...(manager.config ?? {}),
|
||||
params: {
|
||||
...(manager?.config?.params ?? {}),
|
||||
},
|
||||
headers: { ...this.makeHeader(REQUEST_ACTION.VIEW), ...(manager?.config?.headers ?? {}) },
|
||||
});
|
||||
|
||||
if (manager.onSuccess) manager.onSuccess(response as ResponseEntity);
|
||||
} catch (error) {
|
||||
if (manager.onFailed) manager.onFailed(error as ResponseEntity);
|
||||
}
|
||||
}
|
||||
|
||||
async handleCreate(manager: ManagerParamsEntity): Promise<void> {
|
||||
try {
|
||||
const response: AxiosResponse = await axios.request({
|
||||
baseURL: this.baseUrl,
|
||||
url: this.makeApiUrl(manager.variableURL, this.URLs.createUrl),
|
||||
method: this.methods.createMethod,
|
||||
// headers: HeaderPost,
|
||||
...(manager.config ?? {}),
|
||||
params: {
|
||||
...(manager?.config?.params ?? {}),
|
||||
},
|
||||
headers: this.makeHeader(REQUEST_ACTION.CREATE),
|
||||
});
|
||||
|
||||
if (manager.onSuccess) manager.onSuccess(response as ResponseEntity);
|
||||
} catch (error) {
|
||||
if (manager.onFailed) manager.onFailed(error as ResponseEntity);
|
||||
}
|
||||
}
|
||||
|
||||
async handleEdit(manager: ManagerParamsEntity): Promise<void> {
|
||||
try {
|
||||
const response: AxiosResponse = await axios.request({
|
||||
baseURL: this.baseUrl,
|
||||
url: this.makeApiUrl(manager.variableURL, this.URLs.editUrl),
|
||||
method: this.methods.editMethod,
|
||||
// headers: HeaderPost,
|
||||
...(manager.config ?? {}),
|
||||
params: {
|
||||
...(manager?.config?.params ?? {}),
|
||||
},
|
||||
headers: this.makeHeader(REQUEST_ACTION.EDIT),
|
||||
});
|
||||
|
||||
if (manager.onSuccess) manager.onSuccess(response as ResponseEntity);
|
||||
} catch (error) {
|
||||
if (manager.onFailed) manager.onFailed(error as ResponseEntity);
|
||||
}
|
||||
}
|
||||
|
||||
async handleDelete(manager: ManagerParamsEntity): Promise<void> {
|
||||
try {
|
||||
const response: AxiosResponse = await axios.request({
|
||||
baseURL: this.baseUrl,
|
||||
url: this.makeApiUrl(manager.variableURL, this.URLs.deleteUrl),
|
||||
method: this.methods.deleteMethod,
|
||||
...(manager.config ?? {}),
|
||||
params: {
|
||||
...(manager?.config?.params ?? {}),
|
||||
},
|
||||
headers: this.makeHeader(REQUEST_ACTION.DELETE),
|
||||
});
|
||||
|
||||
if (manager.onSuccess) manager.onSuccess(response as ResponseEntity);
|
||||
} catch (error) {
|
||||
if (manager.onFailed) manager.onFailed(error as ResponseEntity);
|
||||
}
|
||||
}
|
||||
|
||||
async handleBatchDelete(manager: ManagerParamsEntity): Promise<void> {
|
||||
try {
|
||||
const response: AxiosResponse = await axios.request({
|
||||
baseURL: this.baseUrl,
|
||||
url: this.makeApiUrl(manager.variableURL, this.URLs.batchDeleteUrl),
|
||||
method: this.methods.batchDeleteMethod,
|
||||
// data: { ids: this.makeIds(manager.config?.data) },
|
||||
...(manager.config ?? {}),
|
||||
params: {
|
||||
...(manager?.config?.params ?? {}),
|
||||
},
|
||||
headers: this.makeHeader(REQUEST_ACTION.DELETE),
|
||||
});
|
||||
|
||||
if (manager.onSuccess) manager.onSuccess(response as ResponseEntity);
|
||||
} catch (error) {
|
||||
if (manager.onFailed) manager.onFailed(error as ResponseEntity);
|
||||
}
|
||||
}
|
||||
|
||||
async handleConfirmProcessData(manager: ManagerParamsEntity): Promise<void> {
|
||||
try {
|
||||
const response: AxiosResponse = await axios.request({
|
||||
baseURL: this.baseUrl,
|
||||
url: this.makeApiUrl(manager.variableURL, this.URLs.confirmProcessDataUrl),
|
||||
method: this.methods.confirmProcessDataMethod,
|
||||
...(manager.config ?? {}),
|
||||
params: {
|
||||
...(manager?.config?.params ?? {}),
|
||||
},
|
||||
headers: this.makeHeader(REQUEST_ACTION.CONFIRM_DATA),
|
||||
});
|
||||
|
||||
if (manager.onSuccess) manager.onSuccess(response as ResponseEntity);
|
||||
} catch (error) {
|
||||
if (manager.onFailed) manager.onFailed(error as ResponseEntity);
|
||||
}
|
||||
}
|
||||
|
||||
async handleBatchConfirmProcessData(manager: ManagerParamsEntity): Promise<void> {
|
||||
try {
|
||||
const response: AxiosResponse = await axios.request({
|
||||
baseURL: this.baseUrl,
|
||||
url: this.makeApiUrl(manager.variableURL, this.URLs.batchConfirmProcessDataUrl),
|
||||
method: this.methods.batchConfirmProcessDataMethod,
|
||||
// data: { ids: this.makeIds(manager.config?.data) },
|
||||
...(manager.config ?? {}),
|
||||
params: {
|
||||
...(manager?.config?.params ?? {}),
|
||||
},
|
||||
headers: this.makeHeader(REQUEST_ACTION.CONFIRM_DATA),
|
||||
});
|
||||
|
||||
if (manager.onSuccess) manager.onSuccess(response as ResponseEntity);
|
||||
} catch (error) {
|
||||
if (manager.onFailed) manager.onFailed(error as ResponseEntity);
|
||||
}
|
||||
}
|
||||
|
||||
async handleCancelProcessData(manager: ManagerParamsEntity): Promise<void> {
|
||||
try {
|
||||
const response: AxiosResponse = await axios.request({
|
||||
baseURL: this.baseUrl,
|
||||
url: this.makeApiUrl(manager.variableURL, this.URLs.cancelProcessDataUrl),
|
||||
method: this.methods.cancelProcessDataMethod,
|
||||
...(manager.config ?? {}),
|
||||
params: {
|
||||
...(manager?.config?.params ?? {}),
|
||||
},
|
||||
headers: this.makeHeader(REQUEST_ACTION.CANCEL_DATA),
|
||||
});
|
||||
|
||||
if (manager.onSuccess) manager.onSuccess(response as ResponseEntity);
|
||||
} catch (error) {
|
||||
if (manager.onFailed) manager.onFailed(error as ResponseEntity);
|
||||
}
|
||||
}
|
||||
|
||||
async handleBatchCancelProcessData(manager: ManagerParamsEntity): Promise<void> {
|
||||
try {
|
||||
const response: AxiosResponse = await axios.request({
|
||||
baseURL: this.baseUrl,
|
||||
url: this.makeApiUrl(manager.variableURL, this.URLs.batchCancelProcessDataUrl),
|
||||
method: this.methods.batchCancelProcessDataMethod,
|
||||
// data: { ids: this.makeIds(manager.config?.data) },
|
||||
...(manager.config ?? {}),
|
||||
params: {
|
||||
...(manager?.config?.params ?? {}),
|
||||
},
|
||||
headers: this.makeHeader(REQUEST_ACTION.CANCEL_DATA),
|
||||
});
|
||||
|
||||
if (manager.onSuccess) manager.onSuccess(response as ResponseEntity);
|
||||
} catch (error) {
|
||||
if (manager.onFailed) manager.onFailed(error as ResponseEntity);
|
||||
}
|
||||
}
|
||||
|
||||
async handleActivate(manager: ManagerParamsEntity): Promise<void> {
|
||||
try {
|
||||
const response: AxiosResponse = await axios.request({
|
||||
baseURL: this.baseUrl,
|
||||
url: this.makeApiUrl(manager.variableURL, this.URLs.activateUrl),
|
||||
method: this.methods.activateMethod,
|
||||
...(manager.config ?? {}),
|
||||
params: {
|
||||
...(manager?.config?.params ?? {}),
|
||||
},
|
||||
headers: this.makeHeader(REQUEST_ACTION.CONFIRM_DATA),
|
||||
});
|
||||
|
||||
if (manager.onSuccess) manager.onSuccess(response as ResponseEntity);
|
||||
} catch (error) {
|
||||
if (manager.onFailed) manager.onFailed(error as ResponseEntity);
|
||||
}
|
||||
}
|
||||
|
||||
async handleBatchActivate(manager: ManagerParamsEntity): Promise<void> {
|
||||
try {
|
||||
const response: AxiosResponse = await axios.request({
|
||||
baseURL: this.baseUrl,
|
||||
url: this.makeApiUrl(manager.variableURL, this.URLs.batchActivateUrl),
|
||||
method: this.methods.batchActivateMethod,
|
||||
// data: { ids: this.makeIds(manager.config?.data) },
|
||||
...(manager.config ?? {}),
|
||||
params: {
|
||||
...(manager?.config?.params ?? {}),
|
||||
},
|
||||
headers: this.makeHeader(REQUEST_ACTION.CONFIRM_DATA),
|
||||
});
|
||||
|
||||
if (manager.onSuccess) manager.onSuccess(response as ResponseEntity);
|
||||
} catch (error) {
|
||||
if (manager.onFailed) manager.onFailed(error as ResponseEntity);
|
||||
}
|
||||
}
|
||||
|
||||
async handleDeactivate(manager: ManagerParamsEntity): Promise<void> {
|
||||
try {
|
||||
const response: AxiosResponse = await axios.request({
|
||||
baseURL: this.baseUrl,
|
||||
url: this.makeApiUrl(manager.variableURL, this.URLs.deactivateUrl),
|
||||
method: this.methods.deactivateMethod,
|
||||
...(manager.config ?? {}),
|
||||
params: {
|
||||
...(manager?.config?.params ?? {}),
|
||||
},
|
||||
headers: this.makeHeader(REQUEST_ACTION.CONFIRM_DATA),
|
||||
});
|
||||
|
||||
if (manager.onSuccess) manager.onSuccess(response as ResponseEntity);
|
||||
} catch (error) {
|
||||
if (manager.onFailed) manager.onFailed(error as ResponseEntity);
|
||||
}
|
||||
}
|
||||
|
||||
async handleBatchDeactivate(manager: ManagerParamsEntity): Promise<void> {
|
||||
try {
|
||||
const response: AxiosResponse = await axios.request({
|
||||
baseURL: this.baseUrl,
|
||||
url: this.makeApiUrl(manager.variableURL, this.URLs.batchDeactivateUrl),
|
||||
method: this.methods.batchDeactivateMethod,
|
||||
// data: { ids: this.makeIds(manager.config?.data) },
|
||||
...(manager.config ?? {}),
|
||||
params: {
|
||||
...(manager?.config?.params ?? {}),
|
||||
},
|
||||
headers: this.makeHeader(REQUEST_ACTION.CONFIRM_DATA),
|
||||
});
|
||||
|
||||
if (manager.onSuccess) manager.onSuccess(response as ResponseEntity);
|
||||
} catch (error) {
|
||||
if (manager.onFailed) manager.onFailed(error as ResponseEntity);
|
||||
}
|
||||
}
|
||||
|
||||
async handleConfirmProcessTransaction(manager: ManagerParamsEntity): Promise<void> {
|
||||
try {
|
||||
const response: AxiosResponse = await axios.request({
|
||||
baseURL: this.baseUrl,
|
||||
url: this.makeApiUrl(manager.variableURL, this.URLs.confirmProcessTransactionUrl),
|
||||
method: this.methods.confirmProcessTransactionMethod,
|
||||
...(manager.config ?? {}),
|
||||
params: {
|
||||
...(manager?.config?.params ?? {}),
|
||||
},
|
||||
headers: this.makeHeader(REQUEST_ACTION.CONFIRM_PROCESS_TRANSACTION),
|
||||
});
|
||||
|
||||
if (manager.onSuccess) manager.onSuccess(response as ResponseEntity);
|
||||
} catch (error) {
|
||||
if (manager.onFailed) manager.onFailed(error as ResponseEntity);
|
||||
}
|
||||
}
|
||||
|
||||
async handleBatchConfirmProcessTransaction(manager: ManagerParamsEntity): Promise<void> {
|
||||
try {
|
||||
const response: AxiosResponse = await axios.request({
|
||||
baseURL: this.baseUrl,
|
||||
url: this.makeApiUrl(manager.variableURL, this.URLs.batchConfirmProcessTransactionUrl),
|
||||
method: this.methods.batchConfirmProcessTransactionMethod,
|
||||
// data: { ids: this.makeIds(manager.config?.data) },
|
||||
...(manager.config ?? {}),
|
||||
params: {
|
||||
...(manager?.config?.params ?? {}),
|
||||
},
|
||||
headers: this.makeHeader(REQUEST_ACTION.CONFIRM_PROCESS_TRANSACTION),
|
||||
});
|
||||
|
||||
if (manager.onSuccess) manager.onSuccess(response as ResponseEntity);
|
||||
} catch (error) {
|
||||
if (manager.onFailed) manager.onFailed(error as ResponseEntity);
|
||||
}
|
||||
}
|
||||
|
||||
async handleCancelProcessTransaction(manager: ManagerParamsEntity): Promise<void> {
|
||||
try {
|
||||
const response: AxiosResponse = await axios.request({
|
||||
baseURL: this.baseUrl,
|
||||
url: this.makeApiUrl(manager.variableURL, this.URLs.cancelProcessTransactionUrl),
|
||||
method: this.methods.cancelProcessTransactionMethod,
|
||||
...(manager.config ?? {}),
|
||||
params: {
|
||||
...(manager?.config?.params ?? {}),
|
||||
},
|
||||
headers: this.makeHeader(REQUEST_ACTION.CANCEL_PROCESS_TRANSACTION),
|
||||
});
|
||||
|
||||
if (manager.onSuccess) manager.onSuccess(response as ResponseEntity);
|
||||
} catch (error) {
|
||||
if (manager.onFailed) manager.onFailed(error as ResponseEntity);
|
||||
}
|
||||
}
|
||||
|
||||
async handleBatchCancelProcessTransaction(manager: ManagerParamsEntity): Promise<void> {
|
||||
try {
|
||||
const response: AxiosResponse = await axios.request({
|
||||
baseURL: this.baseUrl,
|
||||
url: this.makeApiUrl(manager.variableURL, this.URLs.batchCancelProcessTransactionUrl),
|
||||
method: this.methods.batchCancelProcessTransactionMethod,
|
||||
// data: { ids: this.makeIds(manager.config?.data) },
|
||||
...(manager.config ?? {}),
|
||||
params: {
|
||||
...(manager?.config?.params ?? {}),
|
||||
},
|
||||
headers: this.makeHeader(REQUEST_ACTION.CANCEL_PROCESS_TRANSACTION),
|
||||
});
|
||||
|
||||
if (manager.onSuccess) manager.onSuccess(response as ResponseEntity);
|
||||
} catch (error) {
|
||||
if (manager.onFailed) manager.onFailed(error as ResponseEntity);
|
||||
}
|
||||
}
|
||||
|
||||
async handleRollbackProcessTransaction(manager: ManagerParamsEntity): Promise<void> {
|
||||
try {
|
||||
const response: AxiosResponse = await axios.request({
|
||||
baseURL: this.baseUrl,
|
||||
url: this.makeApiUrl(manager.variableURL, this.URLs.rollbackProcessTransactionUrl),
|
||||
method: this.methods.rollbackProcessTransactionMethod,
|
||||
...(manager.config ?? {}),
|
||||
params: {
|
||||
...(manager?.config?.params ?? {}),
|
||||
},
|
||||
headers: this.makeHeader(REQUEST_ACTION.CONFIRM_PROCESS_TRANSACTION),
|
||||
});
|
||||
|
||||
if (manager.onSuccess) manager.onSuccess(response as ResponseEntity);
|
||||
} catch (error) {
|
||||
if (manager.onFailed) manager.onFailed(error as ResponseEntity);
|
||||
}
|
||||
}
|
||||
|
||||
async handleBatchRollbackProcessTransaction(manager: ManagerParamsEntity): Promise<void> {
|
||||
try {
|
||||
const response: AxiosResponse = await axios.request({
|
||||
baseURL: this.baseUrl,
|
||||
url: this.makeApiUrl(manager.variableURL, this.URLs.batchRollbackProcessTransactionUrl),
|
||||
method: this.methods.batchRollbackProcessTransactionMethod,
|
||||
// data: { ids: this.makeIds(manager.config?.data) },
|
||||
...(manager.config ?? {}),
|
||||
params: {
|
||||
...(manager?.config?.params ?? {}),
|
||||
},
|
||||
headers: this.makeHeader(REQUEST_ACTION.CONFIRM_PROCESS_TRANSACTION),
|
||||
});
|
||||
|
||||
if (manager.onSuccess) manager.onSuccess(response as ResponseEntity);
|
||||
} catch (error) {
|
||||
if (manager.onFailed) manager.onFailed(error as ResponseEntity);
|
||||
}
|
||||
}
|
||||
|
||||
async handleHoldProcessTransaction(manager: ManagerParamsEntity): Promise<void> {
|
||||
try {
|
||||
const response: AxiosResponse = await axios.request({
|
||||
baseURL: this.baseUrl,
|
||||
url: this.makeApiUrl(manager.variableURL, this.URLs.holdProcessTransactionUrl),
|
||||
method: this.methods.holdProcessTransactionMethod,
|
||||
...(manager.config ?? {}),
|
||||
params: {
|
||||
action: REQUEST_ACTION.CONFIRM_PROCESS_TRANSACTION,
|
||||
...(manager?.config?.params ?? {}),
|
||||
},
|
||||
});
|
||||
|
||||
if (manager.onSuccess) manager.onSuccess(response as ResponseEntity);
|
||||
} catch (error) {
|
||||
if (manager.onFailed) manager.onFailed(error as ResponseEntity);
|
||||
}
|
||||
}
|
||||
|
||||
async handleBatchHoldProcessTransaction(manager: ManagerParamsEntity): Promise<void> {
|
||||
try {
|
||||
const response: AxiosResponse = await axios.request({
|
||||
baseURL: this.baseUrl,
|
||||
url: this.makeApiUrl(manager.variableURL, this.URLs.batchHoldProcessTransactionUrl),
|
||||
method: this.methods.batchHoldProcessTransactionMethod,
|
||||
// data: { ids: this.makeIds(manager.config?.data) },
|
||||
...(manager.config ?? {}),
|
||||
params: {
|
||||
action: REQUEST_ACTION.CONFIRM_PROCESS_TRANSACTION,
|
||||
...(manager?.config?.params ?? {}),
|
||||
},
|
||||
});
|
||||
|
||||
if (manager.onSuccess) manager.onSuccess(response as ResponseEntity);
|
||||
} catch (error) {
|
||||
if (manager.onFailed) manager.onFailed(error as ResponseEntity);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
import { BaseEntity } from '../../domain/entities';
|
||||
import { BaseRemoteDataServices } from './base-remote.data-services';
|
||||
|
||||
export class CommonRemoteDataServices<E extends BaseEntity = BaseEntity> extends BaseRemoteDataServices<E> {}
|
|
@ -0,0 +1,2 @@
|
|||
export * from './base-remote.data-services';
|
||||
export * from './common-remote.data-services';
|
|
@ -0,0 +1,100 @@
|
|||
import { AxiosRequestConfig, Method as AxiosMethod } from 'axios';
|
||||
|
||||
export interface ResponseErrorEntity {
|
||||
message?: Error | string | string[];
|
||||
status: number;
|
||||
}
|
||||
|
||||
export interface ResponseSuccessEntity<T = any> {
|
||||
data?: T;
|
||||
status: number;
|
||||
}
|
||||
|
||||
export interface VariableURLEntity {
|
||||
[key: string]: string;
|
||||
}
|
||||
|
||||
export interface ManagerParamsEntity {
|
||||
config?: AxiosRequestConfig;
|
||||
variableURL?: VariableURLEntity;
|
||||
onFailed?(error: ResponseErrorEntity): void;
|
||||
onSuccess?(response: ResponseSuccessEntity): void;
|
||||
}
|
||||
|
||||
export type ResponseEntity = ResponseSuccessEntity | ResponseErrorEntity;
|
||||
|
||||
export interface ApiURLEntity {
|
||||
getManyUrl?: string;
|
||||
getOneUrl?: string;
|
||||
createUrl?: string;
|
||||
editUrl?: string;
|
||||
|
||||
deleteUrl?: string;
|
||||
batchDeleteUrl?: string;
|
||||
|
||||
confirmProcessDataUrl?: string;
|
||||
batchConfirmProcessDataUrl?: string;
|
||||
|
||||
cancelProcessDataUrl?: string;
|
||||
batchCancelProcessDataUrl?: string;
|
||||
|
||||
activateUrl?: string;
|
||||
batchActivateUrl?: string;
|
||||
|
||||
deactivateUrl?: string;
|
||||
batchDeactivateUrl?: string;
|
||||
|
||||
confirmProcessTransactionUrl?: string;
|
||||
batchConfirmProcessTransactionUrl?: string;
|
||||
|
||||
cancelProcessTransactionUrl?: string;
|
||||
batchCancelProcessTransactionUrl?: string;
|
||||
|
||||
rollbackProcessTransactionUrl?: string;
|
||||
batchRollbackProcessTransactionUrl?: string;
|
||||
|
||||
holdProcessTransactionUrl?: string;
|
||||
batchHoldProcessTransactionUrl?: string;
|
||||
}
|
||||
|
||||
export interface RequestMethodEntity {
|
||||
getManyMethod?: AxiosMethod;
|
||||
getOneMethod?: AxiosMethod;
|
||||
createMethod?: AxiosMethod;
|
||||
editMethod?: AxiosMethod;
|
||||
|
||||
deleteMethod?: AxiosMethod;
|
||||
batchDeleteMethod?: AxiosMethod;
|
||||
|
||||
confirmProcessDataMethod?: AxiosMethod;
|
||||
batchConfirmProcessDataMethod?: AxiosMethod;
|
||||
|
||||
cancelProcessDataMethod?: AxiosMethod;
|
||||
batchCancelProcessDataMethod?: AxiosMethod;
|
||||
|
||||
activateMethod?: AxiosMethod;
|
||||
batchActivateMethod?: AxiosMethod;
|
||||
|
||||
deactivateMethod?: AxiosMethod;
|
||||
batchDeactivateMethod?: AxiosMethod;
|
||||
|
||||
confirmProcessTransactionMethod?: AxiosMethod;
|
||||
batchConfirmProcessTransactionMethod?: AxiosMethod;
|
||||
|
||||
cancelProcessTransactionMethod?: AxiosMethod;
|
||||
batchCancelProcessTransactionMethod?: AxiosMethod;
|
||||
|
||||
rollbackProcessTransactionMethod?: AxiosMethod;
|
||||
batchRollbackProcessTransactionMethod?: AxiosMethod;
|
||||
|
||||
holdProcessTransactionMethod?: AxiosMethod;
|
||||
batchHoldProcessTransactionMethod?: AxiosMethod;
|
||||
}
|
||||
|
||||
export interface DataServicesConstructorEntity {
|
||||
baseUrl?: string;
|
||||
apiUrl?: string;
|
||||
urls?: ApiURLEntity;
|
||||
requestMethods?: RequestMethodEntity;
|
||||
moduleKey?: string;
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
export type FormPageActionEntity = 'create' | 'edit' | 'duplicate';
|
||||
|
||||
export interface BaseEntity {
|
||||
id?: string;
|
||||
[key: string]: any;
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
export * from './base-data-services.entity';
|
||||
export * from './base.entity';
|
|
@ -0,0 +1,7 @@
|
|||
import { CommonRemoteDataServices } from '@pos/base';
|
||||
import { IBaseDataServicesRepository } from '../repositories';
|
||||
import { DataServicesConstructorEntity } from '../entities';
|
||||
|
||||
export function makeCommonDataServices(params: DataServicesConstructorEntity): IBaseDataServicesRepository {
|
||||
return new CommonRemoteDataServices(params);
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
import { BaseEntity } from '../entities';
|
||||
import { CommonTransformer } from '../transformers';
|
||||
import { IBaseTransformerRepository } from '../repositories';
|
||||
|
||||
export function makeCommonTransformer<E extends BaseEntity = BaseEntity>(): IBaseTransformerRepository<E> {
|
||||
return new CommonTransformer<E>();
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
export * from './base-data-services.factory';
|
||||
export * from './base-transformer.factory';
|
|
@ -0,0 +1,49 @@
|
|||
import { ManagerParamsEntity } from '../entities';
|
||||
|
||||
export interface IBaseDataServicesRepository {
|
||||
handleCustomRequest(manager: ManagerParamsEntity): Promise<void>;
|
||||
|
||||
//get data
|
||||
handleGetOne(manager: ManagerParamsEntity): Promise<void>;
|
||||
handleGetMany(manager: ManagerParamsEntity): Promise<void>;
|
||||
|
||||
//create and edit
|
||||
handleCreate(manager: ManagerParamsEntity): Promise<void>;
|
||||
handleEdit(manager: ManagerParamsEntity): Promise<void>;
|
||||
|
||||
//delete
|
||||
handleDelete(manager: ManagerParamsEntity): Promise<void>;
|
||||
handleBatchDelete(manager: ManagerParamsEntity): Promise<void>;
|
||||
|
||||
//confirm process data
|
||||
handleConfirmProcessData(manager: ManagerParamsEntity): Promise<void>;
|
||||
handleBatchConfirmProcessData(manager: ManagerParamsEntity): Promise<void>;
|
||||
|
||||
//cancel data
|
||||
handleCancelProcessData(manager: ManagerParamsEntity): Promise<void>;
|
||||
handleBatchCancelProcessData(manager: ManagerParamsEntity): Promise<void>;
|
||||
|
||||
//activate
|
||||
handleActivate(manager: ManagerParamsEntity): Promise<void>;
|
||||
handleBatchActivate(manager: ManagerParamsEntity): Promise<void>;
|
||||
|
||||
//deactivate
|
||||
handleDeactivate(manager: ManagerParamsEntity): Promise<void>;
|
||||
handleBatchDeactivate(manager: ManagerParamsEntity): Promise<void>;
|
||||
|
||||
//confirm process transaction
|
||||
handleConfirmProcessTransaction(manager: ManagerParamsEntity): Promise<void>;
|
||||
handleBatchConfirmProcessTransaction(manager: ManagerParamsEntity): Promise<void>;
|
||||
|
||||
//confirm cancel transaction
|
||||
handleCancelProcessTransaction(manager: ManagerParamsEntity): Promise<void>;
|
||||
handleBatchCancelProcessTransaction(manager: ManagerParamsEntity): Promise<void>;
|
||||
|
||||
//confirm rollback transaction
|
||||
handleRollbackProcessTransaction(manager: ManagerParamsEntity): Promise<void>;
|
||||
handleBatchRollbackProcessTransaction(manager: ManagerParamsEntity): Promise<void>;
|
||||
|
||||
//confirm hold transaction
|
||||
handleHoldProcessTransaction(manager: ManagerParamsEntity): Promise<void>;
|
||||
handleBatchHoldProcessTransaction(manager: ManagerParamsEntity): Promise<void>;
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
import { BaseEntity } from '../entities';
|
||||
|
||||
export interface IBaseTransformerRepository<PayloadEntity extends BaseEntity = BaseEntity> {
|
||||
transformerGetList(payload: PayloadEntity[]): PayloadEntity[];
|
||||
transformerGetOne(payload: PayloadEntity): PayloadEntity;
|
||||
transformerCreate(payload: PayloadEntity): PayloadEntity;
|
||||
transformerEdit(payload: PayloadEntity): PayloadEntity;
|
||||
transformerDuplicate(payload: PayloadEntity): PayloadEntity;
|
||||
transformerFilterIndexTable(payload: any): any;
|
||||
transformerDefaultFilterIndexTable(payload: any): any;
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
export * from './base-services.repository';
|
||||
export * from './base-transformer.repository';
|
|
@ -0,0 +1,26 @@
|
|||
import { BaseEntity } from '../entities';
|
||||
import { IBaseTransformerRepository } from '../repositories';
|
||||
|
||||
export abstract class BaseTransformer<E extends BaseEntity = BaseEntity> implements IBaseTransformerRepository<E> {
|
||||
transformerGetList(payload: any): E[] {
|
||||
return payload;
|
||||
}
|
||||
transformerGetOne(payload: any): E {
|
||||
return payload;
|
||||
}
|
||||
transformerCreate(payload: any): E {
|
||||
return { ...payload, id: undefined };
|
||||
}
|
||||
transformerEdit(payload: any): E {
|
||||
return { ...payload, id: undefined };
|
||||
}
|
||||
transformerDuplicate(payload: any): E {
|
||||
return { ...payload, id: undefined };
|
||||
}
|
||||
transformerFilterIndexTable(payload: any): any {
|
||||
return payload;
|
||||
}
|
||||
transformerDefaultFilterIndexTable(payload: any): any {
|
||||
return payload;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
import { BaseEntity } from '../entities';
|
||||
import { BaseTransformer } from '../transformers';
|
||||
|
||||
export class CommonTransformer<PayloadEntity extends BaseEntity = BaseEntity> extends BaseTransformer<PayloadEntity> {}
|
|
@ -0,0 +1,2 @@
|
|||
export * from './base.transformer';
|
||||
export * from './common.transformer';
|
|
@ -0,0 +1,18 @@
|
|||
// Data
|
||||
export * from './data/local-data-services';
|
||||
export * from './data/remote-data-services';
|
||||
|
||||
// Domain
|
||||
export * from './domain/entities';
|
||||
export * from './domain/factories';
|
||||
export * from './domain/repositories';
|
||||
export * from './domain/transformers';
|
||||
|
||||
// Infrastructure
|
||||
export * from './infrastructure/constants';
|
||||
export * from './infrastructure/helpers';
|
||||
|
||||
// Presentations
|
||||
export * from './presentation/hooks';
|
||||
export * from './presentation/providers';
|
||||
export * from './presentation/states';
|
|
@ -0,0 +1,9 @@
|
|||
export const API_URL = {
|
||||
LOGIN: '/v1/auth',
|
||||
LOGOUT: '/v1/auth/logout',
|
||||
FORCE_LOGOUT: '/v1/auth/force-logout',
|
||||
|
||||
REPORT: '/v1/report',
|
||||
REPORT_TENANT: '/v1/report',
|
||||
REPORT_BOOKMARK: '/v1/report-bookmark',
|
||||
};
|
|
@ -0,0 +1,6 @@
|
|||
export enum AppSource {
|
||||
POS_ADMIN = 'POS_ADMIN',
|
||||
POS_COUNTER = 'POS_COUNTER',
|
||||
QUEUE_ADMIN = 'QUEUE_ADMIN',
|
||||
QUEUE_CUSTOMER = 'QUEUE_CUSTOMER',
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
export const APP_MODE: 'development' | 'production' = import.meta.env.VITE_APP_MODE;
|
||||
export const BASE_API_URL: string = import.meta.env.VITE_BASE_API_URL;
|
||||
export const BASE_ASSET_URL: string = import.meta.env.VITE_BASE_ASSET_URL;
|
||||
export const BASE_API_REPORT_URL: string = import.meta.env.VITE_BASE_API_REPORT_URL;
|
||||
export const SUPERSET_URL: string = import.meta.env.VITE_SUPERSET_URL;
|
||||
export const EMBED_DASHBOARD_ID = import.meta.env.VITE_EMBED_DASHBOARD_ID;
|
||||
|
||||
export const DOWLOAD_POS_WINDOWS_URL = import.meta.env.VITE_DOWLOAD_POS_WINDOWS_URL;
|
||||
export const DOWLOAD_POS_LINUX_DEB_URL = import.meta.env.VITE_DOWLOAD_POS_LINUX_DEB_URL;
|
||||
export const DOWLOAD_POS_LINUX_SNAP_URL = import.meta.env.VITE_DOWLOAD_POS_LINUX_SNAP_URL;
|
|
@ -0,0 +1,5 @@
|
|||
export const formatDate = 'DD/MM/YYYY';
|
||||
|
||||
export const formatTime = 'HH:mm';
|
||||
|
||||
export const formatDateTime = `${formatDate} ${formatTime}`;
|
|
@ -0,0 +1,14 @@
|
|||
export * from './environment';
|
||||
export * from './web-url';
|
||||
export * from './sidebar';
|
||||
export * from './module-key';
|
||||
export * from './page-action';
|
||||
export * from './request-action';
|
||||
export * from './request-info';
|
||||
export * from './request-method';
|
||||
export * from './status-data';
|
||||
export * from './api-url';
|
||||
export * from './query-params';
|
||||
export * from './privilege';
|
||||
export * from './format-date';
|
||||
export * from './app-source';
|
|
@ -0,0 +1,47 @@
|
|||
export * from './report-group.constant';
|
||||
|
||||
export const MODULE_KEY = {
|
||||
DASHBOARD: 'DASHBOARD',
|
||||
CALENDAR: 'CALENDAR',
|
||||
BOOKING: 'BOOKING',
|
||||
REFUND: 'REFUND',
|
||||
RECONCILIATION: 'RECONCILIATION',
|
||||
ITEM: {
|
||||
INDEX: 'ITEM',
|
||||
ITEM_ITEM_RATE: 'ITEM.ITEM_RATE',
|
||||
ITEM_ITEM: 'ITEM.ITEM',
|
||||
ITEM_ITEM_CATEGORY: 'ITEM.ITEM_CATEGORY',
|
||||
},
|
||||
SEASON: {
|
||||
INDEX: 'SEASON',
|
||||
SEASON_TYPE: 'SEASON.SEASON_TYPE',
|
||||
SEASON_PERIOD: 'SEASON.SEASON_PERIOD',
|
||||
},
|
||||
USER: {
|
||||
INDEX: 'USER',
|
||||
USER_USER: 'USER.USER',
|
||||
USER_USER_PRIVILEGE: 'USER.USER_PRIVILEGE',
|
||||
},
|
||||
TENANT: 'TENANT',
|
||||
CMS: {
|
||||
INDEX: 'WEB_INFORMATION',
|
||||
CMS_TERMS_AND_CONDITION: 'WEB_INFORMATION.TERMS_AND_CONDITION',
|
||||
CMS_FAQ: 'WEB_INFORMATION.FAQ',
|
||||
CMS_NEWS: 'WEB_INFORMATION.NEWS',
|
||||
CMS_BANNER: 'WEB_INFORMATION.BANNER',
|
||||
},
|
||||
SETTING: {
|
||||
INDEX: 'SETTING',
|
||||
SETTING_TAX: 'SETTING.TAX',
|
||||
SETTING_VIP_CATEGORY: 'SETTING.VIP_CATEGORY',
|
||||
SETTING_PAYMENT_METHOD: 'SETTING.PAYMENT_METHOD',
|
||||
SETTING_GATE: 'SETTING.GATE',
|
||||
SETTING_PROFIT_SHARE_FORMULA: 'SETTING.PROFIT_SHARE_FORMULA',
|
||||
SETTING_SALES_PRICE_FORMULA: 'SETTING.SALES_PRICE_FORMULA',
|
||||
SETTING_QR_SUPER_ADMIN: 'SETTING.QR_SUPER_ADMIN',
|
||||
},
|
||||
REPORT: { INDEX: 'REPORT', REPORT_TRANSACTION: 'REPORT.TRANSACTION', REPORT_TENANT: 'REPORT.TENANT' },
|
||||
REPORT_TENANT: 'REPORT_TENANT',
|
||||
DISCOUNT_CODE: 'DISCOUNT_CODE',
|
||||
DOWNLOAD_POS_APP: 'DOWNLOAD_POS_APP',
|
||||
};
|
|
@ -0,0 +1,4 @@
|
|||
export enum REPORT_GROUP {
|
||||
transaction_report = 'transaction_report',
|
||||
tenant_report = 'tenant_report',
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
export enum PAGE_ACTION {
|
||||
SAVE = 'create.save',
|
||||
DETAIL = 'view',
|
||||
|
||||
CREATE = 'create',
|
||||
EDIT = 'edit',
|
||||
DELETE = 'delete',
|
||||
DUPLICATE = 'create.duplicate',
|
||||
|
||||
PRINT = 'print',
|
||||
PRINT_COPY = 'print_copy',
|
||||
PRINT_PREVIEW = 'print_preview',
|
||||
RESET_PRINT_COUNT = 'reset_print_count',
|
||||
|
||||
APPROVAL_DATA = 'edit.approval_data',
|
||||
CONFIRM_DATA = 'confirm.confirm_data',
|
||||
CANCEL_DATA = 'cancel.cancel_data',
|
||||
ACTIVATE_DATA = 'edit.activate_data',
|
||||
DEACTIVATE_DATA = 'edit.deactivate_data',
|
||||
|
||||
CONFIRM_TRANSACTION = 'confirm.confirm_transaction',
|
||||
CANCEL_TRANSACTION = 'cancel.cancel_transaction',
|
||||
ROLLBACK_TRANSACTION = 'confirm.rollback_transaction',
|
||||
ON_HOLD_TRANSACTION = 'confirm.on_hold_transaction',
|
||||
|
||||
OPEN_DRAWER_FILTER = 'view.open_drawer_filter',
|
||||
|
||||
LOGS = 'log',
|
||||
NOTES = 'note',
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
export const defaultAppPrivilege = {
|
||||
view: true,
|
||||
create: true,
|
||||
edit: true,
|
||||
delete: true,
|
||||
cancel: true,
|
||||
confirm: true,
|
||||
};
|
|
@ -0,0 +1,16 @@
|
|||
export function makeArrayIds({ data, valueWhenNull }: { data: any; valueWhenNull?: string }): string[] {
|
||||
const ids = [];
|
||||
if (!data) {
|
||||
if (valueWhenNull) return [valueWhenNull];
|
||||
else return [];
|
||||
} else if (Array.isArray(data)) {
|
||||
data?.forEach((item) => {
|
||||
const id = item?.id ?? item?.uuid;
|
||||
if (item?.id) ids.push(id);
|
||||
});
|
||||
} else {
|
||||
const id = data?.id ?? data?.uuid;
|
||||
if (id) ids.push(id);
|
||||
}
|
||||
return ids;
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
export const REQUEST_ACTION = {
|
||||
VIEW: 'view',
|
||||
CREATE: 'create',
|
||||
EDIT: 'edit',
|
||||
DELETE: 'delete',
|
||||
|
||||
CONFIRM_DATA: 'edit',
|
||||
CANCEL_DATA: 'edit',
|
||||
ACTIVATE_DATA: 'edit',
|
||||
DEACTIVATE_DATA: 'edit',
|
||||
|
||||
CONFIRM_PROCESS_TRANSACTION: 'confirm',
|
||||
ROLLBACK_PROCESS_TRANSACTION: 'reverse',
|
||||
CANCEL_PROCESS_TRANSACTION: 'cancel',
|
||||
|
||||
PRINT: 'print',
|
||||
};
|
|
@ -0,0 +1,12 @@
|
|||
export const RequestInfoOptions = [
|
||||
{ label: 'Create Data', value: 'Create Data' },
|
||||
{ label: 'Edit Data', value: 'Edit Data' },
|
||||
{ label: 'Edit Active', value: 'Edit Active' },
|
||||
{ label: 'Edit Inactive', value: 'Edit Inactive' },
|
||||
{ label: 'Edit Data & Status Active', value: 'Edit Data & Status Active' },
|
||||
{ label: 'Edit Data & Status Inactive', value: 'Edit Data & Status Inactive' },
|
||||
{ label: 'Delete Data', value: 'Delete Data' },
|
||||
{ label: 'Process Transaction', value: 'Process Transaction' },
|
||||
{ label: 'Cancel Transaction', value: 'Cancel Transaction' },
|
||||
{ label: 'Rollback Transaction', value: 'Rollback Transaction' },
|
||||
];
|
|
@ -0,0 +1,43 @@
|
|||
import { RequestMethodEntity } from '../../../domain/entities';
|
||||
|
||||
export const DEFAULT_METHOD: RequestMethodEntity = {
|
||||
getManyMethod: 'GET',
|
||||
getOneMethod: 'GET',
|
||||
createMethod: 'POST',
|
||||
editMethod: 'PUT',
|
||||
|
||||
deleteMethod: 'DELETE',
|
||||
// batchDeleteMethod: 'DELETE',
|
||||
batchDeleteMethod: 'PUT',
|
||||
|
||||
activateMethod: 'PATCH',
|
||||
// activateMethod: 'PUT',
|
||||
batchActivateMethod: 'PUT',
|
||||
|
||||
deactivateMethod: 'PATCH',
|
||||
// deactivateMethod: 'PUT',
|
||||
batchDeactivateMethod: 'PUT',
|
||||
|
||||
confirmProcessDataMethod: 'PATCH',
|
||||
// confirmProcessDataMethod: 'PUT',
|
||||
batchConfirmProcessDataMethod: 'PUT',
|
||||
|
||||
cancelProcessDataMethod: 'PATCH',
|
||||
// cancelProcessDataMethod: 'PUT',
|
||||
batchCancelProcessDataMethod: 'PUT',
|
||||
|
||||
confirmProcessTransactionMethod: 'PATCH',
|
||||
// confirmProcessTransactionMethod: 'PUT',
|
||||
batchConfirmProcessTransactionMethod: 'PUT',
|
||||
|
||||
cancelProcessTransactionMethod: 'PATCH',
|
||||
// cancelProcessTransactionMethod: 'PUT',
|
||||
batchCancelProcessTransactionMethod: 'PUT',
|
||||
|
||||
rollbackProcessTransactionMethod: 'PATCH',
|
||||
// rollbackProcessTransactionMethod: 'PUT',
|
||||
batchRollbackProcessTransactionMethod: 'PUT',
|
||||
|
||||
holdProcessTransactionMethod: 'PUT',
|
||||
batchHoldProcessTransactionMethod: 'PUT',
|
||||
};
|
|
@ -0,0 +1 @@
|
|||
export const sideConf = { width: 230, collapsedWidth: 75 };
|
|
@ -0,0 +1,247 @@
|
|||
import { capitalizeEachWord } from '../../helpers';
|
||||
|
||||
export enum DATA_TYPE {
|
||||
REQUESTED = 'requested',
|
||||
ORIGINAL = 'original',
|
||||
}
|
||||
export enum STATUS_DATA {
|
||||
DRAFT = 'draft',
|
||||
ACTIVE = 'active',
|
||||
INACTIVE = 'inactive',
|
||||
REQUESTED = 'requested',
|
||||
OPEN = 'open',
|
||||
DECLINE = 'declined',
|
||||
DELETED = 'deleted',
|
||||
WAITING = 'waiting',
|
||||
CANCEL = 'cancel',
|
||||
DONE = 'done',
|
||||
IN_PROCESS = 'in_process',
|
||||
CLOSED = 'closed',
|
||||
TODO = 'todo',
|
||||
ON_HOLD = 'on_hold',
|
||||
BLOCKED = 'blocked',
|
||||
BLACKLIST = 'blacklist',
|
||||
PROBLEM = 'problem',
|
||||
POSTED = 'posted',
|
||||
PAID = 'paid',
|
||||
APPROVED = 'approved',
|
||||
PENDING = 'pending',
|
||||
REJECTED = 'rejected',
|
||||
SETTLED = 'settled',
|
||||
CONFIRMED = 'confirmed',
|
||||
PROCESS_REFUND = 'proses refund',
|
||||
PROCESS_REFUND_WAHANA = 'proses refund wahana',
|
||||
REFUNDED = 'refunded',
|
||||
PARTIAL_REFUND = 'partial refund',
|
||||
}
|
||||
|
||||
export enum STATUS_DATA_COLOR {
|
||||
// DRAFT = '#4A6785',
|
||||
// ACTIVE = '#00875a',
|
||||
// INACTIVE = '#cf1322',
|
||||
// REQUESTED = '#faad14',
|
||||
// OPEN = '#0052cc',
|
||||
// DECLINE = '#cf1322',
|
||||
// DELETED = '#cf1322',
|
||||
// WAITING = '#faad14',
|
||||
// CANCEL = '#cf1322',
|
||||
// DONE = '#00875a',
|
||||
// IN_PROCESS = '#0052cc',
|
||||
// CLOSED = '#cf1322',
|
||||
// TODO = '#4A6785',
|
||||
// ON_HOLD = '#4A6785',
|
||||
// BLOCKED = '#cf1322',
|
||||
// BLACKLIST = '#cf1322',
|
||||
|
||||
DRAFT = '#95A5A6',
|
||||
ACTIVE = '#3EBD93',
|
||||
INACTIVE = '#E74C3C',
|
||||
REQUESTED = '#F39C12',
|
||||
OPEN = '#6F7CBA',
|
||||
DECLINE = '#B71C1C',
|
||||
DELETED = '#FF5252',
|
||||
WAITING = '#6c5dd0',
|
||||
CANCEL = '#9B59B6',
|
||||
// CANCEL = '#FF5252',
|
||||
// DONE = '#27AE60',
|
||||
DONE = '#3EBD93',
|
||||
IN_PROCESS = '#3498DB',
|
||||
// CLOSED = '#8E44AD',
|
||||
CLOSED = '#FF5252',
|
||||
// TODO = '#95A5A6',
|
||||
TODO = '#9B59B6',
|
||||
ON_HOLD = '#607D8B',
|
||||
BLOCKED = '#FF5722',
|
||||
BLACKLIST = '#D32F2F',
|
||||
PROBLEM = '#FF5722',
|
||||
POSTED = '#3EBD93',
|
||||
PAID = '#3EBD93',
|
||||
APPROVED = '#3EBD93',
|
||||
PENDING = '#d4940d',
|
||||
REJECTED = '#ef4444',
|
||||
SETTLED = '#5dadd0',
|
||||
CONFIRMED = '#5dadd0',
|
||||
PROCESS_REFUND = '#d7a29a',
|
||||
REFUNDED = '#fe725e',
|
||||
}
|
||||
|
||||
export const STATUS_DATA_OPTIONS = [
|
||||
{
|
||||
label: capitalizeEachWord(STATUS_DATA.DRAFT.split('_').join(' ')),
|
||||
value: STATUS_DATA.DRAFT,
|
||||
color: STATUS_DATA_COLOR.DRAFT,
|
||||
},
|
||||
|
||||
{
|
||||
label: capitalizeEachWord(STATUS_DATA.ON_HOLD.split('_').join(' ')),
|
||||
value: STATUS_DATA.ON_HOLD,
|
||||
color: STATUS_DATA_COLOR.ON_HOLD,
|
||||
},
|
||||
|
||||
{
|
||||
label: capitalizeEachWord(STATUS_DATA.OPEN.split('_').join(' ')),
|
||||
value: STATUS_DATA.OPEN,
|
||||
color: STATUS_DATA_COLOR.OPEN,
|
||||
},
|
||||
|
||||
{
|
||||
label: capitalizeEachWord(STATUS_DATA.TODO.split('_').join(' ')),
|
||||
value: STATUS_DATA.TODO,
|
||||
color: STATUS_DATA_COLOR.TODO,
|
||||
},
|
||||
{
|
||||
label: capitalizeEachWord(STATUS_DATA.IN_PROCESS.split('_').join(' ')),
|
||||
value: STATUS_DATA.IN_PROCESS,
|
||||
color: STATUS_DATA_COLOR.IN_PROCESS,
|
||||
},
|
||||
{
|
||||
label: capitalizeEachWord(STATUS_DATA.WAITING.split('_').join(' ')),
|
||||
value: STATUS_DATA.WAITING,
|
||||
color: STATUS_DATA_COLOR.WAITING,
|
||||
},
|
||||
{
|
||||
label: capitalizeEachWord(STATUS_DATA.REQUESTED.split('_').join(' ')),
|
||||
value: STATUS_DATA.REQUESTED,
|
||||
color: STATUS_DATA_COLOR.REQUESTED,
|
||||
},
|
||||
{
|
||||
label: capitalizeEachWord(STATUS_DATA.BLOCKED.split('_').join(' ')),
|
||||
value: STATUS_DATA.BLOCKED,
|
||||
color: STATUS_DATA_COLOR.BLOCKED,
|
||||
},
|
||||
|
||||
{
|
||||
label: capitalizeEachWord(STATUS_DATA.PROBLEM.split('_').join(' ')),
|
||||
value: STATUS_DATA.PROBLEM,
|
||||
color: STATUS_DATA_COLOR.PROBLEM,
|
||||
},
|
||||
{
|
||||
label: capitalizeEachWord(STATUS_DATA.CANCEL.split('_').join(' ')),
|
||||
value: STATUS_DATA.CANCEL,
|
||||
color: STATUS_DATA_COLOR.CANCEL,
|
||||
},
|
||||
{
|
||||
label: capitalizeEachWord(STATUS_DATA.CLOSED.split('_').join(' ')),
|
||||
value: STATUS_DATA.CLOSED,
|
||||
color: STATUS_DATA_COLOR.CLOSED,
|
||||
},
|
||||
{
|
||||
label: capitalizeEachWord(STATUS_DATA.DELETED.split('_').join(' ')),
|
||||
value: STATUS_DATA.DELETED,
|
||||
color: STATUS_DATA_COLOR.DELETED,
|
||||
},
|
||||
|
||||
{
|
||||
label: capitalizeEachWord(STATUS_DATA.INACTIVE.split('_').join(' ')),
|
||||
value: STATUS_DATA.INACTIVE,
|
||||
color: STATUS_DATA_COLOR.INACTIVE,
|
||||
},
|
||||
|
||||
{
|
||||
label: capitalizeEachWord(STATUS_DATA.BLACKLIST.split('_').join(' ')),
|
||||
value: STATUS_DATA.BLACKLIST,
|
||||
color: STATUS_DATA_COLOR.BLACKLIST,
|
||||
},
|
||||
{
|
||||
label: capitalizeEachWord(STATUS_DATA.DECLINE.split('_').join(' ')),
|
||||
value: STATUS_DATA.DECLINE,
|
||||
color: STATUS_DATA_COLOR.DECLINE,
|
||||
},
|
||||
{
|
||||
label: capitalizeEachWord(STATUS_DATA.APPROVED.split('_').join(' ')),
|
||||
value: STATUS_DATA.APPROVED,
|
||||
color: STATUS_DATA_COLOR.APPROVED,
|
||||
},
|
||||
{
|
||||
label: capitalizeEachWord(STATUS_DATA.ACTIVE.split('_').join(' ')),
|
||||
value: STATUS_DATA.ACTIVE,
|
||||
color: STATUS_DATA_COLOR.ACTIVE,
|
||||
},
|
||||
{
|
||||
label: capitalizeEachWord(STATUS_DATA.DONE.split('_').join(' ')),
|
||||
value: STATUS_DATA.DONE,
|
||||
color: STATUS_DATA_COLOR.DONE,
|
||||
},
|
||||
{
|
||||
label: capitalizeEachWord(STATUS_DATA.POSTED.split('_').join(' ')),
|
||||
value: STATUS_DATA.POSTED,
|
||||
color: STATUS_DATA_COLOR.POSTED,
|
||||
},
|
||||
{
|
||||
label: capitalizeEachWord(STATUS_DATA.PAID.split('_').join(' ')),
|
||||
value: STATUS_DATA.PAID,
|
||||
color: STATUS_DATA_COLOR.PAID,
|
||||
},
|
||||
{
|
||||
label: capitalizeEachWord(STATUS_DATA.PENDING.split('_').join(' ')),
|
||||
value: STATUS_DATA.PENDING,
|
||||
color: STATUS_DATA_COLOR.PENDING,
|
||||
},
|
||||
{
|
||||
label: capitalizeEachWord(STATUS_DATA.REJECTED.split('_').join(' ')),
|
||||
value: STATUS_DATA.REJECTED,
|
||||
color: STATUS_DATA_COLOR.REJECTED,
|
||||
},
|
||||
{
|
||||
label: capitalizeEachWord(STATUS_DATA.REJECTED.split('_').join(' ')),
|
||||
value: STATUS_DATA.REJECTED,
|
||||
color: STATUS_DATA_COLOR.REJECTED,
|
||||
},
|
||||
{
|
||||
label: capitalizeEachWord(STATUS_DATA.SETTLED.split('_').join(' ')),
|
||||
value: STATUS_DATA.SETTLED,
|
||||
color: STATUS_DATA_COLOR.SETTLED,
|
||||
},
|
||||
{
|
||||
label: capitalizeEachWord(STATUS_DATA.CONFIRMED.split('_').join(' ')),
|
||||
value: STATUS_DATA.CONFIRMED,
|
||||
color: STATUS_DATA_COLOR.CONFIRMED,
|
||||
},
|
||||
{
|
||||
label: capitalizeEachWord(STATUS_DATA.PROCESS_REFUND.split('_').join(' ')),
|
||||
value: STATUS_DATA.PROCESS_REFUND,
|
||||
color: STATUS_DATA_COLOR.PROCESS_REFUND,
|
||||
},
|
||||
{
|
||||
label: capitalizeEachWord(STATUS_DATA.PROCESS_REFUND_WAHANA.split('_').join(' ')),
|
||||
value: STATUS_DATA.PROCESS_REFUND_WAHANA,
|
||||
color: STATUS_DATA_COLOR.PROCESS_REFUND,
|
||||
},
|
||||
{
|
||||
label: capitalizeEachWord(STATUS_DATA.REFUNDED.split('_').join(' ')),
|
||||
value: STATUS_DATA.REFUNDED,
|
||||
color: STATUS_DATA_COLOR.REFUNDED,
|
||||
},
|
||||
{
|
||||
label: capitalizeEachWord(STATUS_DATA.PARTIAL_REFUND.split('_').join(' ')),
|
||||
value: STATUS_DATA.PARTIAL_REFUND,
|
||||
color: STATUS_DATA_COLOR.REFUNDED,
|
||||
},
|
||||
];
|
||||
|
||||
export function makeColorStatus(status: STATUS_DATA): STATUS_DATA_COLOR | undefined {
|
||||
const color = STATUS_DATA_OPTIONS.find(
|
||||
(item) => item.value?.split('_').join('') === status?.split('_').join('').toLowerCase(),
|
||||
);
|
||||
return color?.color;
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
export enum UserRole {
|
||||
SUPERADMIN = 'superadmin',
|
||||
STAFF = 'staff',
|
||||
TENANT = 'tenant',
|
||||
QUEUE_ADMIN = 'queue_admin',
|
||||
}
|
||||
|
||||
export const UserRoleOptions = [
|
||||
{ value: UserRole.SUPERADMIN, label: 'Super Admin' },
|
||||
{ value: UserRole.QUEUE_ADMIN, label: 'Admin Antrian' },
|
||||
{ value: UserRole.STAFF, label: 'Staff' },
|
||||
];
|
|
@ -0,0 +1,4 @@
|
|||
export const WEB_URL = {
|
||||
ITEM: '/app/item',
|
||||
ITEM_MASTER: '/app/item-master',
|
||||
};
|
|
@ -0,0 +1,80 @@
|
|||
import { capitalizeEachWord } from '@pos/base';
|
||||
|
||||
export enum ACCESS_CONTROL_ROLE {
|
||||
SYSTEM = 'System',
|
||||
GLOBAL = 'Global',
|
||||
ORGANIZATION = 'Organization',
|
||||
CONTACT_LEVEL = 'Contact Level',
|
||||
ACCESS_TO_CONTACT = 'Access to Contact',
|
||||
SUPER_ADMIN = 'Super Admin',
|
||||
}
|
||||
|
||||
export enum ACCESS_TO_CONTACT_TYPE {
|
||||
RESTRICTED = 'Restricted',
|
||||
ADDITIONAL = 'Additional',
|
||||
}
|
||||
|
||||
export enum PRIVILEGE_ACTION {
|
||||
VIEW = 'VIEW',
|
||||
CREATE = 'CREATE',
|
||||
EDIT = 'EDIT',
|
||||
DELETE = 'DELETE',
|
||||
CHANGE_STATUS = 'CHANGE_STATUS',
|
||||
CONFIRM = 'CONFIRM',
|
||||
VIEW_EXTERNAL_LINK = 'VIEW_EXTERNAL_LINK',
|
||||
DOWNLOAD = 'DOWNLOAD',
|
||||
CANCEL = 'CANCEL',
|
||||
}
|
||||
|
||||
export enum PRIVILEGE_CONDITION {
|
||||
ORGANIZATION = 'ORGANIZATION',
|
||||
DEPARTMENT = 'DEPARTMENT',
|
||||
MINISTRY_POSITION = 'MINISTRY_POSITION',
|
||||
TEAM = 'TEAM',
|
||||
CARE_GROUP = 'CARE_GROUP',
|
||||
TASK = 'TASK',
|
||||
EVENT = 'EVENT',
|
||||
ONLY_OWN = 'ONLY_OWN',
|
||||
}
|
||||
|
||||
export enum PRIVILEGE_CONDITION_VALUE {
|
||||
OWN = 'OWN',
|
||||
ALL = 'ALL',
|
||||
WITH_CHILD = 'WITH_CHILD',
|
||||
TRUE = 'TRUE',
|
||||
FALSE = 'FALSE',
|
||||
PIC = 'PIC',
|
||||
COORDINATOR = 'COORDINATOR',
|
||||
}
|
||||
|
||||
export function generatePrivilegeValueOptions() {
|
||||
const options = {};
|
||||
Object.values(PRIVILEGE_CONDITION_VALUE).forEach((el) => {
|
||||
Object.assign(options, {
|
||||
[`${el}`]: {
|
||||
label: capitalizeEachWord(el.split('_').join(' ').toLowerCase()),
|
||||
value: el,
|
||||
},
|
||||
});
|
||||
});
|
||||
return options;
|
||||
}
|
||||
|
||||
export const AccessControlRoleOpt: any = {
|
||||
[`${ACCESS_CONTROL_ROLE.SUPER_ADMIN}`]: {
|
||||
label: 'Super Admin',
|
||||
value: ACCESS_CONTROL_ROLE.SUPER_ADMIN,
|
||||
},
|
||||
[`${ACCESS_CONTROL_ROLE.SYSTEM}`]: {
|
||||
label: 'System Admin',
|
||||
value: ACCESS_CONTROL_ROLE.SYSTEM,
|
||||
},
|
||||
[`${ACCESS_CONTROL_ROLE.GLOBAL}`]: {
|
||||
label: 'Global Officer',
|
||||
value: ACCESS_CONTROL_ROLE.GLOBAL,
|
||||
},
|
||||
[`${ACCESS_CONTROL_ROLE.ORGANIZATION}`]: {
|
||||
label: 'Organization Officer',
|
||||
value: ACCESS_CONTROL_ROLE.ORGANIZATION,
|
||||
},
|
||||
};
|
|
@ -0,0 +1,62 @@
|
|||
import { StoragePrivilege } from '@pos/base/data/local-data-services';
|
||||
import { omit } from 'lodash';
|
||||
export * from './access-control.constant';
|
||||
|
||||
export const DefaultAccessControl = {
|
||||
view_index: false,
|
||||
view_detail: false,
|
||||
create: false,
|
||||
update: false,
|
||||
delete: false,
|
||||
change_status: false,
|
||||
confirm: false,
|
||||
view_external_link: false,
|
||||
download: false,
|
||||
};
|
||||
|
||||
export const DefaultAccessControlTrue = {
|
||||
view_index: true,
|
||||
view_detail: true,
|
||||
create: true,
|
||||
update: true,
|
||||
delete: true,
|
||||
change_status: true,
|
||||
confirm: true,
|
||||
view_external_link: true,
|
||||
download: true,
|
||||
};
|
||||
|
||||
export enum ControlTypeEnum {
|
||||
view_index = 'view_index',
|
||||
view_detail = 'view_detail',
|
||||
create = 'create',
|
||||
update = 'update',
|
||||
delete = 'delete',
|
||||
change_status = 'change_status',
|
||||
confirm = 'confirm',
|
||||
view_external_link = 'view_external_link',
|
||||
download = 'download',
|
||||
}
|
||||
|
||||
export type ControlType = {
|
||||
view_index: boolean;
|
||||
view_detail: boolean;
|
||||
create: boolean;
|
||||
update: boolean;
|
||||
delete: boolean;
|
||||
change_status: boolean;
|
||||
confirm: boolean;
|
||||
view_external_link: boolean;
|
||||
download: boolean;
|
||||
};
|
||||
|
||||
interface GetProps {
|
||||
moduleKey: string;
|
||||
}
|
||||
export function getAccessControlByModule(props: GetProps): ControlType {
|
||||
const { moduleKey } = props;
|
||||
const list: any[] = StoragePrivilege.get() as any;
|
||||
const control = list?.find((el: any) => el.module_key === moduleKey) ?? DefaultAccessControl;
|
||||
const fixControl = omit(control, ['module_key']) as ControlType;
|
||||
return fixControl;
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
import { StorageDefaultURL, StoragePrivilege, WEB_URL, encryptData } from '@pos/base';
|
||||
import { StorageAccessToken, StorageUserData, StorageActiveAccount } from '@pos/base';
|
||||
|
||||
export async function handleLogout(authParam?: string) {
|
||||
// INDEXED-DB
|
||||
await StorageUserData.delete(); //remove user data from indexed-db
|
||||
await StorageAccessToken.delete(); //remove access token from local indexed-db
|
||||
await StoragePrivilege.delete();
|
||||
|
||||
//LOCAL STORAGE
|
||||
await StorageActiveAccount.delete(); // remove active account from local storage
|
||||
await StorageDefaultURL.delete();
|
||||
|
||||
window.location.replace(
|
||||
`/auth/login${authParam ? `?u=${encodeURIComponent(encryptData(JSON.stringify(authParam)))}` : ''}`,
|
||||
);
|
||||
}
|
||||
|
||||
export async function handleLogin(respLogin: any) {
|
||||
await StorageAccessToken.delete();
|
||||
try {
|
||||
// save user id to StorageActiveAccount on Local storage
|
||||
const userID = respLogin?.id; // adjust key "id" with key that have userID value
|
||||
await StorageActiveAccount.create({ value: userID });
|
||||
|
||||
// save access token to StorageAccessToken
|
||||
const accessToken = respLogin?.token;
|
||||
await StorageAccessToken.create('Bearer ' + accessToken);
|
||||
|
||||
// save user data information to
|
||||
const userData = respLogin; // adjustment with value user data
|
||||
await StorageUserData.create(userData);
|
||||
|
||||
// find web url module for first menu to access
|
||||
await StorageDefaultURL.create({ value: WEB_URL.ITEM });
|
||||
|
||||
// save default url to local storage
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
export const ENC_STORAGE_KEY = 'zkwqyo3RpNEh8un2CIAs'; //TODO change value from environment
|
|
@ -0,0 +1,13 @@
|
|||
import { AES } from 'crypto-js';
|
||||
import enc from 'crypto-js/enc-utf8';
|
||||
import { ENC_STORAGE_KEY } from './encryption-key';
|
||||
|
||||
// Encryption function
|
||||
export function encryptData(data: any) {
|
||||
return AES.encrypt(data, ENC_STORAGE_KEY).toString();
|
||||
}
|
||||
|
||||
// Decryption function
|
||||
export function decryptData(encryptedData: any) {
|
||||
return AES.decrypt(encryptedData, ENC_STORAGE_KEY).toString(enc);
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
export class AccessDeniedError extends Error {
|
||||
constructor() {
|
||||
super('Denied access!');
|
||||
this.name = 'AccessDeniedError';
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
export * from './unexpected-error';
|
||||
export * from './access-denied-error';
|
||||
export * from './invalid-credentials-error';
|
|
@ -0,0 +1,6 @@
|
|||
export class InvalidCredentialsError extends Error {
|
||||
constructor() {
|
||||
super('Invalid credentials.');
|
||||
this.name = 'InvalidCredentialsError';
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
export class UnexpectedError extends Error {
|
||||
constructor() {
|
||||
super('Something went wrong. Please try again later.');
|
||||
this.name = 'UnexpectedError';
|
||||
}
|
||||
}
|
||||
|
||||
export class HttpError extends Error {
|
||||
public errorObject: any;
|
||||
constructor(object: any) {
|
||||
super('Something went wrong. Please try again later.');
|
||||
this.name = 'HttpError';
|
||||
this.errorObject = object;
|
||||
}
|
||||
}
|
||||
|
||||
export class ErrorRequest<T = any> extends Error {
|
||||
constructor(
|
||||
public data: T = null as any,
|
||||
public message = 'Internal server error.',
|
||||
public status = 500,
|
||||
) {
|
||||
super(message);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
import * as _ from 'lodash';
|
||||
|
||||
export function findMenuItemByPath(menu: any, targetTo: any) {
|
||||
let result;
|
||||
_.forEach(menu, (item): any => {
|
||||
if (item.label && item.label.props && item.label.props.to === targetTo) {
|
||||
result = item;
|
||||
return false; // exit the loop
|
||||
}
|
||||
|
||||
if (item.children) {
|
||||
const nestedResult = findMenuItemByPath(item.children, targetTo);
|
||||
if (nestedResult) {
|
||||
result = nestedResult;
|
||||
return false; // exit the loop
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return result || undefined; // return result or undefined explicitly
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
export * from './filter-menu';
|
|
@ -0,0 +1,18 @@
|
|||
import { CustomFormatConfig } from '@formatjs/intl';
|
||||
|
||||
interface CurrencyProps {
|
||||
currencyOptions?: CustomFormatConfig;
|
||||
value?: number | bigint;
|
||||
}
|
||||
|
||||
export function currencyFormatter(props: CurrencyProps) {
|
||||
const { currencyOptions, value } = props;
|
||||
if (!value) return 'Rp 0,00';
|
||||
return new Intl.NumberFormat('id', {
|
||||
style: 'currency',
|
||||
currency: 'IDR',
|
||||
minimumFractionDigits: 0,
|
||||
currencyDisplay: 'narrowSymbol',
|
||||
...currencyOptions,
|
||||
}).format(value);
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
export * from './string.formatter';
|
||||
export * from './currency.formatter';
|
|
@ -0,0 +1,54 @@
|
|||
interface CurrencyEntity {
|
||||
value: number;
|
||||
currency?: ' IDR' | 'EUR' | 'JPY';
|
||||
}
|
||||
export interface IStringFormatter {
|
||||
capitalizeFistWord(string: string): string;
|
||||
capitalizeEachWord(string: string): string;
|
||||
stringLimiter(string: string, limit: number): string;
|
||||
upperCase(string: string): string;
|
||||
lowerCase(string: string): string;
|
||||
currency(payload: CurrencyEntity): string;
|
||||
}
|
||||
|
||||
export class BaseStringFormatter implements IStringFormatter {
|
||||
capitalizeFistWord(string: string): string {
|
||||
if (typeof string !== 'string') return '';
|
||||
return string.charAt(0).toUpperCase() + string.slice(1);
|
||||
}
|
||||
|
||||
capitalizeEachWord(string: string): string {
|
||||
if (typeof string !== 'string') return '';
|
||||
const newStringSplit = string.split(' ');
|
||||
const newString = newStringSplit.map((item) => {
|
||||
return item.charAt(0).toUpperCase() + item.slice(1);
|
||||
});
|
||||
return newString.join(' ');
|
||||
}
|
||||
|
||||
stringLimiter(string: string, limit: number): string {
|
||||
if (!limit || !string) return string;
|
||||
return string.length > limit ? `${string.substring(0, limit)} ...` : string;
|
||||
}
|
||||
|
||||
upperCase(string: string): string {
|
||||
if (!string) return '';
|
||||
return string.toUpperCase();
|
||||
}
|
||||
lowerCase(string: string): string {
|
||||
if (!string) return '';
|
||||
return string.toLowerCase();
|
||||
}
|
||||
currency(payload: CurrencyEntity): any {
|
||||
const { value, currency = 'IDR' } = payload;
|
||||
if (!value) return '';
|
||||
return new Intl.NumberFormat('en-IN', {
|
||||
style: 'currency',
|
||||
currency,
|
||||
}).format(value);
|
||||
}
|
||||
}
|
||||
|
||||
const stringFormatter = new BaseStringFormatter();
|
||||
export const { capitalizeFistWord, capitalizeEachWord, stringLimiter, upperCase, lowerCase, currency } =
|
||||
stringFormatter;
|
|
@ -0,0 +1,76 @@
|
|||
import axios, { AxiosRequestConfig } from 'axios';
|
||||
|
||||
async function getData(params: any, url: string, axiosParams?: AxiosRequestConfig) {
|
||||
try {
|
||||
const response = await axios({
|
||||
url: url,
|
||||
method: 'get',
|
||||
params: {
|
||||
limit: 10,
|
||||
...params,
|
||||
},
|
||||
...(axiosParams ? axiosParams : {}),
|
||||
});
|
||||
return response;
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
|
||||
interface Result {
|
||||
currentPage: number;
|
||||
data: any[];
|
||||
}
|
||||
|
||||
async function manipulatedGenerateDataPagination(
|
||||
url: string,
|
||||
params: any,
|
||||
prevData: any[] = [],
|
||||
currentPage = 1,
|
||||
axiosParams?: AxiosRequestConfig,
|
||||
): Promise<Result> {
|
||||
try {
|
||||
const response = await getData({ ...params, page: currentPage }, url, axiosParams);
|
||||
|
||||
const data = response?.data?.data ?? [];
|
||||
const meta = response?.data?.meta;
|
||||
|
||||
if (meta.totalPages <= currentPage) {
|
||||
return {
|
||||
currentPage: currentPage,
|
||||
data: [...prevData, ...data],
|
||||
};
|
||||
} else {
|
||||
const response2 = await manipulatedGenerateDataPagination(
|
||||
url,
|
||||
params,
|
||||
[...prevData, ...data],
|
||||
currentPage + 1,
|
||||
axiosParams,
|
||||
);
|
||||
const data2: any[] = response2?.data ?? [];
|
||||
const newCurrentPage: number = response2?.currentPage;
|
||||
return {
|
||||
currentPage: newCurrentPage,
|
||||
data: data2,
|
||||
};
|
||||
}
|
||||
} catch (error) {
|
||||
return {
|
||||
currentPage: 1,
|
||||
data: prevData,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
interface GenerateDataPagination {
|
||||
url: string;
|
||||
params: any;
|
||||
axiosParams?: AxiosRequestConfig;
|
||||
}
|
||||
|
||||
export async function generateDataPagination(props: GenerateDataPagination): Promise<Result> {
|
||||
const { url, params = {}, axiosParams } = props;
|
||||
const data = await manipulatedGenerateDataPagination(url, params, [], 1, axiosParams);
|
||||
return data;
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
export * from './auth-handler';
|
||||
export * from './encryption';
|
||||
export * from './error-handlings';
|
||||
export * from './filter-menu';
|
||||
export * from './notifications';
|
||||
export * from './formatter';
|
||||
export * from './timeout';
|
||||
export * from './localstorage-effect';
|
||||
export * from './access-control';
|
||||
export * from './use-query-param';
|
||||
export * from './get-data-pagination';
|
||||
export * from './validate-formula';
|
|
@ -0,0 +1,12 @@
|
|||
export const localStorageEffect =
|
||||
(key: string) =>
|
||||
({ setSelf, onSet }: any) => {
|
||||
const savedValue = localStorage.getItem(key);
|
||||
if (savedValue != null) {
|
||||
setSelf(JSON.parse(savedValue));
|
||||
}
|
||||
|
||||
onSet((newValue: any, _: any, isReset: any) => {
|
||||
isReset ? localStorage.removeItem(key) : localStorage.setItem(key, JSON.stringify(newValue));
|
||||
});
|
||||
};
|
|
@ -0,0 +1,53 @@
|
|||
import { notification } from 'antd';
|
||||
import { ReactNode } from 'react';
|
||||
|
||||
notification.config({
|
||||
duration: 1.5,
|
||||
});
|
||||
|
||||
export function notificationSuccess(content?: ReactNode | any): void {
|
||||
notification.success({
|
||||
message: 'Success',
|
||||
description: content,
|
||||
className: 'no-print',
|
||||
});
|
||||
}
|
||||
|
||||
export function notificationError(content?: ReactNode | any): void {
|
||||
notification.error({
|
||||
message: 'Error',
|
||||
description: content,
|
||||
className: 'no-print',
|
||||
});
|
||||
}
|
||||
|
||||
export function notificationWarning(content?: ReactNode | any): void {
|
||||
notification.warning({
|
||||
message: 'Warning',
|
||||
description: content,
|
||||
className: 'no-print',
|
||||
});
|
||||
}
|
||||
|
||||
export function notificationInfo(content?: ReactNode | any): void {
|
||||
notification.info({
|
||||
message: 'Info',
|
||||
description: content,
|
||||
className: 'no-print',
|
||||
});
|
||||
}
|
||||
|
||||
interface MultiNotificationParams {
|
||||
success?: string[];
|
||||
failed?: string[];
|
||||
warning?: string[];
|
||||
info?: string[];
|
||||
}
|
||||
|
||||
export function multiNotification(message: MultiNotificationParams) {
|
||||
const { success = [], failed = [], warning = [], info = [] } = message;
|
||||
success.forEach((item) => notificationSuccess(item));
|
||||
failed.forEach((item) => notificationError(item));
|
||||
warning.forEach((item) => notificationWarning(item));
|
||||
info.forEach((item) => notificationInfo(item));
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
export function timeout(ms: number) {
|
||||
return new Promise((resolve) => setTimeout(resolve, ms));
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
// A custom hook that builds on useLocation to parse
|
||||
|
||||
import React from 'react';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
|
||||
// the query string for you.
|
||||
export function useQueryParam() {
|
||||
const { search } = useLocation();
|
||||
|
||||
return React.useMemo(() => new URLSearchParams(search), [search]);
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
// Fungsi untuk mengecek apakah suatu string merupakan angka
|
||||
function isNumeric(value: any) {
|
||||
return !isNaN(value - parseFloat(value));
|
||||
}
|
||||
|
||||
// Fungsi untuk memvalidasi formula number berderet
|
||||
export function validateFormula(formula: any) {
|
||||
for (let i = 0; i < formula.length - 1; i++) {
|
||||
if (isNumeric(formula[i]?.name) && isNumeric(formula[i + 1]?.name)) {
|
||||
return false; // Formula tidak valid
|
||||
}
|
||||
}
|
||||
return true; // Formula valid
|
||||
}
|
|
@ -0,0 +1,94 @@
|
|||
Copyright 2011 The Paytone Project Authors (https://github.com/googlefonts/paytoneFont),
|
||||
with Reserved Font Names "Paytone" and "Paytone One".
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
This license is copied below, and is also available with a FAQ at:
|
||||
https://openfontlicense.org
|
||||
|
||||
|
||||
-----------------------------------------------------------
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
-----------------------------------------------------------
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||
development of collaborative font projects, to support the font creation
|
||||
efforts of academic and linguistic communities, and to provide a free and
|
||||
open framework in which fonts may be shared and improved in partnership
|
||||
with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely as long as they are not sold by themselves. The
|
||||
fonts, including any derivative works, can be bundled, embedded,
|
||||
redistributed and/or sold with any software provided that any reserved
|
||||
names are not used by derivative works. The fonts and derivatives,
|
||||
however, cannot be released under any other type of license. The
|
||||
requirement for fonts to remain under this license does not apply
|
||||
to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright
|
||||
Holder(s) under this license and clearly marked as such. This may
|
||||
include source files, build scripts and documentation.
|
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the
|
||||
copyright statement(s).
|
||||
|
||||
"Original Version" refers to the collection of Font Software components as
|
||||
distributed by the Copyright Holder(s).
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||
or substituting -- in part or in whole -- any of the components of the
|
||||
Original Version, by changing formats or by porting the Font Software to a
|
||||
new environment.
|
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical
|
||||
writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||
redistribute, and sell modified and unmodified copies of the Font
|
||||
Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components,
|
||||
in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled,
|
||||
redistributed and/or sold with any software, provided that each copy
|
||||
contains the above copyright notice and this license. These can be
|
||||
included either as stand-alone text files, human-readable headers or
|
||||
in the appropriate machine-readable metadata fields within text or
|
||||
binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font
|
||||
Name(s) unless explicit written permission is granted by the corresponding
|
||||
Copyright Holder. This restriction only applies to the primary font name as
|
||||
presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||
Software shall not be used to promote, endorse or advertise any
|
||||
Modified Version, except to acknowledge the contribution(s) of the
|
||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||
permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole,
|
||||
must be distributed entirely under this license, and must not be
|
||||
distributed under any other license. The requirement for fonts to
|
||||
remain under this license does not apply to any document created
|
||||
using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are
|
||||
not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
|
@ -0,0 +1,93 @@
|
|||
Copyright 2021 The Urbanist Project Authors (https://github.com/coreyhu/Urbanist)
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
This license is copied below, and is also available with a FAQ at:
|
||||
https://openfontlicense.org
|
||||
|
||||
|
||||
-----------------------------------------------------------
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
-----------------------------------------------------------
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||
development of collaborative font projects, to support the font creation
|
||||
efforts of academic and linguistic communities, and to provide a free and
|
||||
open framework in which fonts may be shared and improved in partnership
|
||||
with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely as long as they are not sold by themselves. The
|
||||
fonts, including any derivative works, can be bundled, embedded,
|
||||
redistributed and/or sold with any software provided that any reserved
|
||||
names are not used by derivative works. The fonts and derivatives,
|
||||
however, cannot be released under any other type of license. The
|
||||
requirement for fonts to remain under this license does not apply
|
||||
to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright
|
||||
Holder(s) under this license and clearly marked as such. This may
|
||||
include source files, build scripts and documentation.
|
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the
|
||||
copyright statement(s).
|
||||
|
||||
"Original Version" refers to the collection of Font Software components as
|
||||
distributed by the Copyright Holder(s).
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||
or substituting -- in part or in whole -- any of the components of the
|
||||
Original Version, by changing formats or by porting the Font Software to a
|
||||
new environment.
|
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical
|
||||
writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||
redistribute, and sell modified and unmodified copies of the Font
|
||||
Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components,
|
||||
in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled,
|
||||
redistributed and/or sold with any software, provided that each copy
|
||||
contains the above copyright notice and this license. These can be
|
||||
included either as stand-alone text files, human-readable headers or
|
||||
in the appropriate machine-readable metadata fields within text or
|
||||
binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font
|
||||
Name(s) unless explicit written permission is granted by the corresponding
|
||||
Copyright Holder. This restriction only applies to the primary font name as
|
||||
presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||
Software shall not be used to promote, endorse or advertise any
|
||||
Modified Version, except to acknowledge the contribution(s) of the
|
||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||
permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole,
|
||||
must be distributed entirely under this license, and must not be
|
||||
distributed under any other license. The requirement for fonts to
|
||||
remain under this license does not apply to any document created
|
||||
using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are
|
||||
not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
|
@ -0,0 +1,81 @@
|
|||
Urbanist Variable Font
|
||||
======================
|
||||
|
||||
This download contains Urbanist as both variable fonts and static fonts.
|
||||
|
||||
Urbanist is a variable font with this axis:
|
||||
wght
|
||||
|
||||
This means all the styles are contained in these files:
|
||||
Urbanist/Urbanist-VariableFont_wght.ttf
|
||||
Urbanist/Urbanist-Italic-VariableFont_wght.ttf
|
||||
|
||||
If your app fully supports variable fonts, you can now pick intermediate styles
|
||||
that aren’t available as static fonts. Not all apps support variable fonts, and
|
||||
in those cases you can use the static font files for Urbanist:
|
||||
Urbanist/static/Urbanist-Thin.ttf
|
||||
Urbanist/static/Urbanist-ExtraLight.ttf
|
||||
Urbanist/static/Urbanist-Light.ttf
|
||||
Urbanist/static/Urbanist-Regular.ttf
|
||||
Urbanist/static/Urbanist-Medium.ttf
|
||||
Urbanist/static/Urbanist-SemiBold.ttf
|
||||
Urbanist/static/Urbanist-Bold.ttf
|
||||
Urbanist/static/Urbanist-ExtraBold.ttf
|
||||
Urbanist/static/Urbanist-Black.ttf
|
||||
Urbanist/static/Urbanist-ThinItalic.ttf
|
||||
Urbanist/static/Urbanist-ExtraLightItalic.ttf
|
||||
Urbanist/static/Urbanist-LightItalic.ttf
|
||||
Urbanist/static/Urbanist-Italic.ttf
|
||||
Urbanist/static/Urbanist-MediumItalic.ttf
|
||||
Urbanist/static/Urbanist-SemiBoldItalic.ttf
|
||||
Urbanist/static/Urbanist-BoldItalic.ttf
|
||||
Urbanist/static/Urbanist-ExtraBoldItalic.ttf
|
||||
Urbanist/static/Urbanist-BlackItalic.ttf
|
||||
|
||||
Get started
|
||||
-----------
|
||||
|
||||
1. Install the font files you want to use
|
||||
|
||||
2. Use your app's font picker to view the font family and all the
|
||||
available styles
|
||||
|
||||
Learn more about variable fonts
|
||||
-------------------------------
|
||||
|
||||
https://developers.google.com/web/fundamentals/design-and-ux/typography/variable-fonts
|
||||
https://variablefonts.typenetwork.com
|
||||
https://medium.com/variable-fonts
|
||||
|
||||
In desktop apps
|
||||
|
||||
https://theblog.adobe.com/can-variable-fonts-illustrator-cc
|
||||
https://helpx.adobe.com/nz/photoshop/using/fonts.html#variable_fonts
|
||||
|
||||
Online
|
||||
|
||||
https://developers.google.com/fonts/docs/getting_started
|
||||
https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Fonts/Variable_Fonts_Guide
|
||||
https://developer.microsoft.com/en-us/microsoft-edge/testdrive/demos/variable-fonts
|
||||
|
||||
Installing fonts
|
||||
|
||||
MacOS: https://support.apple.com/en-us/HT201749
|
||||
Linux: https://www.google.com/search?q=how+to+install+a+font+on+gnu%2Blinux
|
||||
Windows: https://support.microsoft.com/en-us/help/314960/how-to-install-or-remove-a-font-in-windows
|
||||
|
||||
Android Apps
|
||||
|
||||
https://developers.google.com/fonts/docs/android
|
||||
https://developer.android.com/guide/topics/ui/look-and-feel/downloadable-fonts
|
||||
|
||||
License
|
||||
-------
|
||||
Please read the full license text (OFL.txt) to understand the permissions,
|
||||
restrictions and requirements for usage, redistribution, and modification.
|
||||
|
||||
You can use them in your products & projects – print or digital,
|
||||
commercial or otherwise.
|
||||
|
||||
This isn't legal advice, please consider consulting a lawyer and see the full
|
||||
license for all details.
|
|
@ -0,0 +1,34 @@
|
|||
@font-face {
|
||||
font-family: 'Paytone One';
|
||||
src: url('./Paytone_One/PaytoneOne-Regular.ttf') format('truetype');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Urbanist';
|
||||
src: url('./Urbanist/static/Urbanist-Regular.ttf') format('truetype');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Urbanist';
|
||||
src: url('./Urbanist/static/Urbanist-Bold.ttf') format('truetype');
|
||||
font-weight: bold;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Urbanist';
|
||||
src: url('./Urbanist/static/Urbanist-Italic.ttf') format('truetype');
|
||||
font-weight: normal;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Urbanist';
|
||||
src: url('./Urbanist/static/Urbanist-BoldItalic.ttf') format('truetype');
|
||||
font-weight: bold;
|
||||
font-style: italic;
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
<svg width="514" height="164" viewBox="0 0 514 164" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle cx="101" cy="22" r="20" stroke="#667085" stroke-width="2"/>
|
||||
<circle cx="101" cy="142" r="20" stroke="#667085" stroke-width="2"/>
|
||||
<circle cx="21" cy="102" r="20" stroke="#667085" stroke-width="2"/>
|
||||
<circle cx="141" cy="102" r="20" stroke="#667085" stroke-width="2"/>
|
||||
<circle cx="193" cy="82" r="20" stroke="#667085" stroke-width="2"/>
|
||||
<circle cx="313" cy="82" r="20" stroke="#667085" stroke-width="2"/>
|
||||
<circle cx="253" cy="22" r="20" stroke="#667085" stroke-width="2"/>
|
||||
<circle cx="253" cy="142" r="20" stroke="#667085" stroke-width="2"/>
|
||||
<path d="M1 102C1 90.9543 9.9543 82 21 82H141C152.046 82 161 90.9543 161 102C161 113.046 152.046 122 141 122H21C9.9543 122 1 113.046 1 102Z" stroke="#667085" stroke-width="2"/>
|
||||
<path d="M101 162C89.9543 162 81 153.046 81 142L81 22C81 10.9543 89.9543 2 101 2C112.046 2 121 10.9543 121 22L121 142C121 153.046 112.046 162 101 162Z" stroke="#667085" stroke-width="2"/>
|
||||
<path d="M7.14214 115.995C-0.668351 108.184 -0.668351 95.5211 7.14214 87.7106L86.7107 8.1421C94.5212 0.331614 107.184 0.331607 114.995 8.14209C122.805 15.9526 122.805 28.6159 114.995 36.4264L35.4264 115.995C27.6159 123.805 14.9526 123.805 7.14214 115.995Z" stroke="#667085" stroke-width="2"/>
|
||||
<circle cx="453" cy="22" r="20" stroke="#667085" stroke-width="2"/>
|
||||
<circle cx="453" cy="142" r="20" stroke="#667085" stroke-width="2"/>
|
||||
<circle cx="373" cy="102" r="20" stroke="#667085" stroke-width="2"/>
|
||||
<circle cx="493" cy="102" r="20" stroke="#667085" stroke-width="2"/>
|
||||
<path d="M353 102C353 90.9543 361.954 82 373 82H493C504.046 82 513 90.9543 513 102C513 113.046 504.046 122 493 122H373C361.954 122 353 113.046 353 102Z" stroke="#667085" stroke-width="2"/>
|
||||
<path d="M453 162C441.954 162 433 153.046 433 142L433 22C433 10.9543 441.954 2 453 2C464.046 2 473 10.9543 473 22L473 142C473 153.046 464.046 162 453 162Z" stroke="#667085" stroke-width="2"/>
|
||||
<path d="M359.142 115.995C351.332 108.184 351.332 95.5211 359.142 87.7106L438.711 8.1421C446.521 0.331614 459.184 0.331607 466.995 8.14209C474.805 15.9526 474.805 28.6159 466.995 36.4264L387.426 115.995C379.616 123.805 366.953 123.805 359.142 115.995Z" stroke="#667085" stroke-width="2"/>
|
||||
<circle cx="253" cy="82" r="80" stroke="#667085" stroke-width="2"/>
|
||||
<circle cx="253" cy="82" r="40" stroke="#667085" stroke-width="2"/>
|
||||
<line x1="8.74228e-08" y1="1" x2="513" y2="1.00004" stroke="#667085" stroke-width="2"/>
|
||||
<line x1="-8.74228e-08" y1="163" x2="513" y2="163" stroke="#667085" stroke-width="2"/>
|
||||
</svg>
|
After Width: | Height: | Size: 2.5 KiB |
After Width: | Height: | Size: 216 KiB |
After Width: | Height: | Size: 26 KiB |
After Width: | Height: | Size: 110 KiB |
After Width: | Height: | Size: 25 KiB |
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 410 KiB |
After Width: | Height: | Size: 101 KiB |
|
@ -0,0 +1,72 @@
|
|||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
@import url('./ag-grid-theme-builder.css');
|
||||
@import url('../fonts/fonts.less');
|
||||
|
||||
* {
|
||||
font-family: Urbanist, sans-serif;
|
||||
}
|
||||
|
||||
html {
|
||||
-webkit-text-size-adjust: 100%;
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
label {
|
||||
font-size: 15px !important;
|
||||
}
|
||||
|
||||
.ant-modal-title,
|
||||
.color-primary,
|
||||
label {
|
||||
color: #623c7c !important;
|
||||
}
|
||||
|
||||
.bg-warning {
|
||||
background-color: #d4940d;
|
||||
}
|
||||
|
||||
.bg-turqoise {
|
||||
background-color: #c2edf0;
|
||||
}
|
||||
|
||||
.bg-softpurple {
|
||||
background-color: #d5c7f0;
|
||||
}
|
||||
|
||||
.bg-softcyan {
|
||||
background-color: #c4dcf0;
|
||||
}
|
||||
|
||||
.bg-secondary {
|
||||
background-color: #78cbbb;
|
||||
}
|
||||
|
||||
.force-px-2 {
|
||||
.ant-input-number-input {
|
||||
padding: 2px 4px !important;
|
||||
}
|
||||
padding: 2px 4px !important;
|
||||
}
|
||||
|
||||
.bg-primary {
|
||||
background-color: #7a41a1 !important;
|
||||
}
|
||||
|
||||
.bg-waiting {
|
||||
background-color: #6c5dd0;
|
||||
}
|
||||
|
||||
.bg-refunded {
|
||||
background-color: #d7a29a;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none !important;
|
||||
}
|