import { appBasePath } from "@agent-native/core/client/api-path"; import { useT } from "@agent-native/core/client/i18n"; import type { SharedDeckResponse } from "@shared/api"; import { IconAlertCircle } from "@tabler/icons-react"; import { useState, useEffect } from "react"; import { useParams } from "react-router"; import PresentationView from "@/components/presentation/PresentationView"; import type { Slide } from "@/context/DeckContext"; interface SharedPresentationProps { initialDeck?: SharedDeckResponse | null; initialError?: string; } export default function SharedPresentation({ initialDeck = null, initialError = "", }: SharedPresentationProps) { const t = useT(); const { token } = useParams<{ token: string }>(); const [deck, setDeck] = useState(initialDeck); const [error, setError] = useState(initialError); const [loading, setLoading] = useState(!initialDeck && !initialError); useEffect(() => { if (!token) return; if (initialDeck || initialError) { setDeck(initialDeck); setError(initialError); setLoading(false); return; } fetch(`${appBasePath()}/api/share/${token}`) .then(async (res) => { if (!res.ok) { const err = await res.json(); throw new Error(err.error || "Failed to load presentation"); } return res.json(); }) .then((data: SharedDeckResponse) => { setDeck(data); }) .catch((err) => { setError(err.message); }) .finally(() => { setLoading(false); }); }, [token, initialDeck, initialError]); if (loading) { return (
); } if (error || !deck) { return (

{t("raw.presentationNotFound")}

{error || t("raw.sharedPresentationExpired")}

); } const slides: Slide[] = deck.slides.map((s) => ({ ...s, layout: s.layout as Slide["layout"], })); // Use a fake deckId that routes "exit" back to the share page itself return ( ); }