React 'Schedule a Meeting' Shared State Example
Shared State example of a ‘Schedule Meeting’ React form with the agent using hooks.
import { useEffect, useRef, useState } from "react";
type MeetingState = { title: string; date: string; // "2025-09-01" startTime: string; // "14:00" endTime: string; // "15:00" attendees: string; // comma-separated emails location: string; // "Zoom" | "Office TLV" | "Google Meet" | custom notes?: string;};
interface Props { agentKey: string; initial?: Partial<MeetingState>;}
export default function ScheduleMeetingForm({ agentKey, initial }: Props) { const [form, setForm] = useState<MeetingState>({ title: initial?.title ?? "", date: initial?.date ?? "", startTime: initial?.startTime ?? "", endTime: initial?.endTime ?? "", attendees: initial?.attendees ?? "", location: initial?.location ?? "", notes: initial?.notes ?? "", });
const agentRef = useRef<any | null>(null); const stateKey = "meeting_form"; const stateDescription = ` type MeetingState = { title: string; date: string; // "2025-09-01" startTime: string; // "14:00" endTime: string; // "15:00" attendees: string; // comma-separated emails location: string; // "Zoom" | "Office TLV" | "Google Meet" | custom notes?: string; };
interface Props { agentKey: string; initial?: Partial<MeetingState>; }`;
useEffect(() => { agentRef.current = (window as any).foldspace?.agent(agentKey);
const handleStateChange = (key: string, nextState: unknown) => { if (key === stateKey) setForm(nextState as MeetingState); };
agentRef.current?.shareState(stateKey, form, handleStateChange, stateDescription);
return () => { agentRef.current?.clearState(stateKey); agentRef.current = null; }; // eslint-disable-next-line react-hooks/exhaustive-deps }, [agentKey]);
const updateField = <K extends keyof MeetingState>(k: K, v: MeetingState[K]) => { const next = { ...form, [k]: v }; setForm(next); agentRef.current?.shareState(stateKey, next); };
return ( <form style={{ display: "grid", gap: 12, maxWidth: 520 }}> <label> Title <input value={form.title} onChange={(e) => updateField("title", e.target.value)} placeholder="Weekly Sync" /> </label>
<div style={{ display: "grid", gap: 12, gridTemplateColumns: "1fr 1fr" }}> <label> Date <input type="date" value={form.date} onChange={(e) => updateField("date", e.target.value)} /> </label> <label> Start <input type="time" value={form.startTime} onChange={(e) => updateField("startTime", e.target.value)} /> </label> <label> End <input type="time" value={form.endTime} onChange={(e) => updateField("endTime", e.target.value)} /> </label> <label> Location <input value={form.location} onChange={(e) => updateField("location", e.target.value)} placeholder="Zoom / Office TLV / Meet" /> </label> </div>
<label> Attendees (comma-separated emails) <input value={form.attendees} onChange={(e) => updateField("attendees", e.target.value)} placeholder="alex@example.com, dana@example.com" /> </label>
<label> Notes <textarea value={form.notes ?? ""} onChange={(e) => updateField("notes", e.target.value)} placeholder="Agenda, prep, etc." /> </label>
<small> {/* The agent tracks "meeting_form" and can act on it (e.g., draft invites). */} Snapshot: {JSON.stringify(form)} </small> </form> );}