UI redesign: improve readability and add candidate name display

- Add CandidateName property to VeracityReport and display on report page
- Simplify employment verification layout with compact row-based design
- Add UK employment history notice to Home and Check pages
- Improve hero section text readability with text shadow
- Update Login and Register page styling
- Remove Companies House references from UI text

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-21 09:01:01 +01:00
parent 45ca5f6a05
commit 4cc0bb3132
10 changed files with 1733 additions and 423 deletions

View File

@@ -106,6 +106,10 @@
<div class="d-flex justify-content-between align-items-start flex-wrap gap-3">
<div>
<h1 class="fw-bold mb-1">Verification Report</h1>
@if (!string.IsNullOrWhiteSpace(_report.CandidateName))
{
<h2 class="h4 text-primary mb-2">@_report.CandidateName</h2>
}
<p class="text-muted mb-0">
<span class="fw-medium text-dark">@_check.OriginalFileName</span>
<span class="mx-2">|</span>
@@ -149,7 +153,7 @@
<span class="score-max">/100</span>
</div>
</div>
<div class="mt-2 fw-semibold text-white">TrueCV Score</div>
<div class="mt-2 text-white truecv-score-label">TrueCV Score</div>
</div>
<div class="col-md-8">
<div class="row g-4 text-center text-md-start">
@@ -162,7 +166,7 @@
</svg>
</div>
<h3 class="mb-0 fw-bold text-white">@_report.EmploymentVerifications.Count</h3>
<small class="text-white-50">Employers Checked</small>
<small class="stat-label">Employers Checked</small>
</div>
</div>
<div class="col-4">
@@ -174,7 +178,7 @@
</svg>
</div>
<h3 class="mb-0 fw-bold text-white">@_report.TimelineAnalysis.TotalGapMonths</h3>
<small class="text-white-50">Gap Months</small>
<small class="stat-label">Gap Months</small>
</div>
</div>
<div class="col-4">
@@ -185,7 +189,7 @@
</svg>
</div>
<h3 class="mb-0 fw-bold text-white">@_report.Flags.Count</h3>
<small class="text-white-50">Flags Raised</small>
<small class="stat-label">Flags Raised</small>
</div>
</div>
</div>
@@ -208,102 +212,67 @@
</h5>
</div>
<div class="card-body p-0">
<div class="table-responsive">
<table class="table table-hover mb-0">
<thead style="background-color: var(--truecv-bg-muted);">
<tr>
<th>Claimed Employer</th>
<th>Period</th>
<th>Matched Company</th>
<th class="text-center">Match Score</th>
<th class="text-center">Status</th>
<th class="text-center">Points</th>
</tr>
</thead>
<tbody>
@for (int i = 0; i < _report.EmploymentVerifications.Count; i++)
{
var verification = _report.EmploymentVerifications[i];
var index = i;
<tr>
<td class="fw-medium">@verification.ClaimedCompany</td>
<td>
@if (verification.ClaimedStartDate.HasValue)
{
<span>@verification.ClaimedStartDate.Value.ToString("MMM yyyy")</span>
<span> - </span>
@if (verification.ClaimedEndDate.HasValue)
{
<span>@verification.ClaimedEndDate.Value.ToString("MMM yyyy")</span>
}
else
{
<span>Present</span>
}
}
else
{
<span class="text-muted">Not specified</span>
}
</td>
<td>
@if (!string.IsNullOrEmpty(verification.MatchedCompanyName))
{
<span>@verification.MatchedCompanyName</span>
@if (!string.IsNullOrEmpty(verification.MatchedCompanyNumber))
{
<br /><small class="text-muted">@verification.MatchedCompanyNumber</small>
}
}
else
{
<span class="text-muted">No match found</span>
}
</td>
<td class="text-center">
<span class="badge @GetMatchScoreBadgeClass(verification.MatchScore)">
@verification.MatchScore%
</span>
</td>
<td class="text-center">
@if (verification.IsVerified)
{
<span class="badge bg-success">Verified</span>
}
else
{
<span class="badge bg-warning text-dark">Unverified</span>
}
</td>
<td class="text-center">
@{
var companyPoints = GetPointsForCompany(verification.ClaimedCompany, verification.MatchedCompanyName, index);
}
@if (companyPoints < 0)
{
<span class="text-danger fw-medium">@companyPoints</span>
}
else
{
<span class="text-success">0</span>
}
</td>
</tr>
<div class="employment-list">
<div class="employment-header">
<div></div>
<div>Employer</div>
<div>Period</div>
<div>Match</div>
<div>Pts</div>
</div>
@for (int i = 0; i < _report.EmploymentVerifications.Count; i++)
{
var verification = _report.EmploymentVerifications[i];
var index = i;
var companyPoints = GetPointsForCompany(verification.ClaimedCompany, verification.MatchedCompanyName, index);
<div class="employment-row @(verification.IsVerified ? "employment-row-verified" : "employment-row-unverified")">
<div class="employment-status-icon">
@if (verification.IsVerified)
{
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" fill="currentColor" class="text-success" viewBox="0 0 16 16">
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zm-3.97-3.03a.75.75 0 0 0-1.08.022L7.477 9.417 5.384 7.323a.75.75 0 0 0-1.06 1.06L6.97 11.03a.75.75 0 0 0 1.079-.02l3.992-4.99a.75.75 0 0 0-.01-1.05z"/>
</svg>
}
else
{
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" fill="currentColor" class="text-warning" viewBox="0 0 16 16">
<path d="M8.982 1.566a1.13 1.13 0 0 0-1.96 0L.165 13.233c-.457.778.091 1.767.98 1.767h13.713c.889 0 1.438-.99.98-1.767L8.982 1.566zM8 5c.535 0 .954.462.9.995l-.35 3.507a.552.552 0 0 1-1.1 0L7.1 5.995A.905.905 0 0 1 8 5zm.002 6a1 1 0 1 1 0 2 1 1 0 0 1 0-2z"/>
</svg>
}
</div>
<div class="employment-company">
<span class="employment-company-name">@verification.ClaimedCompany</span>
@if (!string.IsNullOrEmpty(verification.VerificationNotes))
{
<tr class="table-light">
<td colspan="6" class="small text-muted py-1 ps-4">
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="currentColor" class="bi bi-info-circle me-1" viewBox="0 0 16 16">
<path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z"/>
<path d="m8.93 6.588-2.29.287-.082.38.45.083c.294.07.352.176.288.469l-.738 3.468c-.194.897.105 1.319.808 1.319.545 0 1.178-.252 1.465-.598l.088-.416c-.2.176-.492.246-.686.246-.275 0-.375-.193-.304-.533L8.93 6.588zM9 4.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0z"/>
</svg>
@verification.VerificationNotes
</td>
</tr>
<span class="employment-note-inline">@verification.VerificationNotes</span>
}
}
</tbody>
</table>
</div>
<div class="employment-dates">
@if (verification.ClaimedStartDate.HasValue)
{
<span>@verification.ClaimedStartDate.Value.ToString("MMM yyyy") @(verification.ClaimedEndDate?.ToString("MMM yyyy") ?? "Present")</span>
}
else
{
<span class="text-muted">—</span>
}
</div>
<div class="employment-score">
<span class="badge @GetMatchScoreBadgeClass(verification.MatchScore)">@verification.MatchScore%</span>
</div>
<div class="employment-points">
@if (companyPoints < 0)
{
<span class="text-danger fw-medium">@companyPoints</span>
}
else
{
<span class="text-success">0</span>
}
</div>
</div>
}
</div>
</div>
</div>
@@ -501,10 +470,23 @@
</div>
<style>
/* Score Header - Neutral Blue */
/* Score Header - Blue gradient */
.score-header {
background: linear-gradient(135deg, #1e40af 0%, #1e3a8a 100%);
background: linear-gradient(135deg, #2563EB 0%, #1D4ED8 100%);
color: white;
position: relative;
overflow: hidden;
}
.score-header::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-image: url("data:image/svg+xml,%3Csvg width='60' height='60' viewBox='0 0 60 60' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='none' fill-rule='evenodd'%3E%3Cg fill='%23ffffff' fill-opacity='0.06'%3E%3Cpath d='M36 34v-4h-2v4h-4v2h4v4h2v-4h4v-2h-4zm0-30V0h-2v4h-4v2h4v4h2V6h4V4h-4zM6 34v-4H4v4H0v2h4v4h2v-4h4v-2H6zM6 4V0H4v4H0v2h4v4h2V6h4V4H6z'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E");
pointer-events: none;
}
/* Score Roundel */
@@ -539,25 +521,25 @@
/* Score color variants - colours both the background ring and progress */
.score-roundel.score-high .score-ring-bg {
stroke: #4ade80;
stroke: rgba(255, 255, 255, 0.3);
}
.score-roundel.score-high .score-ring-progress {
stroke: #22c55e;
stroke: #4ade80;
}
.score-roundel.score-medium .score-ring-bg {
stroke: #ffdd44;
stroke: rgba(255, 255, 255, 0.3);
}
.score-roundel.score-medium .score-ring-progress {
stroke: #eab308;
stroke: #fbbf24;
}
.score-roundel.score-low .score-ring-bg {
stroke: #ff4d4d;
stroke: rgba(255, 255, 255, 0.3);
}
.score-roundel.score-low .score-ring-progress {
stroke: #dc2626;
stroke: #f87171;
}
.score-roundel .score-value-container {
@@ -577,10 +559,17 @@
.score-roundel .score-max {
font-size: 1rem;
opacity: 0.7;
opacity: 0.85;
color: white;
}
.truecv-score-label {
font-family: 'Inter', sans-serif;
font-weight: 700;
font-size: 0.875rem;
letter-spacing: 0.025em;
}
/* Stat Items */
.stat-item {
padding: 0.5rem;
@@ -598,6 +587,11 @@
color: white;
}
.stat-label {
color: rgba(255, 255, 255, 0.85);
font-size: 0.875rem;
}
/* Flag Items */
.flag-item {
border-radius: 12px;
@@ -640,6 +634,94 @@
border-radius: 4px;
}
/* Employment List - Compact Row Layout */
.employment-list {
border-top: 1px solid #e5e7eb;
}
.employment-header {
display: grid;
grid-template-columns: 24px 1fr auto 60px 50px;
gap: 0.5rem;
padding: 0.5rem 0.75rem;
background-color: #f8fafc;
border-bottom: 1px solid #e5e7eb;
font-size: 0.6875rem;
font-weight: 600;
color: #64748b;
text-transform: uppercase;
letter-spacing: 0.025em;
}
.employment-header div:nth-child(3),
.employment-header div:nth-child(4),
.employment-header div:nth-child(5) {
text-align: center;
}
.employment-row {
display: grid;
grid-template-columns: 24px 1fr auto 60px 50px;
gap: 0.5rem;
align-items: center;
padding: 0.5rem 0.75rem;
border-bottom: 1px solid #e5e7eb;
transition: background-color 0.15s ease;
}
.employment-row:hover {
background-color: #f9fafb;
}
.employment-row-verified {
border-left: 3px solid #22c55e;
}
.employment-row-unverified {
border-left: 3px solid #f59e0b;
}
.employment-status-icon {
display: flex;
align-items: center;
justify-content: center;
}
.employment-company {
display: flex;
flex-direction: column;
gap: 0.125rem;
min-width: 0;
}
.employment-company-name {
font-weight: 600;
font-size: 0.8125rem;
color: #1f2937;
}
.employment-note-inline {
font-size: 0.6875rem;
color: #6b7280;
line-height: 1.2;
}
.employment-dates {
font-size: 0.75rem;
color: #6b7280;
white-space: nowrap;
text-align: right;
}
.employment-score {
text-align: center;
}
.employment-points {
text-align: center;
font-size: 0.8125rem;
}
/* Mobile Responsiveness */
@@media (max-width: 768px) {
.score-header .row {
@@ -677,6 +759,24 @@
.page-header .btn {
width: 100%;
}
.employment-row {
grid-template-columns: 20px 1fr 50px;
gap: 0.25rem 0.5rem;
padding: 0.5rem;
}
.employment-dates {
display: none;
}
.employment-points {
display: none;
}
.employment-note-inline {
display: none;
}
}
</style>