Fix account/member form validation, add member number to tables

- Fix account create form blocking on empty name when includeFirstMember
- Add noValidate to forms to prevent browser native validation on optional fields
- Show member number column on account members tab
- Replace DOB with phone in members table for better at-a-glance info
This commit is contained in:
Ryan Moon
2026-03-28 11:31:28 -05:00
parent f4e5a57846
commit 6ca38e2105
3 changed files with 9 additions and 6 deletions

View File

@@ -1,5 +1,6 @@
import { useForm } from 'react-hook-form' import { useForm } from 'react-hook-form'
import { zodResolver } from '@hookform/resolvers/zod' import { zodResolver } from '@hookform/resolvers/zod'
import { z } from 'zod'
import { AccountCreateSchema } from '@forte/shared/schemas' import { AccountCreateSchema } from '@forte/shared/schemas'
import { Button } from '@/components/ui/button' import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input' import { Input } from '@/components/ui/input'
@@ -17,7 +18,7 @@ interface AccountFormProps {
} }
export function AccountForm({ defaultValues, onSubmit, loading, includeFirstMember }: AccountFormProps) { export function AccountForm({ defaultValues, onSubmit, loading, includeFirstMember }: AccountFormProps) {
const optionalNameSchema = AccountCreateSchema.extend({ name: AccountCreateSchema.shape.name.optional() }) const optionalNameSchema = AccountCreateSchema.extend({ name: z.string().max(255).optional() })
const schema = includeFirstMember ? optionalNameSchema : AccountCreateSchema const schema = includeFirstMember ? optionalNameSchema : AccountCreateSchema
const { const {
@@ -29,7 +30,7 @@ export function AccountForm({ defaultValues, onSubmit, loading, includeFirstMemb
} = useForm({ } = useForm({
resolver: zodResolver(schema), resolver: zodResolver(schema),
defaultValues: { defaultValues: {
name: defaultValues?.name ?? '', name: defaultValues?.name ?? (includeFirstMember ? undefined : ''),
email: defaultValues?.email ?? undefined, email: defaultValues?.email ?? undefined,
phone: defaultValues?.phone ?? undefined, phone: defaultValues?.phone ?? undefined,
billingMode: defaultValues?.billingMode ?? 'consolidated', billingMode: defaultValues?.billingMode ?? 'consolidated',
@@ -60,7 +61,7 @@ export function AccountForm({ defaultValues, onSubmit, loading, includeFirstMemb
} }
return ( return (
<form id="account-form" onSubmit={handleSubmit(handleFormSubmit)} className="space-y-4 max-w-lg"> <form id="account-form" onSubmit={handleSubmit(handleFormSubmit)} noValidate className="space-y-4 max-w-lg">
<div className="space-y-2"> <div className="space-y-2">
<Label htmlFor="name">Account Name {includeFirstMember ? '' : '*'}</Label> <Label htmlFor="name">Account Name {includeFirstMember ? '' : '*'}</Label>
<Input id="name" {...register('name')} placeholder={includeFirstMember ? 'Auto-generated from member name if blank' : 'e.g. Smith Family, Lincoln Elementary'} /> <Input id="name" {...register('name')} placeholder={includeFirstMember ? 'Auto-generated from member name if blank' : 'e.g. Smith Family, Lincoln Elementary'} />

View File

@@ -38,7 +38,7 @@ export function MemberForm({ accountId, defaultValues, onSubmit, loading }: Memb
const dateOfBirth = watch('dateOfBirth') const dateOfBirth = watch('dateOfBirth')
return ( return (
<form onSubmit={handleSubmit(onSubmit)} className="space-y-4"> <form onSubmit={handleSubmit(onSubmit)} noValidate className="space-y-4">
<input type="hidden" {...register('accountId')} /> <input type="hidden" {...register('accountId')} />
<div className="grid grid-cols-2 gap-4"> <div className="grid grid-cols-2 gap-4">
<div className="space-y-2"> <div className="space-y-2">

View File

@@ -93,9 +93,10 @@ function MembersTab() {
<Table> <Table>
<TableHeader> <TableHeader>
<TableRow> <TableRow>
<TableHead>#</TableHead>
<TableHead>Name</TableHead> <TableHead>Name</TableHead>
<TableHead>Email</TableHead> <TableHead>Email</TableHead>
<TableHead>Date of Birth</TableHead> <TableHead>Phone</TableHead>
<TableHead>Status</TableHead> <TableHead>Status</TableHead>
<TableHead className="w-24">Actions</TableHead> <TableHead className="w-24">Actions</TableHead>
</TableRow> </TableRow>
@@ -103,9 +104,10 @@ function MembersTab() {
<TableBody> <TableBody>
{members.map((m) => ( {members.map((m) => (
<TableRow key={m.id}> <TableRow key={m.id}>
<TableCell className="font-mono text-sm text-muted-foreground">{m.memberNumber ?? '-'}</TableCell>
<TableCell className="font-medium">{m.firstName} {m.lastName}</TableCell> <TableCell className="font-medium">{m.firstName} {m.lastName}</TableCell>
<TableCell>{m.email ?? '-'}</TableCell> <TableCell>{m.email ?? '-'}</TableCell>
<TableCell>{m.dateOfBirth ?? '-'}</TableCell> <TableCell>{m.phone ?? '-'}</TableCell>
<TableCell> <TableCell>
{m.isMinor ? <Badge variant="secondary">Minor</Badge> : <Badge>Adult</Badge>} {m.isMinor ? <Badge variant="secondary">Minor</Badge> : <Badge>Adult</Badge>}
</TableCell> </TableCell>