feat: Add Education Verification section and use neutral language
- Add Education Verification section to report UI showing institution
verification status, qualifications, and dates
- Add differentiated icons for Information flags (career, timeline,
management, education types)
- Change potentially defamatory language to neutral terms:
- "Diploma Mill" → "Not Accredited"
- "Suspicious" → "Unrecognised"
- Flag descriptions now recommend manual verification rather than
making definitive claims about institution legitimacy
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -398,8 +398,8 @@ public sealed class ProcessCVCheckJob
|
||||
{
|
||||
Category = FlagCategory.Education.ToString(),
|
||||
Severity = FlagSeverity.Critical.ToString(),
|
||||
Title = "Diploma Mill Detected",
|
||||
Description = $"'{edu.ClaimedInstitution}' is a known diploma mill. {edu.VerificationNotes}",
|
||||
Title = "Unaccredited Institution",
|
||||
Description = $"'{edu.ClaimedInstitution}' was not found in accredited institutions databases. Manual verification recommended.",
|
||||
ScoreImpact = -DiplomaMillPenalty
|
||||
});
|
||||
}
|
||||
@@ -413,8 +413,8 @@ public sealed class ProcessCVCheckJob
|
||||
{
|
||||
Category = FlagCategory.Education.ToString(),
|
||||
Severity = FlagSeverity.Warning.ToString(),
|
||||
Title = "Suspicious Institution",
|
||||
Description = $"'{edu.ClaimedInstitution}' has suspicious characteristics. {edu.VerificationNotes}",
|
||||
Title = "Unrecognised Institution",
|
||||
Description = $"'{edu.ClaimedInstitution}' was not found in recognised institutions databases. Manual verification recommended.",
|
||||
ScoreImpact = -SuspiciousInstitutionPenalty
|
||||
});
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ public sealed class EducationVerifierService : IEducationVerifierService
|
||||
IsVerified = false,
|
||||
IsDiplomaMill = true,
|
||||
IsSuspicious = true,
|
||||
VerificationNotes = "Institution is on the diploma mill blacklist",
|
||||
VerificationNotes = "Institution not found in accredited institutions database",
|
||||
ClaimedStartDate = education.StartDate,
|
||||
ClaimedEndDate = education.EndDate,
|
||||
DatesArePlausible = true,
|
||||
@@ -43,7 +43,7 @@ public sealed class EducationVerifierService : IEducationVerifierService
|
||||
IsVerified = false,
|
||||
IsDiplomaMill = false,
|
||||
IsSuspicious = true,
|
||||
VerificationNotes = "Institution name contains suspicious patterns common in diploma mills",
|
||||
VerificationNotes = "Institution not found in recognised institutions database",
|
||||
ClaimedStartDate = education.StartDate,
|
||||
ClaimedEndDate = education.EndDate,
|
||||
DatesArePlausible = true,
|
||||
|
||||
@@ -281,6 +281,100 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Education Verification -->
|
||||
@if (_report.EducationVerifications.Count > 0)
|
||||
{
|
||||
<div class="card border-0 shadow-sm mb-4">
|
||||
<div class="card-header py-3" style="background-color: var(--realcv-bg-surface);">
|
||||
<h5 class="mb-0 fw-bold">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" class="bi bi-mortarboard me-2" viewBox="0 0 16 16">
|
||||
<path d="M8.211 2.047a.5.5 0 0 0-.422 0l-7.5 3.5a.5.5 0 0 0 .025.917l7.5 3a.5.5 0 0 0 .372 0L14 7.14V13a1 1 0 0 0-1 1v2h3v-2a1 1 0 0 0-1-1V6.739l.686-.275a.5.5 0 0 0 .025-.917l-7.5-3.5ZM8 8.46 1.758 5.965 8 3.052l6.242 2.913L8 8.46Z"/>
|
||||
<path d="M4.176 9.032a.5.5 0 0 0-.656.327l-.5 1.7a.5.5 0 0 0 .294.605l4.5 1.8a.5.5 0 0 0 .372 0l4.5-1.8a.5.5 0 0 0 .294-.605l-.5-1.7a.5.5 0 0 0-.656-.327L8 10.466 4.176 9.032Zm-.068 1.873.22-.748L8 11.533l3.672-1.41.22.748L8 12.46l-3.892-1.556Z"/>
|
||||
</svg>
|
||||
Education Verification
|
||||
</h5>
|
||||
</div>
|
||||
<div class="card-body p-0">
|
||||
<div class="education-list">
|
||||
<div class="education-header">
|
||||
<div style="text-align: center;"></div>
|
||||
<div>Institution</div>
|
||||
<div>Qualification</div>
|
||||
<div style="text-align: center;">Period</div>
|
||||
<div style="text-align: center;">Status</div>
|
||||
</div>
|
||||
@foreach (var edu in _report.EducationVerifications)
|
||||
{
|
||||
<div class="education-row @GetEducationRowClass(edu)">
|
||||
<div class="education-status-icon">
|
||||
@if (edu.IsDiplomaMill)
|
||||
{
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" fill="currentColor" class="text-danger" 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="M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708z"/>
|
||||
</svg>
|
||||
}
|
||||
else if (edu.IsSuspicious)
|
||||
{
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" fill="currentColor" class="text-danger" 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>
|
||||
}
|
||||
else if (edu.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 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="M5.255 5.786a.237.237 0 0 0 .241.247h.825c.138 0 .248-.113.266-.25.09-.656.54-1.134 1.342-1.134.686 0 1.314.343 1.314 1.168 0 .635-.374.927-.965 1.371-.673.489-1.206 1.06-1.168 1.987l.003.217a.25.25 0 0 0 .25.246h.811a.25.25 0 0 0 .25-.25v-.105c0-.718.273-.927 1.01-1.486.609-.463 1.244-.977 1.244-2.056 0-1.511-1.276-2.241-2.673-2.241-1.267 0-2.655.59-2.75 2.286zm1.557 5.763c0 .533.425.927 1.01.927.609 0 1.028-.394 1.028-.927 0-.552-.42-.94-1.029-.94-.584 0-1.009.388-1.009.94z"/>
|
||||
</svg>
|
||||
}
|
||||
</div>
|
||||
<div class="education-institution">
|
||||
<span class="education-institution-name">@edu.ClaimedInstitution</span>
|
||||
@if (!string.IsNullOrEmpty(edu.MatchedInstitution) && !edu.ClaimedInstitution.Equals(edu.MatchedInstitution, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
<span class="education-matched-name">Matched: @edu.MatchedInstitution</span>
|
||||
}
|
||||
@if (!string.IsNullOrEmpty(edu.VerificationNotes))
|
||||
{
|
||||
<span class="education-note-inline">@edu.VerificationNotes</span>
|
||||
}
|
||||
</div>
|
||||
<div class="education-qualification">
|
||||
@if (!string.IsNullOrEmpty(edu.ClaimedQualification) || !string.IsNullOrEmpty(edu.ClaimedSubject))
|
||||
{
|
||||
<span>@(edu.ClaimedQualification ?? "") @(edu.ClaimedSubject ?? "")</span>
|
||||
}
|
||||
else
|
||||
{
|
||||
<span class="text-muted">—</span>
|
||||
}
|
||||
</div>
|
||||
<div class="education-dates">
|
||||
@if (edu.ClaimedStartDate.HasValue || edu.ClaimedEndDate.HasValue)
|
||||
{
|
||||
<span>@(edu.ClaimedStartDate?.ToString("yyyy") ?? "?") – @(edu.ClaimedEndDate?.ToString("yyyy") ?? "?")</span>
|
||||
}
|
||||
else
|
||||
{
|
||||
<span class="text-muted">—</span>
|
||||
}
|
||||
</div>
|
||||
<div class="education-status">
|
||||
<span class="badge @GetEducationStatusBadgeClass(edu)">@GetEducationStatusLabel(edu)</span>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
<!-- Timeline Analysis -->
|
||||
<div class="row mb-4">
|
||||
<!-- Gaps -->
|
||||
@@ -462,9 +556,14 @@
|
||||
@foreach (var flag in infoFlags)
|
||||
{
|
||||
<div class="flag-item flag-info">
|
||||
<div class="d-flex align-items-start">
|
||||
<span class="info-flag-icon me-2">@GetInfoFlagIcon(flag.Title)</span>
|
||||
<div>
|
||||
<strong class="flag-title">@flag.Title</strong>
|
||||
<p class="flag-description">@flag.Description</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
@@ -623,6 +722,13 @@
|
||||
border-left-color: var(--realcv-primary);
|
||||
}
|
||||
|
||||
.info-flag-icon {
|
||||
flex-shrink: 0;
|
||||
color: var(--realcv-primary);
|
||||
opacity: 0.85;
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.flag-title {
|
||||
font-weight: 600;
|
||||
margin-bottom: 0.25rem;
|
||||
@@ -745,6 +851,122 @@
|
||||
font-size: 0.8125rem;
|
||||
}
|
||||
|
||||
/* Education List - Compact Row Layout */
|
||||
.education-list {
|
||||
border-top: 1px solid #e5e7eb;
|
||||
}
|
||||
|
||||
.education-header {
|
||||
display: grid;
|
||||
grid-template-columns: 24px 1fr 1fr 100px 90px;
|
||||
gap: 0.5rem;
|
||||
padding: 0.5rem 0.75rem;
|
||||
background-color: #f8fafc;
|
||||
border-bottom: 1px solid #e5e7eb;
|
||||
font-size: 0.75rem;
|
||||
font-weight: 600;
|
||||
color: #475569;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.025em;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.education-header div {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.education-header div:nth-child(4),
|
||||
.education-header div:nth-child(5) {
|
||||
justify-content: center;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.education-row {
|
||||
display: grid;
|
||||
grid-template-columns: 24px 1fr 1fr 100px 90px;
|
||||
gap: 0.5rem;
|
||||
align-items: center;
|
||||
padding: 0.5rem 0.75rem;
|
||||
border-bottom: 1px solid #e5e7eb;
|
||||
transition: background-color 0.15s ease;
|
||||
}
|
||||
|
||||
.education-row:hover {
|
||||
background-color: #f9fafb;
|
||||
}
|
||||
|
||||
.education-row-verified {
|
||||
border-left: 3px solid #22c55e;
|
||||
}
|
||||
|
||||
.education-row-unknown {
|
||||
border-left: 3px solid #f59e0b;
|
||||
}
|
||||
|
||||
.education-row-suspicious {
|
||||
border-left: 3px solid #ef4444;
|
||||
background-color: #fef2f2;
|
||||
}
|
||||
|
||||
.education-row-diploma-mill {
|
||||
border-left: 3px solid #dc2626;
|
||||
background-color: #fef2f2;
|
||||
}
|
||||
|
||||
.education-status-icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.education-institution {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
gap: 0.125rem;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.education-institution-name {
|
||||
font-weight: 600;
|
||||
font-size: 0.8125rem;
|
||||
color: #1f2937;
|
||||
}
|
||||
|
||||
.education-matched-name {
|
||||
font-size: 0.75rem;
|
||||
color: #059669;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.education-note-inline {
|
||||
font-size: 0.75rem;
|
||||
color: #4b5563;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.education-qualification {
|
||||
font-size: 0.8125rem;
|
||||
color: #4b5563;
|
||||
}
|
||||
|
||||
.education-dates {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 0.8125rem;
|
||||
color: #4b5563;
|
||||
white-space: nowrap;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.education-status {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
/* Mobile Responsiveness */
|
||||
@@media (max-width: 768px) {
|
||||
.score-header .row {
|
||||
@@ -800,6 +1022,37 @@
|
||||
.employment-note-inline {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.education-row {
|
||||
grid-template-columns: 20px 1fr 70px;
|
||||
gap: 0.25rem 0.5rem;
|
||||
padding: 0.5rem;
|
||||
}
|
||||
|
||||
.education-header {
|
||||
grid-template-columns: 20px 1fr 70px;
|
||||
}
|
||||
|
||||
.education-header div:nth-child(3),
|
||||
.education-header div:nth-child(4) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.education-qualification {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.education-dates {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.education-note-inline {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.education-matched-name {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -955,6 +1208,37 @@
|
||||
};
|
||||
}
|
||||
|
||||
private static string GetEducationRowClass(EducationVerificationResult edu)
|
||||
{
|
||||
if (edu.IsDiplomaMill) return "education-row-diploma-mill";
|
||||
if (edu.IsSuspicious) return "education-row-suspicious";
|
||||
if (edu.IsVerified) return "education-row-verified";
|
||||
return "education-row-unknown";
|
||||
}
|
||||
|
||||
private static string GetEducationStatusBadgeClass(EducationVerificationResult edu)
|
||||
{
|
||||
return edu.Status switch
|
||||
{
|
||||
"Recognised" => "bg-success",
|
||||
"DiplomaMill" => "bg-danger",
|
||||
"Suspicious" => "bg-danger",
|
||||
_ => "bg-warning text-dark"
|
||||
};
|
||||
}
|
||||
|
||||
private static string GetEducationStatusLabel(EducationVerificationResult edu)
|
||||
{
|
||||
return edu.Status switch
|
||||
{
|
||||
"Recognised" => "Verified",
|
||||
"DiplomaMill" => "Not Accredited",
|
||||
"Suspicious" => "Unrecognised",
|
||||
"Unknown" => "Unverified",
|
||||
_ => edu.Status
|
||||
};
|
||||
}
|
||||
|
||||
private static string FormatFlagTitle(string title)
|
||||
{
|
||||
// Convert variable-style names to readable sentences
|
||||
@@ -972,6 +1256,42 @@
|
||||
};
|
||||
}
|
||||
|
||||
private static MarkupString GetInfoFlagIcon(string title)
|
||||
{
|
||||
var icon = title switch
|
||||
{
|
||||
// Career timeline icons
|
||||
"Career Span" => """<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" fill="currentColor" viewBox="0 0 16 16"><path d="M8 3.5a.5.5 0 0 0-1 0V9a.5.5 0 0 0 .252.434l3.5 2a.5.5 0 0 0 .496-.868L8 8.71V3.5z"/><path d="M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16zm7-8A7 7 0 1 1 1 8a7 7 0 0 1 14 0z"/></svg>""",
|
||||
"Employment Gap" => """<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" fill="currentColor" viewBox="0 0 16 16"><path d="M8.515 1.019A7 7 0 0 0 8 1V0a8 8 0 0 1 .589.022l-.074.997zm2.004.45a7.003 7.003 0 0 0-.985-.299l.219-.976c.383.086.76.2 1.126.342l-.36.933zm1.37.71a7.01 7.01 0 0 0-.439-.27l.493-.87a8.025 8.025 0 0 1 .979.654l-.615.789a6.996 6.996 0 0 0-.418-.302zm1.834 1.79a6.99 6.99 0 0 0-.653-.796l.724-.69c.27.285.52.59.747.91l-.818.576zm.744 1.352a7.08 7.08 0 0 0-.214-.468l.893-.45a7.976 7.976 0 0 1 .45 1.088l-.95.313a7.023 7.023 0 0 0-.179-.483zm.53 2.507a6.991 6.991 0 0 0-.1-1.025l.985-.17c.067.386.106.778.116 1.17l-1 .025zm-.131 1.538c.033-.17.06-.339.081-.51l.993.123a7.957 7.957 0 0 1-.23 1.155l-.964-.267c.046-.165.086-.332.12-.501zm-.952 2.379c.184-.29.346-.594.486-.908l.914.405c-.16.36-.345.706-.555 1.038l-.845-.535zm-.964 1.205c.122-.122.239-.248.35-.378l.758.653a8.073 8.073 0 0 1-.401.432l-.707-.707z"/><path d="M8 1a7 7 0 1 0 4.95 11.95l.707.707A8.001 8.001 0 1 1 8 0v1z"/><path d="M7.5 3a.5.5 0 0 1 .5.5v5.21l3.248 1.856a.5.5 0 0 1-.496.868l-3.5-2A.5.5 0 0 1 7 9V3.5a.5.5 0 0 1 .5-.5z"/></svg>""",
|
||||
"Concurrent Employment" => """<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" fill="currentColor" viewBox="0 0 16 16"><path d="M0 2a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2v2h2a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2v-2H2a2 2 0 0 1-2-2V2zm5 10v2a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1V6a1 1 0 0 0-1-1h-2v5a2 2 0 0 1-2 2H5zm6-8V2a1 1 0 0 0-1-1H2a1 1 0 0 0-1 1v8a1 1 0 0 0 1 1h2V6a2 2 0 0 1 2-2h5z"/></svg>""",
|
||||
"Average Tenure" or "Frequent Job Changes" => """<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" fill="currentColor" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M0 3.5A.5.5 0 0 1 .5 3H1c2.202 0 3.827 1.24 4.874 2.418.49.552.865 1.102 1.126 1.532.26-.43.636-.98 1.126-1.532C9.173 4.24 10.798 3 13 3v1c-1.798 0-3.173 1.01-4.126 2.082A9.624 9.624 0 0 0 7.556 8a9.624 9.624 0 0 0 1.317 1.918C9.828 10.99 11.204 12 13 12v1c-2.202 0-3.827-1.24-4.874-2.418A10.595 10.595 0 0 1 7 9.05c-.26.43-.636.98-1.126 1.532C4.827 11.76 3.202 13 1 13H.5a.5.5 0 0 1 0-1H1c1.798 0 3.173-1.01 4.126-2.082A9.624 9.624 0 0 0 6.444 8a9.624 9.624 0 0 0-1.317-1.918C4.172 5.01 2.796 4 1 4H.5a.5.5 0 0 1-.5-.5z"/><path d="M13 5.466V1.534a.25.25 0 0 1 .41-.192l2.36 1.966c.12.1.12.284 0 .384l-2.36 1.966a.25.25 0 0 1-.41-.192zm0 9v-3.932a.25.25 0 0 1 .41-.192l2.36 1.966c.12.1.12.284 0 .384l-2.36 1.966a.25.25 0 0 1-.41-.192z"/></svg>""",
|
||||
|
||||
// Employment status icons
|
||||
"Current Status" => """<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" fill="currentColor" viewBox="0 0 16 16"><path d="M6.5 1A1.5 1.5 0 0 0 5 2.5V3H1.5A1.5 1.5 0 0 0 0 4.5v8A1.5 1.5 0 0 0 1.5 14h13a1.5 1.5 0 0 0 1.5-1.5v-8A1.5 1.5 0 0 0 14.5 3H11v-.5A1.5 1.5 0 0 0 9.5 1h-3zm0 1h3a.5.5 0 0 1 .5.5V3H6v-.5a.5.5 0 0 1 .5-.5zm1.886 6.914L15 7.151V12.5a.5.5 0 0 1-.5.5h-13a.5.5 0 0 1-.5-.5V7.15l6.614 1.764a1.5 1.5 0 0 0 .772 0zM1.5 4h13a.5.5 0 0 1 .5.5v1.616l-6.614 1.764a.5.5 0 0 1-.772 0L1 6.116V4.5a.5.5 0 0 1 .5-.5z"/></svg>""",
|
||||
"Long Tenure" => """<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" fill="currentColor" viewBox="0 0 16 16"><path d="M2.866 14.85c-.078.444.36.791.746.593l4.39-2.256 4.389 2.256c.386.198.824-.149.746-.592l-.83-4.73 3.522-3.356c.33-.314.16-.888-.282-.95l-4.898-.696L8.465.792a.513.513 0 0 0-.927 0L5.354 5.12l-4.898.696c-.441.062-.612.636-.283.95l3.523 3.356-.83 4.73zm4.905-2.767-3.686 1.894.694-3.957a.565.565 0 0 0-.163-.505L1.71 6.745l4.052-.576a.525.525 0 0 0 .393-.288L8 2.223l1.847 3.658a.525.525 0 0 0 .393.288l4.052.575-2.906 2.77a.565.565 0 0 0-.163.506l.694 3.957-3.686-1.894a.503.503 0 0 0-.461 0z"/></svg>""",
|
||||
|
||||
// Leadership & experience icons
|
||||
"Management Experience" => """<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" fill="currentColor" viewBox="0 0 16 16"><path d="M7 14s-1 0-1-1 1-4 5-4 5 3 5 4-1 1-1 1H7Zm4-6a3 3 0 1 0 0-6 3 3 0 0 0 0 6Zm-5.784 6A2.238 2.238 0 0 1 5 13c0-1.355.68-2.75 1.936-3.72A6.325 6.325 0 0 0 5 9c-4 0-5 3-5 4s1 1 1 1h4.216ZM4.5 8a2.5 2.5 0 1 0 0-5 2.5 2.5 0 0 0 0 5Z"/></svg>""",
|
||||
"Individual Contributor" => """<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" fill="currentColor" viewBox="0 0 16 16"><path d="M8 8a3 3 0 1 0 0-6 3 3 0 0 0 0 6Zm2-3a2 2 0 1 1-4 0 2 2 0 0 1 4 0Zm4 8c0 1-1 1-1 1H3s-1 0-1-1 1-4 6-4 6 3 6 4Zm-1-.004c-.001-.246-.154-.986-.832-1.664C11.516 10.68 10.289 10 8 10c-2.29 0-3.516.68-4.168 1.332-.678.678-.83 1.418-.832 1.664h10Z"/></svg>""",
|
||||
"Director Experience" => """<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" fill="currentColor" viewBox="0 0 16 16"><path d="M9.669.864 8 0 6.331.864l-1.858.282-.842 1.68-1.337 1.32L2.6 6l-.306 1.854 1.337 1.32.842 1.68 1.858.282L8 12l1.669-.864 1.858-.282.842-1.68 1.337-1.32L13.4 6l.306-1.854-1.337-1.32-.842-1.68L9.669.864zm1.196 1.193.684 1.365 1.086 1.072L12.387 6l.248 1.506-1.086 1.072-.684 1.365-1.51.229L8 10.874l-1.355-.702-1.51-.229-.684-1.365-1.086-1.072L3.613 6l-.248-1.506 1.086-1.072.684-1.365 1.51-.229L8 1.126l1.356.702 1.509.229z"/><path d="M4 11.794V16l4-1 4 1v-4.206l-2.018.306L8 13.126 6.018 12.1 4 11.794z"/></svg>""",
|
||||
"Public Company Experience" => """<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" fill="currentColor" viewBox="0 0 16 16"><path d="M4 2.5a.5.5 0 0 1 .5-.5h1a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-1a.5.5 0 0 1-.5-.5v-1Zm3 0a.5.5 0 0 1 .5-.5h1a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-1a.5.5 0 0 1-.5-.5v-1Zm3.5-.5a.5.5 0 0 0-.5.5v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1ZM4 5.5a.5.5 0 0 1 .5-.5h1a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-1a.5.5 0 0 1-.5-.5v-1ZM7.5 5a.5.5 0 0 0-.5.5v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1Zm2.5.5a.5.5 0 0 1 .5-.5h1a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-1a.5.5 0 0 1-.5-.5v-1Z"/><path d="M2 1a1 1 0 0 1 1-1h10a1 1 0 0 1 1 1v14a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V1Zm11 0H3v14h3v-2.5a.5.5 0 0 1 .5-.5h3a.5.5 0 0 1 .5.5V15h3V1Z"/></svg>""",
|
||||
|
||||
// Company & trajectory icons
|
||||
"Company Size Pattern" => """<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" fill="currentColor" viewBox="0 0 16 16"><path d="M12.5 16a3.5 3.5 0 1 0 0-7 3.5 3.5 0 0 0 0 7Zm1.679-4.493-1.335 2.226a.75.75 0 0 1-1.174.144l-.774-.773a.5.5 0 0 1 .708-.708l.547.548 1.17-1.951a.5.5 0 1 1 .858.514ZM11 5a3 3 0 1 1-6 0 3 3 0 0 1 6 0ZM8 7a2 2 0 1 0 0-4 2 2 0 0 0 0 4Z"/><path d="M8.256 14a4.474 4.474 0 0 1-.229-1.004H3c.001-.246.154-.986.832-1.664C4.484 10.68 5.711 10 8 10c.26 0 .507.009.74.025.226-.341.496-.65.804-.918C9.077 9.038 8.564 9 8 9c-5 0-6 3-6 4s1 1 1 1h5.256Z"/></svg>""",
|
||||
|
||||
// Education icons
|
||||
"Unverified Institution" => """<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" fill="currentColor" viewBox="0 0 16 16"><path d="M8.211 2.047a.5.5 0 0 0-.422 0l-7.5 3.5a.5.5 0 0 0 .025.917l7.5 3a.5.5 0 0 0 .372 0L14 7.14V13a1 1 0 0 0-1 1v2h3v-2a1 1 0 0 0-1-1V6.739l.686-.275a.5.5 0 0 0 .025-.917l-7.5-3.5ZM8 8.46 1.758 5.965 8 3.052l6.242 2.913L8 8.46Z"/><path d="M4.176 9.032a.5.5 0 0 0-.656.327l-.5 1.7a.5.5 0 0 0 .294.605l4.5 1.8a.5.5 0 0 0 .372 0l4.5-1.8a.5.5 0 0 0 .294-.605l-.5-1.7a.5.5 0 0 0-.656-.327L8 10.466 4.176 9.032Zm-.068 1.873.22-.748L8 11.533l3.672-1.41.22.748L8 12.46l-3.892-1.556Z"/></svg>""",
|
||||
|
||||
// Default - career trajectory or generic
|
||||
_ when title.StartsWith("Career Trajectory") => """<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" fill="currentColor" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M0 0h1v15h15v1H0V0Zm14.817 3.113a.5.5 0 0 1 .07.704l-4.5 5.5a.5.5 0 0 1-.74.037L7.06 6.767l-3.656 5.027a.5.5 0 0 1-.808-.588l4-5.5a.5.5 0 0 1 .758-.06l2.609 2.61 4.15-5.073a.5.5 0 0 1 .704-.07Z"/></svg>""",
|
||||
|
||||
// Fallback generic info icon
|
||||
_ => """<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" fill="currentColor" 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>"""
|
||||
};
|
||||
|
||||
return new MarkupString(icon);
|
||||
}
|
||||
|
||||
// Lookup for first occurrence of each sequential group of the same company (pre-computed when report loads)
|
||||
private HashSet<int> _firstOccurrenceIndices = new();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user