@model HotlinePlannerWebhook.Models.DashboardViewModel @{ ViewData["Title"] = "Dashboard"; Layout = "~/Views/Shared/_Layout.cshtml"; } @section HeadStyles { }
Sync Dashboard
— viewers
@Model.Stats.TotalUsers
Connected Users
@Model.Stats.ActiveSubscriptions
Active Subscriptions
@Model.Stats.WebhooksToday
Webhooks Today
@Model.Stats.ExpiringSubscriptions
Expiring <24h
Live Activity Feed
Waiting for activity... Connect to Microsoft Calendar to start.
Users & Subscriptions
@foreach (var u in Model.Users) { var statusClass = u.SubscriptionStatus switch { "Active" => "badge-ok", "Expiring" => "badge-warn", "Expired" => "badge-err", _ => "badge-muted" }; } @if (!Model.Users.Any()) { }
Email Status Expires Last Sync Events Δ
@u.DisplayName
@u.Email
@u.SubscriptionStatus @(u.SubscriptionExpiration?.ToString("MM/dd HH:mm") ?? "—") @(u.LastSyncAt?.ToString("MM/dd HH:mm") ?? "—") @u.TotalEventsSynced @(string.IsNullOrEmpty(u.LastDeltaLink) ? "none" : "stored")
No users yet — connect a calendar to start.
Webhook Logs (last 50) Total: @Model.Stats.WebhooksTotal  |  Handshakes: @Model.Stats.HandshakesTotal
@foreach (var log in Model.RecentLogs) { var statusClass = log.ProcessingStatus switch { "Completed" => "badge-ok", "Failed" => "badge-err", "Skipped" => "badge-muted", _ => "badge-warn" }; }
Time Endpoint Type Change Status Events Dupes Sub ID Error Raw
@log.ReceivedAt.ToString("HH:mm:ss") @log.EndpointType @(log.IsHandshake ? "Handshake" : log.LifecycleEvent is not null ? $"{log.LifecycleEvent}" : "Notification") @(log.ChangeType ?? "—") @log.ProcessingStatus @log.EventsProcessed @log.EventsDeduplicated @(log.SubscriptionId?[..Math.Min(8, log.SubscriptionId?.Length ?? 0)] + "…" ?? "—") @log.ErrorMessage
@section Scripts { }