revamp template
This commit is contained in:
14
src/utils/Assets.ts
Normal file
14
src/utils/Assets.ts
Normal file
@ -0,0 +1,14 @@
|
||||
// Exaxmples of usage:
|
||||
//* 1. In a background image: <div style={{backgroundImage: `url('${toAbsoluteUrl('/media/misc/pattern-1.jpg')}')`}}>...
|
||||
//* 2. In img tag: <img src={toAbsoluteUrl('/media/avatars/300-2.jpg')} />
|
||||
const toAbsoluteUrl = (pathname: string): string => {
|
||||
const baseUrl = import.meta.env.BASE_URL;
|
||||
|
||||
if (baseUrl && baseUrl !== '/') {
|
||||
return import.meta.env.BASE_URL + pathname;
|
||||
} else {
|
||||
return pathname;
|
||||
}
|
||||
};
|
||||
|
||||
export { toAbsoluteUrl };
|
||||
47
src/utils/Common.ts
Normal file
47
src/utils/Common.ts
Normal file
@ -0,0 +1,47 @@
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
export const throttle = (func: (...args: any[]) => void, limit: number) => {
|
||||
let lastFunc: any;
|
||||
let lastRan: number;
|
||||
return function (this: any, ...args: any[]) {
|
||||
if (!lastRan) {
|
||||
func.apply(this, args);
|
||||
lastRan = Date.now();
|
||||
} else {
|
||||
clearTimeout(lastFunc);
|
||||
lastFunc = setTimeout(
|
||||
() => {
|
||||
if (Date.now() - lastRan >= limit) {
|
||||
func.apply(this, args);
|
||||
lastRan = Date.now();
|
||||
}
|
||||
},
|
||||
limit - (Date.now() - lastRan)
|
||||
);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
export const jsonToQueryParams = (json: any) => {
|
||||
const params = new URLSearchParams();
|
||||
|
||||
for (const key in json) {
|
||||
if (json.hasOwnProperty(key)) {
|
||||
params.append(key, json[key]);
|
||||
}
|
||||
}
|
||||
|
||||
return params.toString();
|
||||
};
|
||||
|
||||
|
||||
export const ApplicationFileDownloadUrl = (API_URL: any, token: any, fileName: any) => {
|
||||
return `${API_URL}/application/file/download?name=${fileName}&token=${token}`;
|
||||
}
|
||||
|
||||
export const getFileExtension = (filename: string): string | null => {
|
||||
const lastDotIndex = filename.lastIndexOf('.');
|
||||
if (lastDotIndex === -1 || lastDotIndex === 0 || lastDotIndex === filename.length - 1) {
|
||||
return null; // No extension found or invalid format
|
||||
}
|
||||
return filename.substring(lastDotIndex + 1);
|
||||
}
|
||||
24
src/utils/Data.ts
Normal file
24
src/utils/Data.ts
Normal file
@ -0,0 +1,24 @@
|
||||
const deepMerge = (obj1: any, obj2: any): any => {
|
||||
const output = Object.assign({}, obj1);
|
||||
|
||||
for (const key in obj2) {
|
||||
if (Object.prototype.hasOwnProperty.call(obj2, key)) {
|
||||
if (typeof obj2[key] === 'object' && obj2[key] !== null && obj1[key]) {
|
||||
output[key] = deepMerge(obj1[key], obj2[key]);
|
||||
} else {
|
||||
output[key] = obj2[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return output;
|
||||
};
|
||||
|
||||
const generateUniqueToken = (): string => {
|
||||
const timestamp: number = new Date().getTime();
|
||||
const randomString: string = Math.random().toString(36).substring(2, 8); // Random string of length 6
|
||||
|
||||
return `${timestamp}-${randomString}`;
|
||||
};
|
||||
|
||||
export { deepMerge, generateUniqueToken };
|
||||
36
src/utils/Date.ts
Normal file
36
src/utils/Date.ts
Normal file
@ -0,0 +1,36 @@
|
||||
import moment from "moment";
|
||||
|
||||
const formatIsoDate = (isoDate: string) => {
|
||||
const date = new Date(isoDate);
|
||||
const monthNames = [
|
||||
'Jan',
|
||||
'Feb',
|
||||
'Mar',
|
||||
'Apr',
|
||||
'May',
|
||||
'Jun',
|
||||
'Jul',
|
||||
'Aug',
|
||||
'Sep',
|
||||
'Oct',
|
||||
'Nov',
|
||||
'Dec'
|
||||
];
|
||||
const day = date.getDate();
|
||||
const month = monthNames[date.getMonth()];
|
||||
const year = date.getFullYear();
|
||||
return `${day} ${month}, ${year}`;
|
||||
};
|
||||
|
||||
const get5LastYear = () => {
|
||||
const last5Years = [];
|
||||
for (let i = 0; i < 5; i++) {
|
||||
last5Years.push(moment().subtract(i, 'years').format('YYYY'));
|
||||
}
|
||||
|
||||
// console.log('last5Years :', last5Years);
|
||||
return last5Years;
|
||||
|
||||
};
|
||||
|
||||
export { formatIsoDate, get5LastYear };
|
||||
16
src/utils/Devices.ts
Normal file
16
src/utils/Devices.ts
Normal file
@ -0,0 +1,16 @@
|
||||
const isMobileDevice = (): boolean => {
|
||||
const userAgent = typeof navigator === 'undefined' ? 'SSR' : navigator.userAgent;
|
||||
|
||||
const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(userAgent);
|
||||
return isMobile;
|
||||
};
|
||||
|
||||
const isMacDevice = (): boolean => {
|
||||
return navigator.userAgent.includes('Mac OS X');
|
||||
};
|
||||
|
||||
const isWindowsDevice = (): boolean => {
|
||||
return navigator.userAgent.includes('Windows');
|
||||
};
|
||||
|
||||
export { isMacDevice, isMobileDevice, isWindowsDevice };
|
||||
30
src/utils/Dom.ts
Normal file
30
src/utils/Dom.ts
Normal file
@ -0,0 +1,30 @@
|
||||
const getViewPort = (): { width: number; height: number } => {
|
||||
let e: any = window;
|
||||
let a: string = 'inner';
|
||||
|
||||
if (!('innerWidth' in window)) {
|
||||
a = 'client';
|
||||
e = document.documentElement || document.body;
|
||||
}
|
||||
|
||||
return {
|
||||
width: e[a + 'Width'] as number,
|
||||
height: e[a + 'Height'] as number
|
||||
};
|
||||
};
|
||||
|
||||
const getHeight = (element: HTMLElement): number => {
|
||||
if (!element) return 0;
|
||||
|
||||
const styles = window.getComputedStyle(element);
|
||||
|
||||
const height = element.getBoundingClientRect().height; // Actual height of the element
|
||||
const marginTop = parseFloat(styles.marginTop);
|
||||
const marginBottom = parseFloat(styles.marginBottom);
|
||||
|
||||
const totalHeight = height + marginTop + marginBottom;
|
||||
|
||||
return totalHeight;
|
||||
};
|
||||
|
||||
export { getHeight, getViewPort };
|
||||
103
src/utils/FormatNumber.ts
Normal file
103
src/utils/FormatNumber.ts
Normal file
@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Locales code
|
||||
* https://gist.github.com/raushankrjha/d1c7e35cf87e69aa8b4208a8171a8416
|
||||
*/
|
||||
|
||||
export type InputNumberValue = string | number | null | undefined;
|
||||
|
||||
type Options = Intl.NumberFormatOptions | undefined;
|
||||
|
||||
const DEFAULT_LOCALE = { code: 'en-US', currency: 'USD' };
|
||||
|
||||
function processInput(inputValue: InputNumberValue): number | null {
|
||||
if (inputValue == null || Number.isNaN(inputValue)) return null;
|
||||
|
||||
return Number(inputValue);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
export function fNumber(inputValue: InputNumberValue, options?: Options) {
|
||||
const locale = DEFAULT_LOCALE;
|
||||
|
||||
const number = processInput(inputValue);
|
||||
if (number === null) return '';
|
||||
|
||||
const fm = new Intl.NumberFormat(locale.code, {
|
||||
minimumFractionDigits: 0,
|
||||
maximumFractionDigits: 2,
|
||||
...options
|
||||
}).format(number);
|
||||
|
||||
return fm;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
export function fCurrency(inputValue: InputNumberValue, options?: Options) {
|
||||
const locale = DEFAULT_LOCALE;
|
||||
|
||||
const number = processInput(inputValue);
|
||||
if (number === null) return '';
|
||||
|
||||
const fm = new Intl.NumberFormat(locale.code, {
|
||||
style: 'currency',
|
||||
currency: locale.currency,
|
||||
minimumFractionDigits: 2,
|
||||
maximumFractionDigits: 2,
|
||||
...options
|
||||
}).format(number);
|
||||
|
||||
return fm;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
export function fPercent(inputValue: InputNumberValue, options?: Options) {
|
||||
const locale = DEFAULT_LOCALE;
|
||||
|
||||
const number = processInput(inputValue);
|
||||
if (number === null) return '';
|
||||
|
||||
const fm = new Intl.NumberFormat(locale.code, {
|
||||
style: 'percent',
|
||||
minimumFractionDigits: 2,
|
||||
maximumFractionDigits: 2,
|
||||
...options
|
||||
}).format(number / 100);
|
||||
|
||||
return fm;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
export function fShortenNumber(inputValue: InputNumberValue, options?: Options) {
|
||||
const locale = DEFAULT_LOCALE;
|
||||
|
||||
const number = processInput(inputValue);
|
||||
if (number === null) return '';
|
||||
|
||||
const fm = new Intl.NumberFormat(locale.code, {
|
||||
notation: 'compact',
|
||||
maximumFractionDigits: 2,
|
||||
...options
|
||||
}).format(number);
|
||||
|
||||
return fm.replace(/[A-Z]/g, (match) => match.toLowerCase());
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
export function fData(inputValue: InputNumberValue) {
|
||||
const number = processInput(inputValue);
|
||||
if (number === null || number === 0) return '0 bytes';
|
||||
|
||||
const units = ['bytes', 'Kb', 'Mb', 'Gb', 'Tb', 'Pb', 'Eb', 'Zb', 'Yb'];
|
||||
const decimal = 2;
|
||||
const baseValue = 1024;
|
||||
|
||||
const index = Math.floor(Math.log(number) / Math.log(baseValue));
|
||||
const fm = `${parseFloat((number / baseValue ** index).toFixed(decimal))} ${units[index]}`;
|
||||
|
||||
return fm;
|
||||
}
|
||||
28
src/utils/List.ts
Normal file
28
src/utils/List.ts
Normal file
@ -0,0 +1,28 @@
|
||||
export function statusCreditList() {
|
||||
return [
|
||||
{
|
||||
label: 'Draft',
|
||||
value: 'draft'
|
||||
},
|
||||
{
|
||||
label: 'Open',
|
||||
value: 'open'
|
||||
},
|
||||
{
|
||||
label: 'Under Review',
|
||||
value: 'under_review'
|
||||
},
|
||||
{
|
||||
label: 'Revision',
|
||||
value: 'revision'
|
||||
},
|
||||
{
|
||||
label: 'Approved',
|
||||
value: 'approved'
|
||||
},
|
||||
{
|
||||
label: 'Rejected',
|
||||
value: 'rejected'
|
||||
}
|
||||
]
|
||||
}
|
||||
21
src/utils/LocalStorage.ts
Normal file
21
src/utils/LocalStorage.ts
Normal file
@ -0,0 +1,21 @@
|
||||
const getData = (key: string): unknown | undefined => {
|
||||
try {
|
||||
const data = localStorage.getItem(key);
|
||||
|
||||
if (data) {
|
||||
return JSON.parse(data);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Read from local storage', error);
|
||||
}
|
||||
};
|
||||
|
||||
const setData = (key: string, value: unknown): void => {
|
||||
try {
|
||||
localStorage.setItem(key, JSON.stringify(value));
|
||||
} catch (error) {
|
||||
console.error('Save in local storage', error);
|
||||
}
|
||||
};
|
||||
|
||||
export { getData, setData };
|
||||
26
src/utils/Object.ts
Normal file
26
src/utils/Object.ts
Normal file
@ -0,0 +1,26 @@
|
||||
export const excludeKeys = (obj: any, keysToExclude: any) => {
|
||||
return Object.keys(obj).reduce((filteredObj: any, key) => {
|
||||
if (!keysToExclude.includes(key)) {
|
||||
filteredObj[key] = obj[key];
|
||||
}
|
||||
return filteredObj;
|
||||
}, {});
|
||||
};
|
||||
|
||||
export const changeValueImmutable = (obj: any, targetKey: any, sourceKey: any) => {
|
||||
if (obj.hasOwnProperty(sourceKey)) {
|
||||
return { ...obj, [targetKey]: obj[sourceKey] };
|
||||
}
|
||||
return obj;
|
||||
// Example usage:
|
||||
// const updatedImmutable = changeValueImmutable(original, 'name', 'location');
|
||||
};
|
||||
|
||||
export const updateKeyValueInArray = (arr: [], targetKey: any, sourceKey: any) => {
|
||||
return arr.map((obj: any) => {
|
||||
if (obj.hasOwnProperty(sourceKey)) {
|
||||
return { ...obj, [targetKey]: obj[sourceKey] };
|
||||
}
|
||||
return obj; // If sourceKey doesn't exist, return the object unchanged
|
||||
});
|
||||
};
|
||||
23
src/utils/Router.ts
Normal file
23
src/utils/Router.ts
Normal file
@ -0,0 +1,23 @@
|
||||
const getCurrentUrl = (path: string): string => {
|
||||
return path.split(/[?#]/)[0];
|
||||
};
|
||||
|
||||
const matchPath = (path: string, pathname: string): boolean => {
|
||||
const current = getCurrentUrl(path);
|
||||
|
||||
if (!current || !pathname) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (current === pathname) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (current.includes(pathname)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
export { getCurrentUrl, matchPath };
|
||||
22
src/utils/String.ts
Normal file
22
src/utils/String.ts
Normal file
@ -0,0 +1,22 @@
|
||||
export const camelToSnakeCase = (str: string) => {
|
||||
return str.replace(/([a-z])([A-Z])/g, '$1_$2').toLowerCase();
|
||||
};
|
||||
|
||||
export const snakeToCamelCase = (str: string) => {
|
||||
return str.replace(/(_\w)/g, (match) => match[1].toUpperCase());
|
||||
};
|
||||
|
||||
export const toCamelCase = (str: string | undefined | null): string => {
|
||||
if (!str) return '';
|
||||
return str
|
||||
.toLowerCase()
|
||||
.replace(/(?:^|[^a-zA-Z0-9])([a-zA-Z0-9])/g, (match, group1) => group1.toUpperCase())
|
||||
.replace(/[^a-zA-Z0-9]/g, '');
|
||||
};
|
||||
|
||||
export const snakeToTitleCase = (str: string) => {
|
||||
return String(str)
|
||||
.split('_') // Split the string by underscores
|
||||
.map((word) => word.charAt(0).toUpperCase() + word.slice(1)) // Capitalize each word
|
||||
.join(' '); // Join the words with spaces
|
||||
};
|
||||
10
src/utils/index.ts
Normal file
10
src/utils/index.ts
Normal file
@ -0,0 +1,10 @@
|
||||
export * from './Assets';
|
||||
export * from './Data';
|
||||
export * from './Devices';
|
||||
export * from './Dom';
|
||||
export * from './LocalStorage';
|
||||
export * from './Router';
|
||||
export * from './String';
|
||||
export * from './Common';
|
||||
export * from './List';
|
||||
export * from './Object';
|
||||
Reference in New Issue
Block a user