Yaltopia-FIFA/app/(dashboard)/leagues/[leagueId]/competitions/[competitionId]/matches/[matchId]/match-actions.tsx
Kirubel-Kibru-Yaltopia 89440985f1
Some checks failed
Deploy to Cloudflare Workers / deploy (push) Has been cancelled
x
2026-05-24 21:46:10 +03:00

169 lines
5.2 KiB
TypeScript

"use client";
import { useState } from "react";
import { useRouter } from "next/navigation";
import { api } from "@/lib/api/client";
import { GlassCard } from "@/components/ui/glass-card";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
export function MatchActions({
matchId,
homeTeamId,
awayTeamId,
userTeamId,
status,
resultStatus,
isLeagueManager,
proposedAt,
}: {
matchId: string;
homeTeamId: string;
awayTeamId: string;
userTeamId: string | null;
status: string;
resultStatus: string | null;
isLeagueManager: boolean;
proposedAt: string | null;
}) {
const router = useRouter();
const [loading, setLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
async function run(fn: () => Promise<void>) {
setLoading(true);
setError(null);
try {
await fn();
router.refresh();
} catch (e) {
setError(e instanceof Error ? e.message : "Error");
} finally {
setLoading(false);
}
}
return (
<div className="space-y-4">
{error && <p className="text-sm text-red-400">{error}</p>}
{userTeamId && status !== "completed" && (
<GlassCard title="Schedule">
{proposedAt && (
<p className="mb-3 text-sm text-[var(--color-muted)]">
Proposed: {new Date(proposedAt).toLocaleString()}
</p>
)}
<form
className="flex flex-wrap items-end gap-3"
onSubmit={(e) => {
e.preventDefault();
const fd = new FormData(e.currentTarget);
run(async () => {
const raw = fd.get("scheduled_at") as string;
await api.matches.proposeSchedule(
matchId,
new Date(raw).toISOString()
);
});
}}
>
<div>
<Label htmlFor="scheduled_at">Propose kickoff</Label>
<Input
id="scheduled_at"
name="scheduled_at"
type="datetime-local"
className="mt-1"
required
/>
</div>
<Button type="submit" disabled={loading}>
Propose
</Button>
</form>
<Button
className="mt-3"
variant="secondary"
disabled={loading || !userTeamId}
onClick={() =>
run(() => api.matches.signSchedule(matchId, userTeamId!))
}
>
Sign schedule
</Button>
</GlassCard>
)}
{userTeamId && status !== "completed" && (
<GlassCard title="Submit result">
<form
className="flex flex-wrap items-end gap-3"
onSubmit={(e) => {
e.preventDefault();
const fd = new FormData(e.currentTarget);
run(() =>
api.matches.submitResult(matchId, {
teamId: userTeamId!,
homeScore: Number(fd.get("home_score")),
awayScore: Number(fd.get("away_score")),
})
);
}}
>
<div>
<Label>Home score</Label>
<Input name="home_score" type="number" min={0} required className="mt-1 w-20" />
</div>
<div>
<Label>Away score</Label>
<Input name="away_score" type="number" min={0} required className="mt-1 w-20" />
</div>
<Button type="submit" disabled={loading}>
Submit result
</Button>
</form>
</GlassCard>
)}
{isLeagueManager && resultStatus === "pending_approval" && (
<GlassCard title="League manager" highlight>
<Button
disabled={loading}
onClick={() => run(() => api.matches.approveResult(matchId))}
>
Approve matching result
</Button>
</GlassCard>
)}
{isLeagueManager && (
<GlassCard title="Set official result">
<form
className="flex flex-wrap items-end gap-3"
onSubmit={(e) => {
e.preventDefault();
const fd = new FormData(e.currentTarget);
run(() =>
api.matches.setResult(matchId, {
homeScore: Number(fd.get("home_score")),
awayScore: Number(fd.get("away_score")),
note: (fd.get("note") as string) || undefined,
})
);
}}
>
<Input name="home_score" type="number" min={0} placeholder="H" className="w-20" required />
<Input name="away_score" type="number" min={0} placeholder="A" className="w-20" required />
<Input name="note" placeholder="Note (optional)" className="flex-1 min-w-[120px]" />
<Button type="submit" disabled={loading}>
Set result
</Button>
</form>
</GlassCard>
)}
</div>
);
}