1851d2ed47
Add TimeToLeave feature checklist and plan
79 lines
2.8 KiB
TypeScript
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]);
|
|
}
|