From 517605dc7fda996a61bcb04b9e4880ac29981009 Mon Sep 17 00:00:00 2001 From: Dave Gallant Date: Mon, 16 Feb 2026 12:51:39 -0500 Subject: [PATCH] Add toggeable list and card views --- src/App.vue | 42 ++++++++++++++++++++++++-- src/theme.css | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 121 insertions(+), 3 deletions(-) diff --git a/src/App.vue b/src/App.vue index 9cf6d8e..41fc9c5 100644 --- a/src/App.vue +++ b/src/App.vue @@ -57,6 +57,7 @@ export default { filterInput: "", activeFilters: this.parseFiltersFromUrl(), sortMethod: "score", + viewMode: "cards", topics: [], isMobile: false, currentTheme: "auto", @@ -72,6 +73,7 @@ export default { this.detectMobile(); this.fetchDeals(); this.initializeSortMethod(); + this.initializeViewMode(); this.initializeTheme(); this.setupThemeListener(); }, @@ -130,6 +132,19 @@ export default { }; return titles[this.sortMethod]; }, + + viewIcon() { + const icons = { cards: "grid_view", list: "view_list" }; + return icons[this.viewMode]; + }, + + viewTitle() { + const titles = { + cards: "View: Cards (click for List)", + list: "View: List (click for Cards)", + }; + return titles[this.viewMode]; + }, }, methods: { @@ -303,6 +318,19 @@ export default { localStorage.setItem("sortMethod", this.sortMethod); }, + initializeViewMode() { + const saved = localStorage.getItem("viewMode"); + if (saved) { + this.viewMode = saved; + } + }, + + toggleViewMode() { + const cycle = { cards: "list", list: "cards" }; + this.viewMode = cycle[this.viewMode]; + localStorage.setItem("viewMode", this.viewMode); + }, + getDealerColor(dealerName) { if (!dealerName) return null; const isDark = document.documentElement.getAttribute('data-bs-theme') === 'dark' || @@ -354,6 +382,9 @@ export default { + @@ -369,8 +400,8 @@ export default {
refresh
-
-
+
+
-
+
visibility @@ -424,6 +455,11 @@ export default {
Last post: {{ formatDate(topic.last_post_time) }}
+ +
+ {{ topic.total_views }} views + {{ topic.total_replies }} replies +
diff --git a/src/theme.css b/src/theme.css index 17168cc..3b950bd 100644 --- a/src/theme.css +++ b/src/theme.css @@ -325,6 +325,88 @@ a:visited { margin-top: 20px; } +/* ============================================ + List View + ============================================ */ + +.list-view { + display: flex; + flex-direction: column; + gap: 8px; + margin-top: 20px; +} + +.deal-row { + background-color: var(--bg-secondary); + border: 1px solid var(--border-color-light); + border-radius: 6px; + padding: 10px 14px; + display: flex; + align-items: center; + gap: 12px; + transition: all 0.2s ease; +} + +.deal-row .card-header { + display: contents; +} + +.deal-row:hover { + background-color: var(--bg-input); + border-color: var(--border-color-hover); +} + +.deal-row .card-meta { + margin-bottom: 0; + flex-shrink: 0; + order: 2; +} + +.deal-row .title-with-link { + flex: 1; + order: 1; +} + +.deal-row .deal-title { + font-size: 14px; +} + +.deal-row .row-stats { + order: 3; +} + +.deal-row .score-bubble { + min-width: 36px; + height: 24px; + font-size: 10px; + order: 4; +} + +.row-stats { + display: flex; + gap: 12px; + flex-shrink: 0; +} + +.stat-compact { + font-size: 11px; + color: var(--text-secondary); + white-space: nowrap; +} + +@media (max-width: 768px) { + .deal-row { + flex-wrap: wrap; + } + + .row-stats { + width: 100%; + margin-top: 8px; + padding-top: 8px; + border-top: 1px solid var(--border-color); + } +} + .deal-card { background-color: var(--bg-secondary); border: 1.5px solid #aaaaaa;