@page "/gds-sync" @using System.Collections.Generic @using System.Linq @using System.Threading.Tasks @rendermode InteractiveServer
@* Page Header Area *@

GDS Sync Console

Real-time Amadeus, Travelport, and Sabre telemetry synchronization gateway and GDS negotiated rates validator

@* Alert / Feedback Notification Banner *@ @if (!string.IsNullOrEmpty(AlertFeedback)) {
@AlertFeedback
} @* GDS Status Core KPI Cards *@
Amadeus Node
Active / Live
100% Up
Last sync @AmadeusLastSyncs ago
Travelport Node
Active / Live
100% Up
Last sync @TravelportLastSyncs ago
Sabre Node
Active / Live
100% Up
Last sync @SabreLastSyncs ago
In-Flight PNR Queue
@PnrQueueCount
Pending ticket printing checks
@* Spend vs Savings Visual Indicators & GDS Providers Metrics split *@
@* Spend vs Savings Metrics Panel - Left Column (lg:col-span-7) *@

Spend vs. Savings Telemetry

Negotiated corporate GDS fares against open published consumer tickets for May 2026

+18.2% YTD Savings

Below metrics reflect the total savings realized directly from GDS nodes through TMT projects pre-negotiated corporate rates.

Open Published Cost R 2,662,890 Consumer benchmark rates
Negotiated Corporate Cost R 2,250,310 SAQA contracted limits
Direct Savings Realized R @TotalSavingsThisMonth.ToString("N0") May 2026 reporting index
@* Visual Simulated Bar stack *@
May Spend Budget Saved Rate 15.5% Saved
Negotiated (R 2,250,310)
Savings Realized (R @TotalSavingsThisMonth.ToString("N0"))
Database verified by ASATA / IATA standards Sync is operational
@* Savings by GDS Provider progress list - Right Column (lg:col-span-5) *@

Savings by GDS Provider Node

Contribution percentages realized across Amadeus, Travelport, and Sabre connection pools

@* Provider 1 *@
Amadeus Node Domestic & regional flights / local lodging
R @AmadeusSavings.ToString("N0") 52.9% of total
@* Provider 2 *@
Travelport Node International airlines / premium class cabins
R @TravelportSavings.ToString("N0") 30.1% of total
@* Provider 3 *@
Sabre Node Hotel aggregates & car rental structures
R @SabreSavings.ToString("N0") 17.0% of total
@* Highlighted Box *@
Total GDS Savings Verified R @TotalSavingsThisMonth.ToString("N0")
Savings are calculated on GDS booking confirmation vs standard unrestricted booking baseline. Verified by continuous live audit checks.
@* Live Supplier Feed Table & Sync Activity grid *@
@* GDS Supplier Fares Feed - Left Column (lg:col-span-8) *@

Live Supplier Feed via GDS

Contracted tariffs fetched directly from active connection handshakes

@* Search Filter *@
GDS Provider:
@foreach (var feed in FilteredSupplierFeed) { }
Supplier GDS Node Type Open Rate Negotiated ZAR Saved Status
@feed.SupplierName @feed.GdsNode @feed.CategoryType R @feed.OpenPrice.ToString("N0") R @feed.NegotiatedPrice.ToString("N0") R @feed.SavedValue.ToString("N0") (@feed.SavedPercentage%) @feed.Status
* Rates are updated dynamically every 30 seconds. Supplier cache lifetimes are managed according to commercial service agreements.
@* Sync Activity & Health status indicators - Right Column (lg:col-span-4) *@

Node Traffic Analysis

Aggregated telemetry actions logged over last 24 hours

PNRs Generated Across all connection tunnels
142
Fares & Tariff Queries Read operations processed
8,420
Confirmed Air & Hotel Bookings Ticketed in line with SAQA policies
118
Auto Refund / Voucher Queues Cancellations processed smoothly
9
GDS Connection Failure Rate Auto-retry failover threshold
0.04% (Exceptional)

Telemetry Node Health

Direct response times & availability metrics

@* Bar 1 *@
Amadeus API latency 88ms (Avg)
@* Bar 2 *@
Travelport API latency 82ms (Avg)
@* Bar 3 *@
Sabre API latency 124ms (Avg)
GDS Node Uptime: 99.98%

Automatic node failover setup ensures queries bypass any downtime immediately by fetching rates from auxiliary tunnels.

@* ===================== MODAL DIALOGS ===================== *@ @* 1. GDS Sync Logs Modal *@ @if (ShowSyncLogsModal) {

Live GDS Telemetry Sync Logs

Handshake queries and active transaction parameters

@* Console style panel *@
@foreach (var log in SyncLogs) {
@log.Timestamp [@log.Type] @log.Message
}
} @code { // Model Definitions public class GdsSupplierFeed { public int Id { get; set; } public string SupplierName { get; set; } = string.Empty; public string GdsNode { get; set; } = string.Empty; // Amadeus, Travelport, Sabre public string CategoryType { get; set; } = string.Empty; public decimal OpenPrice { get; set; } public decimal NegotiatedPrice { get; set; } public decimal SavedValue => OpenPrice - NegotiatedPrice; public int SavedPercentage => (int)System.Math.Round((SavedValue / OpenPrice) * 100); public string Status { get; set; } = "Live"; } public class GdsConsoleLog { public string Timestamp { get; set; } = string.Empty; public string Type { get; set; } = "Info"; // Success, Warning, Error, Info public string Message { get; set; } = string.Empty; } // Core States private bool IsSyncing { get; set; } = false; private string AlertFeedback { get; set; } = string.Empty; private string SelectedGdsFilter { get; set; } = "All"; private int PnrQueueCount { get; set; } = 14; // Last sync counters private int AmadeusLastSyncs { get; set; } = 14; private int TravelportLastSyncs { get; set; } = 41; private int SabreLastSyncs { get; set; } = 22; // Total aggregate calculations private decimal TotalSavingsThisMonth => AmadeusSavings + TravelportSavings + SabreSavings; private decimal AmadeusSavings { get; set; } = 218400M; private decimal TravelportSavings { get; set; } = 124180M; private decimal SabreSavings { get; set; } = 70000M; // Modal Control private bool ShowSyncLogsModal { get; set; } = false; // Databases private List SupplierFeeds { get; set; } = new(); private List SyncLogs { get; set; } = new(); // Filtered Feed list based on selection private IEnumerable FilteredSupplierFeed => SelectedGdsFilter == "All" ? SupplierFeeds : SupplierFeeds.Where(f => f.GdsNode.Equals(SelectedGdsFilter, System.StringComparison.OrdinalIgnoreCase)); protected override void OnInitialized() { // Populate supplier contracted feeds matching dashboard data SupplierFeeds = new List { new GdsSupplierFeed { Id = 1, SupplierName = "SAA (South African Airways)", GdsNode = "Amadeus", CategoryType = "Air, Domestic", OpenPrice = 3290M, NegotiatedPrice = 2890M, Status = "Live" }, new GdsSupplierFeed { Id = 2, SupplierName = "FlySafair Flights", GdsNode = "Amadeus", CategoryType = "Air, Low Cost", OpenPrice = 2180M, NegotiatedPrice = 1985M, Status = "Live" }, new GdsSupplierFeed { Id = 3, SupplierName = "British Airways Standard", GdsNode = "Travelport", CategoryType = "Air, International", OpenPrice = 21440M, NegotiatedPrice = 18940M, Status = "Live" }, new GdsSupplierFeed { Id = 4, SupplierName = "Emirates Corporate", GdsNode = "Travelport", CategoryType = "Air, International", OpenPrice = 28800M, NegotiatedPrice = 23100M, Status = "Live" }, new GdsSupplierFeed { Id = 5, SupplierName = "Premier Hotels Collection", GdsNode = "Sabre", CategoryType = "Accommodation", OpenPrice = 2200M, NegotiatedPrice = 1895M, Status = "Live" }, new GdsSupplierFeed { Id = 6, SupplierName = "City Lodge Hotels Corp", GdsNode = "Sabre", CategoryType = "Accommodation", OpenPrice = 1850M, NegotiatedPrice = 1520M, Status = "Live" }, new GdsSupplierFeed { Id = 7, SupplierName = "Avis Car Rental", GdsNode = "Sabre", CategoryType = "Car Rental", OpenPrice = 520M, NegotiatedPrice = 420M, Status = "Live" }, new GdsSupplierFeed { Id = 8, SupplierName = "Europcar SA Group", GdsNode = "Sabre", CategoryType = "Car Rental", OpenPrice = 580M, NegotiatedPrice = 460M, Status = "Cached, 2 min" } }; // Populate initial sync terminal logger SyncLogs = new List { new GdsConsoleLog { Timestamp = "11:15:02 AM", Type = "Info", Message = "Opening communication socket with Amadeus JNB Node (196.34.12.8)..." }, new GdsConsoleLog { Timestamp = "11:15:03 AM", Type = "Success", Message = "Handshake authenticated successfully. Security key established." }, new GdsConsoleLog { Timestamp = "11:15:04 AM", Type = "Info", Message = "Fetching May 2026 PNR ticket confirmation logs. Parsing 142 records..." }, new GdsConsoleLog { Timestamp = "11:15:08 AM", Type = "Success", Message = "Amadeus sync process successfully closed. 14 open e-Tickets synced to active dashboard." }, new GdsConsoleLog { Timestamp = "11:15:10 AM", Type = "Info", Message = "Querying Sabre GDS hotel & transfer rates. Auto-refresh threshold enabled." }, new GdsConsoleLog { Timestamp = "11:15:12 AM", Type = "Warning", Message = "Europcar API socket returned lag index of 180ms. Auto-refresh fallback to cache enabled." } }; } // Force Resync Simulation Trigger private async Task TriggerForceResync() { IsSyncing = true; TriggerFeedback("Executing Force GDS Node Resync. Parsing active socket connections..."); // Simulating sync steps and logging parameters SyncLogs.Add(new GdsConsoleLog { Timestamp = "Just Now", Type = "Info", Message = "USER SIGNAL: Initiating full cluster resynchronization..." }); StateHasChanged(); await Task.Delay(1200); SyncLogs.Add(new GdsConsoleLog { Timestamp = "Just Now", Type = "Success", Message = "Amadeus connection flushed and pulled fresh corporate PNR sets." }); AmadeusLastSyncs = 1; StateHasChanged(); await Task.Delay(800); SyncLogs.Add(new GdsConsoleLog { Timestamp = "Just Now", Type = "Success", Message = "Travelport & Sabre nodes auto-recalibrated rates cache parameters." }); TravelportLastSyncs = 1; SabreLastSyncs = 1; PnrQueueCount = System.Math.Max(0, PnrQueueCount - 2); IsSyncing = false; TriggerFeedback("GDS Cluster Sync Complete! Telemetry matrices successfully mapped and negotiated rates parsed smoothly."); StateHasChanged(); } // Modal view triggers private void OpenSyncLogsModal() { ShowSyncLogsModal = true; } private void CloseSyncLogsModal() { ShowSyncLogsModal = false; } private void ClearSyncLogs() { SyncLogs.Clear(); SyncLogs.Add(new GdsConsoleLog { Timestamp = "Terminal Purged", Type = "Info", Message = "Sync log interface successfully cleared by admin command." }); } // Toast alarm toaster private void TriggerFeedback(string message) { AlertFeedback = message; _ = DismissAlertAfterDelay(); } private async Task DismissAlertAfterDelay() { await Task.Delay(5000); AlertFeedback = string.Empty; StateHasChanged(); } }