Files
Momento/memento-note/components/interactive-page/interactive-published-page.tsx
Antigravity 69c99e4f4f feat: page interactive, démos Play/Step et simulateur Carnot
Ajoute le pipeline PageSpec (validation, rendu, publication /p/{slug}),
les démos TipTap /demo, et le simulateur Carnot (modes frigo/PAC/moteur,
énergie kJ vs puissance W, unités K/°C/°F) avec correctifs d’équations KaTeX.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-24 17:51:43 +00:00

49 lines
1.4 KiB
TypeScript

'use client'
import { PageView } from '@/components/interactive-page/page-view'
import { validateInteractivePage, type PageSpecV1 } from '@/lib/interactive-page'
import { AlertCircle } from 'lucide-react'
/**
* Public / preview shell for published interactive pages.
* Parses stored PageSpecV1 JSON from `publishedContent`.
*/
export function InteractivePublishedPage({
publishedContent,
isStale,
}: {
publishedContent: string
isStale?: boolean
}) {
let page: PageSpecV1 | null = null
let error: string | null = null
try {
const raw = JSON.parse(publishedContent)
const result = validateInteractivePage(raw)
if (result.ok) page = result.page
else error = result.issues[0]?.message || 'PageSpec invalide'
} catch {
error = 'JSON de page interactive illisible'
}
if (!page) {
return (
<div className="mx-auto flex max-w-lg gap-3 p-10 text-sm text-destructive">
<AlertCircle className="h-5 w-5 shrink-0" />
<p>{error || 'Page interactive indisponible'}</p>
</div>
)
}
return (
<div>
{isStale ? (
<div className="border-b border-amber-500/30 bg-amber-500/10 px-4 py-2 text-center text-xs text-amber-800 dark:text-amber-200">
Le contenu source a évolué cette page interactive est à régénérer.
</div>
) : null}
<PageView page={page} demoMode="interactive" />
</div>
)
}