Finalize scoring system, release year integration, and fix song deletion

This commit is contained in:
Hördle Bot
2025-11-23 20:37:23 +01:00
parent e5b0512884
commit 7b975dc3e3
15 changed files with 772 additions and 98 deletions

View File

@@ -40,6 +40,7 @@ interface Song {
artist: string;
filename: string;
createdAt: string;
releaseYear: number | null;
activations: number;
puzzles: DailyPuzzle[];
genres: Genre[];
@@ -48,7 +49,7 @@ interface Song {
ratingCount: number;
}
type SortField = 'id' | 'title' | 'artist' | 'createdAt';
type SortField = 'id' | 'title' | 'artist' | 'createdAt' | 'releaseYear';
type SortDirection = 'asc' | 'desc';
export default function AdminPage() {
@@ -91,6 +92,7 @@ export default function AdminPage() {
const [editingId, setEditingId] = useState<number | null>(null);
const [editTitle, setEditTitle] = useState('');
const [editArtist, setEditArtist] = useState('');
const [editReleaseYear, setEditReleaseYear] = useState<number | ''>('');
const [editGenreIds, setEditGenreIds] = useState<number[]>([]);
const [editSpecialIds, setEditSpecialIds] = useState<number[]>([]);
@@ -577,6 +579,7 @@ export default function AdminPage() {
setEditingId(song.id);
setEditTitle(song.title);
setEditArtist(song.artist);
setEditReleaseYear(song.releaseYear || '');
setEditGenreIds(song.genres.map(g => g.id));
setEditSpecialIds(song.specials ? song.specials.map(s => s.id) : []);
};
@@ -585,6 +588,7 @@ export default function AdminPage() {
setEditingId(null);
setEditTitle('');
setEditArtist('');
setEditReleaseYear('');
setEditGenreIds([]);
setEditSpecialIds([]);
};
@@ -597,6 +601,7 @@ export default function AdminPage() {
id,
title: editTitle,
artist: editArtist,
releaseYear: editReleaseYear === '' ? null : Number(editReleaseYear),
genreIds: editGenreIds,
specialIds: editSpecialIds
}),
@@ -706,10 +711,15 @@ export default function AdminPage() {
});
const sortedSongs = [...filteredSongs].sort((a, b) => {
// Handle numeric sorting for ID
// Handle numeric sorting for ID and Release Year
if (sortField === 'id') {
return sortDirection === 'asc' ? a.id - b.id : b.id - a.id;
}
if (sortField === 'releaseYear') {
const yearA = a.releaseYear || 0;
const yearB = b.releaseYear || 0;
return sortDirection === 'asc' ? yearA - yearB : yearB - yearA;
}
// String sorting for other fields
const valA = String(a[sortField]).toLowerCase();
@@ -1223,10 +1233,15 @@ export default function AdminPage() {
style={{ padding: '0.75rem', cursor: 'pointer', userSelect: 'none' }}
onClick={() => handleSort('title')}
>
Title {sortField === 'title' && (sortDirection === 'asc' ? '' : '')}
Song {sortField === 'title' && (sortDirection === 'asc' ? '' : '')}
</th>
<th style={{ padding: '0.75rem' }}>Genres</th>
<th
style={{ padding: '0.75rem', cursor: 'pointer', userSelect: 'none' }}
onClick={() => handleSort('releaseYear')}
>
Year {sortField === 'releaseYear' && (sortDirection === 'asc' ? '' : '')}
</th>
<th style={{ padding: '0.75rem' }}>Genres / Specials</th>
<th
style={{ padding: '0.75rem', cursor: 'pointer', userSelect: 'none' }}
onClick={() => handleSort('createdAt')}
@@ -1263,6 +1278,16 @@ export default function AdminPage() {
placeholder="Artist"
/>
</td>
<td style={{ padding: '0.75rem' }}>
<input
type="number"
value={editReleaseYear}
onChange={e => setEditReleaseYear(e.target.value === '' ? '' : Number(e.target.value))}
className="form-input"
style={{ padding: '0.25rem', width: '80px' }}
placeholder="Year"
/>
</td>
<td style={{ padding: '0.75rem' }}>
<div style={{ display: 'flex', flexWrap: 'wrap', gap: '0.25rem' }}>
{genres.map(genre => (
@@ -1369,6 +1394,9 @@ export default function AdminPage() {
})}
</div>
</td>
<td style={{ padding: '0.75rem', color: '#666' }}>
{song.releaseYear || '-'}
</td>
<td style={{ padding: '0.75rem' }}>
<div style={{ display: 'flex', flexWrap: 'wrap', gap: '0.25rem' }}>
{song.genres?.map(g => (