diff --git a/frontend/src/lib/utils/format.ts b/frontend/src/lib/utils/format.ts new file mode 100644 index 0000000..3b0720d --- /dev/null +++ b/frontend/src/lib/utils/format.ts @@ -0,0 +1,88 @@ +/** + * Shared formatting utilities for consistent display across the app. + */ + +/** + * Convert minutes to a human-readable duration string. + * + * Examples: + * 45 → "45m" + * 60 → "1h" + * 90 → "1h 30m" + * 120 → "2h" + * 150 → "2h 30m" + */ +export function formatDuration(minutes: number): string { + const hours = Math.floor(minutes / 60); + const mins = minutes % 60; + if (hours === 0) return `${mins}m`; + if (mins === 0) return `${hours}h`; + return `${hours}h ${mins}m`; +} + +/** + * Format a date/time to "Weekday, Month Day at HH:MM AM/PM". + * + * Examples: + * "2026-05-29T10:00:00Z" → "Friday, May 29 at 10:00 AM" + * "2026-06-05T14:30:00Z" → "Friday, Jun 5 at 2:30 PM" + */ +export function formatDateTime(date: Date | string): string { + const d = typeof date === 'string' ? new Date(date) : date; + const dateStr = d.toLocaleDateString('en-US', { + weekday: 'long', + month: 'short', + day: 'numeric' + }); + const timeStr = d.toLocaleTimeString('en-US', { + hour: 'numeric', + minute: '2-digit', + hour12: true + }); + return `${dateStr} at ${timeStr}`; +} + +/** + * Format a date value to "Weekday, Month Day" only (no time). + * + * Example: "2026-05-29" → "Friday, May 29" + */ +export function formatDate(date: Date | string): string { + const d = typeof date === 'string' ? new Date(date) : date; + return d.toLocaleDateString('en-US', { + weekday: 'long', + month: 'short', + day: 'numeric' + }); +} + +/** + * Format a time value to "HH:MM AM/PM". + * + * Example: new Date("2026-05-29T14:30:00Z") → "2:30 PM" + */ +export function formatTime(date: Date | string): string { + const d = typeof date === 'string' ? new Date(date) : date; + return d.toLocaleTimeString('en-US', { + hour: 'numeric', + minute: '2-digit', + hour12: true + }); +} + +/** + * Calculate age from a date-of-birth string. + * Returns the number of full years, or null if DOB is invalid. + */ +export function calculateAge(dateOfBirth: string | undefined | null): number | null { + if (!dateOfBirth) return null; + const dob = new Date(dateOfBirth); + if (isNaN(dob.getTime())) return null; + const today = new Date(); + let age = today.getFullYear() - dob.getFullYear(); + const monthDiff = today.getMonth() - dob.getMonth(); + if (monthDiff < 0 || (monthDiff === 0 && today.getDate() < dob.getDate())) { + age--; + } + return age; +}