Fazekit

Code

"use client";
import * as React from "react";
import { MotionConfig, useReducedMotion } from "motion/react";
import { cn } from "@/lib/utils";
import { defaultConferenceData, type ConferenceData } from "./data";
import { Cta, Faq, Footer } from "./sections/faq-cta-footer";
import { Hero } from "./sections/hero";
import { Navbar } from "./sections/navbar";
import { Schedule } from "./sections/schedule";
import { Speakers } from "./sections/speakers";
import { Sponsors } from "./sections/sponsors";
import { Tickets, type TicketOrder } from "./sections/tickets";
import { Tracks } from "./sections/tracks";
import { scrollToId } from "./sections/ui";
import { Venue } from "./sections/venue";

export type { ConferenceData, TicketOrder };
export { defaultConferenceData };

export interface ConferenceTemplateProps {
  /** Override any top-level content group (event, speakers, schedule…). Missing groups use the demo content. */
  data?: Partial<ConferenceData>;
  /** Called when a visitor checks out a ticket order. Return a promise to keep the loading state. */
  onCheckout?: (order: TicketOrder) => void | Promise<void>;
  /** Called whenever the visitor stars/unstars sessions — persist their agenda here. */
  onAgendaChange?: (sessionIds: string[]) => void;
  /** Called from "Become a sponsor". Defaults to scrolling to the footer. */
  onSponsorEnquiry?: () => void;
  className?: string;
}

export function ConferenceTemplate({ data, onCheckout, onAgendaChange, onSponsorEnquiry, className }: ConferenceTemplateProps) {
  const d = React.useMemo(() => ({ ...defaultConferenceData, ...data }), [data]);
  const reduce = useReducedMotion();
  const toTickets = React.useCallback(() => scrollToId("tickets", reduce), [reduce]);
  const toSchedule = React.useCallback(() => scrollToId("schedule", reduce), [reduce]);

  return (
    <MotionConfig reducedMotion="user">
      <div className={cn("relative w-full bg-background text-foreground antialiased selection:bg-fuchsia-500/25", className)}>
        <Navbar name={d.event.shortName} edition={d.event.edition} links={d.nav} onTickets={toTickets} />
        <main>
          <Hero event={d.event} stats={d.stats} onTickets={toTickets} onSchedule={toSchedule} />
          <Tracks tracks={d.tracks} />
          <Speakers speakers={d.speakers} schedule={d.schedule} />
          <Schedule schedule={d.schedule} speakers={d.speakers.items} onAgendaChange={onAgendaChange} />
          <Venue venue={d.venue} />
          <Tickets tickets={d.tickets} currency={d.event.currency} onCheckout={onCheckout} />
          <Sponsors sponsors={d.sponsors} onBecome={onSponsorEnquiry ?? (() => scrollToId("faq", reduce))} />
          <Faq faq={d.faq} />
          <Cta cta={d.cta} event={d.event} onTickets={toTickets} />
        </main>
        <Footer event={d.event} nav={d.nav} footer={d.footer} />
      </div>
    </MotionConfig>
  );
}

More in Landing Pages

View all →