ronaldkwandy

common-helper.ts

Jul 18th, 2022
1,279
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import { MONTH_NAME, MIN_SHOWN_DISCOUNT_PERCENT, MONTH_SHORT_NAME } from 'Helpers/constants';
  2. import { osName, OsTypes, osVersion, browserVersion, browserName, BrowserTypes, isChrome } from 'react-device-detect';
  3. import copy from 'copy-to-clipboard';
  4. import { config } from 'Config/config';
  5. import { ITranslation, translateText, REGION_CODE } from './translation-helper';
  6. import { IRegionData } from 'Redux/reducers/region';
  7. import { IForeignExchangeRate } from './foreign-exchange-helper';
  8.  
  9. export function getStatic(fileName: string) {
  10.   return '/static/' + fileName;
  11. }
  12.  
  13. export function getAbsoluteUrl(path?: string) {
  14.   const slashedPath = path ? (path.startsWith('/') ? path : '/' + path) : '';
  15.   return window.location.origin + slashedPath;
  16. }
  17.  
  18. export function getClientSideValue<T>(value: T, deffaultFalue: T): T {
  19.   return typeof window !== 'undefined' ? value : deffaultFalue;
  20. }
  21.  
  22. export function isNullOrUndefinedHelper(object: any): object is null | undefined {
  23.   return object === undefined || object === null;
  24. }
  25. export const isset = (input: any): boolean => {
  26.   return input !== undefined && input !== null;
  27. };
  28.  
  29. export const getDefault = <T>(input: any, def: T): T => {
  30.   return isset(input) ? input : def;
  31. };
  32.  
  33. export const safeCall = <T extends (...args: any[]) => any>(
  34.   fn: T | null | undefined,
  35.   ...args: Parameters<T>
  36. ): ReturnType<T> | undefined => {
  37.   return fn && fn(...args);
  38. };
  39.  
  40. export function isObjectEmptyHelper(obj: object) {
  41.   if (!obj || typeof obj !== 'object') return true;
  42.   return Object.keys(obj).length === 0;
  43. }
  44.  
  45. export const isJson = (value: any) => {
  46.   if (
  47.     value !== undefined &&
  48.     value !== '' &&
  49.     value !== 0 &&
  50.     /^[\],:{}\s]*$/.test(
  51.       value
  52.         .replace(/\\["\\/bfnrtu]/g, '@')
  53.        .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+-]?\d+)?/g, ']')
  54.         .replace(/(?:^|:|,)(?:\s*\[)+/g, ''),
  55.     )
  56.   ) {
  57.     return true;
  58.   } else {
  59.     return false;
  60.   }
  61. };
  62.  
  63. export const getJson = (value: any) => {
  64.   if (isJson(value)) {
  65.     return JSON.parse(value);
  66.   } else {
  67.     return value;
  68.   }
  69. };
  70.  
  71. export function titleCase(str: string) {
  72.   if (!str || typeof str !== 'string') return str;
  73.   const splitStr = str.replace(/_/g, ' ').toLowerCase().split(' ');
  74.   for (let i = 0; i < splitStr.length; i++) {
  75.     splitStr[i] = splitStr[i].charAt(0).toUpperCase() + splitStr[i].substring(1);
  76.   }
  77.  
  78.   return splitStr.join(' ');
  79. }
  80. export function titleCaseUnder(str: string) {
  81.   if (!str || typeof str !== 'string') return str;
  82.   const splitStr = str.replace(/-/g, ' ').toLowerCase().split(' ');
  83.   for (let i = 0; i < splitStr.length; i++) {
  84.     splitStr[i] = splitStr[i].charAt(0).toUpperCase() + splitStr[i].substring(1);
  85.   }
  86.  
  87.   return splitStr.join(' ');
  88. }
  89.  
  90. export function titleCaseFromCamelCase(str: string) {
  91.   if (!str || typeof str !== 'string') return str;
  92.   let result = str.replace(/([A-Z]+)/g, ' $1').replace(/([A-Z][a-z])/g, ' $1');
  93.   result = result.charAt(0).toUpperCase() + result.substring(1);
  94.  
  95.   return result;
  96. }
  97.  
  98. export function arrayMessage(inputData: { [rule: string]: string[] }) {
  99.   const properties = Object.keys(inputData);
  100.   let message = '';
  101.   for (const i of properties) {
  102.     message = i + ' ' + inputData[i];
  103.   }
  104.  
  105.   return message;
  106. }
  107.  
  108. export function errorMessage(errData: { [rule: string]: any }, fieldName = 'errorMessage') {
  109.   const properties = Object.keys(errData);
  110.   let message = '';
  111.   for (const i of properties) {
  112.     if (typeof errData[i][fieldName] !== 'undefined') {
  113.       message = message + errData[i][fieldName] + ' ';
  114.     }
  115.   }
  116.  
  117.   return message;
  118. }
  119.  
  120. export function numberLimit(nmb: number, nmbMax: number, nmbMin = 1) {
  121.   if (nmb > nmbMax) {
  122.     return nmbMax;
  123.   } else if (nmb < nmbMin) {
  124.     return nmbMin;
  125.   }
  126.  
  127.   return nmb;
  128. }
  129.  
  130. export function getValue(value: any, defaultVal: any = null) {
  131.   return typeof value === 'undefined' ? defaultVal : value;
  132. }
  133.  
  134. export function getValueBoolean(value: any) {
  135.   return typeof value === 'undefined' ? false : value;
  136. }
  137.  
  138. export function issetValue(value: any) {
  139.   return value === undefined || value === null ? false : value;
  140. }
  141.  
  142. export function getObjRefVal(
  143.   objVal: any[], // Haystack
  144.   ref: string,
  145.   idx: number,
  146.   key = 'id',
  147. ): any {
  148.   for (const val of objVal) {
  149.     if (val[key] !== undefined && val[key] === idx) {
  150.       return val[ref];
  151.     }
  152.   }
  153.  
  154.   return null;
  155. }
  156.  
  157. export function getObjectValue(
  158.   val: any, // Haystack
  159.   key: string | string[], // Needle
  160.   defVal: any = null, // Default Value
  161. ): any {
  162.   const datChk = typeof key === 'string' ? [key] : key;
  163.   const isValid = val !== undefined && val[datChk[0]] !== undefined;
  164.   const result = isValid ? val[datChk[0]] : defVal;
  165.  
  166.   if (isValid && datChk.length > 1) {
  167.     return getObjectValue(result, datChk.slice(1), defVal);
  168.   }
  169.  
  170.   return result;
  171. }
  172.  
  173. export function removeDuplicate(arrVal: string[]): any {
  174.   return [...new Set(arrVal)];
  175. }
  176.  
  177. export function getJsonStorageData(name: string, defaultVal: any): any {
  178.   const storageData = localStorage.getItem(name);
  179.   return storageData !== null && isJson(storageData) ? JSON.parse(storageData) : defaultVal;
  180. }
  181.  
  182. export function setJsonStorageData(name: string, val: any): any {
  183.   return localStorage.setItem(name, JSON.stringify(val));
  184. }
  185.  
  186. export const moneyDot = (num: any | undefined | null) => {
  187.   if (num === null || num === undefined) {
  188.     return '';
  189.   } else if (num === 0) {
  190.     return 0;
  191.   }
  192.  
  193.   const str = num.toString().split('.');
  194.  
  195.   if (str[0].length >= 4) {
  196.     str[0] = str[0].replace(/(\d)(?=(\d{3})+$)/g, '$1.');
  197.   }
  198.   if (str[1] && str[1].length >= 4) {
  199.     str[1] = str[1].replace(/(\d{3})/g, '$1 ');
  200.   }
  201.   return str.join(',');
  202. };
  203.  
  204. export const dynamicSort = (property: any) => {
  205.   let sortOrder = 1;
  206.   if (property[0] === '-') {
  207.     sortOrder = -1;
  208.     property = property.substr(1);
  209.   }
  210.   return (a: any, b: any) => {
  211.     const result = a[property] < b[property] ? -1 : a[property] > b[property] ? 1 : 0;
  212.     return result * sortOrder;
  213.   };
  214. };
  215.  
  216. export const dateHelper = (date: string, hideTime?: boolean, shortMonth?: boolean) => {
  217.   if (!date) {
  218.     return '-';
  219.   }
  220.  
  221.   const d = customDateConstructor(date);
  222.  
  223.   const newDate =
  224.     d.getDate() + ' ' + (shortMonth ? MONTH_SHORT_NAME[d.getMonth()] : MONTH_NAME[d.getMonth()]) + ' ' + d.getFullYear();
  225.   const newTime = zeroFormat(d.getHours()) + ':' + zeroFormat(d.getMinutes());
  226.  
  227.   return newDate + (hideTime ? '' : ' pukul ' + newTime);
  228. };
  229.  
  230. // use this function if need to convert timezone by region in FE
  231. export const timezoneDateHelper = (date: string, region: IRegionData | any, hideTime?: boolean, shortMonth?: boolean, showDay?: boolean) => {
  232.   if (!date) {
  233.     return '-';
  234.   }
  235.  
  236.   const d = customDateConstructor(date);
  237.   const timeZone = region ? region.country_timezone : 'Asia/Jakarta';
  238.   const locale = region ? region.default_locale_id : 'id-ID';
  239.   const dayOptions: any = {
  240.     timeZone: timeZone,
  241.     weekday: 'long',
  242.   };
  243.   const dateOptions: any = {
  244.     timeZone: timeZone,
  245.     year: 'numeric',
  246.     month: shortMonth == undefined ? 'long' : (shortMonth ? 'short' : 'long'),
  247.     day: 'numeric',
  248.   };
  249.   const timeOptions: any = {
  250.     timeZone: timeZone,
  251.     hour: 'numeric',
  252.     minute: 'numeric',
  253.   };
  254.  
  255.   if (!region || region.country_code == REGION_CODE.INDONESIA) {
  256.     return dateHelper(date, hideTime, shortMonth);
  257.   } else {
  258.     let options = { ...dateOptions };
  259.     if (!hideTime) {
  260.       options = { ...options, ...timeOptions };
  261.     }
  262.     if (showDay) {
  263.       options = { ...options, ...dayOptions };
  264.     }
  265.     return d.toLocaleString(locale, options);
  266.   }
  267. };
  268.  
  269. export const customDateConstructor = (date: string) => {
  270.   return isIos() || isSafari() ? convertDateForIos(date) : new Date(date);
  271. };
  272.  
  273. export const detailedDateHelper = (date: string, hideTime?: boolean) => {
  274.   const d = customDateConstructor(date);
  275.   const monthNames = ['Jan', 'Feb', 'Mar', 'Apr', 'Mei', 'Jun', 'Jul', 'Agu', 'Sep', 'Okt', 'Nov', 'Des'];
  276.  
  277.   const newDate = d.getDate() + ' ' + monthNames[d.getMonth()] + ' ' + d.getFullYear();
  278.   const newTime =
  279.     ' - ' + zeroFormat(d.getHours()) + ':' + zeroFormat(d.getMinutes()) + ':' + zeroFormat(d.getSeconds());
  280.  
  281.   return newDate + (hideTime ? '' : ' ' + newTime);
  282. };
  283.  
  284. export function convertDateForIos(date: string) {
  285.   const normalDate = new Date(date);
  286.   if (isNaN(normalDate.getDate())) {
  287.     const arr = date.split(/[- :]/);
  288.     const intArray = arr.map((element) => parseInt(element));
  289.     const parsedDate = new Date(intArray[0], intArray[1] - 1, intArray[2], intArray[3], intArray[4], intArray[5]);
  290.     return parsedDate;
  291.   } else {
  292.     return normalDate;
  293.   }
  294. }
  295.  
  296. export const zeroFormat = (num: any) => {
  297.   return num < 10 ? '0' + num : num;
  298. };
  299.  
  300. export const objectSearch = (value: any, nameKey: any, myArray: any) => {
  301.   for (let i = 0; i < myArray.length; i++) {
  302.     if (myArray[i][nameKey] === value) {
  303.       return i;
  304.     }
  305.   }
  306.   return false;
  307. };
  308.  
  309. export const inArray = (needle: number | string, haystack: any[]): boolean => {
  310.   const length = haystack.length;
  311.   for (let i = 0; i < length; i++) {
  312.     if (haystack[i] === needle) {
  313.       return true;
  314.     }
  315.   }
  316.   return false;
  317. };
  318.  
  319. export const isFile = (value: any, checkType?: string) => {
  320.   return (
  321.     value !== undefined &&
  322.     value.name !== undefined &&
  323.     value.size !== undefined &&
  324.     (checkType === undefined || value.name.substring(value.name.lastIndexOf('.') + 1) === checkType)
  325.   );
  326. };
  327.  
  328. export const processCSV = (fileStream: string | ArrayBuffer | null) => {
  329.   let csvObj: any = [];
  330.   if (typeof fileStream === 'string') {
  331.     csvObj = fileStream.split('\n');
  332.     if (csvObj.length) {
  333.       csvObj.forEach((el: string, idx: number) => {
  334.         csvObj[idx] = el.split(',');
  335.       });
  336.     }
  337.   }
  338.  
  339.   return csvObj;
  340. };
  341.  
  342. export function isSupportWebp() {
  343.   const isMac = osName === OsTypes.MAC_OS;
  344.   const isApple = osName === OsTypes.IOS;
  345.   if (isApple) {
  346.     const isNewSafari = isSafari() && parseFloat(browserVersion) >= 14;
  347.     return isNewSafari || isChrome;
  348.   }
  349.   if (isMac) {
  350.     const isMacBigSur = parseFloat(osVersion) >= 11;
  351.     const isNewSafari = browserName === BrowserTypes.Safari && parseFloat(browserVersion) >= 14;
  352.     return isMacBigSur && isNewSafari;
  353.   } else {
  354.     return true;
  355.   }
  356. }
  357.  
  358. export function isNaNOrUndefinedHelper<T = number>(
  359.   userIdNumber: number | undefined,
  360.   defaultValue: T | null = null,
  361. ): T | number | null {
  362.   return userIdNumber ? (isNaN(userIdNumber) ? defaultValue : userIdNumber) : defaultValue;
  363. }
  364.  
  365. export const isImage = (extension?: string) => {
  366.   const imageExtension = ['.webp', '.png', '.jpg', '.jpeg'];
  367.   return extension && imageExtension.includes(extension);
  368. };
  369.  
  370. export function newGenImage(url: string) {
  371.   const isHttp = url?.slice(0, 4) === 'http';
  372.  
  373.   if (isHttp && url) {
  374.     const urlExtension = url.split('.').pop();
  375.     // because some image return like this
  376.     const newUrl = isImage(`.${urlExtension}`) ? url?.replace(`.${urlExtension}`, '.webp') : url + '.webp';
  377.     return newUrl;
  378.   } else {
  379.     return url;
  380.   }
  381. }
  382.  
  383. export const phoneFormatHelper = (phoneNumber: string, reverse?: boolean) => {
  384.   if (phoneNumber) {
  385.     if (reverse) {
  386.       if (phoneNumber.substring(0, 3) === '628') {
  387.         return '08' + phoneNumber.substring(3);
  388.       }
  389.     } else if (phoneNumber.substring(0, 2) === '08') {
  390.       return '628' + phoneNumber.substring(2);
  391.     }
  392.     return phoneNumber;
  393.   }
  394.   return '';
  395. };
  396.  
  397. export const phoneVisualFormatHelper = (phonenumber: string) => {
  398.   phonenumber = phoneFormatHelper(phonenumber, true);
  399.   return `${phonenumber.slice(0, 4)}-${phonenumber.slice(4, 8)}-${phonenumber.slice(8)}`;
  400. };
  401.  
  402. export function isMobile() {
  403.   return typeof window !== 'undefined' ? /(android|iphone|ipad|mobile)/i.test(navigator.userAgent) : false;
  404. }
  405.  
  406. export function isIos() {
  407.   return typeof window !== 'undefined'
  408.     ? /iPad|iPhone|iPod|Mac/.test(navigator.platform) ||
  409.         (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1)
  410.     : false;
  411. }
  412.  
  413. export function isSafari() {
  414.   return typeof window !== 'undefined' ? /^((?!chrome|android).)*safari/i.test(navigator.userAgent) : false;
  415. }
  416.  
  417. export function getBlobUrlFromFile(file: File) {
  418.   return URL.createObjectURL(file);
  419. }
  420.  
  421. export async function blobUrlToFile(url: string, filename: string, mimeType: string) {
  422.   const options = {
  423.     type: mimeType,
  424.   };
  425.   return window
  426.     .fetch(url)
  427.     .then((res: any) => {
  428.       return res.blob();
  429.     })
  430.     .then((blob: any) => {
  431.       return new window.File([blob], filename, options);
  432.     });
  433. }
  434.  
  435. export function secondsToDayHourMinuteFormat(seconds: number, translation: ITranslation) {
  436.   const days = Math.floor(seconds / (3600 * 24));
  437.   const hour = Math.floor((seconds % (3600 * 24)) / 3600);
  438.   const minute = Math.floor((seconds % 3600) / 60);
  439.  
  440.   const dayText = translateText('{{count}}_hari', translation.languageCode, translation.languageList, { count: days });
  441.   const hourText = translateText('{{count}}_jam', translation.languageCode, translation.languageList, { count: hour });
  442.   const minuteText = translateText('{{count}}_menit', translation.languageCode, translation.languageList, { count: minute });
  443.  
  444.   const dDisplay = days > 0 ? dayText + ' ' : '';
  445.   const hDisplay = hour > 0 ? hourText + ' ' : '';
  446.   const mDisplay = minute > 0 ? minuteText : '';
  447.  
  448.   return dDisplay + hDisplay + mDisplay;
  449. }
  450.  
  451. export const localNumberUnitFormat = (inNumber: number, translation: ITranslation) => {
  452.   const millionText = translateText('juta', translation.languageCode, translation.languageList);
  453.   const billionText = translateText('milyar', translation.languageCode, translation.languageList);
  454.   const trillionText = translateText('trilliun', translation.languageCode, translation.languageList);
  455.  
  456.   const unit = ['', millionText, billionText, trillionText];
  457.   const unitAmount = [1, 1000000, 1000000000, 1000000000000];
  458.   let biggestUnitIndex = -1;
  459.   let numberByUnit = 0.0;
  460.   for (let i = unit.length - 1; i >= 0; i--) {
  461.     if (inNumber >= unitAmount[i]) {
  462.       biggestUnitIndex = i;
  463.       numberByUnit = inNumber / unitAmount[i];
  464.       break;
  465.     }
  466.   }
  467.   let unitString = '';
  468.   if (biggestUnitIndex >= 0) {
  469.     unitString = unit[biggestUnitIndex];
  470.     if (unitString !== '') {
  471.       unitString = ' ' + unitString;
  472.     }
  473.   }
  474.   return numberByUnit + unitString;
  475. };
  476. // try to take from laravel https://github.com/laravel/framework/blob/9.x/src/Illuminate/Support/Str.php
  477. export function convertToSlug(str: string) {
  478.   if (typeof str !== 'string') return str;
  479.   return str
  480.     .toLowerCase()
  481.   // Convert all underscores into -
  482.     .replace(/_/g, ' ')
  483.   // Remove all characters that are not  -, letters, numbers, or whitespace.
  484.     .replace(/[^\w\s-]+/g, '')
  485.   // Convert all white space into singgle space
  486.     .replace(/\s+/g, ' ')
  487.     .trim()
  488.   // Convert all white space to -
  489.     .replace(/ /g, '-');
  490. }
  491.  
  492. export function stringToBoolean(str: string) {
  493.   let bool;
  494.   if (str === 'true') {
  495.     bool = true;
  496.   } else if (str === '1') {
  497.     bool = true;
  498.   } else {
  499.     bool = false;
  500.   }
  501.   return bool;
  502. }
  503.  
  504. export function arrayToSentence(arr: string[]) {
  505.   if (arr.length === 0) return '';
  506.   if (arr.length === 1) return arr[0];
  507.   const strArr = [...arr];
  508.   const last = strArr.pop();
  509.   return strArr.join(', ') + ' dan ' + last;
  510. }
  511.  
  512. export function isSlug(params: string) {
  513.   return /^[\w\s-]+$/.test(params);
  514. }
  515.  
  516. export function isAlphaNumericSpace(str: string) {
  517.   return /^[\w\s]+$/.test(str);
  518. }
  519.  
  520. export function isProductKeywordSafe(str: string) {
  521.   return /^[\w\s-()|'.+,!\\/$]+$/.test(str);
  522. }
  523.  
  524. export const stringToSlug = (input: string) => {
  525.   input = input.replace(/^\s+|\s+$/g, ''); // trim
  526.   input = input.toLowerCase();
  527.  
  528.   input = input
  529.     .replace(/[^a-z0-9 -]/g, '')
  530.     .replace(/\s+/g, '-')
  531.     .replace(/-+/g, '-');
  532.  
  533.   return input;
  534. };
  535. export const getRandomNumber = (min: number, max: number) => {
  536.   return Math.floor(Math.random() * (max - min) + min);
  537. };
  538. export function arrayObjectToArray(obj: Array<object>, index: string) {
  539.   const temp: any = [];
  540.   const objTemp: any = {};
  541.  
  542.   try {
  543.     obj.forEach((data: any) => {
  544.       temp.push(data[index]);
  545.       objTemp[data[index]] = data;
  546.     });
  547.     return { temp, objTemp };
  548.   } catch (e) {
  549.     return { temp, objTemp };
  550.   }
  551. }
  552.  
  553. export function filterObjectUndefinedProp(data: any) {
  554.   return Object.keys(data).reduce((acc: any, key: string) => {
  555.     const value = data[key];
  556.     return value === undefined || value === '' ? acc : { ...acc, [key]: data[key] };
  557.   }, {});
  558. }
  559. export function addSpaceOn4thChar(value: any) {
  560.   if (value) {
  561.     value = value.replace(/\W/gi, '').replace(/(.{4})/g, '$1 ');
  562.     value = value.trimEnd();
  563.     return value;
  564.   } else {
  565.     return '';
  566.   }
  567. }
  568.  
  569. export function toCommaDelimiter(number: number) {
  570.   return number.toString().split('.').join(',');
  571. }
  572.  
  573. export function formatMilisecondsToTimeRemaining(duration: number) {
  574.   if (duration < 0) return '00:00:00';
  575.   const seconds = Math.floor((duration / 1000) % 60);
  576.   const minutes = Math.floor((duration / (1000 * 60)) % 60);
  577.   const hours = Math.floor((duration / (1000 * 60 * 60)) % 24);
  578.  
  579.   const strHours = hours < 10 ? '0' + hours : hours;
  580.   const strMinutes = minutes < 10 ? '0' + minutes : minutes;
  581.   const strSeconds = seconds < 10 ? '0' + seconds : seconds;
  582.  
  583.   return strHours + ':' + strMinutes + ':' + strSeconds;
  584. }
  585.  
  586. export function numberToDayOfWeek(number: number) {
  587.   if (number > 6 || number < 0) return '';
  588.   const day = ['Minggu', 'Senin', 'Selasa', 'Rabu', 'Kamis', 'Jumat', 'Sabtu'];
  589.   return day[number];
  590. }
  591.  
  592. export function unixTimeToDayInNumber(date: string) {
  593.   const dateTest = Date.parse(date);
  594.   const today = new Date().getTime();
  595.   const expireDay = Math.round((dateTest - today) / 86400000);
  596.   return expireDay;
  597. }
  598.  
  599. export function formatDayDateTimeWIB(date: Date) {
  600.   const day = numberToDayOfWeek(date.getDay());
  601.   const formattedDate = dateHelper(date.toString());
  602.   return `${day}, ${formattedDate} WIB`;
  603. }
  604.  
  605. // use this function if need to convert timezone by region in FE
  606. export function timezoneFormatDayDateTime(date: Date, region: IRegionData) {
  607.   if (!region || region.country_code == REGION_CODE.INDONESIA) {
  608.     const formattedDate = dateHelper(date.toString());
  609.     const day = numberToDayOfWeek(date.getDay());
  610.     return `${day}, ${formattedDate} WIB`;
  611.   } else {
  612.     return timezoneDateHelper(date.toString(), region, false, false, true);
  613.   }
  614. }
  615.  
  616. export function msToMinutes(ms: number) {
  617.   return Math.floor(ms / 60000);
  618. }
  619.  
  620. export function timeIsBetweenHours(time: Date, startHour: number, endHour: number, options?: { gmt?: number }) {
  621.   let currMinutes = time.getHours() * 60 + time.getMinutes();
  622.   if (options && options.gmt !== null && options.gmt !== undefined) {
  623.     const offsetMins = time.getTimezoneOffset();
  624.     const utcMinutes = currMinutes + offsetMins;
  625.     currMinutes = utcMinutes + options.gmt * 60;
  626.   }
  627.   if (currMinutes < 0) currMinutes += 1440;
  628.   if (currMinutes >= 1440) currMinutes -= 1440;
  629.   const startMinutes = startHour * 60;
  630.   const endMinutes = endHour * 60;
  631.   return currMinutes > startMinutes && currMinutes < endMinutes;
  632. }
  633.  
  634. export function isGmail(data: string) {
  635.   const mailFormat = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/;
  636.  if (data.match(mailFormat)) {
  637.    const mailSplit = data.split('@');
  638.    if (mailSplit[1].search(/gmail/) == 0) {
  639.      return true;
  640.    } else {
  641.      return false;
  642.    }
  643.  } else {
  644.    return false;
  645.  }
  646. }
  647.  
  648. export function arrayIntersects(array1: any[], array2: any[]) {
  649.  if (array1) {
  650.    return array1.some((item: any) => array2.includes(item));
  651.  }
  652. }
  653.  
  654. export function discountCalc(price: number, competitorPrice: number) {
  655.  if (competitorPrice) {
  656.    const value = Math.round(((competitorPrice - price) / competitorPrice) * 100);
  657.    return value >= MIN_SHOWN_DISCOUNT_PERCENT ? value : 0;
  658.  }
  659.  return 0;
  660. }
  661.  
  662. export function getWithdrawAmount(balance: number, topupLimit: number, options = { multiplier: 1000, minimum: 20000 }) {
  663.  if (topupLimit >= balance) return 0;
  664.  const difference = balance - topupLimit;
  665.  if (difference < options.minimum) return options.minimum;
  666.  const withdraw = Math.ceil(difference / options.multiplier) * options.multiplier;
  667.  return withdraw;
  668. }
  669.  
  670. export function getTopUpAmount(balance: number, totalPayment: number, options = { multiplier: 1000, minimum: 10000 }) {
  671.  if (totalPayment <= balance) return 0;
  672.  const difference = totalPayment - balance;
  673.  if (difference < options.minimum) return options.minimum;
  674.  const topup = Math.ceil(difference / options.multiplier) * options.multiplier;
  675.  return topup;
  676. }
  677.  
  678. export function getDayCountBetween(startDate: Date, endDate: Date) {
  679.  const millisecondsPerDay = 24 * 60 * 60 * 1000;
  680.  return (endDate.getTime() - startDate.getTime()) / millisecondsPerDay;
  681. }
  682. export const doCopy = (text: string) => {
  683.  navigator.clipboard.writeText(text);
  684. };
  685. export const toPascalCase = (text: string | undefined) => {
  686.  if (!text || typeof text !== 'string') return text;
  687.  return text
  688.    .replace(/(\w)(\w*)/g, (_g0, g1, g2) => {
  689.      return g1.toUpperCase() + g2.toLowerCase();
  690.    })
  691.    .replace(/\s/g, '');
  692. };
  693. export const arrayObjectToArrayValue = (array: any[], valueName: string) => {
  694.  return array.map((val: any) => {
  695.    return val[valueName];
  696.  });
  697. };
  698.  
  699. export function durationHandler(startTime: string, endTime: string) {
  700.  const startDate = customDateConstructor(startTime);
  701.  const endData = customDateConstructor(endTime);
  702.  const isSameMonth = startDate.getMonth() === endData.getMonth();
  703.  const isSameYear = startDate.getFullYear() === endData.getFullYear();
  704.  let startMounth = '';
  705.  const startYear = isSameYear ? '' : `${startDate.getFullYear()} `;
  706.  if (isSameYear) {
  707.    startMounth = isSameMonth ? '' : MONTH_NAME[startDate.getMonth()] + ' ';
  708.  } else {
  709.    startMounth = MONTH_NAME[startDate.getMonth()] + ' ';
  710.  }
  711.  
  712.  const initalString = `${startDate.getDate()} ${startMounth}${startYear}`;
  713.  return `${initalString} - ${dateHelper(endTime, true)}`;
  714. }
  715.  
  716. export function addDurationDate(date: string, duration: number, region: IRegionData) {
  717.  date = date.replace(/ /g, 'T');
  718.  const endDate = new Date(date);
  719.  endDate.setDate(endDate.getDate() + duration);
  720.  
  721.  const customEndDate = customDateConstructor(endDate.toString());
  722.  return timezoneDateHelper(customEndDate.toString(), region, false, false, false);
  723. }
  724.  
  725. export async function copyText(text: string) {
  726.  if (typeof text !== 'string') return;
  727.  const fallbackCopy = () => {
  728.    try {
  729.      copy(text);
  730.    } catch (error) {
  731.      // Give up trying to copy
  732.      throw Error(error as any);
  733.    }
  734.  };
  735.  
  736.  // New clipboard API for modern browser
  737.  if (navigator?.clipboard?.writeText) {
  738.    try {
  739.      await navigator.clipboard.writeText(text);
  740.    } catch (error) {
  741.      fallbackCopy();
  742.    }
  743.  } else {
  744.    // Fallback for old browser, update if document.execCommand('copy') is not longer supported.
  745.    fallbackCopy();
  746.  }
  747. }
  748.  
  749. export const stringBuilder = (text: string, params: Record<string, string>) => {
  750.  let tempText = text;
  751.  Object.keys(params).forEach((key) => {
  752.    tempText = tempText.replace(`{${key}}`, params[key]);
  753.  });
  754.  return tempText;
  755. };
  756.  
  757. export const getMsDifferenceBetweenDates = (
  758.  startDate: Date,
  759.  endDate: Date,
  760.  options?: { startDateGmt?: number; endDateGmt?: number },
  761. ) => {
  762.  const minutesToMs = 60000;
  763.  
  764.  let startTime = startDate.getTime();
  765.  if (options && options.startDateGmt !== null && options.startDateGmt !== undefined) {
  766.    const offsetTime = startDate.getTimezoneOffset() * minutesToMs;
  767.    const utcTime = startTime + offsetTime;
  768.    startTime = utcTime + options.startDateGmt * 60 * minutesToMs;
  769.  }
  770.  
  771.  let endTime = endDate.getTime();
  772.  if (options && options.endDateGmt !== null && options.endDateGmt !== undefined) {
  773.    const offsetTime = endDate.getTimezoneOffset() * minutesToMs;
  774.    const utcTime = endTime + offsetTime;
  775.    endTime = utcTime + options.endDateGmt * 60 * minutesToMs;
  776.  }
  777.  
  778.  return endTime - startTime;
  779. };
  780.  
  781. export const stringToArrayNumber = (string: string) => {
  782.  if (string) {
  783.    return string.slice(1, -1).split(',').map(Number);
  784.  }
  785.  return [];
  786. };
  787.  
  788. export const sleep = (ms: number) => {
  789.  return new Promise((resolve) => setTimeout(resolve, ms));
  790. };
  791.  
  792. export const removeUndefinedValue = (value: { [key: string]: any }) => {
  793.  const newObjectValue = { ...value };
  794.  Object.keys(newObjectValue).forEach((key: any) => {
  795.    if (newObjectValue[key] === null || newObjectValue[key] === undefined) {
  796.      delete newObjectValue[key];
  797.    }
  798.  });
  799.  return newObjectValue;
  800. };
  801.  
  802. export const replaceUndefinedPropsToNull = <T>(object: { [key: string]: any }) => {
  803.  if (!object || typeof object !== 'object') return object;
  804.  for (const key in object) {
  805.    if (object[key] === undefined) object[key] = null;
  806.  }
  807.  return object as T;
  808. };
  809.  
  810. export const parseStringArray = <T>(str: string) => {
  811.  try {
  812.    const result = JSON.parse(str);
  813.    if (!Array.isArray(result)) return [];
  814.    return result as T[];
  815.  } catch {
  816.    return [] as T[];
  817.  }
  818. };
  819.  
  820. export const isProduction = () => {
  821.  return config.environment === 'production';
  822. };
  823.  
  824. export const isDevelopment = () => {
  825.  return config.environment === 'development' || config.environment === 'local';
  826. };
  827.  
  828. export const capitalizeFirstLetter = (str: string) => {
  829.  if (!str || typeof str !== 'string') return str;
  830.  return str.charAt(0).toUpperCase() + str.slice(1);
  831. };
  832.  
  833. export const isNotificationAPISupported = (): boolean => (typeof window !== 'undefined') && ('Notification' in window);
  834.  
  835. export const replaceAll = (text: string, key: string, replace: string) => {
  836.  return text.replace(new RegExp(key, 'g'), replace);
  837.  
  838. };
  839.  
  840. export const exchangeRateConversionHelper = (foreignExchangeRate: IForeignExchangeRate | any, region: IRegionData | any, amount: number | null): number => {
  841.  if (!amount || !foreignExchangeRate) { return 0; }
  842.  if ((region.country_code == REGION_CODE.INDONESIA) || foreignExchangeRate.source_currency == 'IDR' && foreignExchangeRate.target_currency == 'IDR') {
  843.    return amount;
  844.  }
  845.  const locale = region ? region.default_locale_id : 'id-ID';
  846.  // eslint-disable-next-line @babel/new-cap
  847.  const formater = Intl.NumberFormat(locale, {
  848.    maximumFractionDigits: 2,
  849.  });
  850.  return parseFloat(formater.format((amount / foreignExchangeRate.exchange_rate)));
  851. };
  852.  
  853. export const currencyHelper = (foreignExchangeRate: IForeignExchangeRate | any, region: IRegionData | any, amount: number | null, isConverted: boolean = false): string => {
  854.  if (amount == null || amount == undefined || !foreignExchangeRate) { return ''; }
  855.  if (amount <= 0) { amount = 0; }
  856.  if ((region.country_code == REGION_CODE.INDONESIA) || foreignExchangeRate.source_currency == 'IDR' && foreignExchangeRate.target_currency == 'IDR') {
  857.    return `Rp${moneyDot(amount)}`;
  858.  }
  859.  const locale = region ? region.default_locale_id : 'id-ID';
  860.  let convertedAmounts = amount / foreignExchangeRate.exchange_rate;
  861.  let truncVal = Math.trunc(convertedAmounts * 1000) / 1000;
  862.  let roundedVal = Math.round((truncVal + Number.EPSILON) * 100) / 100;
  863.  let result = (isConverted ? amount : roundedVal).toLocaleString(locale, { style: 'currency', currency: foreignExchangeRate.source_currency, maximumFractionDigits: 2 });
  864.  return result;
  865. };
  866.  
Advertisement
Add Comment
Please, Sign In to add comment