From 93fe319830673a33f429cf766f6d734e634ba320 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 2 Apr 2026 00:51:55 +0000 Subject: [PATCH] Simplify edit state and surface edit errors to user - Combine editingId + editingName into single editing: { id, name } | null state object - Extract cancelEdit() helper called in 3 places instead of repeating setEditing(null) - Tag all update-name action responses with intent: "update-name" so errors can be identified and routed correctly - Show update-name errors inline below the edit input - Guard single-add and bulk-add error displays against showing update-name errors https://claude.ai/code/session_01Q94DWQ1HZEB9PJhGMArU8D --- .../admin.sports-seasons.$id.participants.tsx | 60 +++++++++---------- 1 file changed, 27 insertions(+), 33 deletions(-) diff --git a/app/routes/admin.sports-seasons.$id.participants.tsx b/app/routes/admin.sports-seasons.$id.participants.tsx index da8fbd4..2143e5f 100644 --- a/app/routes/admin.sports-seasons.$id.participants.tsx +++ b/app/routes/admin.sports-seasons.$id.participants.tsx @@ -69,17 +69,17 @@ export async function action({ request, params }: Route.ActionArgs) { const newName = formData.get("newName"); if (typeof participantId !== "string") { - return { error: "Invalid participant" }; + return { error: "Invalid participant", intent: "update-name" }; } if (typeof newName !== "string" || !newName.trim()) { - return { error: "Name is required" }; + return { error: "Name is required", intent: "update-name" }; } const trimmedName = newName.trim(); const existing = await findParticipantByName(params.id, trimmedName); if (existing && existing.id !== participantId) { - return { error: `"${trimmedName}" already exists in this season.` }; + return { error: `"${trimmedName}" already exists in this season.`, intent: "update-name" }; } try { @@ -87,7 +87,7 @@ export async function action({ request, params }: Route.ActionArgs) { return { success: true, intent: "update-name" }; } catch (error) { logger.error("Error updating participant:", error); - return { error: "Failed to update participant. Please try again." }; + return { error: "Failed to update participant. Please try again.", intent: "update-name" }; } } @@ -171,16 +171,16 @@ export async function action({ request, params }: Route.ActionArgs) { export default function ManageParticipants({ loaderData, actionData }: Route.ComponentProps) { const { sportsSeason, participants } = loaderData; - const [editingId, setEditingId] = useState(null); - const [editingName, setEditingName] = useState(""); + const [editing, setEditing] = useState<{ id: string; name: string } | null>(null); + + const cancelEdit = () => setEditing(null); // Use success state to reset forms by changing the key const formKey = actionData?.success ? Date.now() : 'static'; useEffect(() => { if (actionData?.success && actionData?.intent === "update-name") { - setEditingId(null); - setEditingName(""); + cancelEdit(); } }, [actionData]); @@ -221,7 +221,7 @@ export default function ManageParticipants({ loaderData, actionData }: Route.Com /> - {actionData?.error && !actionData?.count && ( + {actionData?.error && !actionData?.count && actionData?.intent !== "update-name" && (
{actionData.error}
@@ -267,7 +267,7 @@ export default function ManageParticipants({ loaderData, actionData }: Route.Com

- {actionData?.error && actionData?.count === undefined && ( + {actionData?.error && actionData?.count === undefined && actionData?.intent !== "update-name" && (
{actionData.error}
@@ -318,30 +318,30 @@ export default function ManageParticipants({ loaderData, actionData }: Route.Com {participants.map((participant) => ( - {editingId === participant.id ? ( - setEditingName(e.target.value)} - className="h-8" - autoFocus - onKeyDown={(e) => { - if (e.key === "Escape") { - setEditingId(null); - setEditingName(""); - } - }} - /> + {editing?.id === participant.id ? ( +
+ setEditing({ id: participant.id, name: e.target.value })} + className="h-8" + autoFocus + onKeyDown={(e) => { if (e.key === "Escape") cancelEdit(); }} + /> + {actionData?.error && actionData?.intent === "update-name" && ( +

{actionData.error}

+ )} +
) : ( participant.name )}
- {editingId === participant.id ? ( + {editing?.id === participant.id ? (
- + @@ -371,10 +368,7 @@ export default function ManageParticipants({ loaderData, actionData }: Route.Com variant="ghost" size="sm" className="h-8 w-8 p-0" - onClick={() => { - setEditingId(participant.id); - setEditingName(participant.name); - }} + onClick={() => setEditing({ id: participant.id, name: participant.name })} >