refactor: fix event edit page code review issues (#87)
- Extract EditEventCard component to eliminate duplicated edit form - Add edit form to non-schedule event types (bracket events) - Move actionData feedback above debug cards for better UX - Guard "Add Result" form from showing on playoff_game events - Fix isPast date comparison to be safe for Date or string types - Remove unused qpConfig/qpStandings destructuring Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
447546a4c2
commit
e72c33d5b5
1 changed files with 51 additions and 46 deletions
|
|
@ -33,11 +33,43 @@ import { useState } from "react";
|
|||
|
||||
export { loader, action };
|
||||
|
||||
function EditEventCard({ event }: { event: { name: string; eventDate?: string | null } }) {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Edit Event</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<Form method="post" className="space-y-4">
|
||||
<input type="hidden" name="intent" value="update-event" />
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="name">Name</Label>
|
||||
<Input id="name" name="name" defaultValue={event.name} required />
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="eventDate">Date</Label>
|
||||
<Input
|
||||
id="eventDate"
|
||||
name="eventDate"
|
||||
type="date"
|
||||
defaultValue={event.eventDate ?? ""}
|
||||
/>
|
||||
</div>
|
||||
<Button type="submit" variant="outline">
|
||||
<Save className="mr-2 h-4 w-4" />
|
||||
Save Changes
|
||||
</Button>
|
||||
</Form>
|
||||
</CardContent>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
|
||||
export default function EventResults({
|
||||
loaderData,
|
||||
actionData,
|
||||
}: Route.ComponentProps) {
|
||||
const { sportsSeason, event, participants, results, participantResults, seasonResults, qpConfig, qpStandings } = loaderData;
|
||||
const { sportsSeason, event, participants, results, participantResults, seasonResults } = loaderData;
|
||||
const [hasChanges, setHasChanges] = useState(false);
|
||||
|
||||
// Create a map of participants with results for easy lookup
|
||||
|
|
@ -63,7 +95,8 @@ export default function EventResults({
|
|||
// Non-scoring events have a simple view — edit name/date and toggle updated status
|
||||
if (event.eventType === "schedule_event") {
|
||||
const today = new Date().toISOString().split("T")[0];
|
||||
const isPast = event.eventDate && event.eventDate < today;
|
||||
const eventDateStr = event.eventDate ? String(event.eventDate).slice(0, 10) : null;
|
||||
const isPast = eventDateStr != null && eventDateStr < today;
|
||||
|
||||
return (
|
||||
<div className="p-8">
|
||||
|
|
@ -107,38 +140,7 @@ export default function EventResults({
|
|||
)}
|
||||
|
||||
<div className="space-y-4">
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Edit Event</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<Form method="post" className="space-y-4">
|
||||
<input type="hidden" name="intent" value="update-event" />
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="name">Name</Label>
|
||||
<Input
|
||||
id="name"
|
||||
name="name"
|
||||
defaultValue={event.name}
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="eventDate">Date</Label>
|
||||
<Input
|
||||
id="eventDate"
|
||||
name="eventDate"
|
||||
type="date"
|
||||
defaultValue={event.eventDate ?? ""}
|
||||
/>
|
||||
</div>
|
||||
<Button type="submit" variant="outline">
|
||||
<Save className="mr-2 h-4 w-4" />
|
||||
Save Changes
|
||||
</Button>
|
||||
</Form>
|
||||
</CardContent>
|
||||
</Card>
|
||||
<EditEventCard event={event} />
|
||||
|
||||
<Card>
|
||||
<CardHeader>
|
||||
|
|
@ -222,6 +224,20 @@ export default function EventResults({
|
|||
</div>
|
||||
|
||||
<div className="space-y-6">
|
||||
{/* Edit Event Name/Date */}
|
||||
<EditEventCard event={event} />
|
||||
|
||||
{actionData?.error && (
|
||||
<div className="bg-destructive/15 text-destructive px-4 py-3 rounded-md text-sm">
|
||||
{actionData.error}
|
||||
</div>
|
||||
)}
|
||||
{actionData?.success && (
|
||||
<div className="bg-emerald-500/15 text-emerald-400 px-4 py-3 rounded-md text-sm">
|
||||
{actionData.success}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Debug info and manual QP processing for completed major tournaments */}
|
||||
{event.isComplete && event.eventType === "major_tournament" && (
|
||||
<Card className="border-electric/30">
|
||||
|
|
@ -266,17 +282,6 @@ export default function EventResults({
|
|||
</CardContent>
|
||||
</Card>
|
||||
)}
|
||||
{actionData?.error && (
|
||||
<div className="bg-destructive/15 text-destructive px-4 py-3 rounded-md text-sm">
|
||||
{actionData.error}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{actionData?.success && (
|
||||
<div className="bg-emerald-500/15 text-emerald-400 px-4 py-3 rounded-md text-sm">
|
||||
{actionData.success}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Season Standings Table for final_standings events */}
|
||||
{event.eventType === "final_standings" && !event.isComplete && (
|
||||
|
|
@ -376,7 +381,7 @@ export default function EventResults({
|
|||
)}
|
||||
|
||||
{/* Regular Result Entry for other event types */}
|
||||
{event.eventType !== "final_standings" && !event.isComplete && (
|
||||
{event.eventType !== "final_standings" && event.eventType !== "playoff_game" && !event.isComplete && (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Add Result</CardTitle>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue