site/lib/use-form.js
Max Wofford 65e9ad5751 Invites on the slack form create multi-channel guests (#23)
* Invites on the slack form create multi-channel guests

* Use CORS only in production

* Open this boi UP

* Remove cors-anywhere

* Remove JSON parse

* Attempt boolean logic for teens

* Attempt to fix som form

* Attempt to fix form routing error

* Don't include post URL in form html

* Remove method from HTML

* Try persisting event

* Remove fetch imports

* Edit submitted button copy

* Add logging

* Fix teen field

Co-authored-by: Lachlan Campbell <lachlan@hackclub.com>
2020-06-18 08:01:21 -04:00

73 lines
1.8 KiB
JavaScript

import { useState, useEffect } from 'react'
const useForm = (
submitURL = '/',
callback,
options = { clearOnSubmit: 5000, method: 'post' }
) => {
const [status, setStatus] = useState('default')
const [data, setData] = useState({})
const [touched, setTouched] = useState({})
const onFieldChange = (e, name, type) => {
e.persist()
const value = e.target[type === 'checkbox' ? 'checked' : 'value']
setData((data) => ({ ...data, [name]: value }))
}
useEffect(() => {
setTouched(Object.keys(data))
}, [data])
const useField = (name, type = 'text', ...props) => {
const checkbox = type === 'checkbox'
const empty = checkbox ? false : ''
const onChange = (e) => onFieldChange(e, name, type)
const value = data[name]
return {
name,
type: name === 'email' ? 'email' : type,
[checkbox ? 'checked' : 'value']: value || empty,
onChange,
...props
}
}
const { method = 'post' } = options
// Workaround for Vercel trailingSlash behavior
const action = process.env.NODE_ENV !== 'development' && submitURL.startsWith('/') ? submitURL + '/' : submitURL
const onSubmit = (e) => {
e.persist()
e.preventDefault()
setStatus('submitting')
fetch(action, {
method,
headers: {
'content-type': 'application/json'
},
mode: 'cors',
body: JSON.stringify(data)
})
.then((r) => r.json())
.then((r) => {
setStatus('success')
if (callback) callback(r)
setTimeout(() => setStatus('default'), 2000)
if (options.clearOnSubmit) {
setTimeout(() => setData({}), options.clearOnSubmit)
}
})
.catch((e) => {
console.error(e)
setStatus('error')
})
}
const formProps = { onSubmit }
return { status, data, touched, useField, formProps }
}
export default useForm