/** * PathViewer component displays the complete navigation path. * * Shows all visited pages in order and allows viewing previous pages (read-only). */ function PathViewer({ gameId, onPageView }) { const { history, loading, error } = useNavigation(gameId); const [viewingPage, setViewingPage] = React.useState(null); const [pageContent, setPageContent] = React.useState(null); const [pageLoading, setPageLoading] = React.useState(false); // Build path from history const path = React.useMemo(() => { if (!history || !history.steps || history.steps.length === 0) { return []; } // Start with the first step's source page const pathPages = [history.steps[0].source_page]; // Add all target pages history.steps.forEach((step) => { pathPages.push(step.target_page); }); return pathPages; }, [history]); // Load page content for viewing const loadPage = React.useCallback((title) => { if (!gameId || !title) return; setPageLoading(true); setViewingPage(title); fetch(`${window.location.origin}/api/v1/pages?game_id=${gameId}&title=${encodeURIComponent(title)}`) .then((res) => { if (!res.ok) { return res.json().then((data) => { throw new Error(data.error?.message || 'Failed to load page'); }); } return res.json(); }) .then((data) => { setPageContent(data); setPageLoading(false); if (onPageView) { onPageView(title, data); } }) .catch((err) => { console.error('Failed to load page', err); setPageContent(null); setPageLoading(false); }); }, [gameId, onPageView]); if (loading) { return React.createElement( 'div', { className: 'path-viewer loading' }, React.createElement('p', null, 'Loading path...') ); } if (error) { return React.createElement( 'div', { className: 'path-viewer error' }, React.createElement('p', { className: 'error-message' }, error) ); } if (path.length === 0) { return React.createElement( 'div', { className: 'path-viewer empty' }, React.createElement('p', null, 'No path to display yet.') ); } return React.createElement( 'div', { className: 'path-viewer' }, React.createElement( 'h3', { className: 'path-title' }, 'Complete Path' ), React.createElement( 'div', { className: 'path-list' }, path.map((page, index) => React.createElement( 'div', { key: `${page}-${index}`, className: `path-item ${viewingPage === page ? 'active' : ''}`, onClick: () => loadPage(page), }, React.createElement( 'span', { className: 'path-number' }, `${index + 1}.` ), React.createElement( 'span', { className: 'path-page' }, page ), React.createElement( 'span', { className: 'path-view-link' }, ' (view)' ) ) ) ), viewingPage && React.createElement( 'div', { className: 'path-viewer-content' }, React.createElement( 'h4', { className: 'viewer-title' }, `Viewing: ${viewingPage}` ), pageLoading && React.createElement( 'p', null, 'Loading page content...' ), pageContent && React.createElement(PageContent, { title: pageContent.title, content: pageContent.content, links: pageContent.links || [], disabled: true, // Read-only mode }) ) ); }