20159262c1
- Introduce `getLeaveStatus` function in `packages/core/src/status-utils.ts` to determine leave-by status based on journey data - Mark Phase 1 mobile app tasks as complete in `CHECKLIST.md` - Add mobile workspace configurations and npm scripts
50 lines
1.2 KiB
TypeScript
50 lines
1.2 KiB
TypeScript
// Status utilities for TimeToLeave
|
|
import type { ServerStatus, Event, Journey } from "./types";
|
|
|
|
export class StatusUtils {
|
|
static async checkServerStatus(url: string): Promise<ServerStatus> {
|
|
try {
|
|
const res = await fetch(url, {
|
|
method: "HEAD",
|
|
signal: AbortSignal.timeout(5000),
|
|
});
|
|
return res.ok;
|
|
} catch {
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Derive a human-readable leave-by status from an event and its journeys.
|
|
* Returns early / on-time / delayed / unknown based on the best journey's
|
|
* real departure time relative to now.
|
|
*/
|
|
export function getLeaveStatus(event: Event, journeys: Journey[]): string {
|
|
if (journeys.length === 0) {
|
|
return "No journey data";
|
|
}
|
|
|
|
// Pick the earliest non-cancelled journey
|
|
const best = journeys
|
|
.filter((j) => !j.cancelled)
|
|
.sort((a, b) => a.rD.getTime() - b.rD.getTime())[0];
|
|
|
|
if (!best) {
|
|
return "All journeys cancelled";
|
|
}
|
|
|
|
const diffMin = (best.rD.getTime() - Date.now()) / 60_000;
|
|
|
|
if (diffMin < 0) {
|
|
return "Departure missed";
|
|
}
|
|
if (best.delay > 10) {
|
|
return `Delayed +${best.delay} min`;
|
|
}
|
|
if (diffMin <= 15) {
|
|
return "Leave now";
|
|
}
|
|
return "On time";
|
|
}
|