add jury host controls component

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-12 20:28:34 +01:00
parent d247c2519e
commit 094fd1feeb

View File

@@ -0,0 +1,91 @@
import { useState } from "react"
import type { Entry, JuryRound, JuryResult } from "@celebrate-esc/shared"
import { Button } from "@/components/ui/button"
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
interface JuryHostProps {
entries: Entry[]
currentRound: JuryRound | null
results: JuryResult[]
onOpenVote: (countryCode: string) => void
onCloseVote: () => void
}
export function JuryHost({ entries, currentRound, results, onOpenVote, onCloseVote }: JuryHostProps) {
const [selectedCountry, setSelectedCountry] = useState<string | null>(null)
const votedCountries = new Set(results.map((r) => r.countryCode))
if (currentRound) {
return (
<Card>
<CardHeader>
<CardTitle>
Voting: {currentRound.countryFlag} {currentRound.countryName}
</CardTitle>
</CardHeader>
<CardContent>
<Button onClick={onCloseVote} variant="destructive" className="w-full">
Close Voting
</Button>
</CardContent>
</Card>
)
}
return (
<Card>
<CardHeader>
<CardTitle>Jury Voting</CardTitle>
</CardHeader>
<CardContent className="flex flex-col gap-3">
{results.length > 0 && (
<div className="mb-2">
<p className="mb-1 text-sm font-medium text-muted-foreground">
Completed ({results.length})
</p>
{results.map((r) => (
<div key={r.countryCode} className="flex items-center justify-between text-sm">
<span>{r.countryFlag} {r.countryName}</span>
<span className="text-muted-foreground">avg {r.averageRating} ({r.totalVotes} votes)</span>
</div>
))}
</div>
)}
<div className="flex flex-col gap-1">
{entries.map((entry) => {
const voted = votedCountries.has(entry.country.code)
const isSelected = selectedCountry === entry.country.code
return (
<button
key={entry.country.code}
type="button"
disabled={voted}
onClick={() => setSelectedCountry(isSelected ? null : entry.country.code)}
className={`rounded-md border px-3 py-2 text-left text-sm transition-colors ${
voted
? "border-transparent bg-muted/50 text-muted-foreground line-through opacity-50"
: isSelected
? "border-primary bg-primary/5"
: "hover:bg-muted"
}`}
>
{entry.country.flag} {entry.artist} {entry.song}
</button>
)
})}
</div>
{selectedCountry && (
<Button
onClick={() => {
onOpenVote(selectedCountry)
setSelectedCountry(null)
}}
className="w-full"
>
Open Voting
</Button>
)}
</CardContent>
</Card>
)
}