Add Google Calendar integration and improve station selection
Implement full OAuth 2.0 flow for Google Calendar, including token exchange, refresh, and status checks. Add UI for connecting, syncing, and disconnecting Google accounts in the Calendar panel. Additionally: - Make mobile station selection async with error handling and alerts - Add HAFAS LocMatch method to API client for finding nearest station - Expose Google OAuth env vars in Next.js config
This commit is contained in:
@@ -178,4 +178,55 @@ export class ApiClient {
|
||||
});
|
||||
return result?.svcReqL?.[0]?.res?.locL ?? [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the nearest station to given GPS coordinates using HAFAS LocMatch.
|
||||
* This is a reliable fallback that works even when the nearby-stops proxy
|
||||
* is unavailable or the base URL is empty.
|
||||
*/
|
||||
async findNearestStationByCoords(lat: number, lng: number): Promise<Station | null> {
|
||||
interface HafasLocation extends Station {
|
||||
type: string;
|
||||
lon: number;
|
||||
}
|
||||
|
||||
const result = await this.hafasRequest<{
|
||||
svcReqL?: Array<{ res?: { match?: { locL?: HafasLocation[] } } }>;
|
||||
}>({
|
||||
svcReqL: [
|
||||
{
|
||||
meth: "LocMatch",
|
||||
req: {
|
||||
input: {
|
||||
loc: {
|
||||
crd: {
|
||||
x: Math.round(lng * 1e6),
|
||||
y: Math.round(lat * 1e6),
|
||||
},
|
||||
type: "S",
|
||||
},
|
||||
maxLoc: 5,
|
||||
field: "S",
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const stations = result?.svcReqL?.[0]?.res?.match?.locL ?? [];
|
||||
if (stations.length === 0) return null;
|
||||
|
||||
// Filter to only "S" (station) type results, then pick the closest
|
||||
const stationResults = stations.filter((s) => s.type === "S");
|
||||
if (stationResults.length === 0) return null;
|
||||
|
||||
// Find the closest station by Euclidean distance
|
||||
const closest = stationResults.reduce((best, candidate) => {
|
||||
const bestDist = Math.hypot((best.lat ?? lat) - lat, (best.lng ?? lng) - lng);
|
||||
const candDist = Math.hypot((candidate.lat ?? lat) - lat, (candidate.lng ?? lng) - lng);
|
||||
return candDist < bestDist ? candidate : best;
|
||||
}, stationResults[0]);
|
||||
|
||||
return closest;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user