139 lines
6.1 KiB
TypeScript
139 lines
6.1 KiB
TypeScript
"use client";
|
||
|
||
import { useState } from "react";
|
||
import { useRouter } from "next/navigation";
|
||
|
||
type Country = { id: string; name: string };
|
||
type Round = { id: string; name: string; number: number };
|
||
|
||
export default function MatchForm({
|
||
countries,
|
||
rounds,
|
||
initial,
|
||
matchId,
|
||
}: {
|
||
countries: Country[];
|
||
rounds: Round[];
|
||
initial?: any;
|
||
matchId?: string;
|
||
}) {
|
||
const router = useRouter();
|
||
const [form, setForm] = useState({
|
||
homeTeamId: initial?.homeTeamId ?? "",
|
||
awayTeamId: initial?.awayTeamId ?? "",
|
||
stage: initial?.stage ?? "GROUP",
|
||
status: initial?.status ?? "SCHEDULED",
|
||
matchDate: initial?.matchDate ? new Date(initial.matchDate).toISOString().slice(0, 16) : "",
|
||
homeScore: initial?.homeScore ?? "",
|
||
awayScore: initial?.awayScore ?? "",
|
||
roundId: initial?.roundId ?? "",
|
||
});
|
||
const [loading, setLoading] = useState(false);
|
||
const [error, setError] = useState("");
|
||
|
||
async function handleSubmit(e: React.FormEvent) {
|
||
e.preventDefault();
|
||
setLoading(true);
|
||
const payload = {
|
||
...form,
|
||
homeScore: form.homeScore !== "" ? parseInt(String(form.homeScore)) : null,
|
||
awayScore: form.awayScore !== "" ? parseInt(String(form.awayScore)) : null,
|
||
roundId: form.roundId || null,
|
||
};
|
||
const res = await fetch(matchId ? `/api/matches/${matchId}` : "/api/matches", {
|
||
method: matchId ? "PUT" : "POST",
|
||
headers: { "Content-Type": "application/json" },
|
||
body: JSON.stringify(payload),
|
||
});
|
||
if (res.ok) {
|
||
router.push("/admin/matches");
|
||
router.refresh();
|
||
} else {
|
||
const d = await res.json();
|
||
setError(d.error ?? "خطا");
|
||
}
|
||
setLoading(false);
|
||
}
|
||
|
||
const stages = [
|
||
{ value: "GROUP", label: "مرحله گروهی" },
|
||
{ value: "ROUND_OF_16", label: "یکهشتم نهایی" },
|
||
{ value: "QUARTER_FINAL", label: "یکچهارم نهایی" },
|
||
{ value: "SEMI_FINAL", label: "نیمهنهایی" },
|
||
{ value: "THIRD_PLACE", label: "ردهبندی" },
|
||
{ value: "FINAL", label: "فینال" },
|
||
];
|
||
|
||
return (
|
||
<form onSubmit={handleSubmit} className="bg-white rounded-2xl shadow p-6 flex flex-col gap-4">
|
||
{error && <p className="text-red-500 text-sm bg-red-50 px-3 py-2 rounded-lg">{error}</p>}
|
||
<div className="grid grid-cols-2 gap-4">
|
||
<div>
|
||
<label className="block text-sm font-medium mb-1">تیم میزبان</label>
|
||
<select value={form.homeTeamId} onChange={(e) => setForm({ ...form, homeTeamId: e.target.value })}
|
||
className="w-full border rounded-xl px-3 py-2.5 focus:outline-none focus:ring-2 focus:ring-green-500" required>
|
||
<option value="">انتخاب کنید</option>
|
||
{countries.map((c) => <option key={c.id} value={c.id}>{c.name}</option>)}
|
||
</select>
|
||
</div>
|
||
<div>
|
||
<label className="block text-sm font-medium mb-1">تیم مهمان</label>
|
||
<select value={form.awayTeamId} onChange={(e) => setForm({ ...form, awayTeamId: e.target.value })}
|
||
className="w-full border rounded-xl px-3 py-2.5 focus:outline-none focus:ring-2 focus:ring-green-500" required>
|
||
<option value="">انتخاب کنید</option>
|
||
{countries.map((c) => <option key={c.id} value={c.id}>{c.name}</option>)}
|
||
</select>
|
||
</div>
|
||
</div>
|
||
<div className="grid grid-cols-2 gap-4">
|
||
<div>
|
||
<label className="block text-sm font-medium mb-1">گل میزبان</label>
|
||
<input type="number" min="0" value={form.homeScore}
|
||
onChange={(e) => setForm({ ...form, homeScore: e.target.value })}
|
||
className="w-full border rounded-xl px-3 py-2.5 focus:outline-none focus:ring-2 focus:ring-green-500" />
|
||
</div>
|
||
<div>
|
||
<label className="block text-sm font-medium mb-1">گل مهمان</label>
|
||
<input type="number" min="0" value={form.awayScore}
|
||
onChange={(e) => setForm({ ...form, awayScore: e.target.value })}
|
||
className="w-full border rounded-xl px-3 py-2.5 focus:outline-none focus:ring-2 focus:ring-green-500" />
|
||
</div>
|
||
</div>
|
||
<div>
|
||
<label className="block text-sm font-medium mb-1">مرحله</label>
|
||
<select value={form.stage} onChange={(e) => setForm({ ...form, stage: e.target.value })}
|
||
className="w-full border rounded-xl px-3 py-2.5 focus:outline-none focus:ring-2 focus:ring-green-500">
|
||
{stages.map((s) => <option key={s.value} value={s.value}>{s.label}</option>)}
|
||
</select>
|
||
</div>
|
||
<div>
|
||
<label className="block text-sm font-medium mb-1">وضعیت</label>
|
||
<select value={form.status} onChange={(e) => setForm({ ...form, status: e.target.value })}
|
||
className="w-full border rounded-xl px-3 py-2.5 focus:outline-none focus:ring-2 focus:ring-green-500">
|
||
<option value="SCHEDULED">برنامهریزی شده</option>
|
||
<option value="LIVE">زنده</option>
|
||
<option value="FINISHED">پایان یافته</option>
|
||
</select>
|
||
</div>
|
||
<div>
|
||
<label className="block text-sm font-medium mb-1">تاریخ و ساعت</label>
|
||
<input type="datetime-local" value={form.matchDate}
|
||
onChange={(e) => setForm({ ...form, matchDate: e.target.value })}
|
||
className="w-full border rounded-xl px-3 py-2.5 focus:outline-none focus:ring-2 focus:ring-green-500" required />
|
||
</div>
|
||
<div>
|
||
<label className="block text-sm font-medium mb-1">دور بازی</label>
|
||
<select value={form.roundId} onChange={(e) => setForm({ ...form, roundId: e.target.value })}
|
||
className="w-full border rounded-xl px-3 py-2.5 focus:outline-none focus:ring-2 focus:ring-green-500">
|
||
<option value="">بدون دور</option>
|
||
{rounds.map((r) => <option key={r.id} value={r.id}>دور {r.number} - {r.name}</option>)}
|
||
</select>
|
||
</div>
|
||
<button type="submit" disabled={loading}
|
||
className="bg-green-700 text-white py-3 rounded-xl font-bold hover:bg-green-800 transition disabled:opacity-50">
|
||
{loading ? "در حال ذخیره..." : matchId ? "ذخیره تغییرات" : "افزودن بازی"}
|
||
</button>
|
||
</form>
|
||
);
|
||
}
|