in genkit/postcard-generator/app/components/Postcard.tsx [73:169]
export default function PostcardImage({ postcardImage, generating, error, mapImage, description, story }: PostcardImageProps) {
const [expanded, setExpanded] = useState(false);
const handleExpandClick = () => {
setExpanded(!expanded);
};
async function download() {
if (postcardImage) {
// Use fetch to convert the image data URL into a blob
const response = await fetch(postcardImage);
// Create a download link
const url = window.URL.createObjectURL(await response.blob());
const link = document.createElement("a");
link.href = url;
link.setAttribute("download", "postcard.png");
// Simulate a click on the link to trigger the download
document.body.appendChild(link);
link.click();
link.parentNode?.removeChild(link);
}
}
return (
<div className="w-full flex justify-center">
<Card sx={{ minWidth: 275, Height: 500 }}>
{generating && (
<CardContent sx={{ Height: 500 }}>
<Alert severity="info" variant="filled">Generating Postcard</Alert>
<LinearProgress />
</CardContent>
)}
{postcardImage && story && mapImage && !generating && (
<>
<CardMedia
component="img"
image={postcardImage}
alt="Generated Postcard Image"
sx={{ padding: "1em 1em 0 1em", objectFit: "contain", maxHeight: 500 }}
/>
<CardContent>
<Typography sx={{ marginBottom: 2 }} component="span">
<Markdown>
{story}
</Markdown>
</Typography>
</CardContent>
<CardActions disableSpacing>
<IconButton aria-label="Download image" onClick={download}>
<DownloadIcon />
</IconButton>
<IconButton aria-label="share">
<ShareIcon />
</IconButton>
<ExpandMore
expand={expanded}
onClick={handleExpandClick}
aria-expanded={expanded}
aria-label="show more"
>
<ExpandMoreIcon />
</ExpandMore>
</CardActions>
<Collapse in={expanded} timeout="auto" unmountOnExit>
<CardContent>
<Typography gutterBottom variant="h5" component="div">
Map
</Typography>
<Typography sx={{ marginBottom: 2 }}>
<CardMedia
component="img"
image={mapImage}
alt="Route Map"
sx={{ padding: "1em 1em 0 1em", objectFit: "contain", maxHeight: 500 }}
/>
</Typography>
<Typography gutterBottom variant="h5" component="div">
Prompt
</Typography>
<Typography sx={{ marginBottom: 2 }} component="span">
<Markdown>
{description}
</Markdown>
</Typography>
</CardContent>
</Collapse>
</>
)}
{error && !generating && (
<CardContent sx={{ Height: 500 }}>
<Alert severity="error">{error}</Alert>
</CardContent>
)}
</Card>
</div>
);
}