@page "/dashboard" @attribute [Authorize] @rendermode InteractiveServer @implements IDisposable @inject ICVCheckService CVCheckService @inject NavigationManager NavigationManager @inject AuthenticationStateProvider AuthenticationStateProvider @inject ILogger Logger @inject IJSRuntime JSRuntime @inject TrueCV.Web.Services.PdfReportService PdfReportService Dashboard - TrueCV

Dashboard

View and manage your CV verification checks

New Check
@if (_isLoading) {
Loading...

Loading your checks...

} else if (!string.IsNullOrEmpty(_errorMessage)) { } else if (_checks.Count == 0) {

No CV Checks Yet

Start by uploading your first CV for verification

Upload CV
} else {

@_checks.Count

Total Checks

@_checks.Count(c => c.Status == "Completed")

Completed

@_checks.Count(c => c.Status is "Pending" or "Processing")

In Progress
Recent CV Checks
@foreach (var check in _checks) { }
File Name Date Status Score Actions
@check.OriginalFileName
@check.CreatedAt.ToString("dd MMM yyyy HH:mm") @switch (check.Status) { case "Completed": Completed break; case "Processing": Processing break; case "Pending": Pending break; case "Failed": Failed break; default: @check.Status break; } @if (check.VeracityScore.HasValue) { @check.VeracityScore } else { - } @if (check.Status == "Completed") { View Report } else if (check.Status is "Pending" or "Processing") { } else { Retry }
}
@code { private List _checks = []; private bool _isLoading = true; private bool _isExporting; private string? _errorMessage; private Guid _userId; private System.Threading.Timer? _pollingTimer; private bool _isPolling; protected override async Task OnInitializedAsync() { await LoadChecks(); StartPollingIfNeeded(); } private void StartPollingIfNeeded() { if (HasProcessingChecks() && !_isPolling) { _isPolling = true; _pollingTimer = new System.Threading.Timer(async _ => { await InvokeAsync(async () => { await LoadChecks(); if (!HasProcessingChecks()) { StopPolling(); } StateHasChanged(); }); }, null, TimeSpan.FromSeconds(3), TimeSpan.FromSeconds(3)); } } private bool HasProcessingChecks() { foreach (var c in _checks) { if (c.Status == "Processing" || c.Status == "Pending") return true; } return false; } private void StopPolling() { _isPolling = false; _pollingTimer?.Dispose(); _pollingTimer = null; } public void Dispose() { StopPolling(); } private async Task LoadChecks() { _isLoading = true; _errorMessage = null; try { var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync(); var userIdClaim = authState.User.FindFirst(ClaimTypes.NameIdentifier)?.Value; if (string.IsNullOrEmpty(userIdClaim) || !Guid.TryParse(userIdClaim, out _userId)) { _errorMessage = "Unable to identify user. Please log in again."; return; } _checks = await CVCheckService.GetUserChecksAsync(_userId); } catch (Exception ex) { Logger.LogError(ex, "Error loading CV checks"); _errorMessage = "An error occurred while loading checks. Please try again."; } finally { _isLoading = false; } } private void ViewReport(CVCheckDto check) { if (check.Status == "Completed") { NavigationManager.NavigateTo($"/report/{check.Id}"); } } private static string GetScoreBadgeClass(int score) { return score switch { > 70 => "bg-success", >= 50 => "bg-warning text-dark", _ => "bg-danger" }; } private async Task ExportToPdf() { if (_isExporting) return; _isExporting = true; StateHasChanged(); try { var reportDataList = new List(); foreach (var check in _checks) { if (check.Status != "Completed") continue; var report = await CVCheckService.GetReportAsync(check.Id, _userId); if (report is null) continue; int verifiedCount = 0; int unverifiedCount = 0; foreach (var v in report.EmploymentVerifications) { if (v.IsVerified) verifiedCount++; else unverifiedCount++; } int criticalFlags = 0; int warningFlags = 0; foreach (var f in report.Flags) { if (f.Severity == "Critical") criticalFlags++; else if (f.Severity == "Warning") warningFlags++; } reportDataList.Add(new TrueCV.Web.Services.PdfReportData { CandidateName = Path.GetFileNameWithoutExtension(check.OriginalFileName) ?? "Unknown", UploadDate = check.CreatedAt, Score = report.OverallScore, ScoreLabel = report.ScoreLabel, VerifiedEmployers = verifiedCount, UnverifiedEmployers = unverifiedCount, GapMonths = report.TimelineAnalysis.TotalGapMonths, OverlapMonths = report.TimelineAnalysis.TotalOverlapMonths, CriticalFlags = criticalFlags, WarningFlags = warningFlags }); } var pdfBytes = PdfReportService.GenerateReport(reportDataList); var base64 = Convert.ToBase64String(pdfBytes); var fileName = "TrueCV_Report_" + DateTime.Now.ToString("yyyyMMdd_HHmmss") + ".pdf"; await JSRuntime.InvokeVoidAsync("downloadFile", fileName, base64, "application/pdf"); } catch (Exception ex) { Logger.LogError(ex, "Error exporting PDF"); } finally { _isExporting = false; StateHasChanged(); } } private bool HasCompletedChecks() { foreach (var c in _checks) { if (c.Status == "Completed") return true; } return false; } }