Files
football-next/app/(admin)/admin/stats/StatsForm.tsx
a.alinaghipour aa9ed69dd2 first commit
2026-04-05 15:53:20 +03:30

139 lines
4.9 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"use client";
import { useState } from "react";
type Player = { id: string; name: string; position: string };
type StatRow = {
playerId: string;
goals: number;
assists: number;
yellowCards: number;
redCards: number;
minutesPlayed: number;
cleanSheet: boolean;
};
export default function StatsForm({ match }: { match: any }) {
const allPlayers: Player[] = [
...match.homeTeam.players,
...match.awayTeam.players,
];
const initStats = (): Record<string, StatRow> => {
const map: Record<string, StatRow> = {};
for (const p of allPlayers) {
const existing = match.playerStats.find((s: any) => s.playerId === p.id);
map[p.id] = existing ?? {
playerId: p.id,
goals: 0,
assists: 0,
yellowCards: 0,
redCards: 0,
minutesPlayed: 0,
cleanSheet: false,
};
}
return map;
};
const [stats, setStats] = useState<Record<string, StatRow>>(initStats);
const [loading, setLoading] = useState(false);
const [saved, setSaved] = useState(false);
function update(playerId: string, field: keyof StatRow, value: any) {
setStats((prev) => ({ ...prev, [playerId]: { ...prev[playerId], [field]: value } }));
}
async function handleSave() {
setLoading(true);
const payload = Object.values(stats).filter((s) => s.minutesPlayed > 0);
await fetch(`/api/matches/${match.id}/stats`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(payload),
});
setSaved(true);
setLoading(false);
setTimeout(() => setSaved(false), 3000);
}
const renderTeam = (players: Player[], teamName: string) => (
<div className="mb-8">
<h3 className="font-bold text-lg mb-3 text-green-800">{teamName}</h3>
<div className="bg-white rounded-2xl shadow overflow-hidden">
<table className="w-full text-sm">
<thead className="bg-gray-100 text-gray-600">
<tr>
<th className="text-right px-4 py-3">بازیکن</th>
<th className="px-3 py-3">دقیقه</th>
<th className="px-3 py-3">گل</th>
<th className="px-3 py-3">پاس گل</th>
<th className="px-3 py-3">زرد</th>
<th className="px-3 py-3">قرمز</th>
<th className="px-3 py-3">کلینشیت</th>
</tr>
</thead>
<tbody>
{players.map((p) => {
const s = stats[p.id];
if (!s) return null;
return (
<tr key={p.id} className="border-t hover:bg-gray-50">
<td className="px-4 py-2">
<div className="font-medium">{p.name}</div>
<div className="text-xs text-gray-400">{p.position}</div>
</td>
{(["minutesPlayed", "goals", "assists", "yellowCards", "redCards"] as const).map((field) => (
<td key={field} className="px-2 py-2 text-center">
<input
type="number"
min="0"
max={field === "minutesPlayed" ? 120 : 10}
value={s[field] as number}
onChange={(e) => update(p.id, field, parseInt(e.target.value) || 0)}
className="w-14 border rounded-lg px-2 py-1 text-center focus:outline-none focus:ring-2 focus:ring-green-400"
/>
</td>
))}
<td className="px-2 py-2 text-center">
<input
type="checkbox"
checked={s.cleanSheet}
onChange={(e) => update(p.id, "cleanSheet", e.target.checked)}
className="w-4 h-4 accent-green-600"
/>
</td>
</tr>
);
})}
</tbody>
</table>
</div>
</div>
);
return (
<div>
<div className="bg-green-50 border border-green-200 rounded-2xl p-4 mb-6 text-center">
<span className="font-bold text-lg">{match.homeTeam.name}</span>
<span className="mx-4 text-gray-400">vs</span>
<span className="font-bold text-lg">{match.awayTeam.name}</span>
</div>
{renderTeam(match.homeTeam.players, match.homeTeam.name)}
{renderTeam(match.awayTeam.players, match.awayTeam.name)}
<div className="flex items-center gap-4">
<button
onClick={handleSave}
disabled={loading}
className="bg-green-700 text-white px-8 py-3 rounded-xl font-bold hover:bg-green-800 transition disabled:opacity-50"
>
{loading ? "در حال ذخیره..." : "ذخیره آمار و محاسبه امتیازات"}
</button>
{saved && <span className="text-green-600 font-medium"> ذخیره شد</span>}
</div>
</div>
);
}