115 lines
2.7 KiB
TypeScript
115 lines
2.7 KiB
TypeScript
import type { ClassValue } from 'clsx'
|
|
import { clsx } from 'clsx'
|
|
import { twMerge } from 'tailwind-merge'
|
|
import { toast } from '~/components/pub/ui/toast'
|
|
|
|
export interface SelectOptionType<_T = string> {
|
|
value: string
|
|
label: string
|
|
code?: string
|
|
}
|
|
|
|
export function cn(...inputs: ClassValue[]) {
|
|
return twMerge(clsx(inputs))
|
|
}
|
|
|
|
export function mapToComboboxOptList(items: Record<string, string>): SelectOptionType<string>[] {
|
|
if (!items) {
|
|
return []
|
|
}
|
|
const result: SelectOptionType<string>[] = []
|
|
Object.keys(items).forEach((item) => {
|
|
result.push({
|
|
label: items[item] as string,
|
|
value: item,
|
|
code: item,
|
|
})
|
|
})
|
|
return result
|
|
}
|
|
|
|
/**
|
|
* Mengkonversi string menjadi title case (huruf pertama setiap kata kapital)
|
|
* @param str - String yang akan dikonversi
|
|
* @returns String dalam format title case
|
|
*/
|
|
export function toTitleCase(str: string): string {
|
|
return str.toLowerCase().replace(/\b\w/g, (char) => char.toUpperCase())
|
|
}
|
|
|
|
|
|
/**
|
|
* Menghitung umur berdasarkan tanggal lahir
|
|
* @param birthDate - Tanggal lahir dalam format Date atau string
|
|
* @returns String umur dalam format "X tahun Y bulan" atau "X bulan" untuk bayi
|
|
*/
|
|
export function calculateAge(birthDate: Date | string | null | undefined): string {
|
|
if (!birthDate) {
|
|
return '-'
|
|
}
|
|
|
|
let birth: Date
|
|
|
|
// Konversi ke Date object
|
|
if (typeof birthDate === 'string') {
|
|
birth = new Date(birthDate)
|
|
} else {
|
|
birth = birthDate
|
|
}
|
|
|
|
// Validasi tanggal
|
|
if (isNaN(birth.getTime())) {
|
|
return '-'
|
|
}
|
|
|
|
const today = new Date()
|
|
const birthYear = birth.getFullYear()
|
|
const birthMonth = birth.getMonth()
|
|
const birthDay = birth.getDate()
|
|
|
|
const currentYear = today.getFullYear()
|
|
const currentMonth = today.getMonth()
|
|
const currentDay = today.getDate()
|
|
|
|
// Hitung tahun
|
|
let years = currentYear - birthYear
|
|
let months = currentMonth - birthMonth
|
|
|
|
// Adjust jika bulan atau hari belum lewat
|
|
if (months < 0 || (months === 0 && currentDay < birthDay)) {
|
|
years--
|
|
months += 12
|
|
}
|
|
|
|
if (currentDay < birthDay) {
|
|
months--
|
|
}
|
|
|
|
// Pastikan months tidak negatif
|
|
if (months < 0) {
|
|
months += 12
|
|
}
|
|
|
|
// Format output
|
|
if (years === 0) {
|
|
if (months === 0) {
|
|
// Hitung hari untuk bayi baru lahir
|
|
const diffTime = today.getTime() - birth.getTime()
|
|
const days = Math.floor(diffTime / (1000 * 60 * 60 * 24))
|
|
return days <= 30 ? `${days} hari` : '1 bulan'
|
|
}
|
|
return `${months} bulan`
|
|
} else if (months === 0) {
|
|
return `${years} tahun`
|
|
} else {
|
|
return `${years} tahun ${months} bulan`
|
|
}
|
|
}
|
|
|
|
export function unauthorizedToast() {
|
|
toast({
|
|
title: 'Unauthorized',
|
|
description: 'You are not authorized to perform this action.',
|
|
variant: 'destructive',
|
|
})
|
|
} |