import gql from 'graphql-tag' import { Mutation, Query } from 'react-apollo' import { useState } from 'react' import { endpoint } from '../config' const DO_LOCAL = gql` { doLocal @client } ` const UPLOAD_FILE = gql` mutation UPLOAD_FILE($files: [Upload!]!, $name: String!, $description: String!) { uploadFiles(files: $files, name: $name, description: $description) { id path name description filename mimetype size } } ` const TestForm = props => { const [state, setState] = useState({ files: null, name: '', description: '' }) function updateState(event) { const { name, type, files, value } = event.target setState({ ...state, [name]: type === 'file' ? files : value }) } return ( <Mutation mutation={UPLOAD_FILE} variables={state}> {(uploadFiles, { data, error, loading }) => ( <form onSubmit={async event => { console.log(state) event.preventDefault() const res = await uploadFiles() console.log(res) }}> <input type='file' multiple required name='files' onChange={updateState} /> <input type='text' name='name' value={state.name} onChange={updateState} /> <textarea name='description' value={state.description} onChange={updateState} /> <button>Send</button> <Query query={DO_LOCAL}> {({ data, client }) => ( <> <button type='button' onClick={ event => { client.writeData({ data: { doLocal: !data.doLocal } }) } }>Do Local</button> <button disabled={data.doLocal}>Uh-Oh!</button> </> )} </Query> </form> )} </Mutation> ) } const FileFormFields = props => { const [state, setState] = useState({ ...FileState }) const updateState = async event => { const { name, type, value, files } = event.target await setState({ ...state, [name]: type === 'file' ? files[0] : value }) console.log(state) props.onChange(event, state) } return ( < fieldset > <label htmlFor='file'>File</label> <input type='file' multiple required name='file' id='file' onChange={updateState} /> <label htmlFor='name'>File name</label> <input type='text' name='name' id='name' placeholder='File name' value={state.name} onChange={updateState} /> <label htmlFor='description'>File description</label> <textarea name='description' id='description' placeholder='File description' value={state.description} onChange={updateState} /> </fieldset > ) } const FileFields = { id: null, path: '', name: '', description: '', filename: '', mimetype: '', size: '', file: null } async function uploadFile(file) { const body = new FormData() body.append('file', file) const res = await fetch(`${endpoint}/upload`, { method: 'POST', body }) return res.json() } class FileUpload extends React.Component { state = { ...FileState } upload = async event => { event.preventDefault() if (!this.state.file) { alert('Please select file first.') return } this.setState({ uploading: true }) const data = new FormData() data.append('file', this.state.file) data.append('description', this.state.description) const res = await fetch(`${endpoint}/upload`, { method: 'POST', body: data }) const { error, file } = await res.json() if (error) { console.error(error) alert('Upload error.') this.setState({ uploading: false }) } this.setState({ path: `${endpoint}/${file.path}`, uploading: false }) } selectFile = event => { const { validity, files } = event.target this.setState({ file: files[0] }) } handleChange = event => { this.setState({ [event.target.name]: event.target.value }) } render() { return ( <form> <fieldset> <input type='file' name='file' id='file' onChange={this.selectFile} /> <textarea name="description" id="description" placeholder="Description" value={this.state.description} onChange={this.handleChange} ></textarea> <img src={this.state.path} alt={this.state.name} /> <button onClick={this.upload} disabled={this.state.uploading}>Save</button> </fieldset> </form> ) } } export default FileUpload export { FileFields, FileFormFields }