Yaltopia-FIFA/lib/services/manager.ts
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

134 lines
4.1 KiB
TypeScript

import type { SupabaseClient } from "@supabase/supabase-js";
export type ManagerCompetitionRow = {
competition_id: string;
competition_name: string;
league_id: string;
league_name: string;
tournament_mode: "league" | "cup";
team_id: string;
team_name: string;
team_nickname: string | null;
team_icon: string | null;
points: number;
goals_for: number;
goals_against: number;
goal_difference: number;
played: number;
};
export async function getManagerCompetitions(
supabase: SupabaseClient,
userId: string,
mode?: "league" | "cup"
) {
const { data: memberships, error: mErr } = await supabase
.from("team_members")
.select("team_id, teams(id, name, nickname, icon, competition_id)")
.eq("user_id", userId)
.eq("role", "manager");
if (mErr) throw new Error(mErr.message);
if (!memberships?.length) return [] as ManagerCompetitionRow[];
const rows: ManagerCompetitionRow[] = [];
for (const m of memberships) {
const team = m.teams as {
id: string;
name: string;
nickname: string | null;
icon: string | null;
competition_id: string;
};
if (!team?.competition_id) continue;
const { data: comp } = await supabase
.from("competitions")
.select("id, name, tournament_mode, league_id, leagues(name)")
.eq("id", team.competition_id)
.single();
if (!comp) continue;
if (mode && comp.tournament_mode !== mode) continue;
const { data: standing } = await supabase
.from("competition_standings")
.select("points, goals_for, goals_against, goal_difference, played")
.eq("competition_id", team.competition_id)
.eq("team_id", team.id)
.maybeSingle();
const league = comp.leagues as { name: string } | null;
rows.push({
competition_id: comp.id,
competition_name: comp.name,
league_id: comp.league_id,
league_name: league?.name ?? "League",
tournament_mode: comp.tournament_mode as "league" | "cup",
team_id: team.id,
team_name: team.name,
team_nickname: team.nickname,
team_icon: team.icon,
points: standing?.points ?? 0,
goals_for: standing?.goals_for ?? 0,
goals_against: standing?.goals_against ?? 0,
goal_difference: standing?.goal_difference ?? 0,
played: standing?.played ?? 0,
});
}
return rows;
}
export async function getManagerDashboard(
supabase: SupabaseClient,
userId: string
) {
const { data: memberships } = await supabase
.from("team_members")
.select("team_id, teams(competition_id)")
.eq("user_id", userId)
.eq("role", "manager");
const teamIds = memberships?.map((m) => m.team_id) ?? [];
if (teamIds.length === 0) {
return { nextFixture: null, recentResults: [], stats: null };
}
const teamFilter = teamIds.join(",");
const { data: nextFixture } = await supabase
.from("matches")
.select(
`id, scheduled_at, proposed_scheduled_at, status, home_team_id, away_team_id,
home:home_team_id(name, nickname, icon),
away:away_team_id(name, nickname, icon),
competitions(name, leagues(name))`
)
.or(`home_team_id.in.(${teamFilter}),away_team_id.in.(${teamFilter})`)
.in("status", ["scheduled", "schedule_pending", "schedule_confirmed"])
.order("scheduled_at", { ascending: true, nullsFirst: false })
.limit(1)
.maybeSingle();
const { data: recentResults } = await supabase
.from("team_match_results")
.select("*")
.in("team_id", teamIds)
.order("scheduled_at", { ascending: false })
.limit(8);
const wins = recentResults?.filter((r) => r.result === "W").length ?? 0;
const draws = recentResults?.filter((r) => r.result === "D").length ?? 0;
const losses = recentResults?.filter((r) => r.result === "L").length ?? 0;
const goalsFor =
recentResults?.reduce((s, r) => s + (r.goals_for ?? 0), 0) ?? 0;
return {
nextFixture,
recentResults: recentResults ?? [],
stats: { wins, draws, losses, goalsFor, played: recentResults?.length ?? 0 },
};
}