mirror of
https://github.com/System-End/site.git
synced 2026-04-19 19:45:07 +00:00
* 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>
73 lines
1.8 KiB
JavaScript
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
|