From 35fe5f2d44bd8da7188034d3fd431af6f66bf74f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=B6rdle=20Bot?= Date: Tue, 25 Nov 2025 00:27:08 +0100 Subject: [PATCH] feat: Add sorting by activations and average rating to admin page and include bonus star in game share text. --- app/admin/page.tsx | 24 ++++++++++++++++++++---- components/Game.tsx | 3 ++- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/app/admin/page.tsx b/app/admin/page.tsx index 5dece73..4c8a181 100644 --- a/app/admin/page.tsx +++ b/app/admin/page.tsx @@ -51,7 +51,7 @@ interface Song { excludeFromGlobal: boolean; } -type SortField = 'id' | 'title' | 'artist' | 'createdAt' | 'releaseYear'; +type SortField = 'id' | 'title' | 'artist' | 'createdAt' | 'releaseYear' | 'activations' | 'averageRating'; type SortDirection = 'asc' | 'desc'; export default function AdminPage() { @@ -824,7 +824,7 @@ export default function AdminPage() { }); const sortedSongs = [...filteredSongs].sort((a, b) => { - // Handle numeric sorting for ID and Release Year + // Handle numeric sorting for ID, Release Year, Activations, and Rating if (sortField === 'id') { return sortDirection === 'asc' ? a.id - b.id : b.id - a.id; } @@ -833,6 +833,12 @@ export default function AdminPage() { const yearB = b.releaseYear || 0; return sortDirection === 'asc' ? yearA - yearB : yearB - yearA; } + if (sortField === 'activations') { + return sortDirection === 'asc' ? a.activations - b.activations : b.activations - a.activations; + } + if (sortField === 'averageRating') { + return sortDirection === 'asc' ? a.averageRating - b.averageRating : b.averageRating - a.averageRating; + } // String sorting for other fields const valA = String(a[sortField]).toLowerCase(); @@ -1414,8 +1420,18 @@ export default function AdminPage() { > Added {sortField === 'createdAt' && (sortDirection === 'asc' ? '↑' : '↓')} - Activations - Rating + handleSort('activations')} + > + Activations {sortField === 'activations' && (sortDirection === 'asc' ? '↑' : '↓')} + + handleSort('averageRating')} + > + Rating {sortField === 'averageRating' && (sortDirection === 'asc' ? '↑' : '↓')} + Actions diff --git a/components/Game.tsx b/components/Game.tsx index 6af8c8e..f932d9a 100644 --- a/components/Game.tsx +++ b/components/Game.tsx @@ -173,6 +173,7 @@ export default function Game({ dailyPuzzle, genre = null, isSpecial = false, max } const speaker = hasWon ? '🔉' : '🔇'; + const bonusStar = (hasWon && gameState.yearGuessed && dailyPuzzle.releaseYear && gameState.scoreBreakdown.some(item => item.reason === 'Bonus: Correct Year')) ? '⭐' : ''; const genreText = genre ? `Genre: ${genre}\n` : ''; let shareUrl = 'https://hoerdle.elpatron.me'; @@ -184,7 +185,7 @@ export default function Game({ dailyPuzzle, genre = null, isSpecial = false, max } } - const text = `Hördle #${dailyPuzzle.puzzleNumber}\n${genreText}\n${speaker}${emojiGrid}\nScore: ${gameState.score}\n\n#Hördle #Music\n\n${shareUrl}`; + const text = `Hördle #${dailyPuzzle.puzzleNumber}\n${genreText}\n${speaker}${emojiGrid}${bonusStar}\nScore: ${gameState.score}\n\n#Hördle #Music\n\n${shareUrl}`; const isMobile = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent);