Some checks failed
Deploy to Cloudflare Workers / deploy (push) Has been cancelled
193 lines
5.8 KiB
TypeScript
193 lines
5.8 KiB
TypeScript
import type { SupabaseClient } from "@supabase/supabase-js";
|
|
|
|
export type CalendarMatch = {
|
|
id: string;
|
|
competition_id: string;
|
|
competition_name: string;
|
|
league_id: string;
|
|
league_name: string;
|
|
scheduled_at: string | null;
|
|
proposed_scheduled_at: string | null;
|
|
status: string;
|
|
result_status: string | null;
|
|
home_team_id: string;
|
|
away_team_id: string;
|
|
home_name: string;
|
|
away_name: string;
|
|
my_team_ids: string[];
|
|
};
|
|
|
|
function pickMatchDate(m: {
|
|
scheduled_at: string | null;
|
|
proposed_scheduled_at: string | null;
|
|
}) {
|
|
return m.scheduled_at ?? m.proposed_scheduled_at;
|
|
}
|
|
|
|
export async function getManagerCalendarMatches(
|
|
supabase: SupabaseClient,
|
|
userId: string,
|
|
rangeStart: string,
|
|
rangeEnd: string
|
|
): Promise<CalendarMatch[]> {
|
|
const { data: memberships } = await supabase
|
|
.from("team_members")
|
|
.select("team_id")
|
|
.eq("user_id", userId)
|
|
.eq("role", "manager");
|
|
|
|
const teamIds = memberships?.map((m) => m.team_id) ?? [];
|
|
if (teamIds.length === 0) return [];
|
|
|
|
const teamFilter = teamIds.join(",");
|
|
const { data: matches, error } = await supabase
|
|
.from("matches")
|
|
.select(
|
|
`id, competition_id, status, result_status, scheduled_at, proposed_scheduled_at,
|
|
home_team_id, away_team_id,
|
|
home:home_team_id(id, name),
|
|
away:away_team_id(id, name),
|
|
competitions(id, name, league_id, leagues(name))`
|
|
)
|
|
.or(`home_team_id.in.(${teamFilter}),away_team_id.in.(${teamFilter})`)
|
|
.order("scheduled_at", { ascending: true });
|
|
|
|
if (error) throw new Error(error.message);
|
|
|
|
const start = new Date(rangeStart).getTime();
|
|
const end = new Date(rangeEnd).getTime();
|
|
|
|
return (matches ?? [])
|
|
.map((m) => {
|
|
const when = pickMatchDate(m);
|
|
const comp = m.competitions as {
|
|
id: string;
|
|
name: string;
|
|
league_id: string;
|
|
leagues: { name: string } | null;
|
|
} | null;
|
|
const home = m.home as { id: string; name: string };
|
|
const away = m.away as { id: string; name: string };
|
|
return {
|
|
id: m.id,
|
|
competition_id: comp?.id ?? m.competition_id,
|
|
competition_name: comp?.name ?? "Competition",
|
|
league_id: comp?.league_id ?? "",
|
|
league_name: comp?.leagues?.name ?? "League",
|
|
scheduled_at: m.scheduled_at,
|
|
proposed_scheduled_at: m.proposed_scheduled_at,
|
|
status: m.status,
|
|
result_status: m.result_status,
|
|
home_team_id: m.home_team_id,
|
|
away_team_id: m.away_team_id,
|
|
home_name: home?.name ?? "Home",
|
|
away_name: away?.name ?? "Away",
|
|
my_team_ids: teamIds.filter(
|
|
(tid) => tid === m.home_team_id || tid === m.away_team_id
|
|
),
|
|
_when: when,
|
|
};
|
|
})
|
|
.filter((m) => {
|
|
if (!m._when) return true;
|
|
const t = new Date(m._when).getTime();
|
|
return t >= start && t <= end;
|
|
})
|
|
.map(({ _when, ...rest }) => rest);
|
|
}
|
|
|
|
export async function getMasterCalendarMatches(
|
|
supabase: SupabaseClient,
|
|
userId: string,
|
|
isGlobalMaster: boolean,
|
|
rangeStart: string,
|
|
rangeEnd: string
|
|
): Promise<CalendarMatch[]> {
|
|
let competitionIds: string[] = [];
|
|
|
|
if (isGlobalMaster) {
|
|
const { data } = await supabase.from("competitions").select("id");
|
|
competitionIds = data?.map((c) => c.id) ?? [];
|
|
} else {
|
|
const { data: owned } = await supabase
|
|
.from("leagues")
|
|
.select("id")
|
|
.eq("created_by", userId);
|
|
const leagueIds = owned?.map((l) => l.id) ?? [];
|
|
|
|
const { data: assigned } = await supabase
|
|
.from("league_masters")
|
|
.select("league_id")
|
|
.eq("user_id", userId);
|
|
const allLeagueIds = [
|
|
...new Set([
|
|
...leagueIds,
|
|
...(assigned?.map((a) => a.league_id) ?? []),
|
|
]),
|
|
];
|
|
|
|
if (allLeagueIds.length === 0) return [];
|
|
|
|
const { data: comps } = await supabase
|
|
.from("competitions")
|
|
.select("id")
|
|
.in("league_id", allLeagueIds);
|
|
competitionIds = comps?.map((c) => c.id) ?? [];
|
|
}
|
|
|
|
if (competitionIds.length === 0) return [];
|
|
|
|
const { data: matches, error } = await supabase
|
|
.from("matches")
|
|
.select(
|
|
`id, competition_id, status, result_status, scheduled_at, proposed_scheduled_at,
|
|
home_team_id, away_team_id,
|
|
home:home_team_id(id, name),
|
|
away:away_team_id(id, name),
|
|
competitions(id, name, league_id, leagues(name))`
|
|
)
|
|
.in("competition_id", competitionIds)
|
|
.order("scheduled_at", { ascending: true });
|
|
|
|
if (error) throw new Error(error.message);
|
|
|
|
const start = new Date(rangeStart).getTime();
|
|
const end = new Date(rangeEnd).getTime();
|
|
|
|
return (matches ?? [])
|
|
.map((m) => {
|
|
const when = pickMatchDate(m);
|
|
const comp = m.competitions as {
|
|
id: string;
|
|
name: string;
|
|
league_id: string;
|
|
leagues: { name: string } | null;
|
|
} | null;
|
|
const home = m.home as { id: string; name: string };
|
|
const away = m.away as { id: string; name: string };
|
|
return {
|
|
id: m.id,
|
|
competition_id: comp?.id ?? m.competition_id,
|
|
competition_name: comp?.name ?? "Competition",
|
|
league_id: comp?.league_id ?? "",
|
|
league_name: comp?.leagues?.name ?? "League",
|
|
scheduled_at: m.scheduled_at,
|
|
proposed_scheduled_at: m.proposed_scheduled_at,
|
|
status: m.status,
|
|
result_status: m.result_status,
|
|
home_team_id: m.home_team_id,
|
|
away_team_id: m.away_team_id,
|
|
home_name: home?.name ?? "Home",
|
|
away_name: away?.name ?? "Away",
|
|
my_team_ids: [],
|
|
_when: when,
|
|
};
|
|
})
|
|
.filter((m) => {
|
|
if (!m._when) return true;
|
|
const t = new Date(m._when).getTime();
|
|
return t >= start && t <= end;
|
|
})
|
|
.map(({ _when, ...rest }) => rest);
|
|
}
|