web: update web interface for tv eps missing date
Local Docker Build (Dev) / build-dev (push) Successful in 4s

This commit is contained in:
2025-10-15 09:55:28 -04:00
parent 913aed1f60
commit 909df0cc83
4 changed files with 130 additions and 8 deletions
+64 -6
View File
@@ -114,13 +114,16 @@ async function loadDashboard() {
function updateDashboardStats() {
if (!dashboardData) return;
// Debug: Log dashboard data to see what fields are available
console.log('Dashboard data received:', dashboardData);
const moviesTotal = dashboardData.movies_total || 0;
const moviesWithDates = dashboardData.movies_with_dates || 0;
const moviesWithoutDates = dashboardData.movies_without_dates || 0;
const moviesWithoutDates = dashboardData.movies_without_dates || (moviesTotal - moviesWithDates);
const episodesTotal = dashboardData.episodes_total || 0;
const episodesWithDates = dashboardData.episodes_with_dates || 0;
const episodesWithoutDates = dashboardData.episodes_without_dates || 0;
const episodesWithoutDates = dashboardData.episodes_without_dates || (episodesTotal - episodesWithDates);
document.getElementById('movies-total').textContent = moviesTotal;
document.getElementById('movies-with-dates').textContent = `${moviesWithDates} with dates, ${moviesWithoutDates} without`;
@@ -429,14 +432,39 @@ async function viewSeriesEpisodes(imdbId) {
}
function showEpisodesModal(data) {
// Calculate statistics
const totalEpisodes = data.episodes.length;
const episodesWithDates = data.episodes.filter(ep => ep.dateadded && ep.dateadded.trim() !== '').length;
const episodesWithoutDates = totalEpisodes - episodesWithDates;
const episodesWithVideo = data.episodes.filter(ep => ep.has_video_file).length;
const modalHtml = `
<div class="modal active" id="episodes-modal">
<div class="modal-content" style="max-width: 800px;">
<div class="modal-content" style="max-width: 900px;">
<div class="modal-header">
<h3>${escapeHtml(data.series.title)} - Episodes</h3>
<button class="modal-close" onclick="closeEpisodesModal()">&times;</button>
</div>
<div class="modal-body">
<div class="episode-stats" style="display: flex; gap: 20px; margin-bottom: 20px; padding: 15px; background: #f8f9fa; border-radius: 5px;">
<div><strong>Total Episodes:</strong> ${totalEpisodes}</div>
<div><strong>With Dates:</strong> ${episodesWithDates}</div>
<div style="color: #dc3545;"><strong>Missing Dates:</strong> ${episodesWithoutDates}</div>
<div><strong>With Video:</strong> ${episodesWithVideo}</div>
</div>
<div class="episode-filters" style="margin-bottom: 15px;">
<label style="margin-right: 15px;">
<input type="radio" name="episode-filter" value="all" checked onchange="filterEpisodes('all')"> Show All
</label>
<label style="margin-right: 15px;">
<input type="radio" name="episode-filter" value="missing" onchange="filterEpisodes('missing')"> Missing Dates Only
</label>
<label>
<input type="radio" name="episode-filter" value="has-dates" onchange="filterEpisodes('has-dates')"> With Dates Only
</label>
</div>
<div class="table-container">
<table class="data-table">
<thead>
@@ -449,18 +477,24 @@ function showEpisodesModal(data) {
<th>Actions</th>
</tr>
</thead>
<tbody>
<tbody id="episodes-table-body">
${data.episodes.map(episode => {
const dateadded = episode.dateadded ? formatDateTime(episode.dateadded) : '';
const hasVideoBadge = episode.has_video_file ?
'<span class="badge badge-success">Yes</span>' :
'<span class="badge badge-secondary">No</span>';
const missingDate = !episode.dateadded || episode.dateadded.trim() === '';
const rowClass = missingDate ? 'missing-date-row' : '';
const dateCell = missingDate ?
'<td style="background-color: #ffebee; color: #c62828;"><strong>MISSING</strong></td>' :
`<td>${dateadded}</td>`;
return `
<tr>
<tr class="${rowClass}" data-has-date="${!missingDate}">
<td>S${episode.season.toString().padStart(2, '0')}E${episode.episode.toString().padStart(2, '0')}</td>
<td>${episode.aired || '-'}</td>
<td>${dateadded || '-'}</td>
${dateCell}
<td><span class="badge badge-secondary">${episode.source || 'Unknown'}</span></td>
<td>${hasVideoBadge}</td>
<td>
@@ -482,6 +516,30 @@ function showEpisodesModal(data) {
document.body.insertAdjacentHTML('beforeend', modalHtml);
}
function filterEpisodes(filterType) {
const rows = document.querySelectorAll('#episodes-table-body tr');
rows.forEach(row => {
const hasDate = row.getAttribute('data-has-date') === 'true';
let shouldShow = true;
switch (filterType) {
case 'missing':
shouldShow = !hasDate;
break;
case 'has-dates':
shouldShow = hasDate;
break;
case 'all':
default:
shouldShow = true;
break;
}
row.style.display = shouldShow ? '' : 'none';
});
}
function closeEpisodesModal() {
const modal = document.getElementById('episodes-modal');
if (modal) {