"use strict"; // Mulige visningsmÃ¥ter: 'ranking' eller 'rating' let currentMode = "rating"; // Element references const elements = { searchInput: document.getElementById("search-input"), dropdown: document.getElementById("dropdown"), selectedContainer: document.getElementById("selected-items-popup"), clearBtn: document.getElementById("clear-button"), sendBtn: document.getElementById("send-button"), openPopup: document.getElementById("open-popup"), closePopup: document.getElementById("close-popup"), overlay: document.getElementById("popup-overlay"), selectedLeagueInput: document.getElementById("selected-league-ids"), selectedClubInput: document.getElementById("selected-club-ids"), loadingOverlay: document.getElementById("loading-overlay"), }; const toggleLoading = (show) => { elements.loadingOverlay.classList.toggle("hidden", !show); }; // Popup toggle const togglePopup = (show) => elements.overlay.classList.toggle("hidden", !show); elements.openPopup.addEventListener("click", () => { togglePopup(true); elements.searchInput.focus(); }); elements.closePopup.addEventListener("click", () => togglePopup(false)); elements.sendBtn.addEventListener("click", () => { togglePopup(false); updateSelectedIds(); const params = new URLSearchParams(); if (elements.selectedLeagueInput.value) { params.append("league-ids", elements.selectedLeagueInput.value); } if (elements.selectedClubInput.value) { params.append("club-ids", elements.selectedClubInput.value); } if (currentMode) { params.append("mode", currentMode); } window.history.pushState(null, "", `?${params}`); const streamId = generateUUID(); toggleLoading(true); // ↠vis spinner her fetch( `/historical-opta-power-rankings/api/prefetchSelected?streamId=${streamId}&club-ids=${elements.selectedClubInput.value}&league-ids=${elements.selectedLeagueInput.value}` ) .then((r) => { if (!r.ok) throw new Error("Prefetch failed"); }) .then(() => initializeSSE(streamId)) .catch((err) => { console.error(err); toggleLoading(false); // ↠skjul spinner ved feil }); }); // Utility: update hidden inputs function updateSelectedIds() { const chips = [...elements.selectedContainer.children].filter( (chip) => !chip.classList.contains("ellipsis-chip") ); elements.selectedClubInput.value = chips .filter((c) => c.dataset.itemType === "club") .map((c) => c.dataset.itemId) .join("-"); elements.selectedLeagueInput.value = chips .filter((c) => c.dataset.itemType === "league") .map((c) => c.dataset.itemId) .join("-"); } function generateUUID() { if (window.crypto && typeof crypto.randomUUID === "function") { return crypto.randomUUID(); } else { // Fallback-løsning return fallbackUUID(); } } function fallbackUUID() { // Generer RFC4122 v4 UUID return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => { const r = (Math.random() * 16) | 0; const v = c === "x" ? r : (r & 0x3) | 0x8; return v.toString(16); }); } // Show up to 20 chips, add ellipsis if more function refreshChipDisplay() { const chips = [...elements.selectedContainer.children]; // Remove old ellipsis const old = elements.selectedContainer.querySelector(".ellipsis-chip"); old?.remove(); chips.forEach((chip, i) => (chip.style.display = i < 20 ? "flex" : "none")); if (chips.length > 20) { const more = document.createElement("div"); more.className = "selected-item ellipsis-chip"; more.innerHTML = `<span>...${chips.length - 20} more</span>`; elements.selectedContainer.append(more); } } // Clear all selections elements.clearBtn.addEventListener("click", () => { elements.selectedContainer.innerHTML = ""; elements.searchInput.focus(); updateSelectedIds(); refreshChipDisplay(); }); elements.searchInput.addEventListener("input", handleSearchInput); document.addEventListener("click", (e) => { if ( !elements.dropdown.contains(e.target) && e.target !== elements.searchInput ) { elements.searchInput.focus(); elements.dropdown.style.display = "none"; } }); // Create <img> with fallback const createImage = (id, name, cls) => { const img = new Image(); img.className = cls; img.alt = `${name} logo`; img.src = `https://file.mackolikfeeds.com/teams/${id}`; img.onerror = () => (img.src = `https://omo.akamai.opta.net/image.php?secure=true&h=omo.akamai.opta.net&sport=football&entity=team&description=badges&dimensions=150&id=${id}`); return img; }; // Add a chip for selected item function addChip({ id, type, contestantId, name }) { // skip duplicates if ( [...elements.selectedContainer.children].some( (c) => c.dataset.itemId === String(id) && c.dataset.itemType === type ) ) return; const chip = document.createElement("div"); chip.className = "selected-item"; chip.dataset.itemId = id; chip.dataset.itemType = type; chip.append(createImage(contestantId, name, "dropdown-icon")); chip.append( Object.assign(document.createElement("span"), { textContent: name }) ); const btn = Object.assign(document.createElement("button"), { type: "button", className: "chip-close", innerHTML: "×", }); btn.addEventListener("click", (e) => { elements.searchInput.focus(); e.stopPropagation(); chip.remove(); updateSelectedIds(); refreshChipDisplay(); }); chip.append(btn); elements.selectedContainer.prepend(chip); updateSelectedIds(); refreshChipDisplay(); } // Build dropdown item function makeDropdownItem(item) { const div = document.createElement("div"); div.className = "dropdown-item"; div.dataset.itemId = item.id; div.dataset.itemType = item.type; div.append(createImage(item.contestantId, item.name, "dropdown-icon")); div.append( Object.assign(document.createElement("span"), { textContent: item.name, }) ); div.addEventListener("click", () => { addChip(item); // elements.searchInput.value = ""; elements.searchInput.focus(); // elements.dropdown.style.display = "none"; }); return div; } // Handle search input and show filtered function handleSearchInput() { const q = elements.searchInput.value.trim(); const results = !q ? [] : filterData(q); elements.dropdown.innerHTML = ""; if (!results.length) { elements.dropdown.style.display = "none"; return; } elements.dropdown.style.display = "block"; results.forEach((item) => elements.dropdown.append(makeDropdownItem(item))); } // Merge and filter items by searchName function filterData(query) { const q = transliterate(query.toLowerCase()); const items = [ ...allClubs.map((c) => ({ ...c, type: "club" })), ...allLeagues.map((l) => ({ ...l, type: "league" })), ]; return items .filter((i) => i.searchName.includes(q)) .sort( (a, b) => (a.latestRanking || a.bestNewestClubRanking) - (b.latestRanking || b.bestNewestClubRanking) ) .slice(0, 20); } // --- Legg inn etter let allClubs = …; let allLeagues = …; --- /** * Henter valgt liste fra URL og rendrer chips */ function loadSelectedFromParams() { const params = new URLSearchParams(window.location.search); let leagueIds = params.get("league-ids")?.split("-").filter(Boolean) || []; const clubIds = params.get("club-ids")?.split("-").filter(Boolean) || []; // Set cookie for mode document.cookie = `mode=${currentMode}; path=/historical-opta-power-rankings; SameSite=Strict`; // If no league-ids or club-ids are in the URL, use selectedLeagues if (leagueIds.length === 0 && clubIds.length === 0) { leagueIds = selectedLeagues || []; // Ensure selectedLeagues is not null const params = new URLSearchParams(); params.set("league-ids", leagueIds.join("-")); params.set("mode", currentMode); window.history.replaceState( null, "", `/historical-opta-power-rankings?${params}` ); } // Render chips for each league-id leagueIds.forEach((id) => { const league = allLeagues.find((l) => String(l.id) === id); if (league) { addChip({ id: league.id, type: "league", contestantId: league.contestantId, name: league.name, }); } }); // Render chips for each club-id clubIds.forEach((id) => { const club = allClubs.find((c) => String(c.id) === id); if (club) { addChip({ id: club.id, type: "club", contestantId: club.contestantId, name: club.name, }); } }); } const params = new URLSearchParams(); currentMode = params.get("mode") || document.cookie .split("; ") .find((row) => row.startsWith("mode=")) ?.split("=")[1] || currentMode; // Kjør pÃ¥ page load window.addEventListener("DOMContentLoaded", () => { loadSelectedFromParams(); }); // Update button text based on screen width function updateButtonText() { if (window.innerWidth < 600) { elements.openPopup.innerText = "Filter"; } else { elements.openPopup.innerText = "Filter selection"; } } // Add event listener for window resize window.addEventListener("resize", updateButtonText); // Initial call to set the correct text on page load updateButtonText();