Chapter 14 - form validation completed (create form only)

This commit is contained in:
2024-01-04 08:11:04 +01:00
parent 69f0e86915
commit 8e51988395

View File

@@ -16,7 +16,7 @@ export default function Form({ customers }: { customers: CustomerField[] }) {
const [state, dispatch] = useFormState(createInvoice, initialState);
console.log(state);
return (
<form action={dispatch}>
<form action={dispatch} aria-describedby="form-error">
<div className="rounded-md bg-gray-50 p-4 md:p-6">
{/* Customer Name */}
<div className="mb-4">
@@ -70,6 +70,13 @@ export default function Form({ customers }: { customers: CustomerField[] }) {
/>
<CurrencyDollarIcon className="pointer-events-none absolute left-3 top-1/2 h-[18px] w-[18px] -translate-y-1/2 text-gray-500 peer-focus:text-gray-900" />
</div>
<div id="amount-error" aria-live="polite" aria-atomic="true">
{state.errors?.amount && state.errors.amount.map(s => (
<p className="mt-2 text-sm text-red-500" key={s}>{s}</p>
)
)
}
</div>
</div>
</div>
@@ -82,42 +89,54 @@ export default function Form({ customers }: { customers: CustomerField[] }) {
<div className="flex gap-4">
<div className="flex items-center">
<input
id="pending"
name="status"
type="radio"
value="pending"
className="h-4 w-4 cursor-pointer border-gray-300 bg-gray-100 text-gray-600 focus:ring-2"
id="pending"
name="status"
type="radio"
value="pending"
className="h-4 w-4 cursor-pointer border-gray-300 bg-gray-100 text-gray-600 focus:ring-2"
aria-describedby="status-error"
/>
<label
htmlFor="pending"
className="ml-2 flex cursor-pointer items-center gap-1.5 rounded-full bg-gray-100 px-3 py-1.5 text-xs font-medium text-gray-600"
htmlFor="pending"
className="ml-2 flex cursor-pointer items-center gap-1.5 rounded-full bg-gray-100 px-3 py-1.5 text-xs font-medium text-gray-600"
>
Pending <ClockIcon className="h-4 w-4" />
Pending <ClockIcon className="h-4 w-4"/>
</label>
</div>
<div className="flex items-center">
<input
id="paid"
name="status"
type="radio"
value="paid"
className="h-4 w-4 cursor-pointer border-gray-300 bg-gray-100 text-gray-600 focus:ring-2"
id="paid"
name="status"
type="radio"
value="paid"
className="h-4 w-4 cursor-pointer border-gray-300 bg-gray-100 text-gray-600 focus:ring-2"
/>
<label
htmlFor="paid"
className="ml-2 flex cursor-pointer items-center gap-1.5 rounded-full bg-green-500 px-3 py-1.5 text-xs font-medium text-white"
htmlFor="paid"
className="ml-2 flex cursor-pointer items-center gap-1.5 rounded-full bg-green-500 px-3 py-1.5 text-xs font-medium text-white"
>
Paid <CheckIcon className="h-4 w-4" />
Paid <CheckIcon className="h-4 w-4"/>
</label>
</div>
</div>
</div>
<div id="status-error" aria-live="polite" aria-atomic="true">
{state.errors?.status && state.errors?.status.map(e => (
<p key={e} className="mt-2 text-sm text-red-500">{e}</p>
))}
</div>
<div id="form-error">
{
state.message && (<p className="mt-2 text-sm text-red-500 font-bold">{state.message}</p>)
}
</div>
</fieldset>
</div>
<div className="mt-6 flex justify-end gap-4">
<Link
href="/dashboard/invoices"
className="flex h-10 items-center rounded-lg bg-gray-100 px-4 text-sm font-medium text-gray-600 transition-colors hover:bg-gray-200"
href="/dashboard/invoices"
className="flex h-10 items-center rounded-lg bg-gray-100 px-4 text-sm font-medium text-gray-600 transition-colors hover:bg-gray-200"
>
Cancel
</Link>