Initial commit of AnimeAnnouncer.Web

This commit is contained in:
2026-09-17 14:10:13 -04:00
parent 2198f6ad84
commit 943aef2f7b
76 changed files with 75146 additions and 0 deletions
+125
View File
@@ -0,0 +1,125 @@
@page
@model IndexModel
@{
ViewData["Title"] = "Airing Soon Anime";
}
<div class="container-fluid airing-container">
<div class="d-flex flex-wrap align-items-center justify-content-between mb-2">
<h1 class="display-5 mb-0 d-flex align-items-center flex-wrap">
<span>🗓️ Airing Soon Anime</span>
<span class="badge rounded-pill bg-dark text-white ms-2 fs-6">@(Model.AiringShows == null ? "No data" : (Model.AiringShows.Count + (Model.AiringShows.Count == 1 ? " show" : " shows")))</span>
</h1>
</div>
<p class="lead text-secondary mb-4">Anime with an upcoming or recent latest episode, fetched from the TMDB cache. Sorted by air date (<strong>newest first</strong>).</p>
@if (!string.IsNullOrEmpty(Model.ErrorMessage))
{
<div class="alert alert-danger shadow-sm" role="alert">
<strong>Error:</strong> @Model.ErrorMessage
</div>
}
@if (Model.AiringShows == null || Model.AiringShows.Count == 0)
{
<div class="text-center py-5">
<div class="mb-3">
<span class="display-1">📺</span>
</div>
<h3>No airing soon shows found</h3>
<p class="text-secondary">The Redis cache either returned no entries or the airing soon list is empty.</p>
</div>
}
else
{
<div class="row row-cols-1 row-cols-sm-2 row-cols-md-3 row-cols-lg-4 row-cols-xl-5 row-cols-xxl-6 g-4">
@foreach (var show in Model.AiringShows)
{
<div class="col">
<div class="card h-100 anime-card @(show.IsFuture ? "border-danger" : "")">
<div class="anime-poster-container">
@if (!string.IsNullOrWhiteSpace(show.PosterUrl))
{
<img src="@show.PosterUrl" class="anime-poster" alt="@show.Title" title="@show.Title" loading="lazy" />
}
else
{
<div class="anime-poster d-flex align-items-center justify-content-center text-secondary">
<span class="display-4">🗂️</span>
</div>
}
@if (show.VoteAverage.HasValue && show.VoteAverage > 0)
{
<span class="position-absolute top-0 start-0 badge rounded-pill bg-warning text-dark m-2 shadow-sm">⭐ @string.Format("{0:0.0}", show.VoteAverage)</span>
}
@if (show.EffectiveLastAirDate.HasValue)
{
@if (show.IsFuture)
{
<span class="position-absolute top-0 end-0 badge rounded-pill bg-danger text-white m-2 shadow-sm">Airs in @Math.Max(show.DaysUntil, 1)d</span>
}
else
{
<span class="position-absolute top-0 end-0 badge rounded-pill bg-secondary text-white m-2 shadow-sm">Aired @Math.Abs(show.DaysUntil)d ago</span>
}
}
</div>
<div class="card-body d-flex flex-column">
<h5 class="card-title text-truncate" title="@show.Title">@show.Title</h5>
<div class="show-meta mb-2 d-flex flex-wrap gap-1">
@if (show.LatestSeasonNumber.HasValue && show.LatestSeasonNumber > 0)
{
<span class="badge rounded-pill bg-light text-dark border">Season @show.LatestSeasonNumber</span>
}
@if (show.LatestEpisodeNumber > 0)
{
@if (show.LastEpisodeNumber.HasValue && show.LastEpisodeNumber > 0)
{
<span class="badge rounded-pill bg-light text-dark border">Ep @show.LatestEpisodeNumber / @show.LastEpisodeNumber</span>
}
else
{
<span class="badge rounded-pill bg-light text-dark border">Ep @show.LatestEpisodeNumber</span>
}
}
@if (show.LatestOrdinalEpisodeNumber.HasValue && show.LatestOrdinalEpisodeNumber > 0)
{
<span class="badge rounded-pill bg-light text-dark border">Total: @show.LatestOrdinalEpisodeNumber</span>
}
</div>
<div class="show-dates mb-2">
@if (show.EffectiveLastAirDate.HasValue)
{
<small class="text-primary fw-semibold">📅 Last air date: @show.AirDateFormatted</small>
}
else
{
<small class="text-secondary">📅 Last air date: @show.AirDateFormatted</small>
}
</div>
</div>
<div class="card-footer bg-transparent border-top-0 pt-0">
@if (!string.IsNullOrWhiteSpace(show.Overview))
{
<p class="show-overview text-muted" title="@show.Overview">@show.Overview</p>
}
else
{
<p class="show-overview text-secondary fst-italic">No overview available.</p>
}
<div class="d-grid mt-2">
<a href="https://www.themoviedb.org/tv/@show.ShowID" target="_blank" rel="noopener noreferrer" class="btn btn-sm btn-outline-primary">View on TMDB</a>
</div>
</div>
</div>
</div>
}
</div>
}
</div>