import { FanfareProvider, useFanfareAuth, useExperienceJourney } from "@fanfare-io/fanfare-sdk-react";
import { useEffect, useState } from "react";
function GuestExperience({ experienceId }: { experienceId: string }) {
const { isAuthenticated, isGuest, guest, session } = useFanfareAuth();
const { view, start } = useExperienceJourney(experienceId);
const [isInitializing, setIsInitializing] = useState(true);
// Step 1: Auto-authenticate as guest
useEffect(() => {
async function init() {
if (!isAuthenticated) {
await guest();
}
setIsInitializing(false);
}
init();
}, [isAuthenticated, guest]);
// Step 2: Start journey when authenticated
useEffect(() => {
if (isAuthenticated && view?.journeyStage === "ready" && !isInitializing) {
void start();
}
}, [isAuthenticated, view?.journeyStage, isInitializing, start]);
if (isInitializing) {
return <div className="loading">Preparing your experience...</div>;
}
return (
<div className="guest-experience">
{/* Session Info */}
<div className="session-info">
<p>Session Type: {isGuest ? "Guest" : "Identified"}</p>
<p>Consumer ID: {session?.consumerId?.slice(0, 8)}...</p>
</div>
{/* Experience Status */}
<div className="experience-status">
<p>Status: {view?.journeyStage ?? "loading"}</p>
</div>
{/* Actions */}
<div className="actions">
{view?.journeyStage === "routed" && view.sequence.phase === "enterable" && "enter" in view.sequence && (
<button onClick={() => void view.sequence.enter()} className="primary-btn">
Join Queue
</button>
)}
{view?.journeyStage === "routed" && view.sequence.phase === "granted" && (
<div className="admitted">
<h3>You're In!</h3>
<button onClick={() => sendAdmissionGrant(view.sequence.grant.token)} className="checkout-btn">
Continue to Checkout
</button>
</div>
)}
</div>
</div>
);
}
export function App() {
return (
<FanfareProvider organizationId="org_xxx" publishableKey="pk_live_xxx" autoRestore={true} autoResume={true}>
<GuestExperience experienceId="exp_product_launch" />
</FanfareProvider>
);
}