Interview notes can print each student's ranked events and a shared attribute legend from the same catalog as the ranking index, without leftover table markup or collapsed answer space. Co-authored-by: Cursor <cursoragent@cursor.com>
90 lines
3.0 KiB
C#
90 lines
3.0 KiB
C#
using Core.Entities;
|
|
|
|
namespace Core.Printing;
|
|
|
|
/// <summary>
|
|
/// Ranking-index style badges: colored rank dot plus a short label.
|
|
/// Student pages list ranked events; event pages list students who ranked them.
|
|
/// </summary>
|
|
public static class PrintRankBadgeHtml
|
|
{
|
|
public static string ForStudentEvents(IEnumerable<StudentEventRanking>? rankings)
|
|
{
|
|
if (rankings is null)
|
|
return string.Empty;
|
|
|
|
var badges = rankings
|
|
.Where(r => r.Rank is >= 1 and <= StudentEventRanking.MaxRank)
|
|
.OrderBy(r => r.Rank)
|
|
.Select(EventBadge)
|
|
.ToList();
|
|
|
|
return Wrap(badges);
|
|
}
|
|
|
|
public static string ForEventStudents(IEnumerable<StudentEventRanking>? rankings)
|
|
{
|
|
if (rankings is null)
|
|
return string.Empty;
|
|
|
|
var badges = rankings
|
|
.Where(r => r.Student is not null && r.Rank is >= 1 and <= StudentEventRanking.MaxRank)
|
|
.OrderBy(r => r.Rank)
|
|
.ThenByDescending(r => r.Student.Grade + r.Student.TsaYear)
|
|
.Select(r => StudentBadge(r.Student.FirstName, r.Rank))
|
|
.ToList();
|
|
|
|
return Wrap(badges);
|
|
}
|
|
|
|
internal static string EventBadge(StudentEventRanking ranking)
|
|
{
|
|
var evt = ranking.EventDefinition;
|
|
var label = !string.IsNullOrWhiteSpace(evt?.ShortName)
|
|
? evt.ShortName
|
|
: evt?.Name;
|
|
var attributes = EventAttributeMarks.For(evt);
|
|
var attrsHtml = string.IsNullOrEmpty(attributes)
|
|
? string.Empty
|
|
: $"<span class=\"print-event-attrs\">{PrintTokenMap.EscapeHtml(attributes)}</span>";
|
|
|
|
return Badge(ranking.Rank, PrintTokenMap.EscapeHtml(label), attrsHtml);
|
|
}
|
|
|
|
internal static string StudentBadge(string? firstName, int rank) =>
|
|
Badge(rank, PrintTokenMap.EscapeHtml(firstName), string.Empty);
|
|
|
|
private static string Badge(int rank, string labelHtml, string extraHtml)
|
|
{
|
|
var extra = string.IsNullOrEmpty(extraHtml) ? string.Empty : $" {extraHtml}";
|
|
return
|
|
$"<span class=\"print-rank-badge\">" +
|
|
$"<span class=\"print-rank-dot event-rank-{rank}\"></span> " +
|
|
$"{labelHtml}{extra}" +
|
|
"</span>";
|
|
}
|
|
|
|
public static string Legend()
|
|
{
|
|
var marks = EventAttributeMarks.LegendItems
|
|
.Select(mark =>
|
|
"<span class=\"print-legend-mark\">" +
|
|
$"<span class=\"print-event-attrs\">{PrintTokenMap.EscapeHtml(mark.Symbol)}</span> " +
|
|
PrintTokenMap.EscapeHtml(mark.Label) +
|
|
"</span>");
|
|
|
|
return
|
|
"<div class=\"print-badge-legend\">" +
|
|
$"<div class=\"print-attr-legend\">{string.Join(" · ", marks)}</div>" +
|
|
"</div>";
|
|
}
|
|
|
|
private static string Wrap(IReadOnlyList<string> badges, string separator = " ")
|
|
{
|
|
if (badges.Count == 0)
|
|
return string.Empty;
|
|
|
|
return $"<div class=\"print-rank-badges\">{string.Join(separator, badges)}</div>";
|
|
}
|
|
}
|