Exercise 11: Upload images
Meetup events sometimes can have an image. For example, someone will add a custom social media sharing image, or simply a sponsor logo. Is that something Amplify can do for us? Well, as you can guess...
Task
Allow users to upload an image when creating the event, then save that image to the event details and show it on the event details page and a list of the events for that meetup group.
Hints
- Check the
amplify add storagecommand. - See the documentation for more details: https://aws-amplify.github.io/docs/js/storage.
Run the amplify add storage command to add storage. Then add "Content (Images, audio, video, etc.)" type of the storage and answer the remaining questions (default answers will work just fine).
Once you finish your setup, run amplify push to deploy all changes to your AWS account, and you'll be ready to integrate storage to your React app.
To do so, you'll need something similar to this code snippet:
import React, { useState, useEffect } from 'react';
import { Form, Tooltip, Icon, Alert, Upload } from 'antd';
import { Storage } from 'aws-amplify';
function NewEventForm(props) {
const [formError, setFormError] = useState(0);
const [imageUrl, setImageUrl] = useState(null);
const [fileToUpload, setFileToUpload] = useState(null);
const [uploading, setUploading] = useState(false);
const { getFieldDecorator } = props.form;
const handleUpload = async () => {
const response = await Storage.put(fileToUpload.name, fileToUpload);
const s3ImageUrl = await Storage.get(response.key, { level: 'public' });
setImageUrl(s3ImageUrl);
setUploading(false);
return s3ImageUrl;
}
useEffect(() => {
if (fileToUpload) {
handleUpload(fileToUpload);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [fileToUpload]);
const handleUploadChange = () => {
setUploading(true);
}
const uploadButton = (
<div>
<Icon type={uploading ? 'loading' : 'plus'} />
<div className="ant-upload-text">Upload</div>
</div>
);
return (
<Form onSubmit={(e) => {
e.preventDefault();
// TODO
} }>
{
formError ? <Alert type="error" message={formError} banner /> : ''
}
<Form.Item
label={
<span>
Event image
<Tooltip title="Upload an image for your event">
<Icon type="question-circle-o" />
</Tooltip>
</span>
}
>
<Upload
name="event-image"
listType="picture-card"
className="event-image-uploader"
showUploadList={false}
action={handleUpload}
beforeUpload={file => {
setFileToUpload(file);
return false;
}}
onChange={handleUploadChange}
>
{imageUrl ? <img src={imageUrl} alt="avatar" style={{ width: '100%' }} /> : uploadButton}
</Upload>
</Form.Item>
// TODO: More form items
</Form>
);
}
const WrappedNewEventForm = Form.create({ name: 'new-event' })(NewEventForm);
export default WrappedNewEventForm;