feat: add toggle watchlist on anime cards and improve dropdown

This commit is contained in:
2026-05-02 15:28:37 +02:00
committed by Mikkel Elvers
parent 94e60e0d8b
commit cc9ca1ba9e
14 changed files with 396 additions and 76 deletions

View File

@@ -6,7 +6,7 @@
<div class="mb-4 flex gap-2">
<ui-dropdown class="relative block" data-align="left" data-width="min-w-[160px]">
<div data-trigger class="cursor-pointer">
<button class="bg-background-button hover:bg-background-button-hover flex items-center justify-between gap-3 px-4 py-2.5 text-sm font-medium text-white transition-colors disabled:opacity-50">
<button type="button" class="bg-background-button hover:bg-background-button-hover flex items-center justify-between gap-3 px-4 py-2.5 text-sm font-medium text-white transition-colors disabled:opacity-50">
<span id="watchlist-status-display-{{$anime.MalID}}">
{{if $status}}
{{if eq $status "watching"}}Watching{{end}}
@@ -23,16 +23,16 @@
<div data-content class="hidden absolute z-50 min-w-[160px] bg-background-button rounded-none shadow-2xl left-0 top-full mt-2">
<div class="flex flex-col py-1">
<button class="flex w-full items-center px-5 py-2.5 transition-colors focus:outline-none hover:bg-white/10 focus:bg-white/10" onclick="updateWatchlist({{$anime.MalID}}, 'watching', 'Watching')">
<button class="flex w-full items-center px-5 py-2.5 transition-colors focus:outline-none hover:bg-white/10 focus:bg-white/10" onclick="updateWatchlist({{$anime.MalID}}, 'watching', 'Watching', this)">
<span class="font-medium text-sm text-white">Watching</span>
</button>
<button class="flex w-full items-center px-5 py-2.5 transition-colors focus:outline-none hover:bg-white/10 focus:bg-white/10" onclick="updateWatchlist({{$anime.MalID}}, 'completed', 'Completed')">
<button class="flex w-full items-center px-5 py-2.5 transition-colors focus:outline-none hover:bg-white/10 focus:bg-white/10" onclick="updateWatchlist({{$anime.MalID}}, 'completed', 'Completed', this)">
<span class="font-medium text-sm text-white">Completed</span>
</button>
<button class="flex w-full items-center px-5 py-2.5 transition-colors focus:outline-none hover:bg-white/10 focus:bg-white/10" onclick="updateWatchlist({{$anime.MalID}}, 'plan to watch', 'Plan to Watch')">
<button class="flex w-full items-center px-5 py-2.5 transition-colors focus:outline-none hover:bg-white/10 focus:bg-white/10" onclick="updateWatchlist({{$anime.MalID}}, 'plan_to_watch', 'Plan to Watch', this)">
<span class="font-medium text-sm text-white">Plan to Watch</span>
</button>
<button class="flex w-full items-center px-5 py-2.5 transition-colors focus:outline-none hover:bg-white/10 focus:bg-white/10" onclick="updateWatchlist({{$anime.MalID}}, 'dropped', 'Dropped')">
<button class="flex w-full items-center px-5 py-2.5 transition-colors focus:outline-none hover:bg-white/10 focus:bg-white/10" onclick="updateWatchlist({{$anime.MalID}}, 'dropped', 'Dropped', this)">
<span class="font-medium text-sm text-white">Dropped</span>
</button>
@@ -52,15 +52,22 @@
</div>
<script>
function updateWatchlist(id, status, display) {
function updateWatchlist(id, status, display, btn) {
fetch('/api/watchlist', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ animeId: id, status: status })
}).then(res => {
if (res.ok) {
watchlistIds.add(id);
document.getElementById('watchlist-status-display-' + id).textContent = display;
document.getElementById('remove-watchlist-container-' + id).classList.remove('hidden');
// Close dropdown after a small delay to let click event finish
requestAnimationFrame(() => {
const dropdown = btn.closest('ui-dropdown');
if (dropdown) dropdown.close();
});
}
});
}
@@ -68,8 +75,16 @@
function removeWatchlist(id) {
fetch('/api/watchlist/' + id, { method: 'DELETE' }).then(res => {
if (res.ok) {
watchlistIds.delete(id);
document.getElementById('watchlist-status-display-' + id).textContent = 'Add to Watchlist';
document.getElementById('remove-watchlist-container-' + id).classList.add('hidden');
// Close dropdown
const btn = document.getElementById('watchlist-status-display-' + id);
if (btn) {
const dropdown = btn.closest('ui-dropdown');
if (dropdown) dropdown.close();
}
}
});
}