Initial commit: RR3 Community Server with web admin panel
- ASP.NET Core 8 REST API server - 12 API endpoints matching EA Synergy protocol - SQLite database with Entity Framework Core - Web admin panel with Bootstrap 5 - User, Catalog, Session, Purchase management - Comprehensive documentation Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
160
RR3CommunityServer/Pages/Sessions.cshtml
Normal file
160
RR3CommunityServer/Pages/Sessions.cshtml
Normal file
@@ -0,0 +1,160 @@
|
||||
@page
|
||||
@model RR3CommunityServer.Pages.SessionsModel
|
||||
@{
|
||||
ViewData["Title"] = "Session Management";
|
||||
}
|
||||
|
||||
<div class="container-fluid mt-4">
|
||||
<div class="row mb-4">
|
||||
<div class="col-12">
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<div>
|
||||
<h1>🔄 Session Management</h1>
|
||||
<p class="text-muted">Monitor active and expired sessions</p>
|
||||
</div>
|
||||
<div>
|
||||
<form method="post" asp-page-handler="CleanupExpired" class="d-inline">
|
||||
<button type="submit" class="btn btn-warning">
|
||||
<i class="bi bi-trash3"></i> Cleanup Expired
|
||||
</button>
|
||||
</form>
|
||||
<a href="/admin" class="btn btn-outline-secondary">← Back</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Statistics -->
|
||||
<div class="row g-3 mb-4">
|
||||
<div class="col-md-4">
|
||||
<div class="card border-success">
|
||||
<div class="card-body">
|
||||
<h6 class="text-muted">Active Sessions</h6>
|
||||
<h2 class="text-success">@Model.ActiveSessions.Count</h2>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="card border-danger">
|
||||
<div class="card-body">
|
||||
<h6 class="text-muted">Expired Sessions</h6>
|
||||
<h2 class="text-danger">@Model.ExpiredSessions.Count</h2>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="card border-info">
|
||||
<div class="card-body">
|
||||
<h6 class="text-muted">Total Sessions</h6>
|
||||
<h2 class="text-info">@Model.AllSessions.Count</h2>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Active Sessions -->
|
||||
@if (Model.ActiveSessions.Any())
|
||||
{
|
||||
<div class="card mb-4">
|
||||
<div class="card-header bg-success text-white">
|
||||
<h5 class="mb-0">🟢 Active Sessions (@Model.ActiveSessions.Count)</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Session ID</th>
|
||||
<th>User ID</th>
|
||||
<th>Device ID</th>
|
||||
<th>Created</th>
|
||||
<th>Expires</th>
|
||||
<th>Time Left</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (var session in Model.ActiveSessions)
|
||||
{
|
||||
var timeLeft = session.ExpiresAt - DateTime.UtcNow;
|
||||
<tr>
|
||||
<td><code>@session.SessionId.Substring(0, 12)...</code></td>
|
||||
<td>@session.UserId</td>
|
||||
<td><code>@session.DeviceId.Substring(0, 12)...</code></td>
|
||||
<td>@session.CreatedAt.ToString("g")</td>
|
||||
<td>@session.ExpiresAt.ToString("g")</td>
|
||||
<td>
|
||||
<span class="badge bg-success">
|
||||
@((int)timeLeft.TotalHours)h @timeLeft.Minutes)m
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<form method="post" asp-page-handler="Delete" class="d-inline">
|
||||
<input type="hidden" name="sessionId" value="@session.Id" />
|
||||
<button type="submit" class="btn btn-sm btn-danger" onclick="return confirm('Terminate this session?')">
|
||||
<i class="bi bi-x-circle"></i> Terminate
|
||||
</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
<!-- Expired Sessions -->
|
||||
@if (Model.ExpiredSessions.Any())
|
||||
{
|
||||
<div class="card">
|
||||
<div class="card-header bg-secondary text-white">
|
||||
<h5 class="mb-0">⚫ Expired Sessions (@Model.ExpiredSessions.Count)</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Session ID</th>
|
||||
<th>User ID</th>
|
||||
<th>Device ID</th>
|
||||
<th>Created</th>
|
||||
<th>Expired</th>
|
||||
<th>Duration</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (var session in Model.ExpiredSessions.Take(20))
|
||||
{
|
||||
var duration = session.ExpiresAt - session.CreatedAt;
|
||||
<tr class="text-muted">
|
||||
<td><code>@session.SessionId.Substring(0, 12)...</code></td>
|
||||
<td>@session.UserId</td>
|
||||
<td><code>@session.DeviceId.Substring(0, 12)...</code></td>
|
||||
<td>@session.CreatedAt.ToString("g")</td>
|
||||
<td>@session.ExpiresAt.ToString("g")</td>
|
||||
<td>@((int)duration.TotalHours)h</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@if (Model.ExpiredSessions.Count > 20)
|
||||
{
|
||||
<div class="text-muted text-center">
|
||||
<small>Showing 20 of @Model.ExpiredSessions.Count expired sessions</small>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
@if (!Model.AllSessions.Any())
|
||||
{
|
||||
<div class="alert alert-info">
|
||||
<i class="bi bi-info-circle"></i> No sessions yet. Sessions will appear when players connect to the server.
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
Reference in New Issue
Block a user