import { useState, useCallback } from "react"; import { useTranslation } from "react-i18next"; import type { YjsState } from "~/lib/use-yjs"; import { buildPlanGpx } from "~/lib/gpx-export"; interface SaveToJournalButtonProps { yjs: YjsState; sessionId: string; returnUrl?: string; } export function SaveToJournalButton({ yjs, sessionId, returnUrl }: SaveToJournalButtonProps) { const { t } = useTranslation("planner"); const [saving, setSaving] = useState(false); const [saved, setSaved] = useState(false); const [error, setError] = useState(null); const handleSave = useCallback(async () => { setSaving(true); setError(null); try { // Full plan GPX (track + waypoints + no-go areas + notes) so the // route round-trips correctly through the journal. const gpx = buildPlanGpx(yjs); // POST to the planner's server-side proxy. The proxy attaches the // journal Bearer token (stored on the session row) and forwards // the GPX. Token never leaves the planner server — see // routes/api.save-to-journal.ts. const response = await fetch("/api/save-to-journal", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ sessionId, gpx }), }); if (!response.ok) { const result = await response.json(); throw new Error(result.error ?? "Save failed"); } setSaved(true); } catch (err) { setError((err as Error).message); } finally { setSaving(false); } }, [yjs, sessionId]); return (
{saved && {t("saved")}} {error && {error}} {saved && returnUrl && ( {t("returnToJournal")} )}
); }