'use client' import { ReactNode, useState, useEffect } from 'react' import { AuthDetails, AuthError, AuthResponse, getAuthDetails } from '../api' import { useAuthContext } from '../contexts/AuthContext' import { useStyles } from '../contexts/StylesContext' interface AuthForm { submit: () => void authDetails: AuthDetails fetching: boolean response: AuthResponse | null errors: AuthError[] } export default function useAuthForm( submissionAction: () => Promise, responseAction?: (response: AuthResponse, authDetails: AuthDetails) => void, ): AuthForm { const auth = useAuthContext().auth const [fetching, setFetching] = useState(false) const [response, setResponse] = useState(null) const [errors, setErrors] = useState([]) const [authDetails, setAuthDetails] = useState(getAuthDetails(auth)) function submit() { setFetching(true) submissionAction() .then((r) => { setResponse(r) setErrors(r.errors || []) setFetching(false) if (r && responseAction) { responseAction(r, authDetails) } setAuthDetails(getAuthDetails(auth)) }) .catch((e) => { console.error(e) setFetching(false) }) } return { submit, authDetails, fetching, response, errors } } interface AuthFieldProps { title: string name: string type: string init: string onChange: (e: React.ChangeEvent) => void authErrors: AuthError[] placeholder?: string children?: ReactNode } export function AuthField({ title, name, type, init, onChange, authErrors, placeholder, children, }: AuthFieldProps) { const styles = useStyles() const [mounted, setMounted] = useState(false) const fieldErrors = authErrors.filter(err => err.param === name) useEffect(() => { setMounted(true) }, []) return (
{mounted ? ( ) : (
)} {fieldErrors.map((err, i) => (

{err.message}

))} {children}
) }