2019-04-03 15:46:09 -04:00
import React , { createRef , useState , useContext } from 'react'
2019-04-01 15:59:38 -04:00
import { Formik } from 'formik'
2019-04-03 15:46:09 -04:00
import LiquidPledging from 'Embark/contracts/LiquidPledging'
2019-04-01 15:59:38 -04:00
import TextField from '@material-ui/core/TextField'
2019-04-01 13:48:53 -04:00
import Divider from '@material-ui/core/Divider'
2019-04-01 15:59:38 -04:00
import FormControlLabel from '@material-ui/core/FormControlLabel'
import Switch from '@material-ui/core/Switch'
import Button from '@material-ui/core/Button'
2019-04-02 15:10:20 -04:00
import InputAdornment from '@material-ui/core/InputAdornment'
import CloudUpload from '@material-ui/icons/CloudUpload'
2019-04-01 13:48:53 -04:00
import { withStyles } from '@material-ui/core/styles'
2019-04-04 12:49:09 -04:00
import { formatForIpfs , uploadToIpfs , formatMedia , isWeb } from '../../utils/ipfs'
2019-04-03 15:46:09 -04:00
import { FundingContext } from '../../context'
const { addProject } = LiquidPledging . methods
const hoursToSeconds = hours => hours * 60 * 60
const helperText = 'The length of time the Project has to veto when the project delegates to another delegate and they pledge those funds to a project'
2019-04-01 13:48:53 -04:00
const styles = theme => ( {
root : {
display : 'grid' ,
gridTemplateColumns : 'repeat(12, [col] 1fr)' ,
gridTemplateRows : 'repeat(5, [row] auto)' ,
gridColumnGap : '1em' ,
2019-04-01 15:59:38 -04:00
gridRowGap : '3ch' ,
2019-04-01 13:48:53 -04:00
fontFamily : theme . typography . fontFamily ,
[ theme . breakpoints . up ( 'sm' ) ] : {
margin : '1.75rem 4.5rem'
}
} ,
title : {
display : 'grid' ,
fontSize : '2.5rem' ,
gridColumnStart : '1' ,
gridColumnEnd : '13' ,
gridRowStart : '1' ,
gridRowEnd : '6' ,
textAlign : 'center'
} ,
submissionRoot : {
2019-04-01 15:59:38 -04:00
display : 'grid' ,
gridTemplateColumns : 'repeat(12, [col] 1fr)' ,
gridTemplateRows : 'repeat(5, [row] auto)' ,
gridColumnGap : '1em' ,
2019-04-01 13:48:53 -04:00
gridColumnStart : '1' ,
2019-04-01 15:59:38 -04:00
gridColumnEnd : '13' ,
gridRowGap : '2ch' ,
} ,
formControl : {
gridColumnStart : '6'
} ,
formButton : {
gridColumnStart : '1' ,
gridColumnEnd : '13' ,
height : '50px'
2019-04-01 13:48:53 -04:00
} ,
textField : {
2019-04-01 15:59:38 -04:00
gridColumnStart : '1' ,
gridColumnEnd : '13'
} ,
textInput : {
fontSize : '2rem'
2019-04-01 13:48:53 -04:00
}
} )
2019-04-04 12:49:09 -04:00
2019-04-02 13:48:05 -04:00
const createJSON = values => {
const {
title ,
subtitle ,
creator ,
avatar ,
goal ,
goalToken ,
video ,
isPlaying ,
description
} = values
const manifest = {
title ,
subtitle ,
creator ,
2019-04-03 15:46:09 -04:00
avatar : formatMedia ( avatar ) ,
2019-04-02 13:48:05 -04:00
goal ,
goalToken ,
description ,
media : {
isPlaying ,
type : 'video'
}
}
2019-04-04 10:53:28 -04:00
if ( isWeb ( video ) ) Object . assign ( manifest . media , { url : formatMedia ( video ) } )
else Object . assign ( manifest . media , { file : formatMedia ( video ) } )
2019-04-03 14:57:50 -04:00
return JSON . stringify ( manifest , null , 2 )
2019-04-02 13:48:05 -04:00
}
2019-04-01 13:48:53 -04:00
const Title = ( { className } ) => (
< div className = { className } >
< div style = { { alignSelf : 'center' } } > Create Project < / div >
< Divider / >
< / div >
)
2019-04-02 15:10:20 -04:00
let uploadInput = createRef ( )
2019-04-04 12:33:59 -04:00
const getProjectId = response => {
const { events : { ProjectAdded : { returnValues : { idProject } } } } = response
return idProject
}
2019-04-03 15:46:09 -04:00
const addProjectSucessMsg = response => {
const { events : { ProjectAdded : { returnValues : { idProject } } } } = response
2019-04-04 12:33:59 -04:00
return ` Project created with ID of ${ idProject } , will redirect to your new project page in a few seconds `
2019-04-03 15:46:09 -04:00
}
2019-04-04 12:33:59 -04:00
const SubmissionSection = ( { classes , history } ) => {
2019-04-03 14:57:50 -04:00
const [ uploads , setUploads ] = useState ( { } )
2019-04-03 15:46:09 -04:00
const { account , openSnackBar } = useContext ( FundingContext )
2019-04-01 15:59:38 -04:00
return (
< Formik
2019-04-02 13:48:05 -04:00
initialValues = { {
title : '' ,
subtitle : '' ,
creator : '' ,
avatar : '' ,
goal : '' ,
goalToken : '' ,
video : '' ,
2019-04-04 12:33:59 -04:00
isPlaying : true ,
2019-04-03 15:46:09 -04:00
description : '' ,
commitTime : 24
2019-04-02 13:48:05 -04:00
} }
onSubmit = { async ( values , { resetForm } ) => {
2019-04-03 15:46:09 -04:00
const { title , commitTime } = values
2019-04-02 13:48:05 -04:00
const manifest = createJSON ( values )
2019-04-03 14:57:50 -04:00
let fileLists = [ ]
Object . keys ( uploads ) . forEach ( k => {
fileLists = [ ... fileLists , formatForIpfs ( uploads [ k ] [ 0 ] ) ]
} )
fileLists . push ( {
path : '/root/manifest.json' , content : Buffer . from ( manifest )
} )
const contentHash = await uploadToIpfs ( fileLists )
2019-04-03 15:46:09 -04:00
const args = [ title , contentHash , account , 0 , hoursToSeconds ( commitTime ) , 0 ]
addProject ( ... args )
. estimateGas ( { from : account } )
. then ( async gas => {
addProject ( ... args )
. send ( { from : account , gas : gas + 100 } )
. then ( res => {
console . log ( { res } )
openSnackBar ( 'success' , addProjectSucessMsg ( res ) )
2019-04-04 12:33:59 -04:00
setTimeout ( ( ) => {
history . push ( ` /project/ ${ getProjectId ( res ) } ` )
resetForm ( )
} , 5000 )
2019-04-03 15:46:09 -04:00
} )
. catch ( e => openSnackBar ( 'error' , e ) )
} )
2019-04-03 14:57:50 -04:00
console . log ( { manifest , values , uploads , fileLists , contentHash } )
2019-04-02 13:48:05 -04:00
} }
2019-04-01 15:59:38 -04:00
>
{ ( {
values ,
errors ,
touched ,
handleChange ,
handleBlur ,
handleSubmit ,
setFieldValue ,
setStatus ,
2019-04-04 12:33:59 -04:00
status ,
isSubmitting
2019-04-01 15:59:38 -04:00
} ) => {
return (
< form onSubmit = { handleSubmit } className = { classes . submissionRoot } >
2019-04-02 15:10:20 -04:00
< input
ref = { ( input ) => { uploadInput = input } }
type = "file"
multiple
onChange = {
( e ) => {
const file = e . target . files
const { activeField } = status
setFieldValue ( activeField , file [ 0 ] [ 'name' ] )
2019-04-03 14:57:50 -04:00
setUploads ( { ... uploads , [ activeField ] : file } )
2019-04-02 15:10:20 -04:00
setStatus ( {
... status ,
2019-04-03 14:57:50 -04:00
activeField : null
2019-04-02 15:10:20 -04:00
} )
}
}
style = { { display : 'none' } }
/ >
2019-04-01 15:59:38 -04:00
< TextField
className = { classes . textField }
InputProps = { {
classes : {
input : classes . textInput
}
} }
2019-04-02 13:48:05 -04:00
id = "title"
name = "title"
2019-04-01 15:59:38 -04:00
label = "Enter Project Name"
placeholder = "Enter Project Name"
margin = "normal"
variant = "outlined"
onChange = { handleChange }
onBlur = { handleBlur }
2019-04-02 13:48:05 -04:00
value = { values . title || '' }
2019-04-01 15:59:38 -04:00
/ >
2019-04-03 15:46:09 -04:00
< TextField
className = { classes . textField }
InputProps = { {
classes : {
input : classes . textInput
}
} }
2019-04-04 10:53:28 -04:00
id = "subtitle"
name = "subtitle"
label = "Enter a sub heading description for your project"
placeholder = "Enter a sub heading description for your project"
2019-04-03 15:46:09 -04:00
margin = "normal"
variant = "outlined"
onChange = { handleChange }
onBlur = { handleBlur }
2019-04-04 10:53:28 -04:00
value = { values . subtitle || '' }
2019-04-03 15:46:09 -04:00
/ >
2019-04-01 15:59:38 -04:00
< TextField
2019-04-04 10:53:28 -04:00
id = "commitTime"
name = "commitTime"
2019-04-01 15:59:38 -04:00
className = { classes . textField }
InputProps = { {
classes : {
input : classes . textInput
}
} }
2019-04-04 10:53:28 -04:00
label = "Commit time in hours"
placeholder = "Commit time in hours"
2019-04-01 15:59:38 -04:00
margin = "normal"
variant = "outlined"
2019-04-04 10:53:28 -04:00
helperText = { helperText }
2019-04-01 15:59:38 -04:00
onChange = { handleChange }
onBlur = { handleBlur }
2019-04-04 10:53:28 -04:00
value = { values . commitTime || '' }
2019-04-01 15:59:38 -04:00
/ >
< TextField
className = { classes . textField }
InputProps = { {
classes : {
input : classes . textInput
}
} }
id = "creator"
name = "creator"
label = "Enter the project creator"
placeholder = "Enter the project creator"
margin = "normal"
variant = "outlined"
onChange = { handleChange }
onBlur = { handleBlur }
value = { values . creator || '' }
/ >
< TextField
className = { classes . textField }
InputProps = { {
2019-04-02 15:10:20 -04:00
startAdornment : (
< InputAdornment position = "start" >
< CloudUpload
style = { { cursor : 'pointer' } }
onClick = { ( ) => {
const activeField = 'avatar'
setStatus ( { ... status , activeField } )
uploadInput . click ( )
}
}
/ >
< / InputAdornment >
) ,
2019-04-01 15:59:38 -04:00
classes : {
input : classes . textInput
}
} }
id = "avatar"
name = "avatar"
label = "Upload or enter link to creator avatar"
placeholder = "upload or enter link to creator avatar"
margin = "normal"
variant = "outlined"
onChange = { handleChange }
onBlur = { handleBlur }
value = { values . avatar || '' }
/ >
< TextField
className = { classes . textField }
InputProps = { {
classes : {
input : classes . textInput
}
} }
id = "goal"
name = "goal"
label = "Enter your funding goal"
placeholder = "Enter your funding goal"
margin = "normal"
variant = "outlined"
onChange = { handleChange }
onBlur = { handleBlur }
value = { values . goal || '' }
/ >
< TextField
className = { classes . textField }
InputProps = { {
classes : {
input : classes . textInput
}
} }
id = "goalToken"
name = "goalToken"
label = "Select Token"
placeholder = "Select Token"
margin = "normal"
variant = "outlined"
onChange = { handleChange }
onBlur = { handleBlur }
value = { values . token || '' }
/ >
< TextField
className = { classes . textField }
InputProps = { {
2019-04-03 14:57:50 -04:00
startAdornment : (
< InputAdornment position = "start" >
< CloudUpload
style = { { cursor : 'pointer' } }
onClick = { ( ) => {
const activeField = 'video'
setStatus ( { ... status , activeField } )
uploadInput . click ( )
}
}
/ >
< / InputAdornment >
) ,
2019-04-01 15:59:38 -04:00
classes : {
input : classes . textInput
}
} }
id = "video"
name = "video"
label = "Upload video or enter url"
placeholder = "Upload video or enter url"
margin = "normal"
variant = "outlined"
onChange = { handleChange }
onBlur = { handleBlur }
value = { values . video || '' }
/ >
< FormControlLabel
className = { classes . formControl }
control = {
< Switch
2019-04-02 13:48:05 -04:00
id = "isPlaying"
2019-04-02 15:10:20 -04:00
checked = { values . isPlaying }
onChange = { handleChange }
value = { values . isPlaying }
2019-04-01 15:59:38 -04:00
/ >
}
label = "Autoplay video?"
/ >
< TextField
className = { classes . textField }
id = "description"
name = "description"
multiline
label = "Enter extended description here"
placeholder = "Enter extended description here"
margin = "normal"
variant = "outlined"
onChange = { handleChange }
onBlur = { handleBlur }
value = { values . description || '' }
/ >
2019-04-04 12:49:09 -04:00
< Button type = "submit" color = "primary" variant = "contained" className = { classes . formButton } > { isSubmitting ? 'Ethereum Submission In Progress' : 'Create Project' } < / Button >
2019-04-01 15:59:38 -04:00
< / form >
)
}
}
< / Formik >
)
}
2019-04-04 12:33:59 -04:00
function CreateProject ( { classes , history } ) {
2019-04-01 13:48:53 -04:00
return (
< div className = { classes . root } >
< Title className = { classes . title } / >
2019-04-04 12:33:59 -04:00
< SubmissionSection classes = { classes } history = { history } / >
2019-04-01 13:48:53 -04:00
< / div >
)
}
const StyledProject = withStyles ( styles ) ( CreateProject )
export default StyledProject