Update and separate the yearly cosmic events. Set to display the next 4 rather than the next x months
73 lines
2.8 KiB
JavaScript
73 lines
2.8 KiB
JavaScript
// ------------------------------------------------------------------------
|
|
// almanac-calendar.js - Extended event calendar for the "What's Coming"
|
|
// panel and getUpcomingEvents() export.
|
|
//
|
|
// The per-year data now lives in ./calendar/<year>.js — each of those files
|
|
// exports an `almanac` array. This module concatenates them (chronological
|
|
// order) and provides the visibility-note and upcoming-events helpers.
|
|
//
|
|
// Each entry has a 'latHint':
|
|
// null = global / no hint
|
|
// 'north' = better from northern latitudes
|
|
// 'south' = better from southern latitudes
|
|
// 'path:...' = specific eclipse path note
|
|
//
|
|
// To add a new year: create ./calendar/<year>.js (copy an existing one),
|
|
// then import it below and add its `almanac` spread to ALMANAC_CALENDAR.
|
|
// ------------------------------------------------------------------------
|
|
|
|
import { almanac as almanac2026 } from './calendar/2026.js';
|
|
import { almanac as almanac2027 } from './calendar/2027.js';
|
|
import { almanac as almanac2028 } from './calendar/2028.js';
|
|
import { almanac as almanac2029 } from './calendar/2029.js';
|
|
import { almanac as almanac2030 } from './calendar/2030.js';
|
|
|
|
export const ALMANAC_CALENDAR = [
|
|
...almanac2026,
|
|
...almanac2027,
|
|
...almanac2028,
|
|
...almanac2029,
|
|
...almanac2030,
|
|
];
|
|
|
|
// Returns a location-aware visibility note for an almanac entry.
|
|
// lat = user's latitude.
|
|
export function getVisibilityNote(entry, lat) {
|
|
if (!entry.latHint) return null;
|
|
if (entry.latHint.startsWith('path:')) {
|
|
return entry.latHint.replace('path:', '').trim();
|
|
}
|
|
if (entry.latHint === 'north') {
|
|
if (lat >= 45) return 'Well placed for your latitude';
|
|
if (lat >= 20) return 'Visible from your location';
|
|
return 'Better from northern latitudes';
|
|
}
|
|
if (entry.latHint === 'south') {
|
|
if (lat <= 10) return 'Well placed for your latitude';
|
|
if (lat <= 40) return 'Visible from your location';
|
|
return 'Better from southern latitudes';
|
|
}
|
|
return null;
|
|
}
|
|
|
|
// --- MAIN ALMANAC EXPORT -------------------------------------------------
|
|
// Returns events with peak dates in the next 'days' days (default 90),
|
|
// sorted by peak date, with a visibility note added.
|
|
export function getUpcomingEvents(location, days = 90) {
|
|
const today = new Date();
|
|
today.setHours(0, 0, 0, 0);
|
|
const cutoff = new Date(today);
|
|
cutoff.setDate(cutoff.getDate() + days);
|
|
const todayStr = today.toISOString().slice(0, 10);
|
|
const cutoffStr = cutoff.toISOString().slice(0, 10);
|
|
|
|
return ALMANAC_CALENDAR
|
|
.filter(ev => ev.peak >= todayStr && ev.peak <= cutoffStr)
|
|
.sort((a, b) => a.peak.localeCompare(b.peak))
|
|
.map(ev => ({
|
|
...ev,
|
|
visibilityNote: getVisibilityNote(ev, location?.lat ?? 51),
|
|
daysUntil: Math.round((new Date(ev.peak + 'T00:00Z') - today) / 86400000),
|
|
}));
|
|
}
|