Rendre le dashboard actionnable (inbox, peek, carte mentale), aligner la facturation sur l’essai 7 jours, et bloquer le login e-mail tant que l’adresse n’est pas confirmée. Co-authored-by: Cursor <cursoragent@cursor.com>
66 lines
1.7 KiB
TypeScript
66 lines
1.7 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'
|
|
|
|
const STRINGS = {
|
|
fr: {
|
|
stale: 'Le contenu source a évolué — cette page interactive est à régénérer.',
|
|
invalid: 'Page interactive indisponible',
|
|
},
|
|
en: {
|
|
stale: 'The source content has changed — this interactive page needs regeneration.',
|
|
invalid: 'Interactive page unavailable',
|
|
},
|
|
}
|
|
|
|
/**
|
|
* 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
|
|
let lang = 'fr'
|
|
try {
|
|
const raw = JSON.parse(publishedContent)
|
|
const result = validateInteractivePage(raw)
|
|
if (result.ok) {
|
|
page = result.page
|
|
lang = result.page.lang || 'fr'
|
|
} else {
|
|
error = result.issues[0]?.message || 'PageSpec invalide'
|
|
}
|
|
} catch {
|
|
error = 'JSON de page interactive illisible'
|
|
}
|
|
const t = lang.startsWith('fr') ? STRINGS.fr : STRINGS.en
|
|
|
|
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 || t.invalid}</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">
|
|
{t.stale}
|
|
</div>
|
|
) : null}
|
|
<PageView page={page} demoMode="interactive" />
|
|
</div>
|
|
)
|
|
}
|