fix: react-doctor label-has-associated-control (-15, nested-interactive -1)

Add htmlFor/id pairs to label/input pairs across ~24 files.
Convert section-header labels (Role/Permissions/Visibility/Environment/
Send via/Quick messages/Campaign Type/When to Send/Preview) to <p>.
Convert clickable divs to buttons (AbandonedCartDashboard → native dialog).
Hoist regex patterns out of loops in ai-import.ts.
This commit is contained in:
Nora
2026-06-26 04:02:10 -06:00
parent f6bf91951e
commit 16a6756ad1
30 changed files with 220 additions and 192 deletions
+8 -8
View File
@@ -561,9 +561,9 @@ export default function UsersPage({ initialUsers, brands, currentUser, onUserCre
{/* Password (create only) */}
{editing.isNew && (
<div>
<label className="block text-sm font-medium text-stone-700">Password</label>
<label htmlFor="fld-password" className="block text-sm font-medium text-stone-700">Password</label>
<p className="mt-1 text-xs text-stone-500 mb-1.5">Minimum 6 characters.</p>
<input aria-label="Choose A Password"
<input id="fld-password" aria-label="Choose A Password"
type="password"
value={editing.password ?? ""}
onChange={(e) => setEditing((p) => ({ ...p, password: e.target.value }))}
@@ -576,9 +576,9 @@ export default function UsersPage({ initialUsers, brands, currentUser, onUserCre
{/* Display Name */}
<div>
<label className="block text-sm font-medium text-stone-700">Display Name</label>
<label htmlFor="fld-display-name" className="block text-sm font-medium text-stone-700">Display Name</label>
<p className="mt-1 text-xs text-stone-500 mb-1.5">Shown in the admin user list.</p>
<input aria-label="Kyle Martinez"
<input id="fld-display-name" aria-label="Kyle Martinez"
type="text"
value={editing.display_name ?? ""}
onChange={(e) => setEditing((p) => ({ ...p, display_name: e.target.value }))}
@@ -589,9 +589,9 @@ export default function UsersPage({ initialUsers, brands, currentUser, onUserCre
{/* Phone Number */}
<div>
<label className="block text-sm font-medium text-stone-700">Phone Number</label>
<label htmlFor="fld-phone" className="block text-sm font-medium text-stone-700">Phone Number</label>
<p className="mt-1 text-xs text-stone-500 mb-1.5">Optional.</p>
<input aria-label="+1 (555) 000 0000"
<input id="fld-phone" aria-label="+1 (555) 000 0000"
type="tel"
value={editing.phone_number ?? ""}
onChange={(e) => setEditing((p) => ({ ...p, phone_number: e.target.value }))}
@@ -602,7 +602,7 @@ export default function UsersPage({ initialUsers, brands, currentUser, onUserCre
{/* Role */}
<div>
<label className="block text-sm font-medium text-stone-700">Role</label>
<p className="block text-sm font-medium text-stone-700">Role</p>
<div className="mt-2 space-y-2">
{availableRoles.map((r) => (
<label key={r} className="flex items-center gap-3 rounded-lg border border-stone-200 px-3 py-2.5 cursor-pointer hover:bg-stone-50">
@@ -662,7 +662,7 @@ export default function UsersPage({ initialUsers, brands, currentUser, onUserCre
{/* Permissions */}
<div>
<label className="block text-sm font-medium text-stone-700 mb-3">Permissions</label>
<p className="block text-sm font-medium text-stone-700 mb-3">Permissions</p>
<div className="space-y-2">
{ALL_FLAGS.map((flag) => (
<label key={flag} className="flex items-center justify-between rounded-lg border border-stone-200 px-4 py-2.5 hover:bg-stone-50 cursor-pointer">