This commit is contained in:
@@ -40,6 +40,82 @@ export class MatchesService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate flag URL from country code or name using flagcdn.com
|
||||||
|
* Falls back to a name-to-code mapping for Turkish country names
|
||||||
|
*/
|
||||||
|
private getCountryFlagUrl(
|
||||||
|
countryCode?: string | null,
|
||||||
|
countryName?: string | null,
|
||||||
|
): string | undefined {
|
||||||
|
// If we have a 2-letter ISO code, use it directly
|
||||||
|
if (countryCode && countryCode.length === 2) {
|
||||||
|
return `https://flagcdn.com/w40/${countryCode.toLowerCase()}.png`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fallback: map common Turkish country names to ISO codes
|
||||||
|
const COUNTRY_NAME_TO_CODE: Record<string, string> = {
|
||||||
|
"Türkiye": "tr",
|
||||||
|
"İngiltere": "gb-eng",
|
||||||
|
"İspanya": "es",
|
||||||
|
"İtalya": "it",
|
||||||
|
"Almanya": "de",
|
||||||
|
"Fransa": "fr",
|
||||||
|
"Portekiz": "pt",
|
||||||
|
"Hollanda": "nl",
|
||||||
|
"Belçika": "be",
|
||||||
|
"İskoçya": "gb-sct",
|
||||||
|
"Galler": "gb-wls",
|
||||||
|
"İrlanda": "ie",
|
||||||
|
"Avusturya": "at",
|
||||||
|
"İsviçre": "ch",
|
||||||
|
"Yunanistan": "gr",
|
||||||
|
"Polonya": "pl",
|
||||||
|
"Çekya": "cz",
|
||||||
|
"Hırvatistan": "hr",
|
||||||
|
"Sırbistan": "rs",
|
||||||
|
"Danimarka": "dk",
|
||||||
|
"Norveç": "no",
|
||||||
|
"İsveç": "se",
|
||||||
|
"Finlandiya": "fi",
|
||||||
|
"Rusya": "ru",
|
||||||
|
"Ukrayna": "ua",
|
||||||
|
"Romanya": "ro",
|
||||||
|
"Macaristan": "hu",
|
||||||
|
"Bulgaristan": "bg",
|
||||||
|
"Arjantin": "ar",
|
||||||
|
"Brezilya": "br",
|
||||||
|
"Meksika": "mx",
|
||||||
|
"ABD": "us",
|
||||||
|
"Japonya": "jp",
|
||||||
|
"Güney Kore": "kr",
|
||||||
|
"Çin": "cn",
|
||||||
|
"Avustralya": "au",
|
||||||
|
"Suudi Arabistan": "sa",
|
||||||
|
"BAE": "ae",
|
||||||
|
"Katar": "qa",
|
||||||
|
"Mısır": "eg",
|
||||||
|
"Güney Afrika": "za",
|
||||||
|
"Kolombiya": "co",
|
||||||
|
"Şili": "cl",
|
||||||
|
"Peru": "pe",
|
||||||
|
"Ekvador": "ec",
|
||||||
|
"Paraguay": "py",
|
||||||
|
"Uruguay": "uy",
|
||||||
|
"Avrupa": "eu",
|
||||||
|
"Dünya": "un",
|
||||||
|
};
|
||||||
|
|
||||||
|
if (countryName) {
|
||||||
|
const code = COUNTRY_NAME_TO_CODE[countryName];
|
||||||
|
if (code) {
|
||||||
|
return `https://flagcdn.com/w40/${code}.png`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
private getLiveFilter(): Prisma.LiveMatchWhereInput {
|
private getLiveFilter(): Prisma.LiveMatchWhereInput {
|
||||||
return {
|
return {
|
||||||
OR: [
|
OR: [
|
||||||
@@ -298,7 +374,7 @@ export class MatchesService {
|
|||||||
country: {
|
country: {
|
||||||
id: match.league?.country?.id || "",
|
id: match.league?.country?.id || "",
|
||||||
name: match.league?.country?.name || "",
|
name: match.league?.country?.name || "",
|
||||||
flagUrl: match.league?.country?.flagUrl || undefined,
|
flagUrl: match.league?.country?.flagUrl || this.getCountryFlagUrl(null, match.league?.country?.name),
|
||||||
},
|
},
|
||||||
sport: sport,
|
sport: sport,
|
||||||
matches: [],
|
matches: [],
|
||||||
@@ -372,20 +448,37 @@ export class MatchesService {
|
|||||||
* Get active leagues with match counts
|
* Get active leagues with match counts
|
||||||
*/
|
*/
|
||||||
async getActiveLeagues(sport: Sport): Promise<ActiveLeagueDto[]> {
|
async getActiveLeagues(sport: Sport): Promise<ActiveLeagueDto[]> {
|
||||||
|
// Start of today in UTC — same reference point as findMatches browse filter
|
||||||
|
const today = new Date();
|
||||||
|
today.setUTCHours(0, 0, 0, 0);
|
||||||
|
const todayMs = BigInt(today.getTime());
|
||||||
|
|
||||||
|
// Build finished statuses/states for exclusion (mirroring getBrowseFilter logic)
|
||||||
|
const finishedStatuses = FINISHED_STATUS_VALUES_FOR_DB;
|
||||||
|
const finishedStates = FINISHED_STATE_VALUES_FOR_DB;
|
||||||
|
const liveStatuses = LIVE_STATUS_VALUES_FOR_DB;
|
||||||
|
const liveStates = LIVE_STATE_VALUES_FOR_DB;
|
||||||
|
|
||||||
// Use raw query for complex aggregation
|
// Use raw query for complex aggregation
|
||||||
|
// Filter: (mstUtc >= today AND NOT finished) OR is currently live
|
||||||
const leagues = await this.prisma.$queryRaw<any[]>`
|
const leagues = await this.prisma.$queryRaw<any[]>`
|
||||||
SELECT
|
SELECT
|
||||||
l.id, l.name, l.code,
|
l.id, l.name, l.code,
|
||||||
c.name as country_name,
|
c.name as country_name,
|
||||||
c.flag_url as country_flag,
|
c.flag_url as country_flag,
|
||||||
COUNT(lm.id)::int as match_count,
|
COUNT(lm.id)::int as match_count,
|
||||||
COUNT(CASE WHEN lm.status IN ('LIVE', '1H', '2H', 'HT', '1Q', '2Q', '3Q', '4Q', 'Playing', 'Half Time')
|
COUNT(CASE WHEN lm.status IN (${Prisma.join(liveStatuses)})
|
||||||
OR lm.state IN ('live', 'firsthalf', 'secondhalf') THEN 1 END)::int as live_count
|
OR lm.state IN (${Prisma.join(liveStates)}) THEN 1 END)::int as live_count
|
||||||
FROM live_matches lm
|
FROM live_matches lm
|
||||||
JOIN leagues l ON lm.league_id = l.id
|
JOIN leagues l ON lm.league_id = l.id
|
||||||
LEFT JOIN countries c ON l.country_id = c.id
|
LEFT JOIN countries c ON l.country_id = c.id
|
||||||
WHERE lm.sport = ${sport}
|
WHERE lm.sport = ${sport}
|
||||||
${this.topLeagueIds.length > 0 ? Prisma.sql`AND l.id IN (${Prisma.join(this.topLeagueIds)})` : Prisma.empty}
|
${this.topLeagueIds.length > 0 ? Prisma.sql`AND l.id IN (${Prisma.join(this.topLeagueIds)})` : Prisma.empty}
|
||||||
|
AND (
|
||||||
|
(lm.mst_utc >= ${todayMs} AND lm.status NOT IN (${Prisma.join(finishedStatuses)}) AND COALESCE(lm.state, '') NOT IN (${Prisma.join(finishedStates)}))
|
||||||
|
OR lm.status IN (${Prisma.join(liveStatuses)})
|
||||||
|
OR lm.state IN (${Prisma.join(liveStates)})
|
||||||
|
)
|
||||||
GROUP BY l.id, l.name, l.code, c.name, c.flag_url
|
GROUP BY l.id, l.name, l.code, c.name, c.flag_url
|
||||||
ORDER BY l.name ASC
|
ORDER BY l.name ASC
|
||||||
`;
|
`;
|
||||||
@@ -404,6 +497,7 @@ export class MatchesService {
|
|||||||
];
|
];
|
||||||
|
|
||||||
return leagues
|
return leagues
|
||||||
|
.filter((l) => l.match_count > 0)
|
||||||
.sort((a, b) => {
|
.sort((a, b) => {
|
||||||
const aIdx = PRIORITY.findIndex((p) => a.name?.includes(p));
|
const aIdx = PRIORITY.findIndex((p) => a.name?.includes(p));
|
||||||
const bIdx = PRIORITY.findIndex((p) => b.name?.includes(p));
|
const bIdx = PRIORITY.findIndex((p) => b.name?.includes(p));
|
||||||
@@ -419,7 +513,7 @@ export class MatchesService {
|
|||||||
name: l.name,
|
name: l.name,
|
||||||
code: l.code,
|
code: l.code,
|
||||||
countryName: l.country_name,
|
countryName: l.country_name,
|
||||||
countryFlag: l.country_flag,
|
countryFlag: l.country_flag || this.getCountryFlagUrl(null, l.country_name),
|
||||||
matchCount: l.match_count,
|
matchCount: l.match_count,
|
||||||
liveCount: l.live_count,
|
liveCount: l.live_count,
|
||||||
}));
|
}));
|
||||||
|
|||||||
Reference in New Issue
Block a user