58 lines
1.7 KiB
TypeScript
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 };
|
|
}
|