Files
bewell-in-ua/lib/utils.ts
2025-02-07 08:34:42 +02:00

160 lines
3.9 KiB
TypeScript

import {Prisma} from '@prisma/client'
import bcrypt from 'bcryptjs'
import {type ClassValue, clsx} from 'clsx'
import {getLocale} from 'next-intl/server'
import slugify from 'slugify'
import {twMerge} from 'tailwind-merge'
import {i18nDefaultLocale} from '@/i18n-config'
/**
* Just output dump using pretty output
*
* @param variable
*/
export function dump(variable: any): [string, string] {
return [
(new Error().stack?.split('\n')[2]?.trim().split(' ')[1] as string) + ' ',
JSON.stringify(variable, null, 2)
]
}
export const toPrice = (price: any) => parseFloat(price).toFixed(2)
/**
* Create fallback avatar for showing during login process or in case if empty
*
* @param name
*/
export const avatarFallback = (name: string): string =>
name
? name
.split(' ')
.slice(0, 2)
.map(w => w[0])
.join('')
.toUpperCase()
: 'U'
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs))
}
/**
* Slugify the string based on locale using kebab case
*
* @param string
* @param locale
*/
export function slug(string: string, locale: string = 'uk'): string {
return slugify(string, {
lower: true,
strict: true,
locale
})
}
export const formatNumberWithDecimal = (num: number): string => {
const [int, decimal] = num.toString().split('.')
return decimal ? `$(num).${decimal.padEnd(2, '0')}` : int
}
export const toInt = (input: unknown): number | null => {
let output = NaN
if (typeof input === 'string' || typeof input === 'number') {
output = parseInt(input as string, 10)
}
if (isNaN(output)) {
console.log('input invalid type: ', typeof input)
return null
}
return output
}
export const hashPassword = async (value: string): Promise<string> => {
return bcrypt.hash(value, 10)
}
export const verifyHashedPassword = async (
value: string,
hashPassword: string
): Promise<boolean> => {
return await bcrypt.compare(value, hashPassword)
}
/**
* Remove empty properties from the object
*
* @param queryParams
*/
export const cleanEmptyParams = (queryParams: any) => {
return Object.keys(queryParams)
.filter(key => queryParams[key] != '')
.reduce((acc, key) => Object.assign(acc, {[key]: queryParams[key]}), {})
}
/**
* Replace null value with empty string for the object and array of them as well
*
* @param data
*/
export const toEmptyParams = (data: object | object[]) => {
const result = []
const isArray = Array.isArray(data)
const toProcess: object[] = isArray ? data : [data]
for (let x in toProcess) {
const norm = Object.keys(toProcess[x]).reduce(
(obj: {}, key: string) =>
Object.assign(obj, {
// @ts-ignore
[key]: toProcess[x][key] === null ? '' : toProcess[x][key]
}),
{}
)
if (!isArray) return norm
result.push(norm)
}
return result
}
export const thisLocales = async (locales: any) => {
const loc = await getLocale()
return locales.filter((locale: any) => locale.lang === loc)
}
export const thisLocale = async (locales: any) => {
const loc = await getLocale()
return locales.find((locale: any) => locale.lang === loc)
}
export const dbErrorHandling = (e: unknown, message?: string | null) => {
if (e instanceof Prisma.PrismaClientKnownRequestError) {
return {error: `${e.code}: ${e.message}`}
} else if ((e as {code: string}).code === 'ETIMEDOUT') {
return {
error:
'Неможливо підключитися до бази даних. Будь ласка, спробуйте згодом.'
}
} else if ((e as {code: string}).code === '503') {
return {
error: 'Сервіс тимчасово недоступний. Будь ласка, спробуйте згодом.'
}
} else {
return {error: 'Сталася несподівана помилка. Будь ласка, спробуйте згодом.'}
}
}
/**
* Check if the object is empty
*
* @param obj
*/
export const isEmptyObj = (obj: object): boolean =>
Object.keys(obj).length === 0