Add status to forms

This commit is contained in:
Sam Becker 2023-09-08 11:16:01 -05:00
parent f0fcc84cc7
commit 8290666abe
3 changed files with 54 additions and 28 deletions

View File

@ -1,45 +1,61 @@
'use client';
import FieldSet from '@/components/FieldSet';
import FieldSetWithStatus from '@/components/FieldSetWithStatus';
import InfoBlock from '@/components/InfoBlock';
import SubmitButtonWithStatus from '@/components/SubmitButtonWithStatus';
import { signIn } from 'next-auth/react';
import { useState } from 'react';
import { useLayoutEffect, useRef, useState } from 'react';
export default function SignInForm() {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [isSigningIn, setIsSigningIn] = useState(false);
const emailRef = useRef<HTMLInputElement>(null);
useLayoutEffect(() => {
emailRef.current?.focus();
}, []);
return (
<InfoBlock>
<div className="space-y-8">
<div className="space-y-4">
<FieldSet
id="email"
label="Admin Email"
value={email}
onChange={setEmail}
/>
<FieldSet
id="password"
label="Admin Password"
value={password}
onChange={setPassword}
type="password"
/>
</div>
<button
onClick={() => signIn(
<form
className="space-y-8"
onSubmitCapture={e => {
e.preventDefault();
setIsSigningIn(true);
signIn(
'credentials',
{
email,
password,
callbackUrl: '/admin/photos',
},
)}
>
)
.catch(() => setIsSigningIn(false));
}}
>
<div className="space-y-4">
<FieldSetWithStatus
id="email"
inputRef={emailRef}
label="Admin Email"
value={email}
onChange={setEmail}
readOnly={isSigningIn}
/>
<FieldSetWithStatus
id="password"
label="Admin Password"
type="password"
value={password}
onChange={setPassword}
readOnly={isSigningIn}
/>
</div>
<SubmitButtonWithStatus disabled={isSigningIn}>
Sign in
</button>
</div>
</SubmitButtonWithStatus>
</form>
</InfoBlock>
);
}

View File

@ -1,4 +1,9 @@
export default function FieldSet({
'use client';
import { LegacyRef } from 'react';
import { experimental_useFormStatus as useFormStatus } from 'react-dom';
export default function FieldSetWithStatus({
id,
label,
value,
@ -6,6 +11,7 @@ export default function FieldSet({
required,
readOnly,
type = 'text',
inputRef,
}: {
id: string
label: string
@ -14,7 +20,10 @@ export default function FieldSet({
required?: boolean
readOnly?: boolean
type?: 'text' | 'password'
inputRef?: LegacyRef<HTMLInputElement>
}) {
const { pending } = useFormStatus();
return (
<div className="space-y-1">
<label
@ -28,13 +37,14 @@ export default function FieldSet({
</span>}
</label>
<input
ref={inputRef}
id={id}
name={id}
value={value}
onChange={e => onChange?.(e.target.value)}
type={type}
autoComplete="off"
readOnly={readOnly}
readOnly={readOnly || pending}
className="w-full"
/>
</div>

View File

@ -5,7 +5,7 @@ import {
FORM_METADATA_ENTRIES,
PhotoFormData,
} from './form';
import FieldSet from '@/components/FieldSet';
import FieldSetWithStatus from '@/components/FieldSetWithStatus';
import NextImage from 'next/image';
import { createPhotoAction, updatePhotoAction } from './actions';
import SubmitButtonWithStatus from '@/components/SubmitButtonWithStatus';
@ -108,7 +108,7 @@ export default function PhotoForm({
{ label, required, readOnly, hideIfEmpty },
]) =>
(!hideIfEmpty || formData[key]) &&
<FieldSet
<FieldSetWithStatus
key={key}
id={key}
label={label}