2025-05-23 16:26:02 +03:00
import { PUBLIC_B2_BUCKET , PUBLIC_B2_ENDPOINT } from "$env/static/public" ;
2025-05-21 21:34:22 +03:00
import { clsx , type ClassValue } from "clsx" ;
import { twMerge } from "tailwind-merge" ;
export function cn ( . . . inputs : ClassValue [ ] ) {
2025-05-24 17:50:42 +03:00
return twMerge ( clsx ( inputs ) ) ;
2025-05-21 21:34:22 +03:00
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export type WithoutChild < T > = T extends { child? : any } ? Omit < T , "child" > : T ;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export type WithoutChildren < T > = T extends { children? : any } ? Omit < T , "children" > : T ;
export type WithoutChildrenOrChild < T > = WithoutChildren < WithoutChild < T > > ;
export type WithElementRef < T , U extends HTMLElement = HTMLElement > = T & { ref? : U | null } ;
2025-05-22 14:00:43 +03:00
export function getTimeBasedGreeting ( name : string ) : string {
const hour = new Date ( ) . getHours ( ) ;
2025-05-24 17:50:42 +03:00
2025-05-22 14:00:43 +03:00
if ( hour < 12 ) {
return ` Good morning, ${ name } ` ;
} else if ( hour < 17 ) {
return ` Good afternoon, ${ name } ` ;
} else if ( hour < 22 ) {
return ` Good evening, ${ name } ` ;
} else {
return ` Good night, ${ name } ` ;
}
}
2025-05-23 16:26:02 +03:00
export function getPublicUrl ( key : string | null ) : string | null {
if ( ! key ) return null ;
return ` ${ PUBLIC_B2_ENDPOINT } / ${ PUBLIC_B2_BUCKET } / ${ key } ` ;
}
export function debounce ( func : ( . . . args : any [ ] ) = > void , wait : number ) {
2025-05-25 12:06:04 +03:00
let timeout : ReturnType < typeof setTimeout > | undefined ;
2025-05-23 16:26:02 +03:00
return function executedFunction ( . . . args : any [ ] ) {
const later = ( ) = > {
clearTimeout ( timeout ) ;
func ( . . . args ) ;
} ;
clearTimeout ( timeout ) ;
timeout = setTimeout ( later , wait ) ;
} ;
2025-05-24 15:50:10 +03:00
}
export function formatPrice ( price : number ) : string {
if ( price < 0.01 ) {
return price . toFixed ( 6 ) ;
} else if ( price < 1 ) {
return price . toFixed ( 4 ) ;
} else {
return price . toLocaleString ( undefined , {
minimumFractionDigits : 2 ,
maximumFractionDigits : 2
} ) ;
}
}
export function formatValue ( value : number ) : string {
if ( value >= 1 e9 ) return ` $ ${ ( value / 1 e9 ) . toFixed ( 2 ) } B ` ;
if ( value >= 1 e6 ) return ` $ ${ ( value / 1 e6 ) . toFixed ( 2 ) } M ` ;
if ( value >= 1 e3 ) return ` $ ${ ( value / 1 e3 ) . toFixed ( 2 ) } K ` ;
return ` $ ${ value . toFixed ( 2 ) } ` ;
}
export function formatQuantity ( value : number ) : string {
if ( value >= 1 e9 ) return ` ${ ( value / 1 e9 ) . toFixed ( 2 ) } B ` ;
if ( value >= 1 e6 ) return ` ${ ( value / 1 e6 ) . toFixed ( 2 ) } M ` ;
if ( value >= 1 e3 ) return ` ${ ( value / 1 e3 ) . toFixed ( 2 ) } K ` ;
return value . toLocaleString ( ) ;
}
export function formatDate ( timestamp : string ) : string {
const date = new Date ( timestamp ) ;
return date . toLocaleDateString ( 'en-US' , {
month : 'short' ,
day : 'numeric' ,
hour : '2-digit' ,
minute : '2-digit'
} ) ;
}
2025-05-24 17:50:42 +03:00
export function formatRelativeTime ( timestamp : string | Date ) : string {
const now = new Date ( ) ;
const past = new Date ( timestamp ) ;
const ms = now . getTime ( ) - past . getTime ( ) ;
const seconds = Math . floor ( ms / 1000 ) ;
const minutes = Math . floor ( seconds / 60 ) ;
const hours = Math . floor ( minutes / 60 ) ;
const days = Math . floor ( hours / 24 ) ;
if ( seconds < 60 ) return ` ${ seconds } s ` ;
if ( minutes < 60 ) return ` ${ minutes } m ` ;
2025-05-24 19:28:38 +03:00
2025-05-24 17:50:42 +03:00
if ( hours < 24 ) {
const extraMinutes = minutes % 60 ;
return extraMinutes === 0 ? ` ${ hours } hr ` : ` ${ hours } hr ${ extraMinutes } m ` ;
}
if ( days < 7 ) return ` ${ days } d ` ;
const yearsDiff = now . getFullYear ( ) - past . getFullYear ( ) ;
const monthsDiff = now . getMonth ( ) - past . getMonth ( ) ;
const totalMonths = yearsDiff * 12 + monthsDiff ;
const adjustedMonths = totalMonths + ( now . getDate ( ) < past . getDate ( ) ? - 1 : 0 ) ;
const years = Math . floor ( adjustedMonths / 12 ) ;
if ( adjustedMonths < 1 ) {
const weeks = Math . floor ( days / 7 ) ;
const extraDays = days % 7 ;
return extraDays === 0 ? ` ${ weeks } w ` : ` ${ weeks } w ${ extraDays } d ` ;
}
if ( years < 1 ) {
const tempDate = new Date ( past ) ;
tempDate . setMonth ( tempDate . getMonth ( ) + adjustedMonths ) ;
const remainingDays = Math . floor ( ( now . getTime ( ) - tempDate . getTime ( ) ) / ( 1000 * 60 * 60 * 24 ) ) ;
const weeks = Math . floor ( remainingDays / 7 ) ;
return weeks === 0 ? ` ${ adjustedMonths } m ` : ` ${ adjustedMonths } m ${ weeks } w ` ;
}
const remainingMonths = adjustedMonths % 12 ;
return remainingMonths === 0 ? ` ${ years } y ` : ` ${ years } y ${ remainingMonths } m ` ;
}
2025-05-24 19:28:38 +03:00
export function formatTimeAgo ( date : string ) {
const now = new Date ( ) ;
const commentDate = new Date ( date ) ;
const diffMs = now . getTime ( ) - commentDate . getTime ( ) ;
const diffMins = Math . floor ( diffMs / ( 1000 * 60 ) ) ;
const diffHours = Math . floor ( diffMs / ( 1000 * 60 * 60 ) ) ;
const diffDays = Math . floor ( diffMs / ( 1000 * 60 * 60 * 24 ) ) ;
if ( diffMins < 1 ) return 'Just now' ;
if ( diffMins < 60 ) return ` ${ diffMins } m ago ` ;
if ( diffHours < 24 ) return ` ${ diffHours } h ago ` ;
return ` ${ diffDays } d ago ` ;
}
2025-05-24 17:50:42 +03:00
export const formatMarketCap = formatValue ;