/**
* renderSlides.tsx
* Renders a SlideContent object to a full HTML string using ReactDOMServer.
* Each HTML output is a self-contained page suitable for Puppeteer screenshot.
*/
import React from 'react';
import ReactDOMServer from 'react-dom/server';
import type { SlideContent } from '../schema/carouselSchema';
import type { Theme } from './themes';
import { HookSlide } from './templates/HookSlide';
import { TimelineSlide } from './templates/TimelineSlide';
import { FitSlide } from './templates/FitSlide';
import { ProofSlide } from './templates/ProofSlide';
import { WorkStyleSlide } from './templates/WorkStyleSlide';
import { ValuePropSlide } from './templates/ValuePropSlide';
import { CtaSlide } from './templates/CtaSlide';
// ---------------------------------------------------------------------------
// Slide router
// ---------------------------------------------------------------------------
/**
* Route a slide to the correct template component based on templateType.
*/
function renderSlideComponent(slide: SlideContent, theme: Theme): React.ReactElement {
switch (slide.templateType) {
case 'hook':
return ;
case 'timeline':
return ;
case 'fit':
return ;
case 'proof':
return ;
case 'workstyle':
return ;
case 'valueprop':
return ;
case 'cta':
return ;
default:
// Fallback: use hook slide template
return ;
}
}
// ---------------------------------------------------------------------------
// HTML wrapper
// ---------------------------------------------------------------------------
/**
* Wrap rendered React markup in a full HTML document.
* Includes Tailwind CDN for utility classes used in templates,
* and base styles to ensure correct rendering at 1080x1080.
*/
function wrapInHtmlDocument(
innerHtml: string,
theme: Theme,
slideIndex: number
): string {
return `
Slide ${slideIndex + 1}
${innerHtml}
`;
}
// ---------------------------------------------------------------------------
// Public API
// ---------------------------------------------------------------------------
/**
* Render a single slide to a full HTML string.
*
* @param slide - The SlideContent object to render
* @param theme - The visual theme to apply
* @param slideIndex - Zero-based index (used for and metadata)
* @returns - Full HTML string ready for Puppeteer/Playwright
*/
export function renderSlideToHtml(
slide: SlideContent,
theme: Theme,
slideIndex: number
): string {
const element = renderSlideComponent(slide, theme);
const innerHtml = ReactDOMServer.renderToStaticMarkup(element);
return wrapInHtmlDocument(innerHtml, theme, slideIndex);
}
/**
* Render all slides to an array of HTML strings.
* Returns one HTML string per slide, in order.
*/
export function renderAllSlidesToHtml(slides: SlideContent[], theme: Theme): string[] {
return slides.map((slide, index) => renderSlideToHtml(slide, theme, index));
}