feat(todos): fix QuickInput — allow input without a product selected
- Product select is no longer required; 'Geen product' is the default - Input and submit button are no longer disabled for users with no products - Form resets only on success (useEffect on state.success) instead of resetting on every submit including failures - Inline error from server action is now displayed below the form - Removed 'Maak eerst een product aan' message that blocked the form Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
e991f4f185
commit
4d08c92af5
1 changed files with 33 additions and 37 deletions
|
|
@ -41,39 +41,39 @@ interface TodoListProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
function QuickInput({ products, isDemo }: { products: Product[]; isDemo: boolean }) {
|
function QuickInput({ products, isDemo }: { products: Product[]; isDemo: boolean }) {
|
||||||
const [, formAction] = useActionState(createTodoAction, undefined)
|
const [state, formAction] = useActionState(createTodoAction, undefined)
|
||||||
const ref = useRef<HTMLFormElement>(null)
|
const ref = useRef<HTMLFormElement>(null)
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (state?.success) ref.current?.reset()
|
||||||
|
}, [state])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<form
|
<div className="mb-6 space-y-1">
|
||||||
ref={ref}
|
<form ref={ref} action={formAction} className="flex gap-2">
|
||||||
action={formAction}
|
<select
|
||||||
onSubmit={() => setTimeout(() => ref.current?.reset(), 0)}
|
name="productId"
|
||||||
className="flex gap-2 mb-6"
|
disabled={isDemo}
|
||||||
>
|
className="border border-border rounded-lg px-3 py-1.5 text-sm bg-input-background shrink-0"
|
||||||
<select
|
>
|
||||||
name="productId"
|
<option value="">Geen product</option>
|
||||||
required
|
{products.map(p => <option key={p.id} value={p.id}>{p.name}</option>)}
|
||||||
disabled={isDemo || products.length === 0}
|
</select>
|
||||||
className="border border-border rounded-lg px-3 py-1.5 text-sm bg-input-background shrink-0"
|
<Input
|
||||||
>
|
name="title"
|
||||||
{products.length === 0 ? (
|
placeholder={isDemo ? 'Alleen-lezen in demo' : 'Nieuwe todo… (Enter om op te slaan)'}
|
||||||
<option value="">Geen producten</option>
|
disabled={isDemo}
|
||||||
) : (
|
className="flex-1"
|
||||||
products.map(p => <option key={p.id} value={p.id}>{p.name}</option>)
|
autoComplete="off"
|
||||||
)}
|
/>
|
||||||
</select>
|
<DemoTooltip show={isDemo}>
|
||||||
<Input
|
<QuickSubmitButton isDemo={isDemo} />
|
||||||
name="title"
|
</DemoTooltip>
|
||||||
placeholder={isDemo ? 'Alleen-lezen in demo' : 'Nieuwe todo… (Enter om op te slaan)'}
|
</form>
|
||||||
disabled={isDemo || products.length === 0}
|
{typeof state?.error === 'string' && (
|
||||||
className="flex-1"
|
<p className="text-xs text-error">{state.error}</p>
|
||||||
autoComplete="off"
|
)}
|
||||||
/>
|
</div>
|
||||||
<DemoTooltip show={isDemo}>
|
|
||||||
<QuickSubmitButton isDemo={isDemo || products.length === 0} />
|
|
||||||
</DemoTooltip>
|
|
||||||
</form>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -260,15 +260,11 @@ export function TodoList({ todos, products, isDemo }: TodoListProps) {
|
||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
<QuickInput products={products} isDemo={isDemo} />
|
<QuickInput products={products} isDemo={isDemo} />
|
||||||
|
|
||||||
{products.length === 0 && (
|
{todos.length === 0 ? (
|
||||||
<p className="text-sm text-muted-foreground">Maak eerst een product aan om todo's toe te voegen.</p>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{todos.length === 0 && products.length > 0 ? (
|
|
||||||
<div className="bg-surface-container-low border border-border rounded-xl p-12 text-center">
|
<div className="bg-surface-container-low border border-border rounded-xl p-12 text-center">
|
||||||
<p className="text-muted-foreground text-sm">Geen todo's. Voeg er een toe hierboven.</p>
|
<p className="text-muted-foreground text-sm">Geen todo's. Voeg er een toe hierboven.</p>
|
||||||
</div>
|
</div>
|
||||||
) : todos.length > 0 ? (
|
) : (
|
||||||
<>
|
<>
|
||||||
<div className="bg-surface-container-low border border-border rounded-xl divide-y divide-border">
|
<div className="bg-surface-container-low border border-border rounded-xl divide-y divide-border">
|
||||||
{open.map(todo => (
|
{open.map(todo => (
|
||||||
|
|
@ -321,7 +317,7 @@ export function TodoList({ todos, products, isDemo }: TodoListProps) {
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
) : null}
|
)}
|
||||||
|
|
||||||
{promotePbi && (
|
{promotePbi && (
|
||||||
<PromotePbiDialog todo={promotePbi} products={products} onClose={() => setPromotePbi(null)} />
|
<PromotePbiDialog todo={promotePbi} products={products} onClose={() => setPromotePbi(null)} />
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue