refactor(js): use InputError for inline form errors (#483)
## What
15 hand-rolled `{errors.x && <p className="text-sm
text-red-500">...</p>}` blocks across 6 components (label/category
create+edit dialogs, automation-rule form, rule builder) replaced with
the existing `InputError` component.
Bonus: `InputError` uses `text-red-600 dark:text-red-400` — the inline
copies had **no dark-mode variant** (CLAUDE.md requires dark-mode
support).
## Stats
- **-63 / +21 lines**
## Checks
- `bun run test` — 154 passed
- `bun run lint` / `format` — clean (1 pre-existing warning)
- `tsc --noEmit` — 59 pre-existing errors, none new
Part of duplication-removal series (#475–#482).
This commit is contained in:
parent
d27905ec3d
commit
faccbc3c5a
|
|
@ -3,6 +3,7 @@ import {
|
|||
update,
|
||||
} from '@/actions/App/Http/Controllers/Settings/AutomationRuleController';
|
||||
import { RuleBuilder } from '@/components/automation-rules/rule-builder';
|
||||
import InputError from '@/components/input-error';
|
||||
import { CategoryCombobox } from '@/components/shared/category-combobox';
|
||||
import { LabelCombobox } from '@/components/shared/label-combobox';
|
||||
import { Button } from '@/components/ui/button';
|
||||
|
|
@ -170,9 +171,7 @@ export function AutomationRuleForm({
|
|||
required
|
||||
/>
|
||||
|
||||
{errors.title && (
|
||||
<p className="text-sm text-red-500">{errors.title}</p>
|
||||
)}
|
||||
<InputError message={errors.title} />
|
||||
</div>
|
||||
|
||||
<RuleBuilder
|
||||
|
|
@ -220,9 +219,7 @@ export function AutomationRuleForm({
|
|||
/>
|
||||
</div>
|
||||
|
||||
{actionError && (
|
||||
<p className="text-sm text-red-500">{actionError}</p>
|
||||
)}
|
||||
<InputError message={actionError} />
|
||||
</div>
|
||||
|
||||
<div className="flex justify-end gap-2">
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import InputError from '@/components/input-error';
|
||||
import { Badge } from '@/components/ui/badge';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Card } from '@/components/ui/card';
|
||||
|
|
@ -225,7 +226,7 @@ export function RuleBuilder({ value, onChange, error }: RuleBuilderProps) {
|
|||
{__('Add Group')}
|
||||
</Button>
|
||||
|
||||
{error && <p className="text-sm text-red-500">{error}</p>}
|
||||
<InputError message={error} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import { store } from '@/actions/App/Http/Controllers/Settings/CategoryController';
|
||||
import { CategoryCashflowDirectionFields } from '@/components/categories/category-cashflow-direction-fields';
|
||||
import InputError from '@/components/input-error';
|
||||
import { Badge } from '@/components/ui/badge';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { CreateButton } from '@/components/ui/create-button';
|
||||
|
|
@ -74,11 +75,7 @@ export function CreateCategoryDialog({
|
|||
required
|
||||
/>
|
||||
|
||||
{errors.name && (
|
||||
<p className="text-sm text-red-500">
|
||||
{errors.name}
|
||||
</p>
|
||||
)}
|
||||
<InputError message={errors.name} />
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
|
|
@ -108,11 +105,7 @@ export function CreateCategoryDialog({
|
|||
})}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
{errors.icon && (
|
||||
<p className="text-sm text-red-500">
|
||||
{errors.icon}
|
||||
</p>
|
||||
)}
|
||||
<InputError message={errors.icon} />
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
|
|
@ -144,11 +137,7 @@ export function CreateCategoryDialog({
|
|||
})}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
{errors.color && (
|
||||
<p className="text-sm text-red-500">
|
||||
{errors.color}
|
||||
</p>
|
||||
)}
|
||||
<InputError message={errors.color} />
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
|
|
@ -173,11 +162,7 @@ export function CreateCategoryDialog({
|
|||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
{errors.type && (
|
||||
<p className="text-sm text-red-500">
|
||||
{errors.type}
|
||||
</p>
|
||||
)}
|
||||
<InputError message={errors.type} />
|
||||
</div>
|
||||
|
||||
<CategoryCashflowDirectionFields
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import { update } from '@/actions/App/Http/Controllers/Settings/CategoryController';
|
||||
import { CategoryCashflowDirectionFields } from '@/components/categories/category-cashflow-direction-fields';
|
||||
import InputError from '@/components/input-error';
|
||||
import { Badge } from '@/components/ui/badge';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import {
|
||||
|
|
@ -78,11 +79,7 @@ export function EditCategoryDialog({
|
|||
required
|
||||
/>
|
||||
|
||||
{errors.name && (
|
||||
<p className="text-sm text-red-500">
|
||||
{errors.name}
|
||||
</p>
|
||||
)}
|
||||
<InputError message={errors.name} />
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
|
|
@ -116,11 +113,7 @@ export function EditCategoryDialog({
|
|||
})}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
{errors.icon && (
|
||||
<p className="text-sm text-red-500">
|
||||
{errors.icon}
|
||||
</p>
|
||||
)}
|
||||
<InputError message={errors.icon} />
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
|
|
@ -156,11 +149,7 @@ export function EditCategoryDialog({
|
|||
})}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
{errors.color && (
|
||||
<p className="text-sm text-red-500">
|
||||
{errors.color}
|
||||
</p>
|
||||
)}
|
||||
<InputError message={errors.color} />
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
|
|
@ -186,11 +175,7 @@ export function EditCategoryDialog({
|
|||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
{errors.type && (
|
||||
<p className="text-sm text-red-500">
|
||||
{errors.type}
|
||||
</p>
|
||||
)}
|
||||
<InputError message={errors.type} />
|
||||
</div>
|
||||
|
||||
<CategoryCashflowDirectionFields
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import { store } from '@/actions/App/Http/Controllers/Settings/LabelController';
|
||||
import InputError from '@/components/input-error';
|
||||
import { Badge } from '@/components/ui/badge';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { CreateButton } from '@/components/ui/create-button';
|
||||
|
|
@ -58,11 +59,7 @@ export function CreateLabelDialog({ onSuccess }: { onSuccess?: () => void }) {
|
|||
required
|
||||
/>
|
||||
|
||||
{errors.name && (
|
||||
<p className="text-sm text-red-500">
|
||||
{errors.name}
|
||||
</p>
|
||||
)}
|
||||
<InputError message={errors.name} />
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
|
|
@ -94,11 +91,7 @@ export function CreateLabelDialog({ onSuccess }: { onSuccess?: () => void }) {
|
|||
})}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
{errors.color && (
|
||||
<p className="text-sm text-red-500">
|
||||
{errors.color}
|
||||
</p>
|
||||
)}
|
||||
<InputError message={errors.color} />
|
||||
</div>
|
||||
|
||||
<div className="flex justify-end gap-2">
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import { update } from '@/actions/App/Http/Controllers/Settings/LabelController';
|
||||
import InputError from '@/components/input-error';
|
||||
import { Badge } from '@/components/ui/badge';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import {
|
||||
|
|
@ -67,11 +68,7 @@ export function EditLabelDialog({
|
|||
required
|
||||
/>
|
||||
|
||||
{errors.name && (
|
||||
<p className="text-sm text-red-500">
|
||||
{errors.name}
|
||||
</p>
|
||||
)}
|
||||
<InputError message={errors.name} />
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
|
|
@ -107,11 +104,7 @@ export function EditLabelDialog({
|
|||
})}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
{errors.color && (
|
||||
<p className="text-sm text-red-500">
|
||||
{errors.color}
|
||||
</p>
|
||||
)}
|
||||
<InputError message={errors.color} />
|
||||
</div>
|
||||
|
||||
<div className="flex justify-end gap-2">
|
||||
|
|
|
|||
Loading…
Reference in New Issue