123 lines
4.6 KiB
Plaintext
123 lines
4.6 KiB
Plaintext
package templates
|
|
|
|
import (
|
|
"fmt"
|
|
"mal/internal/database"
|
|
"mal/internal/shared/ui"
|
|
)
|
|
|
|
templ Watchlist(entries []database.GetUserWatchListRow, layout string, currentStatus string, sortBy string, sortOrder string) {
|
|
@Layout("My Watchlist") {
|
|
<div class="watchlist-header">
|
|
<div class="watchlist-heading">
|
|
<h2>Watchlist</h2>
|
|
<p class="watchlist-subtitle">Track what you're watching with less noise.</p>
|
|
</div>
|
|
<div class="watchlist-controls">
|
|
<a href="/api/watchlist/export" class="text-link">Export</a>
|
|
<button class="text-link" type="button" onclick="document.getElementById('import-file').click()">Import</button>
|
|
<form id="import-form" hx-post="/api/watchlist/import" hx-encoding="multipart/form-data" class="is-hidden">
|
|
<input type="file" id="import-file" name="file" accept=".json" onchange="htmx.trigger('#import-form', 'submit')"/>
|
|
</form>
|
|
<div class="view-toggle">
|
|
<a href={ templ.URL(watchlistURL("grid", currentStatus, sortBy, sortOrder)) } class={ viewClass(layout == "grid") }>Grid</a>
|
|
<a href={ templ.URL(watchlistURL("table", currentStatus, sortBy, sortOrder)) } class={ viewClass(layout == "table") }>Table</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="status-tabs">
|
|
<a href={ templ.URL(watchlistURL(layout, "all", sortBy, sortOrder)) } class={ tabClass(currentStatus == "all") }>All</a>
|
|
<a href={ templ.URL(watchlistURL(layout, "watching", sortBy, sortOrder)) } class={ tabClass(currentStatus == "watching") }>Watching</a>
|
|
<a href={ templ.URL(watchlistURL(layout, "continuing", sortBy, sortOrder)) } class={ tabClass(currentStatus == "continuing") }>Continuing</a>
|
|
<a href={ templ.URL(watchlistURL(layout, "on_hold", sortBy, sortOrder)) } class={ tabClass(currentStatus == "on_hold") }>On hold</a>
|
|
<a href={ templ.URL(watchlistURL(layout, "plan_to_watch", sortBy, sortOrder)) } class={ tabClass(currentStatus == "plan_to_watch") }>Plan to watch</a>
|
|
<a href={ templ.URL(watchlistURL(layout, "dropped", sortBy, sortOrder)) } class={ tabClass(currentStatus == "dropped") }>Dropped</a>
|
|
<a href={ templ.URL(watchlistURL(layout, "completed", sortBy, sortOrder)) } class={ tabClass(currentStatus == "completed") }>Completed</a>
|
|
</div>
|
|
@ui.SortFilter(ui.SortFilterOptions{Sort: sortBy, Order: sortOrder, View: layout, Status: currentStatus})
|
|
if len(entries) == 0 {
|
|
@ui.EmptyState("Nothing here yet") {
|
|
if currentStatus == "all" {
|
|
Your watchlist is empty. <a href="/">Search for anime</a> to get started.
|
|
} else if currentStatus == "continuing" {
|
|
No airing anime with watching or plan to watch status.
|
|
} else {
|
|
No anime in this category.
|
|
}
|
|
}
|
|
} else {
|
|
if layout == "grid" {
|
|
<div class="catalog-grid">
|
|
for _, entry := range entries {
|
|
<div class="catalog-item watchlist-item" id={ fmt.Sprintf("watchlist-entry-%d", entry.AnimeID) }>
|
|
@ui.AnimeCard(ui.AnimeCardProps{
|
|
ID: int(entry.AnimeID),
|
|
Title: entry.DisplayTitle(),
|
|
ImageURL: entry.ImageUrl,
|
|
})
|
|
<button
|
|
class="remove-btn"
|
|
hx-delete={ string(templ.URL(fmt.Sprintf("/api/watchlist/%d?from=watchlist", entry.AnimeID))) }
|
|
hx-target={ fmt.Sprintf("#watchlist-entry-%d", entry.AnimeID) }
|
|
hx-swap="delete"
|
|
>×</button>
|
|
</div>
|
|
}
|
|
</div>
|
|
} else {
|
|
<table class="watchlist-table">
|
|
<thead>
|
|
<tr>
|
|
<th></th>
|
|
<th>Title</th>
|
|
<th></th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
for _, entry := range entries {
|
|
<tr id={ fmt.Sprintf("watchlist-entry-%d", entry.AnimeID) }>
|
|
<td>
|
|
<a href={ templ.SafeURL(fmt.Sprintf("/anime/%d", entry.AnimeID)) }>
|
|
<img src={ entry.ImageUrl } alt={ entry.DisplayTitle() } class="thumb" loading="lazy"/>
|
|
</a>
|
|
</td>
|
|
<td class="title-cell">
|
|
<a href={ templ.SafeURL(fmt.Sprintf("/anime/%d", entry.AnimeID)) }>
|
|
{ entry.DisplayTitle() }
|
|
</a>
|
|
</td>
|
|
<td class="actions-cell">
|
|
<button
|
|
class="remove-link"
|
|
hx-delete={ string(templ.URL(fmt.Sprintf("/api/watchlist/%d?from=watchlist", entry.AnimeID))) }
|
|
hx-target={ fmt.Sprintf("#watchlist-entry-%d", entry.AnimeID) }
|
|
hx-swap="delete"
|
|
>Remove</button>
|
|
</td>
|
|
</tr>
|
|
}
|
|
</tbody>
|
|
</table>
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func viewClass(active bool) string {
|
|
if active {
|
|
return "active"
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func tabClass(active bool) string {
|
|
if active {
|
|
return "active"
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func watchlistURL(view string, status string, sortBy string, sortOrder string) string {
|
|
return fmt.Sprintf("/watchlist?view=%s&status=%s&sort=%s&order=%s", view, status, sortBy, sortOrder)
|
|
}
|