@page "/audit-logs" @using Microsoft.AspNetCore.Authorization @using Microsoft.AspNetCore.Components.Authorization @using TaskTrackingSystem.Shared.Models.AuditLog @using TaskTrackingSystem.WebApp.Components.Partial @rendermode @(new InteractiveServerRenderMode(prerender: false)) @attribute [Authorize] @inject ApiClientService ApiClient @inject IJSRuntime JS @inject AuthenticationStateProvider AuthStateProvider @AppLocalization.PageTitle("auditLogs", "Audit Logs")

@AppLocalization.PageTitle("auditLogs", "Audit Logs")

@AppLocalization.PageDescription("auditLogs", "Review system activity and changes.")

@if (isLoading) { } else {
@if (PagedLogs.Any()) { @foreach (var entry in PagedLogs.Select((log, index) => (log, index))) { var log = entry.log; } } else { }
@AppLocalization.Text("common.index", "No.") @AppLocalization.Text("common.date", "Timestamp") @AppLocalization.Text("common.user", "User") @AppLocalization.Text("common.module", "Module") @AppLocalization.Text("common.actions", "Action") @AppLocalization.Text("common.description", "Description") @AppLocalization.Text("field.ipAddress", "IP Address")
@AppLocalization.Number((currentPage - 1) * pageSize + entry.index + 1) @AppLocalization.LocalizeDigits(log.CreatedAt.ToString("dd-MM-yyyy HH:mm:ss", System.Globalization.CultureInfo.InvariantCulture))
@(GetAuditUserName(log).Length > 0 ? GetAuditUserName(log)[0].ToString().ToUpper() : "S")

@GetAuditUserName(log)

@@@log.Username

@AppLocalization.ModuleName(log.Module) @AppLocalization.ActionName(log.Action) @AppLocalization.AuditDescription(log.Description) @(string.IsNullOrWhiteSpace(log.IpAddress) ? AppLocalization.Text("common.na", "N/A") : AppLocalization.LocalizeDigits(log.IpAddress))
}
@code { private bool isLoading = true; private List auditLogs = new(); private string searchInput = ""; // Pagination state private int currentPage = 1; private int pageSize = 15; private int totalCount = 0; private int totalPages = 0; private int TotalPages => totalPages; private int TotalCount => totalCount; private IEnumerable PagedLogs => auditLogs; protected override async Task OnInitializedAsync() { await LoadLogs(); } protected override async Task OnAfterRenderAsync(bool firstRender) { await JS.InvokeVoidAsync("initIcons"); } private async Task LoadLogs() { isLoading = true; var client = ApiClient.CreateClient(); try { var url = BuildAuditLogsUrl(); var result = await client.GetFromJsonAsync>(url, Serialization.CaseInsensitive); auditLogs = result?.Items ?? new(); totalCount = result?.TotalCount ?? 0; totalPages = result?.TotalPages ?? 0; currentPage = result?.Page ?? currentPage; pageSize = result?.PageSize ?? pageSize; } catch (Exception ex) { Console.WriteLine($"Load audit logs error: {ex.Message}"); } finally { isLoading = false; } } private async Task ApplySearch() { currentPage = 1; await LoadLogs(); } private async Task ResetSearch() { searchInput = ""; currentPage = 1; await LoadLogs(); } private async Task HandleKeyUp(KeyboardEventArgs e) { if (e.Key == "Enter") { await ApplySearch(); } } private string GetAuditUserName(AuditLogDto log) { if (string.Equals(log.UserFullName, "System Admin", StringComparison.OrdinalIgnoreCase)) { return AppLocalization.Text("common.systemAdmin", "System Admin"); } if (string.Equals(log.UserFullName, "System", StringComparison.OrdinalIgnoreCase)) { return AppLocalization.Text("notification.system", "System"); } return Content.GetText(log.UserFullName, log.UserFullNameMy); } private string BuildAuditLogsUrl() { var query = new List { $"page={currentPage}", $"limit={pageSize}" }; if (!string.IsNullOrWhiteSpace(searchInput)) { query.Add($"search={Uri.EscapeDataString(searchInput.Trim())}"); } return $"AuditLog?{string.Join("&", query)}"; } private async Task HandlePageChanged(int page) { currentPage = page; await LoadLogs(); } private async Task HandlePageSizeChanged(int size) { pageSize = size; currentPage = 1; await LoadLogs(); } private string GetActionBadge(string action) { return action.ToLower() switch { "create" => "bg-emerald-50 text-emerald-700 border border-emerald-200", "update" => "bg-amber-50 text-amber-700 border border-amber-200", "delete" => "bg-rose-50 text-rose-700 border border-rose-200", "assignaccess" => "bg-violet-50 text-violet-700 border border-violet-200", _ => "bg-blue-50 text-blue-700 border border-blue-200" }; } }