diff --git a/Contracts/Dtos.cs b/Contracts/Dtos.cs
index 0c5e5d6..7783edd 100644
--- a/Contracts/Dtos.cs
+++ b/Contracts/Dtos.cs
@@ -6,3 +6,4 @@ public record SuggestionDto(int Id, string Name, string? Genre, string? Descript
public record VoteRequest(int SuggestionId, int Score);
public record ResultsOpenRequest(bool ResultsOpen);
public record VoteFinalizeRequest(bool Final);
+public record VoteStatusDto(Guid PlayerId, string Name, bool Finalized);
diff --git a/Endpoints/AdminEndpoints.cs b/Endpoints/AdminEndpoints.cs
index 6af0228..54598eb 100644
--- a/Endpoints/AdminEndpoints.cs
+++ b/Endpoints/AdminEndpoints.cs
@@ -34,6 +34,22 @@ public static class AdminEndpoints
return Results.Ok(new { currentState.ResultsOpen, currentState.UpdatedAt });
});
+ admin.MapGet("/vote-status", async (HttpContext ctx, AppDbContext db, IConfiguration config) =>
+ {
+ if (!await EndpointHelpers.IsAdmin(ctx, db, config)) return Results.Unauthorized();
+
+ var voters = await db.Players
+ .AsNoTracking()
+ .Where(p => p.CurrentPhase == Phase.Vote)
+ .OrderBy(p => p.DisplayName ?? p.Username)
+ .Select(p => new VoteStatusDto(p.Id, p.DisplayName ?? p.Username, p.VotesFinal))
+ .ToListAsync();
+
+ var waiting = voters.Where(v => !v.Finalized).Select(v => v.Name).ToList();
+ var ready = waiting.Count == 0;
+ return Results.Ok(new { voters, ready, waiting });
+ });
+
admin.MapPost("/reset", async (HttpContext ctx, AppDbContext db, IConfiguration config) =>
{
if (!await EndpointHelpers.IsAdmin(ctx, db, config)) return Results.Unauthorized();
diff --git a/wwwroot/index.html b/wwwroot/index.html
index d7dc434..4817345 100644
--- a/wwwroot/index.html
+++ b/wwwroot/index.html
@@ -143,6 +143,10 @@
Admin
+