summaryrefslogtreecommitdiff
path: root/templates
diff options
context:
space:
mode:
Diffstat (limited to 'templates')
-rw-r--r--templates/profile.html108
1 files changed, 106 insertions, 2 deletions
diff --git a/templates/profile.html b/templates/profile.html
index f697efe..745ed32 100644
--- a/templates/profile.html
+++ b/templates/profile.html
@@ -19,9 +19,22 @@
<main>
<div style="max-width: 1200px; margin: 0 auto; padding: 40px 20px;">
<!-- Hero Section -->
- <div style="margin-bottom: 60px; padding-bottom: 40px; border-bottom: 1px solid var(--line);">
+ <div style="margin-bottom: 40px; padding-bottom: 24px; border-bottom: 1px solid var(--line);">
<h1 style="margin: 0 0 8px 0; font-size: 40px; color: var(--text);">Tyler's Film Diary</h1>
- <p style="margin: 0; color: var(--muted); font-size: 18px;">A curated collection of films watched and loved</p>
+ <p style="margin: 0 0 24px 0; color: var(--muted); font-size: 18px;">A curated collection of films watched and loved</p>
+
+ <!-- Tabs -->
+ <div style="display: flex; gap: 24px; border-bottom: 1px solid var(--line); padding-bottom: 16px;">
+ <button id="tab-overview" class="profile-tab is-active" data-tab="overview" style="background: none; border: none; color: var(--text); cursor: pointer; font-size: 16px; padding: 0; border-bottom: 2px solid var(--accent);">Overview</button>
+ <button id="tab-films" class="profile-tab" data-tab="films" style="background: none; border: none; color: var(--muted); cursor: pointer; font-size: 16px; padding: 0; border-bottom: 2px solid transparent;">All Films</button>
+ </div>
+ </div>
+
+ <!-- Overview Tab -->
+ <div id="panel-overview" class="tab-panel is-active" style="display: block;">
+ <!-- Hero Section Stats -->
+ <div style="margin-bottom: 60px;">
+
<!-- Summary Stats -->
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 24px; margin-top: 32px;">
@@ -114,6 +127,17 @@
</div>
</div>
{% endif %}
+ </div>
+ <!-- End Overview Tab -->
+
+ <!-- All Films Tab -->
+ <div id="panel-films" class="tab-panel" style="display: none;">
+ <div id="films-feed" style="display: grid; gap: 20px;">
+ <!-- Films will be loaded here via infinite scroll -->
+ </div>
+ <div id="films-sentinel" data-shelf="diary" data-offset="0" data-total="{{ total_watched }}" style="height: 1px; margin: 20px 0;"></div>
+ </div>
+ <!-- End All Films Tab -->
</div>
</main>
@@ -121,5 +145,85 @@
<p style="margin: 0;">Made with <a href="https://github.com/tylerhoang/lumiere" style="color: var(--accent); text-decoration: none;">Lumière</a></p>
</footer>
</div>
+
+ <script>
+ // Tab switching
+ document.querySelectorAll(".profile-tab").forEach((tab) => {
+ tab.addEventListener("click", () => {
+ const tabName = tab.dataset.tab;
+
+ // Update tab buttons
+ document.querySelectorAll(".profile-tab").forEach((t) => {
+ t.classList.remove("is-active");
+ t.style.color = "var(--muted)";
+ t.style.borderBottomColor = "transparent";
+ });
+ tab.classList.add("is-active");
+ tab.style.color = "var(--text)";
+ tab.style.borderBottomColor = "var(--accent)";
+
+ // Update panels
+ document.querySelectorAll(".tab-panel").forEach((panel) => {
+ panel.style.display = "none";
+ });
+ document.getElementById(`panel-${tabName}`).style.display = "block";
+
+ // Load films if switching to all films tab
+ if (tabName === "films" && !tab.dataset.loaded) {
+ loadInitialFilms();
+ tab.dataset.loaded = "true";
+ }
+ });
+ });
+
+ // Load all films with infinite scroll
+ function loadInitialFilms() {
+ const sentinel = document.querySelector("#films-sentinel");
+ const feed = document.querySelector("#films-feed");
+ let loading = false;
+
+ const loadMore = async () => {
+ if (loading) return;
+ loading = true;
+
+ const offset = Number(sentinel.dataset.offset);
+ const total = Number(sentinel.dataset.total);
+
+ try {
+ const response = await fetch(`/films/partial?shelf=diary&offset=${offset}&limit=20`);
+ if (!response.ok) return;
+
+ const hasMore = response.headers.get("X-Has-More") === "true";
+ const html = await response.text();
+
+ if (html.trim()) {
+ feed.insertAdjacentHTML("beforeend", html);
+ }
+
+ if (!hasMore) {
+ observer.disconnect();
+ sentinel.remove();
+ } else {
+ sentinel.dataset.offset = String(offset + 20);
+ }
+ } catch (error) {
+ console.error("Failed to load films", error);
+ } finally {
+ loading = false;
+ }
+ };
+
+ const observer = new IntersectionObserver((entries) => {
+ entries.forEach((entry) => {
+ if (entry.isIntersecting) {
+ loadMore();
+ }
+ });
+ }, { rootMargin: "100px" });
+
+ observer.observe(sentinel);
+ loadMore(); // Load first batch immediately
+ }
+ </script>
</body>
</html>