Files
marechai/Marechai.App/Presentation/ViewModels/MainViewModel.cs

263 lines
9.8 KiB
C#
Raw Normal View History

2025-11-14 20:59:12 +00:00
using System;
2025-11-14 19:00:01 +00:00
using System.Collections.Generic;
2025-11-16 23:09:47 +00:00
using System.Linq;
2025-11-16 20:35:00 +00:00
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Input;
using Marechai.App.Services;
2025-11-16 23:09:47 +00:00
using Marechai.App.Services.Authentication;
2025-11-16 20:35:00 +00:00
using Uno.Extensions.Authentication;
using Uno.Extensions.Navigation;
using Uno.Extensions.Toolkit;
2025-11-15 02:46:54 +00:00
namespace Marechai.App.Presentation.ViewModels;
public partial class MainViewModel : ObservableObject
{
2025-11-16 20:35:00 +00:00
private readonly IAuthenticationService _authService;
2025-11-16 23:09:47 +00:00
private readonly IJwtService _jwtService;
2025-11-16 20:35:00 +00:00
private readonly IStringLocalizer _localizer;
private readonly INavigator _navigator;
2025-11-16 23:09:47 +00:00
private readonly ITokenService _tokenService;
2025-11-14 19:00:01 +00:00
[ObservableProperty]
2025-11-15 02:48:40 +00:00
private bool _isSidebarOpen = true;
2025-11-14 19:00:01 +00:00
[ObservableProperty]
2025-11-16 23:09:47 +00:00
private bool _isUberadminUser;
[ObservableProperty]
2025-11-15 02:48:40 +00:00
private Dictionary<string, string> _localizedStrings = new();
2025-11-14 19:00:01 +00:00
[ObservableProperty]
2025-11-15 02:48:40 +00:00
private string _loginLogoutButtonText = "";
2025-11-14 15:18:30 +00:00
[ObservableProperty]
2025-11-15 02:48:40 +00:00
private string? _name;
2025-11-14 15:18:30 +00:00
[ObservableProperty]
2025-11-15 02:48:40 +00:00
private NewsViewModel? _newsViewModel;
2025-11-14 19:00:01 +00:00
[ObservableProperty]
2025-11-15 02:48:40 +00:00
private bool _sidebarContentVisible = true;
2025-11-14 15:18:30 +00:00
public MainViewModel(IStringLocalizer localizer, IOptions<AppConfig> appInfo, INavigator navigator,
2025-11-16 20:35:00 +00:00
NewsViewModel newsViewModel, IColorThemeService colorThemeService, IThemeService themeService,
2025-11-16 23:09:47 +00:00
IAuthenticationService authService, IJwtService jwtService, ITokenService tokenService)
{
2025-11-14 15:18:30 +00:00
_navigator = navigator;
2025-11-14 19:00:01 +00:00
_localizer = localizer;
2025-11-16 20:35:00 +00:00
_authService = authService;
2025-11-16 23:09:47 +00:00
_jwtService = jwtService;
_tokenService = tokenService;
2025-11-14 15:18:30 +00:00
NewsViewModel = newsViewModel;
Title = "Marechai";
Title += $" - {localizer["ApplicationName"]}";
2025-11-14 19:00:01 +00:00
if(appInfo?.Value?.Environment != null) Title += $" - {appInfo.Value.Environment}";
GoToSecond = new AsyncRelayCommand(GoToSecondView);
// Initialize color theme service with theme service
_ = InitializeThemeServicesAsync(colorThemeService, themeService);
2025-11-14 19:00:01 +00:00
// Initialize localized strings
InitializeLocalizedStrings();
// Initialize commands
NavigateToNewsCommand = new AsyncRelayCommand(NavigateToMainAsync);
NavigateToBooksCommand = new AsyncRelayCommand(() => NavigateTo("books"));
NavigateToCompaniesCommand = new AsyncRelayCommand(() => NavigateTo("companies"));
NavigateToComputersCommand = new AsyncRelayCommand(() => NavigateTo("computers"));
NavigateToConsolesCommand = new AsyncRelayCommand(() => NavigateTo("consoles"));
NavigateToDocumentsCommand = new AsyncRelayCommand(() => NavigateTo("documents"));
NavigateToDumpsCommand = new AsyncRelayCommand(() => NavigateTo("dumps"));
2025-11-16 04:56:26 +00:00
NavigateToGraphicalProcessingUnitsCommand = new AsyncRelayCommand(() => NavigateTo("gpus"));
2025-11-14 19:00:01 +00:00
NavigateToMagazinesCommand = new AsyncRelayCommand(() => NavigateTo("magazines"));
NavigateToPeopleCommand = new AsyncRelayCommand(() => NavigateTo("people"));
NavigateToProcessorsCommand = new AsyncRelayCommand(() => NavigateTo("processors"));
NavigateToSoftwareCommand = new AsyncRelayCommand(() => NavigateTo("software"));
2025-11-16 16:48:24 +00:00
NavigateToSoundSynthesizersCommand = new AsyncRelayCommand(() => NavigateTo("sound-synths"));
2025-11-16 23:09:47 +00:00
NavigateToUsersCommand = new AsyncRelayCommand(() => NavigateTo("users"));
2025-11-14 19:00:01 +00:00
NavigateToSettingsCommand = new AsyncRelayCommand(() => NavigateTo("settings"));
LoginLogoutCommand = new RelayCommand(HandleLoginLogout);
ToggleSidebarCommand = new RelayCommand(() => IsSidebarOpen = !IsSidebarOpen);
2025-11-16 20:35:00 +00:00
// Subscribe to authentication events
_authService.LoggedOut += OnLoggedOut;
2025-11-14 19:00:01 +00:00
UpdateLoginLogoutButtonText();
2025-11-16 23:09:47 +00:00
UpdateUberadminStatus();
}
public string? Title { get; }
public ICommand GoToSecond { get; }
2025-11-14 19:00:01 +00:00
public ICommand NavigateToNewsCommand { get; }
public ICommand NavigateToBooksCommand { get; }
public ICommand NavigateToCompaniesCommand { get; }
public ICommand NavigateToComputersCommand { get; }
public ICommand NavigateToConsolesCommand { get; }
public ICommand NavigateToDocumentsCommand { get; }
public ICommand NavigateToDumpsCommand { get; }
public ICommand NavigateToGraphicalProcessingUnitsCommand { get; }
public ICommand NavigateToMagazinesCommand { get; }
public ICommand NavigateToPeopleCommand { get; }
public ICommand NavigateToProcessorsCommand { get; }
public ICommand NavigateToSoftwareCommand { get; }
public ICommand NavigateToSoundSynthesizersCommand { get; }
2025-11-16 23:09:47 +00:00
public ICommand NavigateToUsersCommand { get; }
2025-11-14 19:00:01 +00:00
public ICommand NavigateToSettingsCommand { get; }
public ICommand LoginLogoutCommand { get; }
public ICommand ToggleSidebarCommand { get; }
private async Task InitializeThemeServicesAsync(IColorThemeService colorThemeService, IThemeService themeService)
{
try
{
// Wait for theme service to be ready
await themeService.InitializeAsync();
// Set the theme service reference and reapply the saved theme
colorThemeService.SetThemeService(themeService);
}
catch
{
// Silently fail - theme will work but without refresh on startup
}
}
2025-11-14 19:00:01 +00:00
private void InitializeLocalizedStrings()
{
LocalizedStrings = new Dictionary<string, string>
{
{
"News", _localizer["News"]
},
{
"Books", _localizer["Books"]
},
{
"Companies", _localizer["Companies"]
},
{
"Computers", _localizer["Computers"]
},
{
"Consoles", _localizer["Consoles"]
},
{
"Documents", _localizer["Documents"]
},
{
"Dumps", _localizer["Dumps"]
},
{
"GraphicalProcessingUnits", _localizer["GraphicalProcessingUnits"]
},
{
"Magazines", _localizer["Magazines"]
},
{
"People", _localizer["People"]
},
{
"Processors", _localizer["Processors"]
},
{
"Software", _localizer["Software"]
},
{
"SoundSynthesizers", _localizer["SoundSynthesizers"]
},
{
"Settings", _localizer["Settings"]
},
{
"Login", _localizer["Login"]
},
{
"Logout", _localizer["Logout"]
}
};
}
2025-11-16 20:35:00 +00:00
private async void UpdateLoginLogoutButtonText()
{
bool isAuthenticated = await _authService.IsAuthenticated(CancellationToken.None);
LoginLogoutButtonText = isAuthenticated ? LocalizedStrings["Logout"] : LocalizedStrings["Login"];
}
2025-11-16 23:09:47 +00:00
private void UpdateUberadminStatus()
{
try
{
string token = _tokenService.GetToken();
if(!string.IsNullOrWhiteSpace(token))
{
IEnumerable<string> roles = _jwtService.GetRoles(token);
IsUberadminUser = roles.Contains("Uberadmin", StringComparer.OrdinalIgnoreCase);
}
else
IsUberadminUser = false;
}
catch
{
IsUberadminUser = false;
}
}
2025-11-16 20:35:00 +00:00
private void OnLoggedOut(object? sender, EventArgs e)
{
// Update button text when user logs out
UpdateLoginLogoutButtonText();
2025-11-16 23:09:47 +00:00
UpdateUberadminStatus();
2025-11-16 20:35:00 +00:00
}
public void RefreshAuthenticationState()
2025-11-14 19:00:01 +00:00
{
2025-11-16 20:35:00 +00:00
// Public method to refresh authentication state (called after login)
UpdateLoginLogoutButtonText();
2025-11-16 23:09:47 +00:00
UpdateUberadminStatus();
2025-11-14 19:00:01 +00:00
}
2025-11-16 20:35:00 +00:00
private async void HandleLoginLogout()
2025-11-14 19:00:01 +00:00
{
2025-11-16 20:35:00 +00:00
bool isAuthenticated = await _authService.IsAuthenticated(CancellationToken.None);
if(isAuthenticated)
{
// Logout
await _authService.LogoutAsync(null, CancellationToken.None);
UpdateLoginLogoutButtonText();
2025-11-16 23:09:47 +00:00
UpdateUberadminStatus();
2025-11-16 20:35:00 +00:00
}
else
{
// Navigate to login page - use absolute path starting from root
await _navigator.NavigateRouteAsync(this, "/Login");
}
2025-11-14 19:00:01 +00:00
}
private async Task NavigateTo(string destination)
{
2025-11-14 20:59:12 +00:00
try
{
// Navigate within the Main region using relative navigation
// The "./" prefix means navigate within the current page's region
await _navigator.NavigateRouteAsync(this, $"./{destination}");
}
catch(Exception)
{
// Navigation error - fail silently for now
// TODO: Add error handling/logging
}
2025-11-14 19:00:01 +00:00
}
private async Task NavigateToMainAsync()
{
2025-11-14 20:59:12 +00:00
// Navigate to News page (the default/home page)
await NavigateTo("News");
2025-11-14 19:00:01 +00:00
}
private async Task GoToSecondView()
{
2025-11-14 19:00:01 +00:00
// Navigate to Second view model providing qualifier and data
await _navigator.NavigateViewModelAsync<SecondViewModel>(this, "Second", new Entity(Name ?? ""));
}
2025-11-14 15:18:30 +00:00
}