Files
movie-checklist-zpilpy/index.php
2026-03-27 02:17:43 +00:00

215 lines
10 KiB
PHP

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Watchlist</title>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link href="https://fonts.googleapis.com/css2?family=DM+Sans:ital,opsz,wght@0,9..40,300;0,9..40,400;0,9..40,500;0,9..40,600;0,9..40,700;1,9..40,400&family=DM+Serif+Display:ital@0;1&display=swap" rel="stylesheet" />
<!-- Bootstrap 5 -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" />
<link rel="stylesheet" href="style.css?v=7" />
<script>
// Apply dark mode immediately before render to avoid flash
(function() {
function getCookie(name) {
const match = document.cookie.match(new RegExp('(?:^|; )' + name + '=([^;]*)'));
return match ? decodeURIComponent(match[1]) : null;
}
if (getCookie('theme') === 'dark') {
document.documentElement.classList.add('dark');
}
})();
</script>
</head>
<body>
<!-- Ambient background -->
<div class="ambient">
<div class="ambient-orb orb-1"></div>
<div class="ambient-orb orb-2"></div>
<div class="ambient-orb orb-3"></div>
</div>
<div class="app">
<!-- HEADER -->
<header class="header">
<div class="header-brand">
<span class="header-icon"></span>
<div class="header-text">
<h1 class="header-title">Watchlist</h1>
<p class="header-sub">Your personal streaming guide</p>
</div>
</div>
<div class="header-right">
<!-- Dark mode toggle -->
<button class="theme-toggle" id="themeToggle" aria-label="Toggle dark mode" title="Toggle dark mode">
<!-- Sun icon (shown in dark mode) -->
<svg class="icon-sun" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<circle cx="12" cy="12" r="5"/><line x1="12" y1="1" x2="12" y2="3"/><line x1="12" y1="21" x2="12" y2="23"/>
<line x1="4.22" y1="4.22" x2="5.64" y2="5.64"/><line x1="18.36" y1="18.36" x2="19.78" y2="19.78"/>
<line x1="1" y1="12" x2="3" y2="12"/><line x1="21" y1="12" x2="23" y2="12"/>
<line x1="4.22" y1="19.78" x2="5.64" y2="18.36"/><line x1="18.36" y1="5.64" x2="19.78" y2="4.22"/>
</svg>
<!-- Moon icon (shown in light mode) -->
<svg class="icon-moon" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/>
</svg>
</button>
<button class="btn-primary" id="openAddModal">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg>
Add Title
</button>
</div>
</header>
<!-- STATS -->
<section class="stats">
<div class="stat">
<span class="stat-value" id="statTotal"></span>
<span class="stat-label">Total</span>
</div>
<div class="stat-sep"></div>
<div class="stat">
<span class="stat-value" id="statUnwatched"></span>
<span class="stat-label">To Watch</span>
</div>
<div class="stat-sep"></div>
<div class="stat">
<span class="stat-value" id="statWatched"></span>
<span class="stat-label">Watched</span>
</div>
<div class="stat-sep"></div>
<div class="stat stat-progress">
<div class="progress-track">
<div class="progress-fill" id="progressFill"></div>
</div>
<span class="stat-label" id="statPercent">0% complete</span>
</div>
</section>
<!-- CONTROLS -->
<section class="controls">
<div class="pill-group" id="filterGroup">
<button class="pill" data-filter="all">All</button>
<button class="pill active" data-filter="unwatched">To Watch</button>
<button class="pill" data-filter="watched">Watched</button>
</div>
<div class="pill-group" id="typeGroup">
<button class="type-pill active" data-type="">All</button>
<button class="type-pill" data-type="movie">Movies</button>
<button class="type-pill" data-type="show">Shows</button>
</div>
<div class="pill-group" id="forGroup">
<button class="for-pill active" data-for="">All</button>
<button class="for-pill" data-for="nik">Nik</button>
<button class="for-pill" data-for="tod">Tod</button>
</div>
<div class="search-box">
<svg class="search-icon" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>
<input type="text" class="search-input" id="searchInput" placeholder="Search titles" />
</div>
</section>
<!-- SERVICE ROW -->
<div class="service-row" id="serviceRow"></div>
<!-- LOADING -->
<div class="loading-state" id="loadingState" style="display:none">
<div class="spinner"></div>
</div>
<!-- GRID -->
<div class="grid" id="grid"></div>
</div><!-- /.app -->
<!-- ADD / EDIT MODAL -->
<div class="modal-overlay hidden" id="modalOverlay">
<div class="modal" id="modal">
<div class="modal-header">
<h2 class="modal-title" id="modalTitle">Add Title</h2>
<button class="modal-close" id="closeModal" aria-label="Close">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
</button>
</div>
<form class="modal-form" id="addForm" autocomplete="off">
<input type="hidden" id="editId" />
<!-- Type toggle -->
<div class="form-group">
<label class="form-label">Type</label>
<div class="type-options" id="typeOptions">
<button type="button" class="type-option active" data-type-val="movie">Movie</button>
<button type="button" class="type-option" data-type-val="show">Show</button>
</div>
</div>
<!-- For whom toggle -->
<div class="form-group">
<label class="form-label">For</label>
<div class="for-options" id="forOptions">
<button type="button" class="for-option" data-for="nik">Nik</button>
<button type="button" class="for-option" data-for="tod">Tod</button>
<button type="button" class="for-option active" data-for="all">Both</button>
</div>
</div>
<div class="form-group">
<label class="form-label" for="inputTitle">Title <span class="required">*</span></label>
<input type="text" class="form-input" id="inputTitle" placeholder="e.g. Oppenheimer" required />
</div>
<div class="form-row">
<div class="form-group">
<label class="form-label" for="inputService">Service</label>
<input type="text" class="form-input" id="inputService" placeholder="e.g. Netflix" list="serviceList" />
<datalist id="serviceList"></datalist>
</div>
<div class="form-group">
<label class="form-label" for="inputGenre">Genre</label>
<input type="text" class="form-input" id="inputGenre" placeholder="e.g. Drama" />
</div>
</div>
<div class="form-group">
<label class="form-label" for="inputNotes">Notes</label>
<textarea class="form-input form-textarea" id="inputNotes" placeholder="Any thoughts..." rows="3"></textarea>
</div>
<div class="modal-actions">
<button type="button" class="btn-ghost" id="cancelModal">Cancel</button>
<button type="submit" class="btn-primary" id="submitBtn">Add to Watchlist</button>
</div>
</form>
</div>
</div>
<!-- DELETE CONFIRM MODAL -->
<div class="modal-overlay hidden" id="deleteOverlay">
<div class="modal modal-sm" id="deleteModal">
<div class="modal-header">
<h2 class="modal-title">Remove Title</h2>
<button class="modal-close" id="closeDeleteModal" aria-label="Close">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
</button>
</div>
<div class="modal-form">
<p class="delete-msg">Remove <strong id="deleteTitle"></strong> from your watchlist?</p>
<div class="modal-actions">
<button type="button" class="btn-ghost" id="cancelDelete">Cancel</button>
<button type="button" class="btn-danger" id="confirmDelete">Remove</button>
</div>
</div>
</div>
</div>
<!-- TOAST CONTAINER -->
<div class="toast-container" id="toastContainer"></div>
<script src="app.js?v=y"></script>
</body>
</html>