diff --git a/src/AliasVault.Admin/Main/Pages/Dashboard/Components/ActiveUsersCard.razor b/src/AliasVault.Admin/Main/Pages/Dashboard/Components/ActiveUsersCard.razor
index 53bfb37e5..b0dfe4968 100644
--- a/src/AliasVault.Admin/Main/Pages/Dashboard/Components/ActiveUsersCard.razor
+++ b/src/AliasVault.Admin/Main/Pages/Dashboard/Components/ActiveUsersCard.razor
@@ -1,11 +1,6 @@
Total active users
-
@if (IsLoading)
{
@@ -16,63 +11,31 @@
Last 24 hours
-
@UserStats.Last24Hours
- @if (ShowUserNames)
- {
-
-
- @foreach (var user in UserStats.Last24HourUsers)
- {
- - @user
- }
-
-
- }
+
+
@UserStats.Last24Hours
+ (@UserStats.ReturningLast24Hours)
+
Last 3 days
-
@UserStats.Last3Days
- @if (ShowUserNames)
- {
-
-
- @foreach (var user in UserStats.Last3DayUsers)
- {
- - @user
- }
-
-
- }
+
+
@UserStats.Last3Days
+ (@UserStats.ReturningLast3Days)
+
Last 7 days
-
@UserStats.Last7Days
- @if (ShowUserNames)
- {
-
-
- @foreach (var user in UserStats.Last7DayUsers)
- {
- - @user
- }
-
-
- }
+
+
@UserStats.Last7Days
+ (@UserStats.ReturningLast7Days)
+
-
Last 14 days
-
@UserStats.Last14Days
- @if (ShowUserNames)
- {
-
-
- @foreach (var user in UserStats.Last14DayUsers)
- {
- - @user
- }
-
-
- }
+
Last 30 days
+
+
@UserStats.Last30Days
+ (@UserStats.ReturningLast30Days)
+
}
@@ -81,7 +44,6 @@
@code {
private bool IsLoading { get; set; } = true;
private UserStatistics UserStats { get; set; } = new();
- private bool ShowUserNames { get; set; }
///
/// Refreshes the data displayed on the card.
@@ -95,50 +57,56 @@
var last24Hours = now.AddHours(-24);
var last3Days = now.AddDays(-3);
var last7Days = now.AddDays(-7);
- var last14Days = now.AddDays(-14);
+ var last30Days = now.AddDays(-30);
// Get user statistics
- var (count24h, users24h) = await GetActiveUserCount(last24Hours);
- var (count3d, users3d) = await GetActiveUserCount(last3Days);
- var (count7d, users7d) = await GetActiveUserCount(last7Days);
- var (count14d, users14d) = await GetActiveUserCount(last14Days);
+ var (count24h, returning24h) = await GetActiveUserCount(last24Hours);
+ var (count3d, returning3d) = await GetActiveUserCount(last3Days);
+ var (count7d, returning7d) = await GetActiveUserCount(last7Days);
+ var (count30d, returning30d) = await GetActiveUserCount(last30Days);
UserStats = new UserStatistics
{
Last24Hours = count24h,
Last3Days = count3d,
Last7Days = count7d,
- Last14Days = count14d,
- Last24HourUsers = users24h,
- Last3DayUsers = users3d,
- Last7DayUsers = users7d,
- Last14DayUsers = users14d
+ Last30Days = count30d,
+ ReturningLast24Hours = returning24h,
+ ReturningLast3Days = returning3d,
+ ReturningLast7Days = returning7d,
+ ReturningLast30Days = returning30d,
};
IsLoading = false;
StateHasChanged();
}
- private async Task<(int count, List users)> GetActiveUserCount(DateTime since)
+ private async Task<(int totalCount, int returningCount)> GetActiveUserCount(DateTime since)
{
- // Get unique users who:
- // 1. Have successful auth logs
- // 2. Are not the admin user
await using var dbContext = await DbContextFactory.CreateDbContextAsync();
+ // Get all active users for the period
var activeUsers = await dbContext.AuthLogs
.Where(l => l.Timestamp >= since && l.IsSuccess && l.Username != "admin")
.Select(l => l.Username)
.Distinct()
.ToListAsync();
- return (activeUsers.Count, activeUsers);
- }
+ // Get returning users (those who have activity at least 24h after registration
+ var returningUsers = await dbContext.AuthLogs
+ .Where(l => l.Timestamp >= since && l.IsSuccess && l.Username != "admin")
+ .Join(
+ dbContext.AliasVaultUsers,
+ log => log.Username,
+ user => user.UserName,
+ (log, user) => new { log, user }
+ )
+ .Where(x => x.log.Timestamp >= x.user.CreatedAt.AddHours(24))
+ .Select(x => x.log.Username)
+ .Distinct()
+ .ToListAsync();
- private void ToggleUserNames()
- {
- ShowUserNames = !ShowUserNames;
- StateHasChanged();
+ return (activeUsers.Count, returningUsers.Count);
}
private sealed class UserStatistics
@@ -146,10 +114,10 @@
public int Last24Hours { get; set; }
public int Last3Days { get; set; }
public int Last7Days { get; set; }
- public int Last14Days { get; set; }
- public List Last24HourUsers { get; set; } = new();
- public List Last3DayUsers { get; set; } = new();
- public List Last7DayUsers { get; set; } = new();
- public List Last14DayUsers { get; set; } = new();
+ public int Last30Days { get; set; }
+ public int ReturningLast24Hours { get; set; }
+ public int ReturningLast3Days { get; set; }
+ public int ReturningLast7Days { get; set; }
+ public int ReturningLast30Days { get; set; }
}
}
diff --git a/src/AliasVault.Admin/Main/Pages/Dashboard/Components/EmailClaimsCard.razor b/src/AliasVault.Admin/Main/Pages/Dashboard/Components/EmailClaimsCard.razor
index 2764776c0..57942b8fd 100644
--- a/src/AliasVault.Admin/Main/Pages/Dashboard/Components/EmailClaimsCard.razor
+++ b/src/AliasVault.Admin/Main/Pages/Dashboard/Components/EmailClaimsCard.razor
@@ -27,8 +27,8 @@
@EmailClaimsStats.Days7.ToString("N0")
-
Last 14 days
-
@EmailClaimsStats.Days14.ToString("N0")
+
Last 30 days
+
@EmailClaimsStats.Days30.ToString("N0")
}
@@ -95,7 +95,7 @@
var hours24 = now.AddHours(-24);
var days3 = now.AddDays(-3);
var days7 = now.AddDays(-7);
- var days14 = now.AddDays(-14);
+ var days30 = now.AddDays(-30);
// Get email claims statistics
await using var dbContext = await DbContextFactory.CreateDbContextAsync();
@@ -105,7 +105,7 @@
Hours24 = await emailClaimsQuery.CountAsync(e => e.CreatedAt >= hours24),
Days3 = await emailClaimsQuery.CountAsync(e => e.CreatedAt >= days3),
Days7 = await emailClaimsQuery.CountAsync(e => e.CreatedAt >= days7),
- Days14 = await emailClaimsQuery.CountAsync(e => e.CreatedAt >= days14)
+ Days30 = await emailClaimsQuery.CountAsync(e => e.CreatedAt >= days30)
};
}
@@ -142,6 +142,7 @@
claimCount => claimCount.Date,
(date, claimCounts) => claimCounts.FirstOrDefault() ?? new DailyEmailClaimCount { Date = date, Count = 0 }
)
+ .OrderByDescending(e => e.Date)
.ToList();
}
}
@@ -166,7 +167,7 @@
public int Hours24 { get; set; }
public int Days3 { get; set; }
public int Days7 { get; set; }
- public int Days14 { get; set; }
+ public int Days30 { get; set; }
}
private sealed class DailyEmailClaimCount
diff --git a/src/AliasVault.Admin/Main/Pages/Dashboard/Components/EmailStatisticsCard.razor b/src/AliasVault.Admin/Main/Pages/Dashboard/Components/EmailStatisticsCard.razor
index 66ad0c140..7ef5cfb56 100644
--- a/src/AliasVault.Admin/Main/Pages/Dashboard/Components/EmailStatisticsCard.razor
+++ b/src/AliasVault.Admin/Main/Pages/Dashboard/Components/EmailStatisticsCard.razor
@@ -27,8 +27,8 @@
@EmailStats.Days7.ToString("N0")
-
Last 14 days
-
@EmailStats.Days14.ToString("N0")
+
Last 30 days
+
@EmailStats.Days30.ToString("N0")
}
@@ -95,7 +95,7 @@
var hours24 = now.AddHours(-24);
var days3 = now.AddDays(-3);
var days7 = now.AddDays(-7);
- var days14 = now.AddDays(-14);
+ var days30 = now.AddDays(-30);
// Get email statistics
await using var dbContext = await DbContextFactory.CreateDbContextAsync();
@@ -105,7 +105,7 @@
Hours24 = await emailQuery.CountAsync(e => e.DateSystem >= hours24),
Days3 = await emailQuery.CountAsync(e => e.DateSystem >= days3),
Days7 = await emailQuery.CountAsync(e => e.DateSystem >= days7),
- Days14 = await emailQuery.CountAsync(e => e.DateSystem >= days14)
+ Days30 = await emailQuery.CountAsync(e => e.DateSystem >= days30)
};
}
@@ -142,6 +142,7 @@
emailCount => emailCount.Date,
(date, emailCounts) => emailCounts.FirstOrDefault() ?? new DailyEmailCount { Date = date, Count = 0 }
)
+ .OrderByDescending(e => e.Date)
.ToList();
}
}
@@ -166,7 +167,7 @@
public int Hours24 { get; set; }
public int Days3 { get; set; }
public int Days7 { get; set; }
- public int Days14 { get; set; }
+ public int Days30 { get; set; }
}
private sealed class DailyEmailCount
diff --git a/src/AliasVault.Admin/Main/Pages/Dashboard/Components/RegistrationStatisticsCard.razor b/src/AliasVault.Admin/Main/Pages/Dashboard/Components/RegistrationStatisticsCard.razor
index 973c5fa92..651b863c7 100644
--- a/src/AliasVault.Admin/Main/Pages/Dashboard/Components/RegistrationStatisticsCard.razor
+++ b/src/AliasVault.Admin/Main/Pages/Dashboard/Components/RegistrationStatisticsCard.razor
@@ -22,8 +22,8 @@
@RegistrationStats.Days7.ToString("N0")
-
Last 14 days
-
@RegistrationStats.Days14.ToString("N0")
+
Last 30 days
+
@RegistrationStats.Days30.ToString("N0")
}
@@ -45,7 +45,7 @@
var hours24 = now.AddHours(-24);
var days3 = now.AddDays(-3);
var days7 = now.AddDays(-7);
- var days14 = now.AddDays(-14);
+ var days30 = now.AddDays(-30);
// Get registration statistics
await using var dbContext = await DbContextFactory.CreateDbContextAsync();
@@ -55,7 +55,7 @@
Hours24 = await registrationQuery.CountAsync(u => u.CreatedAt >= hours24),
Days3 = await registrationQuery.CountAsync(u => u.CreatedAt >= days3),
Days7 = await registrationQuery.CountAsync(u => u.CreatedAt >= days7),
- Days14 = await registrationQuery.CountAsync(u => u.CreatedAt >= days14)
+ Days30 = await registrationQuery.CountAsync(u => u.CreatedAt >= days30)
};
IsLoading = false;
@@ -67,6 +67,6 @@
public int Hours24 { get; set; }
public int Days3 { get; set; }
public int Days7 { get; set; }
- public int Days14 { get; set; }
+ public int Days30 { get; set; }
}
}
diff --git a/src/AliasVault.Admin/wwwroot/css/tailwind.css b/src/AliasVault.Admin/wwwroot/css/tailwind.css
index 7a3386738..1db02e6dd 100644
--- a/src/AliasVault.Admin/wwwroot/css/tailwind.css
+++ b/src/AliasVault.Admin/wwwroot/css/tailwind.css
@@ -723,10 +723,6 @@ video {
margin-inline-start: 0.25rem;
}
-.ms-2 {
- margin-inline-start: 0.5rem;
-}
-
.mt-0 {
margin-top: 0px;
}
@@ -980,6 +976,10 @@ video {
align-items: center;
}
+.items-baseline {
+ align-items: baseline;
+}
+
.justify-start {
justify-content: flex-start;
}
@@ -996,6 +996,10 @@ video {
justify-content: space-between;
}
+.gap-2 {
+ gap: 0.5rem;
+}
+
.gap-4 {
gap: 1rem;
}
@@ -1004,10 +1008,6 @@ video {
gap: 2rem;
}
-.gap-2 {
- gap: 0.5rem;
-}
-
.space-x-1 > :not([hidden]) ~ :not([hidden]) {
--tw-space-x-reverse: 0;
margin-right: calc(0.25rem * var(--tw-space-x-reverse));