feat: update MatchEditor to use tournament-specific scoring rules
This commit is contained in:
@@ -78,7 +78,13 @@ export default async function TournamentResultsPage({ params }: PageProps) {
|
|||||||
|
|
||||||
{/* Match Editor */}
|
{/* Match Editor */}
|
||||||
<div className="bg-white shadow rounded-lg p-6">
|
<div className="bg-white shadow rounded-lg p-6">
|
||||||
<MatchEditor tournamentId={tournamentId} players={players} matches={matches} />
|
<MatchEditor
|
||||||
|
tournamentId={tournamentId}
|
||||||
|
players={players}
|
||||||
|
matches={matches}
|
||||||
|
targetScore={tournament.targetScore}
|
||||||
|
allowTies={tournament.allowTies}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Existing Matches */}
|
{/* Existing Matches */}
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ interface MatchEditorProps {
|
|||||||
tournamentId: number
|
tournamentId: number
|
||||||
players: Player[]
|
players: Player[]
|
||||||
matches: Match[]
|
matches: Match[]
|
||||||
|
targetScore: number | null
|
||||||
|
allowTies: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
interface MatchData {
|
interface MatchData {
|
||||||
@@ -18,9 +20,10 @@ interface MatchData {
|
|||||||
team2Score: number
|
team2Score: number
|
||||||
round: number
|
round: number
|
||||||
table: string
|
table: string
|
||||||
|
isCasual: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function MatchEditor({ tournamentId, players }: MatchEditorProps) {
|
export default function MatchEditor({ tournamentId, players, targetScore, allowTies }: MatchEditorProps) {
|
||||||
const [formData, setFormData] = useState<MatchData>({
|
const [formData, setFormData] = useState<MatchData>({
|
||||||
team1P1Id: null,
|
team1P1Id: null,
|
||||||
team1P2Id: null,
|
team1P2Id: null,
|
||||||
@@ -30,6 +33,7 @@ export default function MatchEditor({ tournamentId, players }: MatchEditorProps)
|
|||||||
team2Score: 0,
|
team2Score: 0,
|
||||||
round: 1,
|
round: 1,
|
||||||
table: "Clubs",
|
table: "Clubs",
|
||||||
|
isCasual: false,
|
||||||
})
|
})
|
||||||
const [error, setError] = useState("")
|
const [error, setError] = useState("")
|
||||||
const [success, setSuccess] = useState("")
|
const [success, setSuccess] = useState("")
|
||||||
@@ -38,10 +42,12 @@ export default function MatchEditor({ tournamentId, players }: MatchEditorProps)
|
|||||||
const tables = ["Clubs", "Hearts", "Diamonds", "Spades", "Stars"]
|
const tables = ["Clubs", "Hearts", "Diamonds", "Spades", "Stars"]
|
||||||
|
|
||||||
const handleChange = (e: React.ChangeEvent<HTMLSelectElement | HTMLInputElement>) => {
|
const handleChange = (e: React.ChangeEvent<HTMLSelectElement | HTMLInputElement>) => {
|
||||||
const { name, value } = e.target
|
const { name, value, type } = e.target
|
||||||
|
const checked = (e.target as HTMLInputElement).checked
|
||||||
setFormData(prev => ({
|
setFormData(prev => ({
|
||||||
...prev,
|
...prev,
|
||||||
[name]: name.includes("Id") ? (value ? parseInt(value) : null) :
|
[name]: type === 'checkbox' ? checked :
|
||||||
|
name.includes("Id") ? (value ? parseInt(value) : null) :
|
||||||
name === "round" ? parseInt(value) :
|
name === "round" ? parseInt(value) :
|
||||||
name === "team1Score" || name === "team2Score" ? parseInt(value) :
|
name === "team1Score" || name === "team2Score" ? parseInt(value) :
|
||||||
value,
|
value,
|
||||||
@@ -72,6 +78,30 @@ export default function MatchEditor({ tournamentId, players }: MatchEditorProps)
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Validate target score if provided
|
||||||
|
if (targetScore) {
|
||||||
|
const team1ReachedTarget = formData.team1Score >= targetScore;
|
||||||
|
const team2ReachedTarget = formData.team2Score >= targetScore;
|
||||||
|
|
||||||
|
// Check if one team reached the target
|
||||||
|
if (!team1ReachedTarget && !team2ReachedTarget) {
|
||||||
|
setError(`Scores must reach the target score of ${targetScore}`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if both teams reached the target (invalid unless ties are allowed and it's a tie)
|
||||||
|
if (team1ReachedTarget && team2ReachedTarget && formData.team1Score !== formData.team2Score) {
|
||||||
|
setError(`Only one team can reach the target score of ${targetScore}`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate ties
|
||||||
|
if (!allowTies && formData.team1Score === formData.team2Score) {
|
||||||
|
setError("Ties are not allowed in this tournament")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
setIsLoading(true)
|
setIsLoading(true)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -90,6 +120,7 @@ export default function MatchEditor({ tournamentId, players }: MatchEditorProps)
|
|||||||
team2Score: formData.team2Score,
|
team2Score: formData.team2Score,
|
||||||
round: formData.round,
|
round: formData.round,
|
||||||
table: formData.table,
|
table: formData.table,
|
||||||
|
isCasual: formData.isCasual,
|
||||||
}),
|
}),
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -114,6 +145,7 @@ export default function MatchEditor({ tournamentId, players }: MatchEditorProps)
|
|||||||
team2Score: 0,
|
team2Score: 0,
|
||||||
round: formData.round,
|
round: formData.round,
|
||||||
table: formData.table,
|
table: formData.table,
|
||||||
|
isCasual: false,
|
||||||
})
|
})
|
||||||
|
|
||||||
// Reload the page to show updated matches
|
// Reload the page to show updated matches
|
||||||
@@ -286,7 +318,18 @@ export default function MatchEditor({ tournamentId, players }: MatchEditorProps)
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex justify-end">
|
<div className="flex items-center justify-between">
|
||||||
|
<label className="flex items-center">
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
name="isCasual"
|
||||||
|
checked={formData.isCasual}
|
||||||
|
onChange={handleChange}
|
||||||
|
className="h-4 w-4 text-green-600 focus:ring-green-500 border-gray-300 rounded"
|
||||||
|
/>
|
||||||
|
<span className="ml-2 text-sm text-gray-700">Casual Match</span>
|
||||||
|
</label>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
type="submit"
|
type="submit"
|
||||||
disabled={isLoading}
|
disabled={isLoading}
|
||||||
|
|||||||
Reference in New Issue
Block a user