cosmo/frontend/src/hooks/useTrajectory.ts

58 lines
1.7 KiB
TypeScript

/**
* Custom hook for fetching trajectory data for a celestial body
*/
import { useState, useEffect } from 'react';
import { fetchCelestialPositions } from '../utils/api';
import type { CelestialBody, Position } from '../types';
export function useTrajectory(body: CelestialBody | null) {
const [trajectoryPositions, setTrajectoryPositions] = useState<Position[]>([]);
const [loading, setLoading] = useState(false);
useEffect(() => {
if (!body || body.type !== 'probe') {
setTrajectoryPositions([]);
return;
}
async function loadTrajectory() {
if (!body) return;
try {
setLoading(true);
// Fetch positions for the last 30 days
// Align to UTC midnight to leverage caching
const now = new Date();
now.setUTCHours(0, 0, 0, 0);
const endTime = now.toISOString();
const startTime = new Date(now.getTime() - 30 * 24 * 60 * 60 * 1000).toISOString();
const data = await fetchCelestialPositions(startTime, endTime, '1d');
// Find the body's data and extract positions
const bodyData = data.bodies.find((b) => b.id === body.id);
if (bodyData && bodyData.positions.length > 0) {
setTrajectoryPositions(bodyData.positions);
} else {
// Fallback to current position if no historical data
setTrajectoryPositions(body.positions);
}
} catch (err) {
console.error('Failed to fetch trajectory data:', err);
// Fallback to current position
if (body) {
setTrajectoryPositions(body.positions);
}
} finally {
setLoading(false);
}
}
loadTrajectory();
}, [body?.id, body?.type]);
return { trajectoryPositions, loading };
}