Skip to content

Commit

Permalink
Merge pull request #8 from donarbl/branch-500
Browse files Browse the repository at this point in the history
LONDON| DONARA BLANC | TV PROJECT SHOW | LEVEL 500
donarbl authored Jan 17, 2025
2 parents 09cba16 + 5d7e506 commit e3580f0
Showing 3 changed files with 146 additions and 68 deletions.
37 changes: 18 additions & 19 deletions index.html
Original file line number Diff line number Diff line change
@@ -3,38 +3,37 @@
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>TV Show Project |Donara Blanc (donarbl)</title>
<title>TV Show Project | Donara Blanc (donarbl)</title>
<link href="style.css" rel="stylesheet" />
<link rel="icon" href="/favicon.ico" type="image/x-icon" />
</head>

<body>

<header>
<div class="container">
<h1>TV Series Episodes</h1>
<input type="text" id="search-box" placeholder="Search episodes..." />
<h1>TV Series Shows and Episodes</h1>
<input type="text" id="show-search" placeholder="Search shows..." />
<select id="show-selector">
<option value="">Select a Show</option>
</select>
<div id="episode-controls" style="display: none;">
<input type="text" id="episode-search" placeholder="Search episodes..." />
<select id="episode-selector">
<option value="">Select an Episode</option>
</select>
<p id="search-result"></p>
<select id ="show-selector">
<option value ="">Select a Show></option>
</select>
</div>
</header>

<main class="container">
<div id="episodes-grid" class="episodes-grid">
<!-- Episodes will be inserted here -->
<button id="back-to-shows">Back to Shows</button>
</div>
</div>
</main>

<footer>
</header>
<main class="container">
<div id="shows-grid" class="shows-grid"></div>
<div id="episodes-grid" class="episodes-grid" style="display: none;"></div>
</main>
<footer>
<div class="container">
<p>&copy; 2024 TV Series Episodes. All rights reserved.</p>
<p>&copy; 2025 TV Series Shows and Episodes. All rights reserved.</p>
</div>
</footer>
</footer>
<script src="script.js"></script>
</body>
</html>
106 changes: 85 additions & 21 deletions script.js
Original file line number Diff line number Diff line change
@@ -6,26 +6,63 @@ function padNumber(number) {
return number.toString().padStart(2, '0');
}

function generateShowHTML(show) {
return `
<article class="show-card" data-show-id="${show.id}">
<img src="${show.image?.medium || 'https://via.placeholder.com/210x295'}" alt="${show.name}">
<div class="show-content">
<h2>${show.name}</h2>
<p><strong>Genres:</strong> ${show.genres.join(', ')}</p>
<p><strong>Status:</strong> ${show.status}</p>
<p><strong>Rating:</strong> ${show.rating.average || 'N/A'}</p>
<p><strong>Runtime:</strong> ${show.runtime} minutes</p>
<p>${show.summary || 'No description available.'}</p>
</div>
</article>`;
}

function generateEpisodeHTML(episode) {
const episodeNumber = `S${padNumber(episode.season)}E${padNumber(episode.number)}`;
return `
<article class="episode-card">
<div class="episode-badge">${episodeNumber}</div>
<img src="${episode.image?.medium || 'https://via.placeholder.com/210x295'}" alt="${episode.name}">
<div class="episode-content">
<h2>${episode.name}</h2>
<p>${episode.summary || 'No description available.'}</p>
</div>
<article class="episode-card" data-episode-id="${episode.id}">
<div class="episode-badge">${episodeNumber}</div>
<img src="${episode.image?.medium || 'https://via.placeholder.com/210x295'}" alt="${episode.name}">
<div class="episode-content">
<h2>${episode.name}</h2>
<p>${episode.summary || 'No description available.'}</p>
<a href="https://www.tvmaze.com/episodes/${episode.id}" target="_blank">View on TV Maze</a>
</div>
</article>`;
}

function renderShows(showsToDisplay) {
const showsGrid = document.getElementById('shows-grid');
showsGrid.innerHTML = showsToDisplay.map(generateShowHTML).join('');
showsGrid.style.display = 'grid';
document.getElementById('episodes-grid').style.display = 'none';
document.getElementById('episode-controls').style.display = 'none';
}

function renderEpisodes(episodesToDisplay) {
const episodesGrid = document.getElementById('episodes-grid');
episodesGrid.innerHTML = episodesToDisplay.map(generateEpisodeHTML).join('');
episodesGrid.style.display = 'grid';
document.getElementById('shows-grid').style.display = 'none';
document.getElementById('episode-controls').style.display = 'block';
const searchResult = document.getElementById('search-result');
searchResult.textContent = `Showing ${episodesToDisplay.length} out of ${allEpisodes.length} episodes`;
}

function filterShows(event) {
const searchTerm = event.target.value.toLowerCase();
const filteredShows = allShows.filter(show =>
show.name.toLowerCase().includes(searchTerm) ||
show.genres.some(genre => genre.toLowerCase().includes(searchTerm)) ||
(show.summary && show.summary.toLowerCase().includes(searchTerm))
);
renderShows(filteredShows);
}

function filterEpisodes(event) {
const searchTerm = event.target.value.toLowerCase();
const filteredEpisodes = allEpisodes.filter(episode =>
@@ -91,39 +128,66 @@ function populateShowSelector(shows) {
});
}

async function handleShowSelection(event) {
const selectedShowId = event.target.value;
if (selectedShowId) {
async function handleShowSelection(showId) {
if (showId) {
try {
allEpisodes = await fetchEpisodes(selectedShowId);
allEpisodes = await fetchEpisodes(showId);
renderEpisodes(allEpisodes);
populateEpisodeSelector();
} catch (error) {
const episodesGrid = document.getElementById('episodes-grid');
episodesGrid.innerHTML = `<p class="error">Error loading episodes: ${error.message}</p>`;
}
} else {
allEpisodes = [];
renderEpisodes([]);
populateEpisodeSelector();
renderShows(allShows);
}
}

function handleBackToShows() {
renderShows(allShows);
}

function handleEpisodeClick(event) {
const episodeLink = event.target.closest('a[href^="https://www.tvmaze.com/episodes/"]');
if (episodeLink) {
event.preventDefault();
window.open(episodeLink.href, '_blank');
}
}

document.addEventListener('DOMContentLoaded', async () => {
try {
const shows = await fetchShows();
populateShowSelector(shows);
allShows = await fetchShows();
renderShows(allShows);
populateShowSelector(allShows);

const showSelector = document.getElementById('show-selector');
showSelector.addEventListener('change', handleShowSelection);
showSelector.addEventListener('change', (event) => handleShowSelection(event.target.value));

const showSearch = document.getElementById('show-search');
showSearch.addEventListener('input', filterShows);

const searchBox = document.getElementById('search-box');
searchBox.addEventListener('input', filterEpisodes);
const episodeSearch = document.getElementById('episode-search');
episodeSearch.addEventListener('input', filterEpisodes);

const episodeSelector = document.getElementById('episode-selector');
episodeSelector.addEventListener('change', handleEpisodeSelection);
} catch (error) {

const showsGrid = document.getElementById('shows-grid');
showsGrid.addEventListener('click', (event) => {
const showCard = event.target.closest('.show-card');
if (showCard) {
handleShowSelection(showCard.dataset.showId);
}
});

const episodesGrid = document.getElementById('episodes-grid');
episodesGrid.innerHTML = `<p class="error">Error loading shows: ${error.message}</p>`;
episodesGrid.addEventListener('click', handleEpisodeClick);

const backToShowsButton = document.getElementById('back-to-shows');
backToShowsButton.addEventListener('click', handleBackToShows);
} catch (error) {
const showsGrid = document.getElementById('shows-grid');
showsGrid.innerHTML = `<p class="error">Error loading shows: ${error.message}</p>`;
}
});
71 changes: 43 additions & 28 deletions style.css
Original file line number Diff line number Diff line change
@@ -33,7 +33,7 @@ header h1 {
}

/* Search Box */
#search-box, #show-selector {
#search-box, #show-selector, #show-search, #episode-search {
width: 100%;
max-width: 400px;
padding: 5px 5px;
@@ -47,20 +47,20 @@ header h1 {
transition: all 0.3s ease;
}

#search-box:focus {
#search-box:focus, #show-search:focus, #episode-search:focus {
border-color: #3498db;
box-shadow: 0 4px 10px rgba(52, 152, 219, 0.3);
outline: none;
background-color: #fff;
}

#search-box::placeholder {
#search-box::placeholder, #show-search::placeholder, #episode-search::placeholder {
color: #aaa;
font-style: italic;
}

/* Episode Selector */
#episode-selector {
#episode-selector, #show-selector {
width: 100%;
max-width: 400px;
padding: 5px 5px;
@@ -78,38 +78,38 @@ header h1 {
transition: all 0.3s ease;
}

#episode-selector:focus {
#episode-selector:focus, #show-selector:focus {
border-color: #3498db;
box-shadow: 0 4px 10px rgba(52, 152, 219, 0.3);
outline: none;
background-color: #fff;
}


/* Episodes Grid */
.episodes-grid {
.episodes-grid, .shows-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 2rem;
padding: 2rem 0;
}

/* Episode Card */
.episode-card {
.episode-card, .show-card {
background: white;
border-radius: 10px;
overflow: hidden;
position: relative;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
transition: transform 0.3s ease, box-shadow 0.3s ease;
cursor: pointer;
}

.episode-card:hover {
.episode-card:hover, .show-card:hover {
transform: translateY(-5px);
box-shadow: 0 5px 20px rgba(0, 0, 0, 0.2);
}

.episode-card img {
.episode-card img, .show-card img {
width: 100%;
height: 200px;
object-fit: cover;
@@ -128,17 +128,17 @@ header h1 {
font-size: 0.9rem;
}

.episode-content {
.episode-content, .show-content {
padding: 1.5rem;
}

.episode-content h2 {
.episode-content h2, .show-content h2 {
font-size: 1.4rem;
margin-bottom: 1rem;
color: #2c3e50;
}

.episode-content p {
.episode-content p, .show-content p {
color: #666;
font-size: 0.95rem;
display: -webkit-box;
@@ -156,42 +156,57 @@ footer {
text-align: center;
}

/* Back to Shows Button */
#back-to-shows {
background-color: #3498db;
color: white;
border: none;
padding: 0.5rem 1rem;
border-radius: 5px;
cursor: pointer;
transition: background-color 0.3s ease;
}

#back-to-shows:hover {
background-color: #2980b9;
}

/* Responsive Design */
@media (max-width: 768px) {
header h1 {
font-size: 2rem;
font-size: 2rem;
}

.episodes-grid {
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 1.5rem;
padding: 1rem;
.episodes-grid, .shows-grid {
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 1.5rem;
padding: 1rem;
}

.episode-content {
padding: 1rem;
.episode-content, .show-content {
padding: 1rem;
}

.episode-content h2 {
font-size: 1.2rem;
.episode-content h2, .show-content h2 {
font-size: 1.2rem;
}
}

@media (max-width: 480px) {
.container {
padding: 0 15px;
padding: 0 15px;
}

header {
padding: 1.5rem 0;
padding: 1.5rem 0;
}

header h1 {
font-size: 1.8rem;
font-size: 1.8rem;
}

.episodes-grid {
grid-template-columns: 1fr;
gap: 1rem;
.episodes-grid, .shows-grid {
grid-template-columns: 1fr;
gap: 1rem;
}
}

0 comments on commit e3580f0

Please sign in to comment.