diff --git a/ProjectLighthouse.Servers.Website/Controllers/Admin/AdminUserController.cs b/ProjectLighthouse.Servers.Website/Controllers/Admin/AdminUserController.cs
index 00babada..3a05d089 100644
--- a/ProjectLighthouse.Servers.Website/Controllers/Admin/AdminUserController.cs
+++ b/ProjectLighthouse.Servers.Website/Controllers/Admin/AdminUserController.cs
@@ -108,6 +108,6 @@ public class AdminUserController : ControllerBase
return this.Redirect($"/moderation/newCase?type={(int)CaseType.UserBan}&affectedId={id}");
}
- return this.Redirect("/admin/users");
+ return this.Redirect("/admin/users/0");
}
}
\ No newline at end of file
diff --git a/ProjectLighthouse.Servers.Website/Controllers/Moderator/ModerationCaseController.cs b/ProjectLighthouse.Servers.Website/Controllers/Moderator/ModerationCaseController.cs
index 71a92c29..b0db7021 100644
--- a/ProjectLighthouse.Servers.Website/Controllers/Moderator/ModerationCaseController.cs
+++ b/ProjectLighthouse.Servers.Website/Controllers/Moderator/ModerationCaseController.cs
@@ -34,6 +34,6 @@ public class ModerationCaseController : ControllerBase
await this.database.SaveChangesAsync();
- return this.Ok();
+ return this.Redirect($"/moderation/cases/0");
}
}
\ No newline at end of file
diff --git a/ProjectLighthouse.Servers.Website/Pages/Admin/AdminPanelPage.cshtml.cs b/ProjectLighthouse.Servers.Website/Pages/Admin/AdminPanelPage.cshtml.cs
index 345f722d..8a80e2d2 100644
--- a/ProjectLighthouse.Servers.Website/Pages/Admin/AdminPanelPage.cshtml.cs
+++ b/ProjectLighthouse.Servers.Website/Pages/Admin/AdminPanelPage.cshtml.cs
@@ -27,7 +27,7 @@ public class AdminPanelPage : BaseLayout
if (user == null) return this.Redirect("~/login");
if (!user.IsAdmin) return this.NotFound();
- this.Statistics.Add(new AdminPanelStatistic("Users", await StatisticsHelper.UserCount(this.Database), "/admin/users"));
+ this.Statistics.Add(new AdminPanelStatistic("Users", await StatisticsHelper.UserCount(this.Database), "/admin/users/0"));
this.Statistics.Add(new AdminPanelStatistic("Slots", await StatisticsHelper.SlotCount(this.Database, new SlotQueryBuilder())));
this.Statistics.Add(new AdminPanelStatistic("Photos", await StatisticsHelper.PhotoCount(this.Database)));
this.Statistics.Add(new AdminPanelStatistic("API Keys", await StatisticsHelper.ApiKeyCount(this.Database), "/admin/keys"));
diff --git a/ProjectLighthouse.Servers.Website/Pages/Admin/AdminPanelUsersPage.cshtml b/ProjectLighthouse.Servers.Website/Pages/Admin/AdminPanelUsersPage.cshtml
index 16b2f571..b5f04b92 100644
--- a/ProjectLighthouse.Servers.Website/Pages/Admin/AdminPanelUsersPage.cshtml
+++ b/ProjectLighthouse.Servers.Website/Pages/Admin/AdminPanelUsersPage.cshtml
@@ -1,4 +1,4 @@
-@page "/admin/users"
+@page "/admin/users/{pageNumber:int}"
@using LBPUnion.ProjectLighthouse.Types.Entities.Profile
@using LBPUnion.ProjectLighthouse.Types.Users
@model LBPUnion.ProjectLighthouse.Servers.Website.Pages.Admin.AdminPanelUsersPage
@@ -11,6 +11,15 @@
There are currently @Model.UserCount users registered to your instance.
Note: Users are ordered by their permissions, then by most-recent-first.
+
+
+
+
@foreach (UserEntity user in Model.Users)
{
@@ -19,22 +28,21 @@
switch (user.PermissionLevel)
{
- // jank but works
case PermissionLevel.Banned:
{
- color = "red";
+ color = "grey";
subtitle = $"Banned user! Reason: {user.BannedReason}";
break;
}
case PermissionLevel.Moderator:
{
- color = "green";
+ color = "orange";
subtitle = "Moderator";
break;
}
case PermissionLevel.Administrator:
{
- color = "yellow";
+ color = "red";
subtitle = "Admin";
break;
}
@@ -72,4 +80,16 @@
}
-
\ No newline at end of file
+
+
+
+
+@if (Model.PageNumber != 0)
+{
+ Previous Page
+}
+@(Model.PageNumber + 1) / @(Model.PageAmount)
+@if (Model.PageNumber < Model.PageAmount - 1)
+{
+ Next Page
+}
\ No newline at end of file
diff --git a/ProjectLighthouse.Servers.Website/Pages/Admin/AdminPanelUsersPage.cshtml.cs b/ProjectLighthouse.Servers.Website/Pages/Admin/AdminPanelUsersPage.cshtml.cs
index b6ed868a..16a4ec88 100644
--- a/ProjectLighthouse.Servers.Website/Pages/Admin/AdminPanelUsersPage.cshtml.cs
+++ b/ProjectLighthouse.Servers.Website/Pages/Admin/AdminPanelUsersPage.cshtml.cs
@@ -1,4 +1,5 @@
#nullable enable
+using LBPUnion.ProjectLighthouse.Configuration;
using LBPUnion.ProjectLighthouse.Database;
using LBPUnion.ProjectLighthouse.Servers.Website.Pages.Layouts;
using LBPUnion.ProjectLighthouse.Types.Entities.Profile;
@@ -12,21 +13,39 @@ public class AdminPanelUsersPage : BaseLayout
public int UserCount;
public List Users = new();
+
+ public int PageAmount;
+ public int PageNumber;
+ public string SearchValue = "";
+
public AdminPanelUsersPage(DatabaseContext database) : base(database)
{}
- public async Task OnGet()
+ public async Task OnGet([FromRoute] int pageNumber, [FromQuery] string? name)
{
UserEntity? user = this.Database.UserFromWebRequest(this.Request);
if (user == null) return this.Redirect("~/login");
if (!user.IsAdmin) return this.NotFound();
+ if (string.IsNullOrWhiteSpace(name)) name = "";
+
+ this.SearchValue = name.Replace(" ", string.Empty);
+
+ this.UserCount = await this.Database.Users.CountAsync(u => u.Username.Contains(this.SearchValue));
+
+ this.PageNumber = pageNumber;
+ this.PageAmount = Math.Max(1, (int)Math.Ceiling((double)this.UserCount / ServerStatics.PageSize));
+
+ if (this.PageNumber < 0 || this.PageNumber >= this.PageAmount)
+ return this.Redirect($"/admin/users/{Math.Clamp(this.PageNumber, 0, this.PageAmount - 1)}");
+
this.Users = await this.Database.Users
.OrderByDescending(u => u.PermissionLevel)
.ThenByDescending(u => u.UserId)
+ .Where(u => u.Username.Contains(this.SearchValue))
+ .Skip(pageNumber * ServerStatics.PageSize)
+ .Take(ServerStatics.PageSize)
.ToListAsync();
-
- this.UserCount = this.Users.Count;
return this.Page();
}
diff --git a/ProjectLighthouse.Servers.Website/Pages/Moderation/CasePage.cshtml b/ProjectLighthouse.Servers.Website/Pages/Moderation/CasePage.cshtml
index eef4d801..1d3b5137 100644
--- a/ProjectLighthouse.Servers.Website/Pages/Moderation/CasePage.cshtml
+++ b/ProjectLighthouse.Servers.Website/Pages/Moderation/CasePage.cshtml
@@ -10,11 +10,11 @@
string timeZone = Model.GetTimeZone();
}
-There are @Model.CaseCount total cases, @Model.DismissedCaseCount of which have been dismissed.
+There are @Model.CaseCount total cases, @Model.ExpiredCaseCount of which are queued for dismissal, and @Model.DismissedCaseCount of which have been dismissed.
@@ -24,4 +24,14 @@
@foreach (ModerationCaseEntity @case in Model.Cases)
{
@(await Html.PartialAsync("Partials/ModerationCasePartial", @case, ViewData.WithTime(timeZone)))
+}
+
+@if (Model.PageNumber != 0)
+{
+ Previous Page
+}
+@(Model.PageNumber + 1) / @(Model.PageAmount)
+@if (Model.PageNumber < Model.PageAmount - 1)
+{
+ Next Page
}
\ No newline at end of file
diff --git a/ProjectLighthouse.Servers.Website/Pages/Moderation/CasePage.cshtml.cs b/ProjectLighthouse.Servers.Website/Pages/Moderation/CasePage.cshtml.cs
index 8be500c4..29d8f9c4 100644
--- a/ProjectLighthouse.Servers.Website/Pages/Moderation/CasePage.cshtml.cs
+++ b/ProjectLighthouse.Servers.Website/Pages/Moderation/CasePage.cshtml.cs
@@ -11,10 +11,11 @@ namespace LBPUnion.ProjectLighthouse.Servers.Website.Pages.Moderation;
public class CasePage : BaseLayout
{
public CasePage(DatabaseContext database) : base(database)
- {}
+ { }
public List Cases = new();
public int CaseCount;
+ public int ExpiredCaseCount;
public int DismissedCaseCount;
public int PageAmount;
@@ -31,18 +32,30 @@ public class CasePage : BaseLayout
this.SearchValue = name.Replace(" ", string.Empty);
- this.Cases = await this.Database.Cases
- .Include(c => c.Creator)
- .Include(c => c.Dismisser)
- .OrderByDescending(c => c.CaseId)
- .ToListAsync();
-
- this.CaseCount = await this.Database.Cases.CountAsync(c => c.Reason.Contains(this.SearchValue));
- this.DismissedCaseCount = await this.Database.Cases.CountAsync(c => c.Reason.Contains(this.SearchValue) && c.DismissedAt != null);
+ this.CaseCount =
+ await this.Database.Cases.CountAsync(c =>
+ c.AffectedId.ToString().Contains(this.SearchValue));
+ this.ExpiredCaseCount =
+ await this.Database.Cases.CountAsync(c =>
+ c.AffectedId.ToString().Contains(this.SearchValue) && c.DismissedAt == null && c.ExpiresAt < DateTime.UtcNow);
+ this.DismissedCaseCount =
+ await this.Database.Cases.CountAsync(c =>
+ c.AffectedId.ToString().Contains(this.SearchValue)&& c.DismissedAt != null);
this.PageNumber = pageNumber;
this.PageAmount = Math.Max(1, (int)Math.Ceiling((double)this.CaseCount / ServerStatics.PageSize));
+ if (this.PageNumber < 0 || this.PageNumber >= this.PageAmount)
+ return this.Redirect($"/moderation/cases/{Math.Clamp(this.PageNumber, 0, this.PageAmount - 1)}");
+
+ this.Cases = await this.Database.Cases.Include(c => c.Creator)
+ .Include(c => c.Dismisser)
+ .Where(c => c.AffectedId.ToString().Contains(this.SearchValue))
+ .OrderByDescending(c => c.CaseId)
+ .Skip(pageNumber * ServerStatics.PageSize)
+ .Take(ServerStatics.PageSize)
+ .ToListAsync();
+
return this.Page();
}
}
\ No newline at end of file
diff --git a/ProjectLighthouse.Servers.Website/Pages/Partials/ModerationCasePartial.cshtml b/ProjectLighthouse.Servers.Website/Pages/Partials/ModerationCasePartial.cshtml
index 2f108dec..a5011055 100644
--- a/ProjectLighthouse.Servers.Website/Pages/Partials/ModerationCasePartial.cshtml
+++ b/ProjectLighthouse.Servers.Website/Pages/Partials/ModerationCasePartial.cshtml
@@ -7,42 +7,19 @@
@inject DatabaseContext Database
@{
- string color = "blue";
-
string timeZone = (string?)ViewData["TimeZone"] ?? TimeZoneInfo.Local.Id;
TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById(timeZone);
- if (Model.Expired) color = "yellow";
- if (Model.Dismissed) color = "green";
+ string color = "red";
+
+ if (Model.Expired)
+ color = "yellow";
+ if (Model.Dismissed)
+ color = "green";
}
Case #@Model.CaseId: @Model.Type
-
- @if (Model.Dismissed)
- {
- Debug.Assert(Model.DismissedAt != null);
-
- @if (Model.Dismisser != null)
- {
-
- }
- else
- {
-
- }
-
- }
- else if (Model.Expired)
- {
-
- }
@if (Model.Creator != null && Model.Creator.Username.Length != 0)
{
@@ -66,14 +43,15 @@
}
}
-
-
+
@if (Model.Type.AffectsLevel())
{
SlotEntity? slot = await Model.GetSlotAsync(Database);
if (slot != null)
{
-
Affected level: @slot.Name
+
+ Affected level: @slot.Name (@slot.SlotId)
+
}
}
else if (Model.Type.AffectsUser())
@@ -81,10 +59,55 @@
UserEntity? user = await Model.GetUserAsync(Database);
if (user != null)
{
-
Affected user: @user.Username
+
+ Affected user: @user.Username (@user.UserId)
+
}
}
+
Case Status
+ @if (Model.Dismissed)
+ {
+ Debug.Assert(Model.DismissedAt != null);
+
+ @if (Model.Dismisser != null)
+ {
+
+
+
+ This case was dismissed by @Model.DismisserUsername on @TimeZoneInfo.ConvertTime(Model.DismissedAt.Value, timeZoneInfo).ToString("M/d/yyyy @ h:mm tt").
+
+
+ }
+ else
+ {
+
+
+
+ This case was dismissed by @Model.DismisserUsername on @TimeZoneInfo.ConvertTime(Model.DismissedAt.Value, timeZoneInfo).ToString("M/d/yyyy @ h:mm tt").
+
+
+ }
+ }
+ else if (Model.Expired)
+ {
+
+
+
+ This case expired on @TimeZoneInfo.ConvertTime(Model.ExpiresAt!.Value, timeZoneInfo).ToString("M/d/yyyy @ h:mm tt") and has been queued for dismissal.
+
+
+ }
+ else
+ {
+
+
+
+ This case is currently active and will expire on @TimeZoneInfo.ConvertTime(Model.ExpiresAt!.Value, timeZoneInfo).ToString("M/d/yyyy @ h:mm tt").
+
+
+ }
+
Reason
@if (!string.IsNullOrWhiteSpace(Model.Reason))
{
@@ -94,7 +117,7 @@
{
No reason was provided.
}
-
+
Moderator Notes
@if (!string.IsNullOrWhiteSpace(Model.ModeratorNotes))
{
@@ -104,8 +127,8 @@
{
No notes were provided.
}
-
- @if (!Model.Dismissed)
+
+ @if (Model is { Dismissed: false, Expired: false, })
{
diff --git a/ProjectLighthouse/Administration/Maintenance/RepeatingTasks/DismissExpiredCasesTask.cs b/ProjectLighthouse/Administration/Maintenance/RepeatingTasks/DismissExpiredCasesTask.cs
index 84b282ad..e6620662 100644
--- a/ProjectLighthouse/Administration/Maintenance/RepeatingTasks/DismissExpiredCasesTask.cs
+++ b/ProjectLighthouse/Administration/Maintenance/RepeatingTasks/DismissExpiredCasesTask.cs
@@ -14,7 +14,7 @@ namespace LBPUnion.ProjectLighthouse.Administration.Maintenance.RepeatingTasks;
public class DismissExpiredCasesTask : IRepeatingTask
{
public string Name => "Dismiss Expired Cases";
- public TimeSpan RepeatInterval => TimeSpan.FromHours(4);
+ public TimeSpan RepeatInterval => TimeSpan.FromHours(1);
public DateTime LastRan { get; set; }
public async Task Run(DatabaseContext database)
@@ -31,7 +31,8 @@ public class DismissExpiredCasesTask : IRepeatingTask
foreach (ModerationCaseEntity @case in expiredCases)
{
- @case.DismissedAt = DateTime.Now;
+ @case.DismissedAt = DateTime.UtcNow;
+ @case.DismisserUsername = "maintenance task";
Logger.Info($"Dismissed expired case {@case.CaseId}", LogArea.Maintenance);
}