Initial commit of AnimeAnnouncer.Web
This commit is contained in:
@@ -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>
|
||||
Reference in New Issue
Block a user