57 lines
1.7 KiB
JavaScript
57 lines
1.7 KiB
JavaScript
const STALE_MS = 2 * 60 * 60 * 1000
|
|
const CRITICAL_STALE_MS = 4 * 60 * 60 * 1000
|
|
|
|
export function formatLengthOfStay(admittedAt, asOf = new Date()) {
|
|
if (!admittedAt) return '—'
|
|
const start = new Date(admittedAt).getTime()
|
|
if (Number.isNaN(start)) return '—'
|
|
|
|
const diffMs = Math.max(0, asOf.getTime() - start)
|
|
const days = Math.floor(diffMs / (24 * 60 * 60 * 1000))
|
|
if (days >= 1) return `${days}d`
|
|
const hours = Math.floor(diffMs / (60 * 60 * 1000))
|
|
if (hours >= 1) return `${hours}h`
|
|
return '<1h'
|
|
}
|
|
|
|
export function observationStaleness(lastObservationAt, status, asOf = new Date()) {
|
|
if (status && status !== 'Active') return null
|
|
if (!lastObservationAt) return 'missing'
|
|
|
|
const ageMs = asOf.getTime() - new Date(lastObservationAt).getTime()
|
|
if (ageMs > CRITICAL_STALE_MS) return 'critical'
|
|
if (ageMs > STALE_MS) return 'stale'
|
|
return 'fresh'
|
|
}
|
|
|
|
export function formatLastObservation(lastObservationAt) {
|
|
if (!lastObservationAt) return 'No vitals'
|
|
return new Date(lastObservationAt).toLocaleString([], {
|
|
month: 'short',
|
|
day: 'numeric',
|
|
hour: '2-digit',
|
|
minute: '2-digit',
|
|
})
|
|
}
|
|
|
|
export function stalenessClass(level) {
|
|
if (level === 'critical') return 'text-red-600 dark:text-red-400'
|
|
if (level === 'stale') return 'text-amber-600 dark:text-amber-400'
|
|
if (level === 'missing') return 'text-gray-400 dark:text-gray-500'
|
|
return 'text-gray-700 dark:text-gray-300'
|
|
}
|
|
|
|
export function formatGcsClassification(classification) {
|
|
if (!classification) return ''
|
|
const map = {
|
|
MILD: 'Mild',
|
|
MODERATE: 'Mod',
|
|
SEVERE: 'Severe',
|
|
}
|
|
return map[classification] ?? classification
|
|
}
|
|
|
|
export function patientRoom(patient) {
|
|
return patient.roomBed ?? patient.room ?? '—'
|
|
}
|