145c18d8a3
- Define --color-surface in theme.css (light: #f0f0f8, dark: #1a1b22) — was used across 10+ components with no-op fallbacks; now properly defined alongside --color-bg and --color-bg-card - Extract shared date formatters into utils/dateFormat.ts: fmtTime, fmtDateTime, fmtRelativeDateTime, fmtDayLabel, fmtCompact - Replace duplicate inline formatters in CalendarView, HomeView (formatUpcomingTime), and KnowledgeView (formatEventDate) - CalendarView: replace hardcoded rgba(99,102,241,0.4) hover colour with color-mix(in srgb, var(--color-primary) 40%, transparent); fix --color-input-bg fallback to use var(--color-bg); remove hardcoded hex fallbacks now that --color-surface is defined Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
66 lines
2.3 KiB
TypeScript
66 lines
2.3 KiB
TypeScript
/** Shared date/time formatting helpers used across Calendar, Home, Knowledge, etc. */
|
|
|
|
function _isSameDay(a: Date, b: Date): boolean {
|
|
return a.getFullYear() === b.getFullYear() &&
|
|
a.getMonth() === b.getMonth() &&
|
|
a.getDate() === b.getDate()
|
|
}
|
|
|
|
/** "9:30 AM" */
|
|
export function fmtTime(dt: string): string {
|
|
return new Date(dt).toLocaleTimeString(undefined, { hour: "numeric", minute: "2-digit" })
|
|
}
|
|
|
|
/** "Mon, Jan 15" or "Mon, Jan 15, 9:30 AM" */
|
|
export function fmtDateTime(dt: string, allDay: boolean): string {
|
|
const d = new Date(dt)
|
|
const datePart = d.toLocaleDateString(undefined, { weekday: "short", month: "short", day: "numeric" })
|
|
if (allDay) return datePart
|
|
return `${datePart}, ${d.toLocaleTimeString(undefined, { hour: "numeric", minute: "2-digit" })}`
|
|
}
|
|
|
|
/**
|
|
* "Today 9:30 AM" / "Tomorrow 9:30 AM" / "Mon, Jan 15 9:30 AM"
|
|
* For all-day events returns "Today" / "Tomorrow" / "Mon, Jan 15"
|
|
*/
|
|
export function fmtRelativeDateTime(dt: string, allDay: boolean): string {
|
|
try {
|
|
const d = new Date(dt)
|
|
const now = new Date()
|
|
const tomorrow = new Date(now)
|
|
tomorrow.setDate(now.getDate() + 1)
|
|
|
|
const timeStr = allDay ? "" : ` ${d.toLocaleTimeString(undefined, { hour: "numeric", minute: "2-digit" })}`
|
|
|
|
if (_isSameDay(d, now)) return `Today${timeStr}`
|
|
if (_isSameDay(d, tomorrow)) return `Tomorrow${timeStr}`
|
|
return d.toLocaleDateString(undefined, { weekday: "short", month: "short", day: "numeric" }) + timeStr
|
|
} catch {
|
|
return dt
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Label-only: "Today" / "Tomorrow" / "Mon, Jan 15"
|
|
*/
|
|
export function fmtDayLabel(dt: string): string {
|
|
try {
|
|
const d = new Date(dt)
|
|
const now = new Date()
|
|
const tomorrow = new Date(now)
|
|
tomorrow.setDate(now.getDate() + 1)
|
|
if (_isSameDay(d, now)) return "Today"
|
|
if (_isSameDay(d, tomorrow)) return "Tomorrow"
|
|
return d.toLocaleDateString(undefined, { weekday: "short", month: "short", day: "numeric" })
|
|
} catch {
|
|
return dt
|
|
}
|
|
}
|
|
|
|
/** "Jan 15" or "Jan 15, 9:30 AM" — compact, no weekday */
|
|
export function fmtCompact(dt: string, allDay: boolean): string {
|
|
const d = new Date(dt)
|
|
if (allDay) return d.toLocaleDateString(undefined, { month: "short", day: "numeric" })
|
|
return d.toLocaleString(undefined, { month: "short", day: "numeric", hour: "numeric", minute: "2-digit" })
|
|
}
|