proshu-sozdat-sportivnyy-say/script.js

220 lines
8.2 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

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.

// СпортПортал — данные и логика (мок-данные, фаза 1)
const SPORTS = [
{
icon: "trophy",
name: "Футбол",
desc: "Премьер-лига, Кубок, трансферы и лучшие моменты.",
chip: "12 матчей сегодня",
},
{
icon: "dashboard",
name: "Теннис",
desc: "Туры ATP/WTA, турниры Большой четвёрки, рейтинги.",
chip: "Полуфиналы турнира",
},
{
icon: "chart",
name: "Хоккей",
desc: "КХЛ, НХЛ: очки, шайбы и гонка бомбардиров.",
chip: "Турнирная таблица КХЛ",
},
{
icon: "users",
name: "Бокс",
desc: "Большие бои, рейтинги и история рекордов.",
chip: "Пояс WBA в игре",
},
];
const LEAGUES = {
premier: {
label: "Премьер-лига",
cols: ["И", "В", "Н", "П", "ГЗ", "ГП"],
rows: [
["Арсенал", 38, 24, 10, 4, 78, 32],
["Ливерпуль", 38, 23, 11, 4, 85, 34],
["Манчестер Сити", 38, 22, 8, 8, 80, 41],
["Челси", 38, 20, 8, 10, 64, 42],
["Лестер", 38, 19, 7, 12, 58, 44],
["Тоттенхэм", 38, 18, 7, 13, 54, 44],
],
},
laliga: {
label: "Ла Лига",
cols: ["И", "В", "Н", "П", "ГЗ", "ГП"],
rows: [
["Реал Мадрид", 38, 27, 4, 7, 78, 33],
["Барселона", 38, 26, 5, 7, 87, 38],
["Атлетико", 38, 21, 9, 8, 64, 35],
["Атлетик", 38, 17, 11, 10, 47, 36],
["Райо", 38, 15, 10, 13, 44, 45],
["Вильярреал", 38, 14, 12, 12, 55, 43],
],
},
khl: {
label: "КХЛ",
cols: ["И", "В", "Н", "П", "ШЗ", "ШП"],
rows: [
["СКА", 60, 42, 6, 12, 180, 98],
["ЦСКА", 60, 40, 6, 14, 172, 101],
["Ак Барс", 60, 38, 5, 17, 160, 97],
["Локомотив", 60, 35, 6, 19, 148, 104],
["Металлург", 60, 32, 5, 23, 137, 115],
["Авангард", 60, 30, 5, 25, 140, 121],
],
},
nhl: {
label: "НХЛ",
cols: ["И", "В", "Н", "П", "ШЗ", "ШП"],
rows: [
["Эдмонтон", 82, 48, 10, 24, 290, 238],
["Виннипег", 82, 46, 10, 26, 271, 227],
["Филадельфия", 82, 44, 10, 28, 263, 237],
["Даллас", 82, 44, 0, 38, 270, 215],
["Колорадо", 82, 42, 8, 32, 286, 235],
["Нэшвилл", 82, 41, 8, 33, 265, 240],
],
},
};
const MATCHES = [
{ sport: "Футбол", home: "Арсенал", away: "Челси", score: "2:1", time: "Финал" },
{ sport: "Футбол", home: "Реал Мадрид", away: "Барселона", score: "1:1", time: "110-я минута" },
{ sport: "Теннис", home: "Сафара", away: "Медведев", score: "3:2", time: "Победа Сафары" },
{ sport: "Хоккей", home: "СКА", away: "ЦСКА", score: "3:2", time: "После буллитов" },
{ sport: "Бокс", home: "Алимхан", away: "Гарсия", score: "TKO", time: "раунд 9" },
];
const ARTICLES = [
{
sport: "Футбол",
date: "22.09.2026",
title: "Как Премьер-лига дошла до рекордной гонки за титул",
excerpt: "Впервые за десять лет три команды делят первые места с разницей в два очка. Разбираем, что решает чемпионство.",
},
{
sport: "Теннис",
date: "21.09.2026",
title: "Медведев и Сафара: разбор полуфинала турнира",
excerpt: "Пять сетов, 3 часа 12 минут. Ключевые моменты и статистика матча, который войдёт в историю турнира.",
},
{
sport: "Хоккей",
date: "20.09.2026",
title: "Гонка бомбардиров КХЛ: кто впереди и почему",
excerpt: "Три форварда набрали больше 40 очков. Сравниваем их стили игры и роли в командах.",
},
{
sport: "Бокс",
date: "19.09.2026",
title: "Большой бой года: что ждать от реванша",
excerpt: "Два чемпиона, два стиля и титул в двух версиях. Прогнозы экспертов и история их предыдущего боя.",
},
{
sport: "Футбол",
date: "18.09.2026",
title: "Молодые вратари, которые изменят Европу",
excerpt: "Обзор пяти голкиперов до 22 лет, которые в этом сезоне уже доказали класс. Где посмотреть их игры.",
},
{
sport: "Теннис",
date: "17.09.2026",
title: "Как изменился грунтовый сезон за десять лет",
excerpt: "Цифры и тренды: скорости подачи, длина матчей и новые герои сезона на медленных кортах.",
},
];
const fmtDate = (s) => s;
function icon(name) {
return `<svg class="kt-ai-icon" aria-hidden="true"><use href="#${name}"></use></svg>`;
}
function renderSports() {
const grid = document.getElementById("sports-grid");
if (!grid) return;
grid.style.gridTemplateColumns = "repeat(4, 1fr)";
grid.innerHTML = SPORTS.map((s) => `
<article class="kt-ai-tile" style="display:flex; flex-direction:column;">
<div class="sport-tile-head">
<span class="sport-badge">${icon(s.icon)}</span>
<h3>${s.name}</h3>
</div>
<p>${s.desc}</p>
<div class="tile-more">
<span class="kt-ai-chip">${s.chip}</span>
</div>
</article>
`).join("");
}
function renderLeagueTabs() {
const tabs = document.getElementById("league-tabs");
if (!tabs) return;
tabs.innerHTML = Object.entries(LEAGUES).map(([key, l], i) => `
<button class="kt-ai-btn" data-league="${key}" data-variant="${i === 0 ? "primary" : "ghost"}">${l.label}</button>
`).join("");
tabs.addEventListener("click", (e) => {
const btn = e.target.closest("[data-league]");
if (!btn) return;
tabs.querySelectorAll("button").forEach((b) => b.setAttribute("data-variant", "ghost"));
btn.setAttribute("data-variant", "primary");
renderTable(btn.dataset.league);
});
}
function renderTable(key) {
const league = LEAGUES[key] || LEAGUES.premier;
const table = document.getElementById("league-table");
if (!table) return;
const head = `<tr><th>#</th><th>Команда</th>${league.cols.map((c) => `<th>${c}</th>`).join("")}</tr>`;
const body = league.rows.map((r, i) => {
const pts = r[1] * 3 + r[2];
return `
<tr class="${i < 3 ? "top" : ""}">
<td><span class="pos">${i + 1}</span></td>
<td>${r[0]}</td>
<td style="text-align:center; font-variant-numeric: tabular-nums;">${pts}</td>
${r.slice(1).map((v) => `<td style="text-align:center; font-variant-numeric: tabular-nums;">${v}</td>`).join("")}
</tr>`;
}).join("");
table.innerHTML = head + `<tbody class="nums">${body}</tbody>`;
}
function renderMatches() {
const strip = document.getElementById("match-strip");
if (!strip) return;
strip.innerHTML = MATCHES.map((m) => `
<div class="match">
<div class="vs"><span>${m.home}</span><span>${m.away}</span></div>
<div class="score">${m.score}</div>
<div class="info">${m.sport} · ${m.time}</div>
</div>
`).join("");
}
function renderArticles() {
const grid = document.getElementById("article-grid");
if (!grid) return;
grid.innerHTML = ARTICLES.map((a) => `
<article class="kt-ai-card article" style="padding: 16px;">
<div class="article-meta">
<span class="kt-ai-chip">${a.sport}</span>
<span>${fmtDate(a.date)}</span>
</div>
<h3>${a.title}</h3>
<p class="excerpt">${a.excerpt}</p>
<a class="kt-ai-link" href="#articles">Читать далее →</a>
</article>
`).join("");
}
document.addEventListener("DOMContentLoaded", () => {
renderSports();
renderLeagueTabs();
renderTable("premier");
renderMatches();
renderArticles();
});