create abstract FormGenerator && Use generator in Album -> Create.js / refactor spaghetti

develop
TBS093A 2020-08-12 14:41:20 +02:00
parent 13914f4283
commit 67703a4a0c
9 changed files with 220 additions and 65 deletions

View File

@ -0,0 +1,125 @@
import React from 'react'
/**
*
* @param { [ {}, {}, ...{} ] } inputList - list of dicts with info about input
* @param { } action - fetch method
*/
const FormGenerator = ({
inputList, action
}) => {
return (
<form onSubmit={ event => action( event ) }>
{
inputList.map( input => {
if ( input.type === 'text' ) {
return (
<TextInputGenerator
input={ input }
/>
)
} else if ( input.type === 'file' ) {
return (
<UploadInputGenerator
input={ input }
/>
)
}
})
}
<button type='submit' />
</form>
)
}
/**
* Text input generator, example:
* @param {
* {
* type: 'text',
* name: 'name',
* ref: React.createRef()
* } } input - basic text input
*/
const TextInputGenerator = ({
input
}) => {
return (
<div>
{ input.name + ':' }
<input
id={ input.name + 'Input' }
autoComplete='off'
ref={ input.ref }
/>
</div>
)
}
/**
* Upload file input generator, example:
* @param {
* {
* type: 'file',
* name: 'name',
* fileType: 'image',
* dropInfo: dropInfo, setDropInfo: setDropInfo(), #useState
* file: file, setFile: setFile() #useState
* } } input -
*/
const UploadInputGenerator = ({
input
}) => {
const onLoadFile = async ( event ) => {
event.preventDefault()
let data = event.target.files[0]
input.setFile( await toBase64( data ) )
setDropInfos(data.name, data.size)
}
const onLoadFileDrop = async ( event ) => {
event.preventDefault()
event.persist()
let data = event.dataTransfer.files[0]
input.setFile( await toBase64( data ) )
setDropInfos(data.name, data.size)
}
const toBase64 = ( file ) => new Promise( (resolve, reject) => {
let fileReader = new FileReader()
fileReader.readAsDataURL( file )
fileReader.onload = () => resolve( fileReader.result )
fileReader.onerror = error => reject( error )
})
const setDropInfos = (name, size) => {
input.setDropInfo(
'name: "'
+ name
+ '"\nsize: '
+ (Math.round(size / 100 + 'e-2') / 100 )
+ ' MB'
)
}
return (
<div onDrop={ event => onLoadFileDrop( event ) } >
<pre style={ {marginTop: '25px', marginLeft: '40px'} }>
{ input.dropInfo }
</pre>
<input
style={ { marginTop: '-55px' } }
id={ input.name + 'Input' }
className='uploadInput'
type='file'
autoComplete='off'
onChange={ event => onLoadFile( event ) }
/>
</div>
)
}
export default FormGenerator

View File

@ -2,7 +2,8 @@ import React, { useState, useEffect } from 'react'
import { connect } from 'react-redux'
import { createAlbum } from '../../../../../../stores/album/duck/operations'
import { progressStream } from '../../../../../../stores/AppService'
import FormGenerator from '../Abstract Utils/FormGenerator'
const AlbumCreate = ({
user,
@ -19,6 +20,28 @@ const AlbumCreate = ({
const titleInput = React.createRef()
const descriptionInput = React.createRef()
let inputList = [
{
type: 'text',
name: 'titleAlbum',
ref: titleInput
},
{
type: 'text',
name: 'descriptionAlbum',
ref: descriptionInput
},
{
type: 'file',
name: 'imageAlbum',
fileType: 'image',
dropInfo: imageInfo,
setDropInfo: setImageInfo,
file: image,
setFile: setImage
}
]
const create = async (event) => {
event.preventDefault()
let title = titleInput.current.value
@ -90,70 +113,77 @@ const AlbumCreate = ({
}
)
const toBase64 = ( file ) => new Promise( (resolve, reject) => {
let fileReader = new FileReader()
fileReader.readAsDataURL( file )
fileReader.onload = () => resolve( fileReader.result )
fileReader.onerror = error => reject( error )
})
const onLoadFile = async ( event ) => {
event.preventDefault()
let data = event.target.files[0]
setImage( await toBase64( data ) )
setImageInfos(data.name, data.size)
}
const onLoadFileDrop = async ( event ) => {
event.preventDefault()
event.persist()
let data = event.dataTransfer.files[0]
setImage( await toBase64( data ) )
setImageInfos(data.name, data.size)
}
const setImageInfos = (name, size) => {
setImageInfo(
'name: "'
+ name
+ '"\nsize: '
+ (Math.round(size / 100 + 'e-2') / 100 )
+ ' MB'
)
}
return (
<div
onDrop={ event => onLoadFileDrop(event) }
>
<form
onSubmit={ event => create(event) }>
title:
<input
id='titleAlbumInput'
autoComplete='off'
ref={ titleInput }
/> <br />
description:
<input
id='descriptionAlbumInput'
autoComplete='off'
ref={ descriptionInput }
/> <br />
<pre style={ {marginTop: '25px', marginLeft: '40px'} }>
{ imageInfo }
</pre>
<input style={ {marginTop: '-55px'} }
id='imageAlbumInput'
className='uploadInput'
type='file'
autoComplete='off'
onChange={ event => onLoadFile(event) }
/> <br />
<button type='submit' />
</form>
</div>
<FormGenerator
inputList={ inputList }
action={ create }
/>
)
// const toBase64 = ( file ) => new Promise( (resolve, reject) => {
// let fileReader = new FileReader()
// fileReader.readAsDataURL( file )
// fileReader.onload = () => resolve( fileReader.result )
// fileReader.onerror = error => reject( error )
// })
// const onLoadFile = async ( event ) => {
// event.preventDefault()
// let data = event.target.files[0]
// setImage( await toBase64( data ) )
// setImageInfos(data.name, data.size)
// }
// const onLoadFileDrop = async ( event ) => {
// event.preventDefault()
// event.persist()
// let data = event.dataTransfer.files[0]
// setImage( await toBase64( data ) )
// setImageInfos(data.name, data.size)
// }
// const setImageInfos = (name, size) => {
// setImageInfo(
// 'name: "'
// + name
// + '"\nsize: '
// + (Math.round(size / 100 + 'e-2') / 100 )
// + ' MB'
// )
// }
// return (
// <div
// onDrop={ event => onLoadFileDrop(event) }
// >
// <form
// onSubmit={ event => create(event) }>
// title:
// <input
// id='titleAlbumInput'
// autoComplete='off'
// ref={ titleInput }
// /> <br />
// description:
// <input
// id='descriptionAlbumInput'
// autoComplete='off'
// ref={ descriptionInput }
// /> <br />
// <pre style={ {marginTop: '25px', marginLeft: '40px'} }>
// { imageInfo }
// </pre>
// <input style={ {marginTop: '-55px'} }
// id='imageAlbumInput'
// className='uploadInput'
// type='file'
// autoComplete='off'
// onChange={ event => onLoadFile(event) }
// /> <br />
// <button type='submit' />
// </form>
// </div>
// )
}
const mapStateToProps = state => ({

View File

@ -124,8 +124,8 @@ const responseCRU = async (address, method, body, token) => {
/**
* fetch bonus exceptions ( not blank fields in request / bad requests )
* @param {Response} response
* @param {number} status
* @param {Response} response - response from fetch
* @param {number} status - request status
*/
const responseExceptions = async (response, status) => {
try {