@page "/sla-reports"
@using System.Collections.Generic
@using System.Linq
@using System.Threading.Tasks
@rendermode InteractiveServer
@* Page Header Area *@
SLA & Monthly Reports Dashboard
Enterprise service level compliance, National Treasury rate-cap checking, and monthly operational reports ledger prepared for SAQA bid submission by TMT Projects
@* Filters & Controls *@
Period:
May 2026 (Active)
April 2026
Q1 2026 (Quarterly)
Cost Centre:
All Cost Centres
Office of the CEO
Qualifications & Standards
Verifications
Export SLA Pack (PDF)
Download Logs (Excel)
@* Alert / Action Feedback Banner *@
@if (!string.IsNullOrEmpty(AlertFeedback))
{
AlertFeedback = string.Empty" class="text-[#8a96a8] hover:text-[#1f2a3a]">
}
@* SLA Scorecard Cards - Quick telemetry indicators *@
@foreach (var metric in CoreSlaMetrics)
{
@metric.Name
@metric.Actual
@metric.Unit
Target: @metric.Target
@metric.StatusLabel
}
@* Navigation Tabs Bar *@
SetActiveTab("scorecard"))"
class="inline-flex items-center gap-2 px-5 py-3 text-xs font-bold whitespace-nowrap border-b-2 transition-all cursor-pointer @(ActiveTab == "scorecard" ? "border-[#003b71] text-[#003b71]" : "border-transparent text-[#5a6577] hover:text-[#1f2a3a]")">
SLA Scorecard Details
SetActiveTab("library"))"
class="inline-flex items-center gap-2 px-5 py-3 text-xs font-bold whitespace-nowrap border-b-2 transition-all cursor-pointer @(ActiveTab == "library" ? "border-[#0066b3] text-[#0066b3]" : "border-transparent text-[#5a6577] hover:text-[#1f2a3a]")">
Monthly Reports Library
4 Logs
SetActiveTab("consultants"))"
class="inline-flex items-center gap-2 px-5 py-3 text-xs font-bold whitespace-nowrap border-b-2 transition-all cursor-pointer @(ActiveTab == "consultants" ? "border-[#00a3a1] text-[#00a3a1]" : "border-transparent text-[#5a6577] hover:text-[#1f2a3a]")">
Consultant Performance Index
SetActiveTab("disputes"))"
class="inline-flex items-center gap-2 px-5 py-3 text-xs font-bold whitespace-nowrap border-b-2 transition-all cursor-pointer @(ActiveTab == "disputes" ? "border-[#dc2626] text-[#dc2626]" : "border-transparent text-[#5a6577] hover:text-[#1f2a3a]")">
Log Service Violation / Query
@ServiceQueries.Count(q => q.Status != "Resolved") Open
@* ===================== TAB 1: SCORECARD DETAILS ===================== *@
@if (ActiveTab == "scorecard")
{
@* Left block: Target meters list (lg:col-span-8) *@
SAQA Dedicated SLA Telemetry Matrix
May 2026 contractual performance indexes, target deviations, and billing benchmarks
97.8% SLA Aggregated Compliance
@* Metric row 1 *@
Booking Response turn-around (Domestic)
Measure of time elapsed from travel authorization submission to first quote iteration
44 minutes
Target: < 60 mins (98.4% met)
@* Metric row 2 *@
Emergency After-Hours response speed
Emergency helpline consultant response and ticket remediation threshold
9 minutes
Target: < 15 mins (100% met)
@* Metric row 3 *@
National Treasury Price Caps Adherence Rate
Adherence to Treasury instructions on flight quotas, hotel matrices and shuttle spending caps
94.1% compliance
Target: 100% (7 authorized deviations)
@* Metric row 4 *@
Billing Reconciliation & Lodge Matching
Automated lodge card clearing speed and invoice linkages matching PO guidelines
28 hours
Target: < 48 hours (99.1% met)
@* Metric row 5 *@
Ticketing Accuracy / Zero Voucher Error Rate
Zero ticketing rejects or hotel vouchers invalid on check-in
99.96% accuracy
Target: > 99.90% (0 errors)
@* Consolidated SLA Quality Box *@
SLA Target Met Rating
TMT Projects dedicated operations are strictly aligned with ASATA standards, assuring SAQA of seamless continuity.
97.8% Achieved
@* Right block: Live SLA alerts & warnings desk (lg:col-span-4) *@
Live SLA Alert Desk
Real-time GDS operational alerts matching May SLAs
Hotel Cap Deviation Pending Review
Cape Town peak-booking R 2,400/night has passed 24h limit without CFO override. Ticket pending hold.
SLA limit: 4h response standard
After-Hours Call log triggered
London flight delay rerouting handled for Dr. Sithole. Resolution verified in 12 mins.
Target met (9m actual)
Lodge Reconciliation auto-cleared
142 May flight billing matched automatically with zero manual discrepancies logged.
Reconciled standard: 100%
Real-time monitoring nodes are automatically backed by failover pathways. Performance thresholds audited independently.
}
@* ===================== TAB 2: REPORTS LIBRARY ===================== *@
@if (ActiveTab == "library")
{
@* Reports Listing column (lg:col-span-4) *@
Standard Monthly Logs
Select a ledger below to view the interactive live telemetry data
@foreach (var report in MonthlyReportTemplates)
{
SelectReport(report.Key))"
class="w-full text-left p-3 rounded-lg border transition-all flex items-start gap-3 cursor-pointer @(SelectedReportKey == report.Key ? "bg-[#e2eefb] border-[#0066b3] text-[#003b71]" : "border-[#e4eaf2] hover:bg-[#f4f7fb] text-gray-700")">
@report.Value.Emoji
@report.Value.Name
@report.Value.Description
@GetReportCount(report.Key) Records
}
National Treasury compliant formats
All ledgers export smoothly to National Treasury standard spreadsheets with pre-populated cost centers.
@* Report Interactive Preview Table (lg:col-span-8) *@
@* Table Header Area *@
@ActiveReportMetadata.Emoji
@ActiveReportMetadata.Name
Active data preview for @SelectedPeriod period
@* Search Filter *@
Search:
@* Table Renderings based on chosen reports *@
@if (SelectedReportKey == "deviations")
{
Traveller
Route
Paid
Justification / Reason
Approver
Status
@foreach (var row in FilteredDeviations)
{
@row.Traveller
@row.CostCentre
@row.Route (@row.Supplier)
@row.Date
R @row.PaidPrice.ToString("N0")
Saved: R @row.Saving.ToString("N0")
@row.Justification
Code: @row.ReasonCode
@row.ApprovedBy
@row.Status
}
@if (!FilteredDeviations.Any())
{
No matching records found.
}
}
else if (SelectedReportKey == "afterhours")
{
Timestamp
Traveller
Category / Reason
Resolution Process
SLA Speed
Status
@foreach (var row in FilteredAfterHours)
{
@row.Date
@row.Time
@row.Traveller
@row.Category
@row.Reason
@row.Resolution
@row.ResponseTimeMinutes mins
Target: <15m
@row.Status
}
@if (!FilteredAfterHours.Any())
{
No matching records found.
}
}
else if (SelectedReportKey == "refunds")
{
Traveller / Ticket #
Airline & Route
Face Value
Issue / Expiry Date
Claim Status
Action Required
@foreach (var row in FilteredRefunds)
{
@row.Traveller
Ticket: @row.TicketNumber
@row.Airline
@row.Route
R @row.FaceValue.ToString("N0")
Issued: @row.IssueDate
Expires: @row.ExpiryDate
@row.RefundStatus
TriggerVoucherAction(row)"
class="px-2 py-1 bg-white border border-[#e4eaf2] text-[#1f2a3a] hover:bg-[#fafcfe] rounded text-[10px] font-bold shadow-xs cursor-pointer">
@row.ActionPending
}
@if (!FilteredRefunds.Any())
{
No matching records found.
}
}
else if (SelectedReportKey == "carbon")
{
@{
decimal totalCarbon = FilteredCarbon.Sum(c => c.CarbonFootprint);
decimal greenAccommodationRatio = FilteredCarbon.Any(c => c.Category == "Lodging" && c.EcoPerformanceTag.Contains("Eco")) ? 42.8M : 0M;
int treesOffset = (int)(totalCarbon * 41.5M);
}
Total Carbon Emitted
@totalCarbon.ToString("F1") Tons CO₂
@((totalCarbon * -0.24M).ToString("F1"))% vs baseline
Green Accommodation Ratio
@(greenAccommodationRatio > 0 ? "42.8%" : "0.0%") Bookings
Target: 30.0% standard
Tree-Offset Equivalent
@treesOffset.ToString("N0") Trees/Year
SLA Sustainability Match
Category
Activity Metric
Carbon Footprint
Eco Performance Tag
Green Recommendations
@foreach (var row in FilteredCarbon)
{
@row.Category
@row.ActivityMetric
@row.EcoPerformanceTag
@row.GreenRecommendation
}
@if (!FilteredCarbon.Any())
{
No matching records found.
}
}
* Showing live data queried directly from ASATA-linked accounts. Securely verified by POPIA guidelines.
Export Ledger (.xlsx)
}
@* ===================== TAB 3: CONSULTANTS PERFORMANCE ===================== *@
@if (ActiveTab == "consultants")
{
SAQA Dedicated Travel Consultants Performance
SLA productivity tracker for TMT Projects specialists permanently assigned to South African Qualifications Authority
100% Availability Verified
@foreach (var consultant in ConsultantPerformances)
{
@string.Concat(consultant.Name.Split(' ').Select(n => n[0]))
@consultant.Name
@consultant.Role
Specialty Focus:
@consultant.Specialty
Bookings Handled:
@consultant.BookingsHandled
Avg Response Speed:
@consultant.ResponseTimeMinutes mins
Error Ticket Volume:
@consultant.ErrorsCount
@* Performance bar *@
SLA Success Score:
@(consultant.ErrorsCount == 0 ? "100%" : "99.8%")
@* CSAT Score rating representation *@
CSAT Rating:
★ @consultant.CsatScore.ToString("F2")
/ 5.0
StartConsultantChatSim(consultant.Name))"
class="mt-4 w-full py-1.5 bg-[#f4f7fb] hover:bg-[#e2eefb] text-[#0066b3] text-xs font-bold rounded transition">
Request SLA Priority Contact
}
Dedicated SLA Service Protocols
TMT Projects provides a dedicated 24/7 corporate desk. For executive and VIP bookings, Thabo Khumalo is assigned as the primary liaison officer. Escalated service matters and disputes bypass the standard queue and route instantly to Lerato Nkosi for immediate SLA verification and reconciliation logs.
}
@* ===================== TAB 4: DISPUTE & SERVICE LOGS ===================== *@
@if (ActiveTab == "disputes")
{
@* Service dispute logging form (lg:col-span-5) *@
Log SLA Query or Service Violation
Submit service delays or rate cap disputes for priority TMT investigation
Select SLA Category
Booking Response Delay
National Treasury Cap Discrepancy
Billing / Invoice Dispute
Consultant / Service Quality Issue
Voucher Validation Delay
Describe Service Violation Parameter
Submit SLA Query to Response Desk
@* Active disputes / Queries tracking ledger (lg:col-span-7) *@
SAQA Active Service Quality Log
Live status tracker of submitted queries in May 2026
@ServiceQueries.Count(q => q.Status != "Resolved") Active Disputes
@foreach (var query in ServiceQueries)
{
@if (query.Urgency == "High")
{
}
else
{
}
@query.Category
@query.Date
@query.Description
Traveller Reference: @query.TravellerName
@query.Status
@if (query.Status != "Resolved")
{
ResolveSlaQuerySim(query.Id))"
class="px-2 py-0.5 bg-[#22a06b] hover:bg-[#1b8054] text-white text-[9px] font-bold rounded shadow-xs cursor-pointer">
Mark Resolved
}
}
Disputes logged are actioned by Lerato Nkosi within 4 hours. Escalations are automatically flagged in daily reports.
}
@code {
// Reporting parameters
private string SelectedPeriod { get; set; } = "May 2026";
private string SelectedCostCentre { get; set; } = "All";
// SLA state feedback messages
private string AlertFeedback { get; set; } = string.Empty;
// Primary Tab Selection
private string ActiveTab { get; set; } = "scorecard";
// Reports Library state
private string SelectedReportKey { get; set; } = "deviations";
private string ReportSearchQuery { get; set; } = string.Empty;
// SLA Query / Dispute form bind states
private string NewQueryCategory { get; set; } = "Booking Response Delay";
private string NewQueryTraveller { get; set; } = string.Empty;
private string NewQueryUrgency { get; set; } = "Medium";
private string NewQueryDescription { get; set; } = string.Empty;
// Data Structures & Models
public class SlaMetric
{
public string Name { get; set; } = string.Empty;
public string Target { get; set; } = string.Empty;
public string Actual { get; set; } = string.Empty;
public string Unit { get; set; } = string.Empty;
public string StatusLabel { get; set; } = string.Empty;
public string StatusClass { get; set; } = string.Empty;
public string BarColorClass { get; set; } = string.Empty;
}
public class MonthlyReportMetadata
{
public string Name { get; set; } = string.Empty;
public string Description { get; set; } = string.Empty;
public string Emoji { get; set; } = string.Empty;
public int RecordCount { get; set; }
}
public class DeviationReportRow
{
public string Traveller { get; set; } = string.Empty;
public string CostCentre { get; set; } = string.Empty;
public string Route { get; set; } = string.Empty;
public string Date { get; set; } = string.Empty;
public string Supplier { get; set; } = string.Empty;
public decimal OpenPrice { get; set; }
public decimal PaidPrice { get; set; }
public decimal Saving => OpenPrice - PaidPrice;
public string ReasonCode { get; set; } = string.Empty;
public string Justification { get; set; } = string.Empty;
public string ApprovedBy { get; set; } = string.Empty;
public string Status { get; set; } = "Approved";
}
public class AfterHoursLogRow
{
public string Date { get; set; } = string.Empty;
public string Time { get; set; } = string.Empty;
public string Traveller { get; set; } = string.Empty;
public string Category { get; set; } = string.Empty;
public string Reason { get; set; } = string.Empty;
public string Resolution { get; set; } = string.Empty;
public int ResponseTimeMinutes { get; set; }
public string Status { get; set; } = "Resolved";
public string CostCentre { get; set; } = string.Empty;
}
public class UnusedTicketRow
{
public string Traveller { get; set; } = string.Empty;
public string TicketNumber { get; set; } = string.Empty;
public string Airline { get; set; } = string.Empty;
public string Route { get; set; } = string.Empty;
public decimal FaceValue { get; set; }
public string IssueDate { get; set; } = string.Empty;
public string ExpiryDate { get; set; } = string.Empty;
public string RefundStatus { get; set; } = "Pending";
public string ActionPending { get; set; } = "Process Refund";
public string CostCentre { get; set; } = string.Empty;
}
public class CarbonReportRow
{
public string Category { get; set; } = string.Empty;
public string ActivityMetric { get; set; } = string.Empty;
public decimal CarbonFootprint { get; set; }
public string EcoPerformanceTag { get; set; } = string.Empty;
public string GreenRecommendation { get; set; } = string.Empty;
public string CostCentre { get; set; } = string.Empty;
public string Date { get; set; } = string.Empty;
}
public class ConsultantPerformance
{
public string Name { get; set; } = string.Empty;
public string Role { get; set; } = string.Empty;
public string Specialty { get; set; } = string.Empty;
public int BookingsHandled { get; set; }
public int ErrorsCount { get; set; }
public int ResponseTimeMinutes { get; set; }
public double CsatScore { get; set; }
}
public class SlaQueryDispute
{
public int Id { get; set; }
public string Date { get; set; } = string.Empty;
public string Category { get; set; } = string.Empty;
public string TravellerName { get; set; } = string.Empty;
public string Urgency { get; set; } = string.Empty;
public string Description { get; set; } = string.Empty;
public string Status { get; set; } = "In Review";
}
// Databases
private List