in genkit/postcard-generator/app/components/PostcardForm.tsx [37:152]
export default function PostcardForm() {
const [start, setStart] = useState<string>("");
const [end, setEnd] = useState<string>("");
const [sender, setSender] = useState<string>("");
const [recipient, setRecpient] = useState<string>("");
const [loading, setLoading] = useState<boolean>(true);
const [postcardImage, setPostcardImage] = useState<string | null>(null);
const [mapImage, setMapImage] = useState<string | null>(null);
const [description, setDescription] = useState<string>("");
const [story, setStory] = useState<string>("");
const [error, setError] = useState<string | null>(null);
const [loginError, setLoginError] = useState<string | null>(null);
const [generating, setGenerating] = useState<boolean>(false);
function updateStartAddress(e: Event) {
if (e.target) {
const eventValue = (e.target as HTMLSelectElement).value;
const place = eventValue as unknown as google.maps.places.Place;
setStart(`${place.displayName}, ${place.formattedAddress}`);
}
}
function updateEndAddress(e: Event) {
if (e.target) {
const eventValue = (e.target as HTMLSelectElement).value;
const place = eventValue as unknown as google.maps.places.Place;
setEnd(`${place.displayName}, ${place.formattedAddress}`);
}
}
async function generatePostcard(event: React.FormEvent) {
try {
event.preventDefault();
setGenerating(true);
const image = await callPostcardFlow(r);
setError(null);
setPostcardImage(image.image);
setDescription(image.description);
setStory(image.story);
setMapImage(image.map);
}
catch {
// TODO - show an error in the UI
setError("An error occurred generating your postcard. Please try again.");
}
finally {
setGenerating(false);
}
}
// This page requires authentication, check we have that
const { user, googleSignIn, enabled } = UserAuth();
useEffect(() => {
const checkAuthentication = async () => {
await new Promise(resolve => setTimeout(resolve, 50));
setLoading(false);
};
checkAuthentication();
}, [user]);
const handleSignIn = async () => {
try {
await googleSignIn();
setLoginError(null);
}
catch (error) {
setLoginError(`Login failed with error: ${error}`);
}
};
const r = {
start: start,
end: end,
stops: [],
sender: sender,
recipient: recipient,
} as PostcardFlow;
if (loading) {
return <CircularProgress />;
}
if (!enabled) {
<Alert severity="warning">
<AlertTitle>Login is disabled in this project.</AlertTitle>
{loginError}
</Alert>;
}
if ((!user) && (enabled)) {
// Install a proxying service worker if Firebase is configured
if (("serviceWorker" in navigator) && (firebaseConfig) && (firebaseConfig.apiKey) && (firebaseConfig.apiKey !== "")) {
navigator.serviceWorker.register("/auth-service-worker.js", { scope: "/" });
}
return (
<>
{loginError && !loading && (
<Alert severity="error">
<AlertTitle>An Error Occurred</AlertTitle>
{loginError}
</Alert>
)}
<Alert severity="warning" variant="outlined">Only logged-in users may view this page.</Alert>
<Button color="inherit" onClick={handleSignIn}>
Login with Google
</Button>
</>
);
}
return (
<Container maxWidth="lg">
<PostcardImage postcardImage={postcardImage} generating={generating} description={description} start={start} end={end} error={error} mapImage={mapImage} story={story} />
<form>
<APILoader apiKey={process.env.NEXT_PUBLIC_GOOGLE_MAPS_PUBLIC_API_KEY} solutionChannel="GMP_GCC_placepicker_v1" />
<Stack spacing={2} direction="row">
<TextField required sx={{ width: "50%" }} label="Sender" variant="outlined" value={sender} onChange={e => setSender(e.target.value)} />