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

215 lines
10 KiB
PHP
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!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="movie">🎬 Movie</button>
<button type="button" class="type-option" data-type="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=6"></script>
</body>
</html>