Initial commit: MSP Monitor Dashboard
- Next.js 14 frontend with dark cyan/navy theme - tRPC API with Prisma ORM - MeshCentral, LibreNMS, Headwind MDM integrations - Multi-tenant architecture - Alert system with email/SMS/webhook notifications - Docker Compose deployment - Complete documentation
This commit is contained in:
123
src/lib/utils.ts
Normal file
123
src/lib/utils.ts
Normal file
@@ -0,0 +1,123 @@
|
||||
import { type ClassValue, clsx } from 'clsx'
|
||||
import { twMerge } from 'tailwind-merge'
|
||||
|
||||
export function cn(...inputs: ClassValue[]) {
|
||||
return twMerge(clsx(inputs))
|
||||
}
|
||||
|
||||
export function formatBytes(bytes: number, decimals = 2): string {
|
||||
if (bytes === 0) return '0 Bytes'
|
||||
const k = 1024
|
||||
const dm = decimals < 0 ? 0 : decimals
|
||||
const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB']
|
||||
const i = Math.floor(Math.log(bytes) / Math.log(k))
|
||||
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i]
|
||||
}
|
||||
|
||||
export function formatUptime(seconds: number): string {
|
||||
const days = Math.floor(seconds / 86400)
|
||||
const hours = Math.floor((seconds % 86400) / 3600)
|
||||
const minutes = Math.floor((seconds % 3600) / 60)
|
||||
|
||||
if (days > 0) return `${days}d ${hours}h`
|
||||
if (hours > 0) return `${hours}h ${minutes}m`
|
||||
return `${minutes}m`
|
||||
}
|
||||
|
||||
export function formatDate(date: Date | string): string {
|
||||
const d = new Date(date)
|
||||
return d.toLocaleDateString('es-MX', {
|
||||
year: 'numeric',
|
||||
month: 'short',
|
||||
day: 'numeric',
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
})
|
||||
}
|
||||
|
||||
export function formatRelativeTime(date: Date | string): string {
|
||||
const d = new Date(date)
|
||||
const now = new Date()
|
||||
const diff = now.getTime() - d.getTime()
|
||||
|
||||
const seconds = Math.floor(diff / 1000)
|
||||
const minutes = Math.floor(seconds / 60)
|
||||
const hours = Math.floor(minutes / 60)
|
||||
const days = Math.floor(hours / 24)
|
||||
|
||||
if (days > 0) return `hace ${days}d`
|
||||
if (hours > 0) return `hace ${hours}h`
|
||||
if (minutes > 0) return `hace ${minutes}m`
|
||||
return 'ahora'
|
||||
}
|
||||
|
||||
export function getStatusColor(status: string): string {
|
||||
switch (status.toUpperCase()) {
|
||||
case 'ONLINE':
|
||||
return 'text-success'
|
||||
case 'OFFLINE':
|
||||
return 'text-gray-500'
|
||||
case 'ALERTA':
|
||||
return 'text-danger'
|
||||
case 'MANTENIMIENTO':
|
||||
return 'text-warning'
|
||||
default:
|
||||
return 'text-gray-400'
|
||||
}
|
||||
}
|
||||
|
||||
export function getStatusBgColor(status: string): string {
|
||||
switch (status.toUpperCase()) {
|
||||
case 'ONLINE':
|
||||
return 'bg-success/20'
|
||||
case 'OFFLINE':
|
||||
return 'bg-gray-500/20'
|
||||
case 'ALERTA':
|
||||
return 'bg-danger/20'
|
||||
case 'MANTENIMIENTO':
|
||||
return 'bg-warning/20'
|
||||
default:
|
||||
return 'bg-gray-400/20'
|
||||
}
|
||||
}
|
||||
|
||||
export function getSeverityColor(severity: string): string {
|
||||
switch (severity.toUpperCase()) {
|
||||
case 'CRITICAL':
|
||||
return 'text-danger'
|
||||
case 'WARNING':
|
||||
return 'text-warning'
|
||||
case 'INFO':
|
||||
return 'text-info'
|
||||
default:
|
||||
return 'text-gray-400'
|
||||
}
|
||||
}
|
||||
|
||||
export function getSeverityBgColor(severity: string): string {
|
||||
switch (severity.toUpperCase()) {
|
||||
case 'CRITICAL':
|
||||
return 'bg-danger/20'
|
||||
case 'WARNING':
|
||||
return 'bg-warning/20'
|
||||
case 'INFO':
|
||||
return 'bg-info/20'
|
||||
default:
|
||||
return 'bg-gray-400/20'
|
||||
}
|
||||
}
|
||||
|
||||
export function debounce<T extends (...args: Parameters<T>) => ReturnType<T>>(
|
||||
func: T,
|
||||
wait: number
|
||||
): (...args: Parameters<T>) => void {
|
||||
let timeout: NodeJS.Timeout | null = null
|
||||
return (...args: Parameters<T>) => {
|
||||
if (timeout) clearTimeout(timeout)
|
||||
timeout = setTimeout(() => func(...args), wait)
|
||||
}
|
||||
}
|
||||
|
||||
export function generateId(): string {
|
||||
return Math.random().toString(36).substring(2, 15)
|
||||
}
|
||||
Reference in New Issue
Block a user