@using System.Security.Claims @implements IAsyncDisposable @inject NavigationManager Navigation @inject IJSRuntime JS @code { private static readonly string[] HomePaths = ["", "index.html"]; private static readonly string[] ApplicationPaths = ["application", "application.html"]; private static readonly string[] RulesPaths = ["reglement", "reglement.html"]; private DotNetObjectReference? _dotNetReference; private bool _listenerRegistered; private string? AuthModalSource; private string AuthModalTitle = "Authentification"; private bool ShowAuthModal; private string LoginHref => BuildAuthHref("login", EffectiveReturnUrl); private string RegisterHref => BuildAuthHref("register", EffectiveReturnUrl); private string LogoutHref => BuildAuthHref("logout", "/"); private string CurrentPath { get { var absolutePath = new Uri(Navigation.Uri).AbsolutePath; return absolutePath.Trim('/'); } } private string EffectiveReturnUrl { get { var absolutePath = new Uri(Navigation.Uri).AbsolutePath; if (absolutePath.StartsWith("/authentication/", StringComparison.OrdinalIgnoreCase)) { return "/"; } return string.IsNullOrWhiteSpace(absolutePath) ? "/" : absolutePath; } } private string BuildNavLinkClass(string[] paths) => IsCurrentPage(paths) ? "site-menu-link is-active" : "site-menu-link"; private string? BuildAriaCurrent(string[] paths) => IsCurrentPage(paths) ? "page" : null; private bool IsCurrentPage(string[] paths) => paths.Any(path => string.Equals(CurrentPath, path, StringComparison.OrdinalIgnoreCase)); private static string BuildAuthHref(string action, string returnUrl) => $"authentication/{action}?returnUrl={Uri.EscapeDataString(returnUrl)}"; private static string BuildDisplayName(ClaimsPrincipal user) => user.Identity?.Name ?? user.FindFirst("name")?.Value ?? user.FindFirst("preferred_username")?.Value ?? "Utilisateur connecte"; private static string BuildMeta(ClaimsPrincipal user) => user.FindFirst("email")?.Value ?? "Session active"; protected override async Task OnAfterRenderAsync(bool firstRender) { if (!firstRender) { return; } _dotNetReference = DotNetObjectReference.Create(this); await JS.InvokeVoidAsync("chesscubingAuthModal.registerListener", _dotNetReference); _listenerRegistered = true; } private void OpenLoginModal() => OpenAuthModal("Se connecter", LoginHref); private void OpenRegisterModal() => OpenAuthModal("Creer un compte", RegisterHref); private void OpenAuthModal(string title, string source) { AuthModalTitle = title; AuthModalSource = source; ShowAuthModal = true; } private void CloseAuthModal() { ShowAuthModal = false; AuthModalSource = null; } [JSInvokable] public Task HandleAuthModalMessage(string status) { if (!string.Equals(status, "login-succeeded", StringComparison.OrdinalIgnoreCase) && !string.Equals(status, "logout-succeeded", StringComparison.OrdinalIgnoreCase)) { return Task.CompletedTask; } CloseAuthModal(); StateHasChanged(); Navigation.NavigateTo(Navigation.Uri, forceLoad: true); return Task.CompletedTask; } public async ValueTask DisposeAsync() { if (_listenerRegistered) { try { await JS.InvokeVoidAsync("chesscubingAuthModal.unregisterListener"); } catch { } } _dotNetReference?.Dispose(); } private static string BoolString(bool value) => value ? "true" : "false"; }