React 'Schedule a Meeting' Shared State Example
Shared State example of a 'Schedule Meeting' React form with the agent using hooks.
// ScheduleMeetingForm.tsx
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).eucera?.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="[email protected], [email protected]"
/>
</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>
);
}
Updated 8 days ago