@chrono-os/admin-lp-editor
v0.9.0
Published
Editor visual de Landing Pages (forms por section do @chrono-os/lp-schema, preview vivo em iframe, paletas/cores recentes, sticky CTA, activity feed) com injeção de dependências por context — neutro, consumível por qualquer app admin.
Downloads
504
Maintainers
Readme
@chrono-os/admin-lp-editor
Editor visual de Landing Pages — neutro e consumível por qualquer app admin.
Entrega o componente <LPEditor>:
- Forms por section do
@chrono-os/lp-schema(15 tipos: hero, problema, benefícios, depoimentos, FAQ, pricing, form, vídeo, countdown, garantia, footer, programa, instrutores, cta-strip, qualificação interativa). - Preview vivo em iframe (desktop + mobile) por section + sticky CTA, com
postMessagepra refletir edições de cor sem salvar. - Paletas salvas + histórico de cores recentes por kind (
bg/text/hover). - Sticky CTA bar configurável.
- Activity feed (opcional).
O editor não conhece o backend, o roteador, nem o storage do app. Tudo entra por
injeção de dependências via <AdminLpEditorProvider>.
Instalação
yarn add @chrono-os/admin-lp-editor \
@chrono-os/lp-schema @chrono-os/lp-react \
@chrono-os/image-editor-react lucide-reactreact/react-dom >= 18 são peers. @chrono-os/lp-react é peer opcional
(usado pelas rotas de preview do consumer, não pelo editor em si).
Uso
'use client'
import {
LPEditor,
AdminLpEditorProvider,
type AdminLpEditorApi,
type AdminLpEditorNav,
type EditorLp,
} from '@chrono-os/admin-lp-editor'
import { useRouter } from 'next/navigation'
const api: AdminLpEditorApi = {
createLP: (payload) => myApi.createLP(payload),
updateLP: (id, payload) => myApi.updateLP(id, payload),
loadPalettes: () => myApi.loadPalettes(),
savePalette: (name, theme) => myApi.savePalette(name, theme),
deletePalette: (id) => myApi.deletePalette(id),
loadRecentColors: () => myApi.loadRecentColors(),
pushThemeColors: (theme) => myApi.pushThemeColors(theme),
uploadAdapter: myUploadAdapter, // do @chrono-os/image-editor-react
loadActivity: (lpId) => myApi.loadActivity(lpId), // opcional
}
export function EditPage({ lp }: { lp?: EditorLp }) {
const router = useRouter()
const nav: AdminLpEditorNav = {
onCreated: (id) => router.replace(`/admin/dashboard/lps/${id}`),
onCancel: () => router.back(),
statsHref: (id) => `/admin/dashboard/lps/${id}/stats`,
publicHref: (slug) => `/lp/${slug}`,
previewBasePath: '/admin-preview', // default
}
return (
<AdminLpEditorProvider api={api} nav={nav}>
<LPEditor lp={lp} />
</AdminLpEditorProvider>
)
}Rotas de preview
O editor renderiza iframes apontando para:
<previewBasePath>/lp/:id/section/:index?v=...&viewport=desktop|mobile<previewBasePath>/lp/:id/sticky-cta?v=...
O consumer é responsável por servir essas rotas (renderizando a section/sticky
isolada via @chrono-os/lp-react). previewBasePath default é /admin-preview.
Tailwind
Os componentes usam classes utilitárias + tokens do design system Chrono/Naírio
(brand-blue, brand-navy). Inclua o dist deste pacote no content do seu
tailwind.config pra não purgar as classes:
content: [
// ...
'./node_modules/@chrono-os/admin-lp-editor/dist/**/*.{js,cjs}',
]API pública
| Export | Tipo |
|---|---|
| LPEditor | ({ lp?: EditorLp }) => JSX.Element |
| AdminLpEditorProvider | ({ api, nav, children }) => JSX.Element |
| useAdminLpEditor | () => { api, nav } |
| SECTION_LABELS | Record<LPSectionType, string> |
| defaultSection | (type: LPSectionType) => LPSection |
Tipos: AdminLpEditorApi, AdminLpEditorNav, EditorLp, EditorStickyCta,
SavedPalette, RecentColorsByKind, RecentColorKind, LpThemeState,
ThemeResolvedColors, LpActivity.
