Files
time_to_leave/apps/web/src/hooks/useDepartureTime.ts
T
fegger 1851d2ed47 Add TimeToLeave feature checklist and plan (50)
Add TimeToLeave feature checklist and plan
2026-05-12 13:17:17 +02:00

79 lines
2.8 KiB
TypeScript

"use client";
import { useMemo } from "react";
import type { Journey } from "@timetoleave/core";
import { useReminderSettings } from "@/hooks/useReminderSettings";
interface DepartureTimeResult {
departureTime: Date | null;
arrivalTime: Date | null;
mode: "train" | "bike" | null;
}
export function useDepartureTime(
eventTime: Date,
journeys: Journey[] | null,
bikeRoute: number | null, // duration in seconds
activeMode: "train" | "bike" | null
): DepartureTimeResult {
const { arrivalBufferMinutes } = useReminderSettings();
return useMemo(() => {
// Calculate target arrival time (event time minus buffer)
const targetArrivalTime = new Date(eventTime);
targetArrivalTime.setMinutes(targetArrivalTime.getMinutes() - arrivalBufferMinutes);
// Filter out cancelled journeys
const validJourneys = journeys?.filter(journey => !journey.cancelled) || [];
let departureTime: Date | null = null;
let arrivalTime: Date | null = null;
let mode: "train" | "bike" | null = null;
// Handle train mode
if (activeMode === "train" && validJourneys.length > 0) {
// Find journeys that arrive before or at the target arrival time
const onTimeJourneys = validJourneys.filter(journey =>
journey.sA.getTime() <= targetArrivalTime.getTime()
);
if (onTimeJourneys.length > 0) {
// Pick the journey with the latest departure time
const bestJourney = onTimeJourneys.reduce((latest, current) =>
current.sD.getTime() > latest.sD.getTime() ? current : latest
);
departureTime = new Date(bestJourney.sD);
arrivalTime = new Date(bestJourney.sA);
mode = "train";
}
}
// Handle bike mode
if (activeMode === "bike" && bikeRoute !== null && bikeRoute > 0) {
// Convert bike route duration from seconds to milliseconds
const bikeDurationMs = bikeRoute * 1000;
// Calculate arrival time by subtracting bike duration from event time
const calculatedArrivalTime = new Date(eventTime);
calculatedArrivalTime.setTime(calculatedArrivalTime.getTime() - bikeDurationMs);
// Calculate departure time by subtracting bike duration from calculated arrival time
const calculatedDepartureTime = new Date(calculatedArrivalTime);
calculatedDepartureTime.setTime(calculatedArrivalTime.getTime() - bikeDurationMs);
// Calculate how much earlier we need to account for arrival buffer
const totalBufferMs = arrivalBufferMinutes * 60 * 1000;
const totalTravelTimeMs = bikeDurationMs * 2 + totalBufferMs;
departureTime = new Date(eventTime);
departureTime.setTime(eventTime.getTime() - totalTravelTimeMs);
arrivalTime = new Date(calculatedArrivalTime);
mode = "bike";
}
return { departureTime, arrivalTime, mode };
}, [eventTime, journeys, bikeRoute, activeMode, arrivalBufferMinutes]);
}