"use client";
import * as React from "react";
import { MotionConfig, useReducedMotion } from "motion/react";
import { cn } from "@/lib/utils";
import { defaultFluxData, type FluxData, type Piece } from "./data";
import { Contact, Footer, Manifesto, type FluxInquiry } from "./sections/closing";
import type { GenParams } from "./sections/gen";
import { Hero } from "./sections/hero";
import { Maker, type MakerPreset } from "./sections/maker";
import { Navbar } from "./sections/navbar";
import { scrollToId } from "./sections/ui";
import { Gallery, Studio } from "./sections/work";
export type { FluxData, FluxInquiry, GenParams };
export { defaultFluxData };
export interface GenerativeStudioTemplateProps {
/** Override any content group (hero, gallery pieces, palettes…). Missing groups use the demo content. */
data?: Partial<FluxData>;
/** Size of the square PNG exported by the generator. Default 2048. */
exportSize?: number;
/** Called with the parameters and PNG blob whenever someone downloads a piece. */
onDownload?: (params: GenParams, blob: Blob) => void;
/** Called when the contact form is submitted. */
onInquiry?: (v: FluxInquiry) => Promise<void> | void;
className?: string;
}
export function GenerativeStudioTemplate({ data, exportSize, onDownload, onInquiry, className }: GenerativeStudioTemplateProps) {
const d = React.useMemo(() => ({ ...defaultFluxData, ...data }), [data]);
const reduce = useReducedMotion();
const [preset, setPreset] = React.useState<MakerPreset | null>(null);
const openInMaker = React.useCallback(
(p: Piece) => {
setPreset((cur) => ({ style: p.style, seed: p.seed, palette: p.palette, density: p.density, turbulence: p.turbulence, nonce: (cur?.nonce ?? 0) + 1 }));
scrollToId("make", reduce);
},
[reduce],
);
return (
<MotionConfig reducedMotion="user">
<div className={cn("relative w-full overflow-x-clip bg-background text-foreground antialiased selection:bg-orange-600 selection:text-white", className)}>
<Navbar brand={d.brand} links={d.nav} />
<main>
<Hero data={d} onCta={() => scrollToId("contact", reduce)} onWork={() => scrollToId("work", reduce)} />
<Studio data={d} />
<Gallery data={d} onOpenInMaker={openInMaker} />
<Maker data={d} preset={preset} exportSize={exportSize} onDownload={onDownload} />
<Manifesto data={d} />
<Contact data={d} onSubmit={onInquiry} />
</main>
<Footer data={d} />
</div>
</MotionConfig>
);
}