From 8b9b780a8d9d53267d68b55d3bc45564d0494a6a Mon Sep 17 00:00:00 2001 From: vmoratti Date: Sat, 15 Aug 2026 22:04:29 +0100 Subject: [PATCH 01/32] add name to the title --- index.html | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/index.html b/index.html index 9a400d1..67d4ca2 100644 --- a/index.html +++ b/index.html @@ -3,7 +3,7 @@ - TV Show Project | My Name (My GitHub username) + TV Show Project | Vito Moratti (vmoratti) @@ -11,11 +11,15 @@
+ - + From fbd0f15c83509a82e7db9e8495abc62c648d649a Mon Sep 17 00:00:00 2001 From: vmoratti Date: Sun, 16 Aug 2026 11:14:06 +0100 Subject: [PATCH 02/32] write makePageForEpisodes() function --- script.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/script.js b/script.js index 87a7de8..8ff20f3 100644 --- a/script.js +++ b/script.js @@ -7,6 +7,17 @@ function setup() { function makePageForEpisodes(episodeList) { const rootElem = document.getElementById("root"); rootElem.textContent = `Got ${episodeList.length} episode(s)`; + const template = document.getElementById("episode-template"); + const paddedSeason = (season) => season.toString().padStart(2, "0"); + const paddedEpisode = (episode) => episode.toString().padStart(2, "0"); + episodeList.forEach((episode) => { + const clone = template.content.cloneNode(true); + clone.querySelector("h3").textContent = `${episode.name} - S${paddedSeason(episode.season)}E${paddedEpisode(episode.number)}`; + clone.querySelector("img").src = episode.image.medium; + clone.querySelector("p").textContent = episode.summary; + rootElem.appendChild(clone); + }); } + window.onload = setup; From 1e94c0cabaa44dcd1560dc95d5171a9039020fd3 Mon Sep 17 00:00:00 2001 From: vmoratti Date: Sun, 16 Aug 2026 11:14:39 +0100 Subject: [PATCH 03/32] create template --- index.html | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/index.html b/index.html index 67d4ca2..08a7446 100644 --- a/index.html +++ b/index.html @@ -11,9 +11,12 @@
- diff --git a/script.js b/script.js index 2d5fe6d..d28930b 100644 --- a/script.js +++ b/script.js @@ -27,7 +27,7 @@ function makePageForEpisodes(episodeList) { const clone = template.content.cloneNode(true); clone.querySelector("h3").textContent = `${episode.name} - S${paddedSeason(episode.season)}E${paddedEpisode(episode.number)}`; clone.querySelector("img").src = episode.image.medium; - clone.querySelector("#synopsis").textContent = episodeSynopsis(episode.summary); + clone.querySelector(".synopsis").textContent = episodeSynopsis(episode.summary); rootElem.appendChild(clone); }); } diff --git a/style.css b/style.css index 666a003..1146118 100644 --- a/style.css +++ b/style.css @@ -5,21 +5,34 @@ gap: 20px; } section { - - - border-style: outset; - padding: 10px; - margin: 10px; + border: 1px solid #ccc; + border-radius: 8px; + padding: 16px; + margin: 0; } h3 { - font-size: 1.5em; - margin: 0; + font-size: 1em; + margin: -16px -16px 16px; + padding: 12px; text-align: center; - + border: 1px solid #999; + border-radius: 8px; } + + #title { border-style: solid; border-width: 2px; } -/*display: flex; - flex-direction: column; */ \ No newline at end of file +img { + width: 100%; + height: 150px; + object-fit: cover; +} +.synopsis { + font-size: 1rem; + line-height: 1.4; +} +footer { + text-align: right; +} From 27f53acc51ac39075d92b86ba5e3806641462b43 Mon Sep 17 00:00:00 2001 From: vmoratti Date: Mon, 17 Aug 2026 11:38:29 +0100 Subject: [PATCH 09/32] level 100 complete --- index.html | 2 ++ script.js | 10 +++++----- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/index.html b/index.html index 3653d5b..925db2b 100644 --- a/index.html +++ b/index.html @@ -11,6 +11,8 @@
+ + -

© TV. All rights reserved.

diff --git a/script.js b/script.js index 0f9cbcd..7b79c24 100644 --- a/script.js +++ b/script.js @@ -1,13 +1,18 @@ -/* +/* For each episode, at least following must be displayed: The name of the episode The season number The episode number The medium-sized image for the episode The summary text of the episode - */ +*/ + +const paddedSeason = (season) => season.toString().padStart(2, "0"); + +const paddedEpisode = (episode) => episode.toString().padStart(2, "0"); + +const episodeSynopsis = (summary) => summary.replace(/<[^>]*>/g, ""); -//You can edit ALL of the code here function setup() { const allEpisodes = getAllEpisodes(); makePageForEpisodes(allEpisodes); @@ -16,9 +21,6 @@ function setup() { function makePageForEpisodes(episodeList) { const rootElem = document.getElementById("root"); const template = document.getElementById("episode-template"); - const paddedSeason = (season) => season.toString().padStart(2, "0"); - const paddedEpisode = (episode) => episode.toString().padStart(2, "0"); - const episodeSynopsis = (summary) => summary.replace(/<[^>]*>/g, ""); // Remove HTML tags from summary const footer = document.querySelector("footer"); footer.innerHTML = `© TV. All rights reserved. TVMaze.com`; // Add copyright notice with link to TVMaze.com episodeList.forEach((episode) => { From 384ba7304bb4efbb52c8691cd562fd6d4306e659 Mon Sep 17 00:00:00 2001 From: cyf Date: Tue, 18 Aug 2026 14:59:22 +0100 Subject: [PATCH 13/32] Refactor episode rendering --- script.js | 40 ++++++++++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/script.js b/script.js index 7b79c24..591f42b 100644 --- a/script.js +++ b/script.js @@ -15,24 +15,40 @@ const episodeSynopsis = (summary) => summary.replace(/<[^>]*>/g, ""); function setup() { const allEpisodes = getAllEpisodes(); + + setupFooter(); makePageForEpisodes(allEpisodes); } +function setupFooter() { + const footer = document.querySelector("footer"); + + footer.innerHTML = `© TV. All rights reserved. TVMaze.com`; +} + +function createEpisodeElement(episode) { + const template = document.getElementById("episode-template"); + const clone = template.content.cloneNode(true); + + clone.querySelector(".title").textContent = + `${episode.name} - S${paddedSeason(episode.season)}E${paddedEpisode(episode.number)}`; + + clone.querySelector("img").src = episode.image.medium; + + clone.querySelector(".synopsis").textContent = episodeSynopsis( + episode.summary, + ); + + return clone; +} + function makePageForEpisodes(episodeList) { const rootElem = document.getElementById("root"); - const template = document.getElementById("episode-template"); - const footer = document.querySelector("footer"); - footer.innerHTML = `© TV. All rights reserved. TVMaze.com`; // Add copyright notice with link to TVMaze.com + episodeList.forEach((episode) => { - const clone = template.content.cloneNode(true); - clone.querySelector("h3").textContent = - `${episode.name} - S${paddedSeason(episode.season)}E${paddedEpisode(episode.number)}`; - clone.querySelector("img").src = episode.image.medium; - clone.querySelector(".synopsis").textContent = episodeSynopsis( - episode.summary, - ); - rootElem.appendChild(clone); + const episodeElement = createEpisodeElement(episode); + rootElem.appendChild(episodeElement); }); } -window.onload = setup; +window.onload = setup; \ No newline at end of file From fc5398331e82e91fcc1c653a438a98a108a487a8 Mon Sep 17 00:00:00 2001 From: cyf Date: Tue, 18 Aug 2026 15:48:55 +0100 Subject: [PATCH 14/32] Add episode search interface --- index.html | 43 +++++++++++++++++++++++++++++-------------- 1 file changed, 29 insertions(+), 14 deletions(-) diff --git a/index.html b/index.html index 6fd84c7..8499485 100644 --- a/index.html +++ b/index.html @@ -9,21 +9,36 @@ -
-
- - +
+ + + + +

+
+ +
+ + +
+

Film title

+ Film poster +

Synopsis

+
+ +
-

© TV. All rights reserved.

-
- +

© TV. All rights reserved.

+ @@ -31,4 +46,4 @@

Film title

- + \ No newline at end of file From ab66d54aadc1f3206fa665ba08b6138733b35fea Mon Sep 17 00:00:00 2001 From: cyf Date: Tue, 18 Aug 2026 15:49:04 +0100 Subject: [PATCH 15/32] Implement live episode search --- script.js | 80 ++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 64 insertions(+), 16 deletions(-) diff --git a/script.js b/script.js index 591f42b..c9cbdd3 100644 --- a/script.js +++ b/script.js @@ -1,53 +1,101 @@ /* -For each episode, at least following must be displayed: -The name of the episode -The season number -The episode number -The medium-sized image for the episode -The summary text of the episode +For each episode, at least the following must be displayed: +- The name of the episode +- The season number +- The episode number +- The medium-sized image for the episode +- The summary text of the episode */ const paddedSeason = (season) => season.toString().padStart(2, "0"); const paddedEpisode = (episode) => episode.toString().padStart(2, "0"); -const episodeSynopsis = (summary) => summary.replace(/<[^>]*>/g, ""); +function getEpisodeCode(episode) { + return `S${paddedSeason(episode.season)}E${paddedEpisode(episode.number)}`; +} + +function getEpisodeTitle(episode) { + return `${getEpisodeCode(episode)} - ${episode.name}`; +} + +function cleanSummary(summary) { + return summary.replace(/<[^>]*>/g, ""); +} function setup() { const allEpisodes = getAllEpisodes(); setupFooter(); makePageForEpisodes(allEpisodes); + setupSearch(allEpisodes); } function setupFooter() { const footer = document.querySelector("footer"); - footer.innerHTML = `© TV. All rights reserved. TVMaze.com`; + footer.innerHTML = + '© TV. All rights reserved. TVMaze.com'; } function createEpisodeElement(episode) { const template = document.getElementById("episode-template"); - const clone = template.content.cloneNode(true); + const episodeElement = template.content.cloneNode(true); - clone.querySelector(".title").textContent = - `${episode.name} - S${paddedSeason(episode.season)}E${paddedEpisode(episode.number)}`; + episodeElement.querySelector(".title").textContent = + getEpisodeTitle(episode); - clone.querySelector("img").src = episode.image.medium; + episodeElement.querySelector("img").src = episode.image.medium; + episodeElement.querySelector("img").alt = `${episode.name} poster`; - clone.querySelector(".synopsis").textContent = episodeSynopsis( + episodeElement.querySelector(".synopsis").textContent = cleanSummary( episode.summary, ); - return clone; + return episodeElement; } function makePageForEpisodes(episodeList) { - const rootElem = document.getElementById("root"); + const rootElement = document.getElementById("root"); + + rootElement.innerHTML = ""; episodeList.forEach((episode) => { const episodeElement = createEpisodeElement(episode); - rootElem.appendChild(episodeElement); + rootElement.appendChild(episodeElement); + }); +} + +function searchEpisodes(searchTerm, episodeList) { + const normalizedSearchTerm = searchTerm.toLowerCase().trim(); + + return episodeList.filter((episode) => { + const episodeName = episode.name.toLowerCase(); + const episodeSummary = episode.summary.toLowerCase(); + + return ( + episodeName.includes(normalizedSearchTerm) || + episodeSummary.includes(normalizedSearchTerm) + ); + }); +} + +function setupSearch(allEpisodes) { + const searchInput = document.getElementById("search-input"); + const episodeCount = document.getElementById("episode-count"); + + function updateSearchResults(searchTerm) { + const filteredEpisodes = searchEpisodes(searchTerm, allEpisodes); + + makePageForEpisodes(filteredEpisodes); + + episodeCount.textContent = `${filteredEpisodes.length} episodes found`; + } + + updateSearchResults(""); + + searchInput.addEventListener("input", (event) => { + updateSearchResults(event.target.value); }); } From a76d795bdde5693c4bdf7d23bcc8b24592b9eaa7 Mon Sep 17 00:00:00 2001 From: cyf Date: Tue, 18 Aug 2026 15:49:11 +0100 Subject: [PATCH 16/32] Style search interface and episode grid --- style.css | 161 ++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 144 insertions(+), 17 deletions(-) diff --git a/style.css b/style.css index 6d92f91..b1062e6 100644 --- a/style.css +++ b/style.css @@ -1,38 +1,165 @@ -#root { - display: grid; - grid-template-columns: 1fr 1fr 1fr; +body { + margin: 0; + padding: 20px; + font-family: Arial, sans-serif; + background: #f5f5f5; color: rgb(33, 31, 31); - gap: 20px; } -section { - border: 1px solid #ccc; + +/* Search */ + +.search-panel { + max-width: 700px; + margin: 0 auto 30px; + padding: 24px; + background: #ffffff; + border: 1px solid #ddd; + border-radius: 12px; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08); +} + +.search-panel label { + display: block; + margin-bottom: 10px; + font-size: 1.1rem; + font-weight: bold; +} + +.search-box { + display: flex; + align-items: center; + border: 2px solid #ccc; border-radius: 8px; - padding: 16px; + padding: 0 12px; + background: #ffffff; + transition: + border-color 0.2s ease, + box-shadow 0.2s ease; +} + +.search-box:focus-within { + border-color: #555; + box-shadow: 0 0 0 3px rgba(0, 0, 0, 0.08); +} + +.search-icon { + margin-right: 8px; + font-size: 1.4rem; +} + +#search-input { + width: 100%; + padding: 12px 0; + border: none; + outline: none; + background: transparent; + font-size: 1rem; +} + +#search-input::placeholder { + color: #888; +} + +#episode-count { + margin: 12px 0 0; + color: #666; + font-size: 0.95rem; +} + +/* Episode grid */ + +#root { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 24px; + max-width: 1400px; + margin: 0 auto; +} + +/* Episode cards */ + +.episode { margin: 0; + padding: 16px; + background: #ffffff; + border: 1px solid #ddd; + border-radius: 12px; + box-shadow: 0 3px 10px rgba(0, 0, 0, 0.06); + transition: + transform 0.2s ease, + box-shadow 0.2s ease; } -h3 { - font-size: 1em; - margin: -16px -16px 16px; - padding: 12px; - text-align: center; - border: 1px solid #999; - border-radius: 8px; + +.episode:hover { + transform: translateY(-3px); + box-shadow: 0 8px 20px rgba(0, 0, 0, 0.1); } +/* Episode title */ .title { - border-style: solid; - border-width: 2px; + margin: -16px -16px 16px; + padding: 14px; + border-bottom: 1px solid #ddd; + border-radius: 12px 12px 0 0; + background: #f7f7f7; + text-align: center; + font-size: 1rem; } + +/* Episode image */ + img { + display: block; width: 100%; height: 150px; object-fit: cover; + border-radius: 6px; } + +/* Episode summary */ + .synopsis { + margin-bottom: 0; font-size: 1rem; - line-height: 1.4; + line-height: 1.5; } + +/* Footer */ + footer { + max-width: 1400px; + margin: 30px auto 0; text-align: right; + color: #666; } + +/* Tablet */ + +@media (max-width: 900px) { + #root { + grid-template-columns: repeat(2, 1fr); + } +} + +/* Mobile */ + +@media (max-width: 600px) { + body { + padding: 12px; + } + + #root { + grid-template-columns: 1fr; + gap: 18px; + } + + .search-panel { + margin-bottom: 20px; + padding: 18px; + } + + footer { + text-align: center; + } +} \ No newline at end of file From adc1fb8a18b58ebb112e1d5a88158440f1feadde Mon Sep 17 00:00:00 2001 From: cyf Date: Tue, 18 Aug 2026 16:16:33 +0100 Subject: [PATCH 17/32] Fix episode counter layout --- index.html | 32 ++++++-------- script.js | 63 +++++++++++++++++++++++++--- style.css | 120 +++++++++++++++++++++++------------------------------ 3 files changed, 122 insertions(+), 93 deletions(-) diff --git a/index.html b/index.html index 8499485..766e875 100644 --- a/index.html +++ b/index.html @@ -9,30 +9,27 @@ -
- +
+ - +

-
+
- @@ -40,10 +37,7 @@

Film title

© TV. All rights reserved.

- - - \ No newline at end of file diff --git a/script.js b/script.js index c9cbdd3..622ee24 100644 --- a/script.js +++ b/script.js @@ -15,7 +15,11 @@ function getEpisodeCode(episode) { return `S${paddedSeason(episode.season)}E${paddedEpisode(episode.number)}`; } -function getEpisodeTitle(episode) { +function getEpisodeCardTitle(episode) { + return `${episode.name} - ${getEpisodeCode(episode)}`; +} + +function getEpisodeSelectorTitle(episode) { return `${getEpisodeCode(episode)} - ${episode.name}`; } @@ -29,6 +33,7 @@ function setup() { setupFooter(); makePageForEpisodes(allEpisodes); setupSearch(allEpisodes); + setupEpisodeSelector(allEpisodes); } function setupFooter() { @@ -42,11 +47,15 @@ function createEpisodeElement(episode) { const template = document.getElementById("episode-template"); const episodeElement = template.content.cloneNode(true); + episodeElement.querySelector(".episode").id = `episode-${episode.id}`; + episodeElement.querySelector(".title").textContent = - getEpisodeTitle(episode); + getEpisodeCardTitle(episode); - episodeElement.querySelector("img").src = episode.image.medium; - episodeElement.querySelector("img").alt = `${episode.name} poster`; + const image = episodeElement.querySelector("img"); + + image.src = episode.image.medium; + image.alt = `${episode.name} poster`; episodeElement.querySelector(".synopsis").textContent = cleanSummary( episode.summary, @@ -89,7 +98,7 @@ function setupSearch(allEpisodes) { makePageForEpisodes(filteredEpisodes); - episodeCount.textContent = `${filteredEpisodes.length} episodes found`; + episodeCount.textContent = `Displaying ${filteredEpisodes.length}/${allEpisodes.length} episodes.`; } updateSearchResults(""); @@ -99,4 +108,48 @@ function setupSearch(allEpisodes) { }); } +function setupEpisodeSelector(allEpisodes) { + const episodeSelect = document.getElementById("episode-select"); + + allEpisodes.forEach((episode) => { + const option = document.createElement("option"); + + option.value = episode.id; + option.textContent = getEpisodeSelectorTitle(episode); + + episodeSelect.appendChild(option); + }); + + episodeSelect.addEventListener("change", (event) => { + const selectedEpisodeId = Number(event.target.value); + + if (!selectedEpisodeId) { + return; + } + + const selectedEpisode = allEpisodes.find( + (episode) => episode.id === selectedEpisodeId, + ); + + const searchInput = document.getElementById("search-input"); + + searchInput.value = ""; + + makePageForEpisodes(allEpisodes); + + scrollToEpisode(selectedEpisode); + }); +} + +function scrollToEpisode(episode) { + const episodeElement = document.getElementById(`episode-${episode.id}`); + + if (episodeElement) { + episodeElement.scrollIntoView({ + behavior: "smooth", + block: "start", + }); + } +} + window.onload = setup; \ No newline at end of file diff --git a/style.css b/style.css index b1062e6..bb261d7 100644 --- a/style.css +++ b/style.css @@ -6,64 +6,39 @@ body { color: rgb(33, 31, 31); } -/* Search */ +/* Search, selector and counter */ -.search-panel { - max-width: 700px; - margin: 0 auto 30px; - padding: 24px; - background: #ffffff; - border: 1px solid #ddd; - border-radius: 12px; - box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08); -} - -.search-panel label { - display: block; - margin-bottom: 10px; - font-size: 1.1rem; - font-weight: bold; -} - -.search-box { +.controls { display: flex; align-items: center; - border: 2px solid #ccc; - border-radius: 8px; - padding: 0 12px; - background: #ffffff; - transition: - border-color 0.2s ease, - box-shadow 0.2s ease; -} - -.search-box:focus-within { - border-color: #555; - box-shadow: 0 0 0 3px rgba(0, 0, 0, 0.08); + gap: 12px; + margin-bottom: 20px; + width: 100%; } -.search-icon { - margin-right: 8px; - font-size: 1.4rem; +#episode-select { + width: 230px; + padding: 8px; + border: 1px solid #aaa; + border-radius: 4px; + background: white; + font-size: 0.9rem; } #search-input { - width: 100%; - padding: 12px 0; - border: none; - outline: none; - background: transparent; - font-size: 1rem; -} - -#search-input::placeholder { - color: #888; + width: 220px; + padding: 8px; + border: 1px solid #aaa; + border-radius: 0; + font-size: 0.9rem; + box-sizing: border-box; } #episode-count { - margin: 12px 0 0; - color: #666; - font-size: 0.95rem; + margin: 0; + color: #777; + font-size: 0.9rem; + white-space: nowrap; } /* Episode grid */ @@ -82,39 +57,32 @@ body { margin: 0; padding: 16px; background: #ffffff; - border: 1px solid #ddd; - border-radius: 12px; + border: 1px solid #ccc; + border-radius: 10px; box-shadow: 0 3px 10px rgba(0, 0, 0, 0.06); - transition: - transform 0.2s ease, - box-shadow 0.2s ease; -} - -.episode:hover { - transform: translateY(-3px); - box-shadow: 0 8px 20px rgba(0, 0, 0, 0.1); } /* Episode title */ .title { - margin: -16px -16px 16px; + margin: -16px -16px 20px; padding: 14px; - border-bottom: 1px solid #ddd; - border-radius: 12px 12px 0 0; - background: #f7f7f7; + background: #ffffff; + border: 1px solid #999; + border-radius: 10px; text-align: center; font-size: 1rem; + line-height: 1.5; } /* Episode image */ img { display: block; - width: 100%; + width: 70%; height: 150px; + margin: 0 auto 18px; object-fit: cover; - border-radius: 6px; } /* Episode summary */ @@ -123,6 +91,7 @@ img { margin-bottom: 0; font-size: 1rem; line-height: 1.5; + color: #666; } /* Footer */ @@ -130,8 +99,8 @@ img { footer { max-width: 1400px; margin: 30px auto 0; - text-align: right; color: #666; + text-align: right; } /* Tablet */ @@ -140,6 +109,10 @@ footer { #root { grid-template-columns: repeat(2, 1fr); } + + .controls { + flex-wrap: wrap; + } } /* Mobile */ @@ -149,16 +122,25 @@ footer { padding: 12px; } + .controls { + align-items: stretch; + flex-direction: column; + } + + #episode-select, + #search-input { + width: 100%; + } + + #episode-count { + white-space: normal; + } + #root { grid-template-columns: 1fr; gap: 18px; } - .search-panel { - margin-bottom: 20px; - padding: 18px; - } - footer { text-align: center; } From d7325a8af21c5fe776def7d6cabf875d9d736ec4 Mon Sep 17 00:00:00 2001 From: vmoratti Date: Tue, 18 Aug 2026 18:09:48 +0100 Subject: [PATCH 18/32] refactored --- script.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script.js b/script.js index 622ee24..b7c5766 100644 --- a/script.js +++ b/script.js @@ -152,4 +152,4 @@ function scrollToEpisode(episode) { } } -window.onload = setup; \ No newline at end of file +window.onload = setup; // refactored From dae4681c65745df4f4d0635fc22e70e4c77799e9 Mon Sep 17 00:00:00 2001 From: vmoratti Date: Tue, 18 Aug 2026 23:39:39 +0100 Subject: [PATCH 19/32] change setup() function --- script.js | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/script.js b/script.js index b7c5766..81aa495 100644 --- a/script.js +++ b/script.js @@ -26,15 +26,28 @@ function getEpisodeSelectorTitle(episode) { function cleanSummary(summary) { return summary.replace(/<[^>]*>/g, ""); } - function setup() { + fetch("https://api.tvmaze.com/shows/82/episodes") + .then((response) => response.json()) + .then((allEpisodes) => { + setupFooter(); + makePageForEpisodes(allEpisodes); + setupSearch(allEpisodes); + setupEpisodeSelector(allEpisodes); + }) + .catch(() => { + document.getElementById("root").textContent = + "Sorry, we couldn't load the episodes. Please try again later."; + }); +} +/*function setup() { const allEpisodes = getAllEpisodes(); setupFooter(); makePageForEpisodes(allEpisodes); setupSearch(allEpisodes); setupEpisodeSelector(allEpisodes); -} +} */ function setupFooter() { const footer = document.querySelector("footer"); From 186e806ef9a414a22fa36f0c92b7b6edb4994b9d Mon Sep 17 00:00:00 2001 From: vmoratti Date: Tue, 18 Aug 2026 23:40:55 +0100 Subject: [PATCH 20/32] add 'please wait 'message --- index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.html b/index.html index 766e875..06ec842 100644 --- a/index.html +++ b/index.html @@ -24,6 +24,7 @@
+

Loading episodes, please wait...