blob: 9d008e21b05f809ebddc9bd6645503c9d522fe4c (
plain) (
tree)
|
|
import type { BodyElement } from "../../lib/api";
import { ChartRenderer } from "../charts/ChartRenderer";
interface BodyRendererProps {
elements: BodyElement[];
}
export function BodyRenderer({ elements }: BodyRendererProps) {
if (elements.length === 0) {
return (
<div className="text-[#555] font-mono text-sm italic">
No content yet. Use the CLI below to add content.
</div>
);
}
return (
<div className="space-y-4">
{elements.map((element, index) => (
<BodyElementRenderer key={index} element={element} />
))}
</div>
);
}
function BodyElementRenderer({ element }: { element: BodyElement }) {
switch (element.type) {
case "heading":
return <HeadingElement level={element.level} text={element.text} />;
case "paragraph":
return <ParagraphElement text={element.text} />;
case "chart":
return (
<ChartElement
chartType={element.chartType}
data={element.data}
title={element.title}
config={element.config}
/>
);
case "image":
return (
<ImageElement
src={element.src}
alt={element.alt}
caption={element.caption}
/>
);
default:
return null;
}
}
function HeadingElement({ level, text }: { level: number; text: string }) {
const className = "font-mono text-[#9bc3ff]";
switch (level) {
case 1:
return <h1 className={`${className} text-2xl font-bold`}>{text}</h1>;
case 2:
return <h2 className={`${className} text-xl font-bold`}>{text}</h2>;
case 3:
return <h3 className={`${className} text-lg font-semibold`}>{text}</h3>;
case 4:
return <h4 className={`${className} text-base font-semibold`}>{text}</h4>;
case 5:
return <h5 className={`${className} text-sm font-semibold`}>{text}</h5>;
case 6:
return <h6 className={`${className} text-xs font-semibold`}>{text}</h6>;
default:
return <h3 className={`${className} text-lg font-semibold`}>{text}</h3>;
}
}
function ParagraphElement({ text }: { text: string }) {
return <p className="font-mono text-sm text-white/80 leading-relaxed">{text}</p>;
}
function ChartElement({
chartType,
data,
title,
config,
}: {
chartType: "line" | "bar" | "pie" | "area";
data: Record<string, unknown>[];
title?: string;
config?: Record<string, unknown>;
}) {
return (
<div className="border border-[#333] p-4 bg-black/30">
<ChartRenderer
chartType={chartType}
data={data}
title={title}
config={config}
/>
</div>
);
}
function ImageElement({
src,
alt,
caption,
}: {
src: string;
alt?: string;
caption?: string;
}) {
return (
<figure className="space-y-2">
<img
src={src}
alt={alt || ""}
className="max-w-full border border-[#333]"
/>
{caption && (
<figcaption className="text-[#555] font-mono text-xs italic">
{caption}
</figcaption>
)}
</figure>
);
}
|