-
-
Save DanyF-github/a57f0c68307d9b62c075b6f919d4b8ce to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// client/src/component/HomeworkFileForm.tsx | |
import React from 'react'; | |
import { useMutation, useQuery } from '@apollo/client'; | |
import { | |
ADD_HOMEWORK_FILE, | |
PRESIGN_HOMEWORK_FILE_UPLOAD, | |
} from '../../data/mutations'; | |
import { GET_HOMEWORK } from '../../data/queries'; | |
import { Homework } from '../../models'; | |
// this components receives the uuid of the homework and the authentication token as properties | |
const HomeworkFileForm = ({ uuid, token }: { uuid: string; token: string }) => { | |
// create a reference of the html element | |
let homeworkFileRef: HTMLInputElement; | |
// use the uuid to retrieve the information of the homework | |
const { data, loading, error } = useQuery< | |
{ homework: Homework }, | |
{ uuid: string } | |
>(GET_HOMEWORK, { | |
variables: { | |
uuid | |
} | |
}); | |
// setup the mutate functions for presiging the file and for adding the reference to the database | |
const [presignHomeworkFileUpload] = useMutation(PRESIGN_HOMEWORK_FILE_UPLOAD); | |
const [addHomeworkFile] = useMutation(ADD_HOMEWORK_FILE); | |
render the component | |
return ( | |
<> | |
{loading && <p>Loading...</p>} | |
{error && <p>Error!</p>} | |
{data && ( | |
<> | |
<p>Description: {data.homework.description}</p> | |
<form | |
onSubmit={async (e) => { | |
e.preventDefault(); | |
try { | |
// get the file from the html element reference | |
const file = | |
homeworkFileRef && | |
homeworkFileRef.files && | |
homeworkFileRef.files[0]; | |
// make sure a file was provided | |
if (!file) { | |
throw new Error('file is not defined'); | |
} | |
// get the presign informatio from the server | |
const { data } = await presignHomeworkFileUpload({ | |
variables: { | |
fileName: `homeworks/uuid/${Date.now()}`, | |
isPublic: true, | |
token, | |
}, | |
}); | |
// parse the stringified JSON | |
const imageData = JSON.parse(data.presignDocument); | |
// create a form programatically for sending the file to S3 | |
const formData = new FormData(); | |
// add the required headers | |
formData.append('Content-Type', file?.type); | |
formData.append('acl', 'public-read'); | |
// add the signing information | |
Object.keys(imageData.fields).forEach((key) => { | |
formData.append(key, imageData.fields[key]); | |
}); | |
// and finally add the file | |
formData.append('file', file); | |
// use fetch to send a POST requests to S3 | |
const result = await fetch(imageData.url, { | |
method: 'POST', | |
body: formData, | |
}); | |
// if the file was uploaded sucessfully then add the file information to the database | |
if (result.status >= 200 && result.status <= 299) { | |
addHomeworkFile({ | |
variables: { | |
url: imageData.url + '/' + imageData.fields.Key, | |
uuid, | |
token, | |
}, | |
}); | |
} | |
} catch (err) { | |
console.error('An error ocurred', err); | |
} | |
}} | |
> | |
<input | |
id="homeworkFile" | |
type="file" | |
name="homeworkFile" | |
ref={(node: HTMLInputElement) => (homeworkFileRef = node)} | |
/> | |
<button type="submit">Send</button> | |
</form> | |
</> | |
)} | |
</> | |
); | |
}; | |
export default HomeworkFileForm; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment