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 };
|
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({
|
export default function EventResults({
|
||||||
loaderData,
|
loaderData,
|
||||||
actionData,
|
actionData,
|
||||||
}: Route.ComponentProps) {
|
}: 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);
|
const [hasChanges, setHasChanges] = useState(false);
|
||||||
|
|
||||||
// Create a map of participants with results for easy lookup
|
// 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
|
// Non-scoring events have a simple view — edit name/date and toggle updated status
|
||||||
if (event.eventType === "schedule_event") {
|
if (event.eventType === "schedule_event") {
|
||||||
const today = new Date().toISOString().split("T")[0];
|
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 (
|
return (
|
||||||
<div className="p-8">
|
<div className="p-8">
|
||||||
|
|
@ -107,38 +140,7 @@ export default function EventResults({
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
<Card>
|
<EditEventCard event={event} />
|
||||||
<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>
|
|
||||||
|
|
||||||
<Card>
|
<Card>
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
|
|
@ -222,6 +224,20 @@ export default function EventResults({
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="space-y-6">
|
<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 */}
|
{/* Debug info and manual QP processing for completed major tournaments */}
|
||||||
{event.isComplete && event.eventType === "major_tournament" && (
|
{event.isComplete && event.eventType === "major_tournament" && (
|
||||||
<Card className="border-electric/30">
|
<Card className="border-electric/30">
|
||||||
|
|
@ -266,17 +282,6 @@ export default function EventResults({
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</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 */}
|
{/* Season Standings Table for final_standings events */}
|
||||||
{event.eventType === "final_standings" && !event.isComplete && (
|
{event.eventType === "final_standings" && !event.isComplete && (
|
||||||
|
|
@ -376,7 +381,7 @@ export default function EventResults({
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Regular Result Entry for other event types */}
|
{/* Regular Result Entry for other event types */}
|
||||||
{event.eventType !== "final_standings" && !event.isComplete && (
|
{event.eventType !== "final_standings" && event.eventType !== "playoff_game" && !event.isComplete && (
|
||||||
<Card>
|
<Card>
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<CardTitle>Add Result</CardTitle>
|
<CardTitle>Add Result</CardTitle>
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue