mirror of
https://github.com/claunia/marechai.git
synced 2025-12-16 11:04:25 +00:00
Add login page.
This commit is contained in:
@@ -8,7 +8,7 @@
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<!-- Load WinUI resources -->
|
||||
<XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls" />
|
||||
|
||||
|
||||
<!-- Load Uno.UI.Toolkit resources -->
|
||||
<ToolkitResources xmlns="using:Uno.Toolkit.UI" />
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
@@ -17,6 +17,10 @@
|
||||
<local:ObjectToVisibilityConverter x:Key="ObjectToVisibilityConverter" />
|
||||
<local:StringToVisibilityConverter x:Key="StringToVisibilityConverter" />
|
||||
<local:ZeroToVisibilityConverter x:Key="ZeroToVisibilityConverter" />
|
||||
<local:InvertBoolConverter x:Key="InvertBoolConverter" />
|
||||
<local:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter" />
|
||||
<local:InvertBoolToVisibilityConverter x:Key="InvertBoolToVisibilityConverter" />
|
||||
<local:NullToVisibilityConverter x:Key="NullToVisibilityConverter" />
|
||||
|
||||
</ResourceDictionary>
|
||||
</Application.Resources>
|
||||
|
||||
@@ -27,6 +27,7 @@ using ProcessorsListViewModel = Marechai.App.Presentation.ViewModels.ProcessorsL
|
||||
using SettingsViewModel = Marechai.App.Presentation.ViewModels.SettingsViewModel;
|
||||
using SoundSynthDetailViewModel = Marechai.App.Presentation.ViewModels.SoundSynthDetailViewModel;
|
||||
using SoundSynthsListViewModel = Marechai.App.Presentation.ViewModels.SoundSynthsListViewModel;
|
||||
using LoginViewModel = Marechai.App.Presentation.ViewModels.LoginViewModel;
|
||||
|
||||
namespace Marechai.App;
|
||||
|
||||
@@ -164,6 +165,7 @@ public partial class App : Application
|
||||
services.AddTransient<SoundSynthsListViewModel>();
|
||||
services.AddTransient<SoundSynthDetailViewModel>();
|
||||
services.AddTransient<SettingsViewModel>();
|
||||
services.AddTransient<LoginViewModel>();
|
||||
})
|
||||
.UseNavigation(RegisterRoutes));
|
||||
|
||||
@@ -181,6 +183,7 @@ public partial class App : Application
|
||||
{
|
||||
views.Register(new ViewMap(ViewModel: typeof(ShellViewModel)),
|
||||
new ViewMap<MainPage, MainViewModel>(),
|
||||
new ViewMap<LoginPage, LoginViewModel>(),
|
||||
new ViewMap<NewsPage, NewsViewModel>(),
|
||||
new ViewMap<ComputersPage, ComputersViewModel>(),
|
||||
new ViewMap<ComputersListPage, ComputersListViewModel>(),
|
||||
@@ -203,6 +206,7 @@ public partial class App : Application
|
||||
views.FindByViewModel<ShellViewModel>(),
|
||||
Nested:
|
||||
[
|
||||
new RouteMap("Login", views.FindByViewModel<LoginViewModel>()),
|
||||
new RouteMap("Main",
|
||||
views.FindByViewModel<MainViewModel>(),
|
||||
true,
|
||||
|
||||
93
Marechai.App/Presentation/ViewModels/LoginViewModel.cs
Normal file
93
Marechai.App/Presentation/ViewModels/LoginViewModel.cs
Normal file
@@ -0,0 +1,93 @@
|
||||
#nullable enable
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Uno.Extensions.Authentication;
|
||||
using Uno.Extensions.Navigation;
|
||||
|
||||
namespace Marechai.App.Presentation.ViewModels;
|
||||
|
||||
public partial class LoginViewModel : ObservableObject
|
||||
{
|
||||
private readonly IAuthenticationService _authService;
|
||||
private readonly INavigator _navigator;
|
||||
private readonly IStringLocalizer _stringLocalizer;
|
||||
|
||||
[ObservableProperty]
|
||||
private string _email = string.Empty;
|
||||
[ObservableProperty]
|
||||
private string? _errorMessage;
|
||||
[ObservableProperty]
|
||||
private bool _isLoggingIn;
|
||||
[ObservableProperty]
|
||||
private string _password = string.Empty;
|
||||
|
||||
public LoginViewModel(INavigator navigator, IAuthenticationService authService, IStringLocalizer stringLocalizer)
|
||||
{
|
||||
_navigator = navigator;
|
||||
_authService = authService;
|
||||
_stringLocalizer = stringLocalizer;
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private async Task LoginAsync()
|
||||
{
|
||||
// Clear previous error
|
||||
ErrorMessage = null;
|
||||
|
||||
// Validate inputs
|
||||
if(string.IsNullOrWhiteSpace(Email))
|
||||
{
|
||||
ErrorMessage = _stringLocalizer["LoginPage.Error.EmailRequired"];
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if(string.IsNullOrWhiteSpace(Password))
|
||||
{
|
||||
ErrorMessage = _stringLocalizer["LoginPage.Error.PasswordRequired"];
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
IsLoggingIn = true;
|
||||
|
||||
try
|
||||
{
|
||||
var credentials = new Dictionary<string, string>
|
||||
{
|
||||
["Email"] = Email,
|
||||
["Password"] = Password
|
||||
};
|
||||
|
||||
bool success = await _authService.LoginAsync(null, credentials, null, CancellationToken.None);
|
||||
|
||||
if(success)
|
||||
{
|
||||
// Navigate back to main page on successful login
|
||||
await _navigator.NavigateRouteAsync(this, "/Main");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Check if there's an error message in credentials
|
||||
if(credentials.TryGetValue("error", out string? error))
|
||||
ErrorMessage = error;
|
||||
else
|
||||
ErrorMessage = _stringLocalizer["LoginPage.Error.LoginFailed"];
|
||||
}
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
ErrorMessage = ex.Message;
|
||||
}
|
||||
finally
|
||||
{
|
||||
IsLoggingIn = false;
|
||||
}
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private void ClearError() => ErrorMessage = null;
|
||||
}
|
||||
@@ -1,8 +1,10 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
using Marechai.App.Services;
|
||||
using Uno.Extensions.Authentication;
|
||||
using Uno.Extensions.Navigation;
|
||||
using Uno.Extensions.Toolkit;
|
||||
|
||||
@@ -10,8 +12,9 @@ namespace Marechai.App.Presentation.ViewModels;
|
||||
|
||||
public partial class MainViewModel : ObservableObject
|
||||
{
|
||||
private readonly IStringLocalizer _localizer;
|
||||
private readonly INavigator _navigator;
|
||||
private readonly IAuthenticationService _authService;
|
||||
private readonly IStringLocalizer _localizer;
|
||||
private readonly INavigator _navigator;
|
||||
[ObservableProperty]
|
||||
private bool _isSidebarOpen = true;
|
||||
[ObservableProperty]
|
||||
@@ -27,10 +30,12 @@ public partial class MainViewModel : ObservableObject
|
||||
private bool _sidebarContentVisible = true;
|
||||
|
||||
public MainViewModel(IStringLocalizer localizer, IOptions<AppConfig> appInfo, INavigator navigator,
|
||||
NewsViewModel newsViewModel, IColorThemeService colorThemeService, IThemeService themeService)
|
||||
NewsViewModel newsViewModel, IColorThemeService colorThemeService, IThemeService themeService,
|
||||
IAuthenticationService authService)
|
||||
{
|
||||
_navigator = navigator;
|
||||
_localizer = localizer;
|
||||
_authService = authService;
|
||||
NewsViewModel = newsViewModel;
|
||||
Title = "Marechai";
|
||||
Title += $" - {localizer["ApplicationName"]}";
|
||||
@@ -62,6 +67,9 @@ public partial class MainViewModel : ObservableObject
|
||||
LoginLogoutCommand = new RelayCommand(HandleLoginLogout);
|
||||
ToggleSidebarCommand = new RelayCommand(() => IsSidebarOpen = !IsSidebarOpen);
|
||||
|
||||
// Subscribe to authentication events
|
||||
_authService.LoggedOut += OnLoggedOut;
|
||||
|
||||
UpdateLoginLogoutButtonText();
|
||||
}
|
||||
|
||||
@@ -157,16 +165,39 @@ public partial class MainViewModel : ObservableObject
|
||||
};
|
||||
}
|
||||
|
||||
private void UpdateLoginLogoutButtonText()
|
||||
private async void UpdateLoginLogoutButtonText()
|
||||
{
|
||||
// TODO: Check if user is logged in
|
||||
// For now, always show "Login"
|
||||
LoginLogoutButtonText = LocalizedStrings["Login"];
|
||||
bool isAuthenticated = await _authService.IsAuthenticated(CancellationToken.None);
|
||||
LoginLogoutButtonText = isAuthenticated ? LocalizedStrings["Logout"] : LocalizedStrings["Login"];
|
||||
}
|
||||
|
||||
private static void HandleLoginLogout()
|
||||
private void OnLoggedOut(object? sender, EventArgs e)
|
||||
{
|
||||
// TODO: Implement login/logout logic
|
||||
// Update button text when user logs out
|
||||
UpdateLoginLogoutButtonText();
|
||||
}
|
||||
|
||||
public void RefreshAuthenticationState()
|
||||
{
|
||||
// Public method to refresh authentication state (called after login)
|
||||
UpdateLoginLogoutButtonText();
|
||||
}
|
||||
|
||||
private async void HandleLoginLogout()
|
||||
{
|
||||
bool isAuthenticated = await _authService.IsAuthenticated(CancellationToken.None);
|
||||
|
||||
if(isAuthenticated)
|
||||
{
|
||||
// Logout
|
||||
await _authService.LogoutAsync(null, CancellationToken.None);
|
||||
UpdateLoginLogoutButtonText();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Navigate to login page - use absolute path starting from root
|
||||
await _navigator.NavigateRouteAsync(this, "/Login");
|
||||
}
|
||||
}
|
||||
|
||||
private async Task NavigateTo(string destination)
|
||||
|
||||
@@ -8,5 +8,6 @@ public class ShellViewModel
|
||||
|
||||
public ShellViewModel(INavigator navigator) => _navigator = navigator;
|
||||
|
||||
// Add code here to initialize or attach event handlers to singleton services
|
||||
// Users can browse the app without authentication
|
||||
// Login is available from the sidebar when needed
|
||||
}
|
||||
209
Marechai.App/Presentation/Views/LoginPage.xaml
Normal file
209
Marechai.App/Presentation/Views/LoginPage.xaml
Normal file
@@ -0,0 +1,209 @@
|
||||
<?xml version="1.0"
|
||||
encoding="utf-8"?>
|
||||
|
||||
<Page x:Class="Marechai.App.Presentation.Views.LoginPage"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:vm="using:Marechai.App.Presentation.ViewModels"
|
||||
xmlns:utu="using:Uno.Toolkit.UI"
|
||||
mc:Ignorable="d"
|
||||
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
|
||||
d:DataContext="{d:DesignInstance vm:LoginViewModel}">
|
||||
|
||||
<Grid utu:SafeArea.Insets="VisibleBounds">
|
||||
<!-- Center content on screen -->
|
||||
<Grid HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
MaxWidth="480"
|
||||
Padding="32">
|
||||
|
||||
<!-- Login Card with Mac OS 9 styling -->
|
||||
<Border Background="{ThemeResource CardBackgroundFillColorDefaultBrush}"
|
||||
BorderBrush="{ThemeResource CardStrokeColorDefaultBrush}"
|
||||
BorderThickness="2"
|
||||
CornerRadius="8"
|
||||
Padding="0"
|
||||
Translation="0,0,16">
|
||||
<Border.Shadow>
|
||||
<ThemeShadow />
|
||||
</Border.Shadow>
|
||||
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" /> <RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- Header with Mac OS 9 Title Bar Style -->
|
||||
<Border Grid.Row="0"
|
||||
Background="{ThemeResource AccentFillColorDefaultBrush}"
|
||||
Padding="16,12"
|
||||
CornerRadius="6,6,0,0">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" /> <ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<!-- Icon -->
|
||||
<FontIcon Grid.Column="0"
|
||||
Glyph=""
|
||||
FontSize="24"
|
||||
Foreground="White"
|
||||
Margin="0,0,12,0"
|
||||
VerticalAlignment="Center" />
|
||||
|
||||
<!-- Title -->
|
||||
<TextBlock Grid.Column="1"
|
||||
x:Uid="LoginPage_Title"
|
||||
Text="Sign In to Marechai"
|
||||
Style="{StaticResource TitleTextBlockStyle}"
|
||||
Foreground="White"
|
||||
VerticalAlignment="Center" />
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
<!-- Login Form Content -->
|
||||
<ScrollViewer Grid.Row="1"
|
||||
VerticalScrollBarVisibility="Auto">
|
||||
<StackPanel Padding="32"
|
||||
Spacing="24">
|
||||
|
||||
<!-- Welcome Message -->
|
||||
<TextBlock x:Uid="LoginPage_WelcomeMessage"
|
||||
Text="Welcome back! Please sign in to continue."
|
||||
Style="{StaticResource BodyTextBlockStyle}"
|
||||
TextWrapping="Wrap"
|
||||
HorizontalAlignment="Center"
|
||||
TextAlignment="Center" />
|
||||
|
||||
<!-- Email Input -->
|
||||
<StackPanel Spacing="8">
|
||||
<TextBlock x:Uid="LoginPage_EmailLabel"
|
||||
Text="Email Address"
|
||||
Style="{StaticResource BodyStrongTextBlockStyle}" />
|
||||
<TextBox x:Name="EmailTextBox"
|
||||
x:Uid="LoginPage_EmailTextBox"
|
||||
Text="{Binding Email, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
||||
PlaceholderText="Enter your email"
|
||||
InputScope="EmailSmtpAddress"
|
||||
IsSpellCheckEnabled="False"
|
||||
AutomationProperties.Name="Email address"
|
||||
KeyDown="OnEmailKeyDown" />
|
||||
</StackPanel>
|
||||
|
||||
<!-- Password Input -->
|
||||
<StackPanel Spacing="8">
|
||||
<TextBlock x:Uid="LoginPage_PasswordLabel"
|
||||
Text="Password"
|
||||
Style="{StaticResource BodyStrongTextBlockStyle}" />
|
||||
<PasswordBox x:Name="PasswordBox"
|
||||
x:Uid="LoginPage_PasswordBox"
|
||||
Password="{Binding Password, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
||||
PlaceholderText="Enter your password"
|
||||
AutomationProperties.Name="Password"
|
||||
KeyDown="OnPasswordKeyDown" />
|
||||
</StackPanel>
|
||||
|
||||
<!-- Error Message -->
|
||||
<Border x:Name="ErrorBorder"
|
||||
Background="#FFF4E6"
|
||||
BorderBrush="#FFB84D"
|
||||
BorderThickness="2"
|
||||
CornerRadius="4"
|
||||
Padding="12"
|
||||
Visibility="{Binding ErrorMessage, Converter={StaticResource NullToVisibilityConverter}}">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" /> <ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<!-- Warning Icon -->
|
||||
<FontIcon Grid.Column="0"
|
||||
Glyph=""
|
||||
Foreground="#D97706"
|
||||
FontSize="20"
|
||||
Margin="0,0,8,0"
|
||||
VerticalAlignment="Top" />
|
||||
|
||||
<!-- Error Text -->
|
||||
<TextBlock Grid.Column="1"
|
||||
Text="{Binding ErrorMessage}"
|
||||
Foreground="#92400E"
|
||||
TextWrapping="Wrap"
|
||||
VerticalAlignment="Center" />
|
||||
|
||||
<!-- Close Button -->
|
||||
<Button Grid.Column="2"
|
||||
Command="{Binding ClearErrorCommand}"
|
||||
Background="Transparent"
|
||||
BorderThickness="0"
|
||||
Padding="8"
|
||||
Margin="8,0,0,0"
|
||||
VerticalAlignment="Center"
|
||||
AutomationProperties.Name="Close error message">
|
||||
<FontIcon Glyph=""
|
||||
FontSize="12"
|
||||
Foreground="#92400E" />
|
||||
</Button>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
<!-- Login Button -->
|
||||
<Button x:Name="LoginButton"
|
||||
x:Uid="LoginPage_LoginButton"
|
||||
Command="{Binding LoginCommand}"
|
||||
IsEnabled="{Binding IsLoggingIn, Converter={StaticResource InvertBoolConverter}}"
|
||||
HorizontalAlignment="Stretch"
|
||||
Padding="16,12"
|
||||
Style="{StaticResource AccentButtonStyle}"
|
||||
AutomationProperties.Name="Sign in button">
|
||||
<Button.Content>
|
||||
<Grid>
|
||||
<TextBlock x:Uid="LoginPage_LoginButtonText"
|
||||
Text="Sign In"
|
||||
Visibility="{Binding IsLoggingIn, Converter={StaticResource InvertBoolToVisibilityConverter}}" />
|
||||
<StackPanel Orientation="Horizontal"
|
||||
HorizontalAlignment="Center"
|
||||
Spacing="8"
|
||||
Visibility="{Binding IsLoggingIn, Converter={StaticResource BoolToVisibilityConverter}}">
|
||||
<ProgressRing IsActive="True"
|
||||
Width="20"
|
||||
Height="20"
|
||||
Foreground="White" />
|
||||
<TextBlock x:Uid="LoginPage_SigningInText"
|
||||
Text="Signing in..."
|
||||
Foreground="White" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Button.Content>
|
||||
</Button>
|
||||
|
||||
<!-- Additional Options -->
|
||||
<StackPanel Spacing="8"
|
||||
HorizontalAlignment="Center">
|
||||
<HyperlinkButton x:Uid="LoginPage_ForgotPasswordLink"
|
||||
Content="Forgot your password?"
|
||||
HorizontalAlignment="Center"
|
||||
Visibility="Collapsed" />
|
||||
|
||||
<StackPanel Orientation="Horizontal"
|
||||
HorizontalAlignment="Center"
|
||||
Spacing="4"
|
||||
Visibility="Collapsed">
|
||||
<TextBlock x:Uid="LoginPage_NoAccountText"
|
||||
Text="Don't have an account?"
|
||||
VerticalAlignment="Center" />
|
||||
<HyperlinkButton x:Uid="LoginPage_SignUpLink"
|
||||
Content="Sign up"
|
||||
Padding="4,0" />
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
</Grid>
|
||||
</Border>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Page>
|
||||
33
Marechai.App/Presentation/Views/LoginPage.xaml.cs
Normal file
33
Marechai.App/Presentation/Views/LoginPage.xaml.cs
Normal file
@@ -0,0 +1,33 @@
|
||||
using Windows.System;
|
||||
using Marechai.App.Presentation.ViewModels;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using Microsoft.UI.Xaml.Input;
|
||||
|
||||
namespace Marechai.App.Presentation.Views;
|
||||
|
||||
public sealed partial class LoginPage : Page
|
||||
{
|
||||
public LoginPage() => InitializeComponent();
|
||||
|
||||
private void OnEmailKeyDown(object sender, KeyRoutedEventArgs e)
|
||||
{
|
||||
if(e.Key == VirtualKey.Enter)
|
||||
{
|
||||
// Move focus to password field
|
||||
PasswordBox.Focus(FocusState.Keyboard);
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnPasswordKeyDown(object sender, KeyRoutedEventArgs e)
|
||||
{
|
||||
if(e.Key == VirtualKey.Enter)
|
||||
{
|
||||
// Trigger login when Enter is pressed
|
||||
if(DataContext is LoginViewModel viewModel && LoginButton.IsEnabled) viewModel.LoginCommand.Execute(null);
|
||||
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -224,4 +224,51 @@
|
||||
<data name="SettingsPage_DesignSystemChange_Notice.Text" xml:space="preserve">
|
||||
<value>Design system changes will be applied the next time you start the application. Color theme changes are applied immediately.</value>
|
||||
</data>
|
||||
|
||||
<!-- Login Page -->
|
||||
<data name="LoginPage_Title.Text" xml:space="preserve">
|
||||
<value>Sign In to Marechai</value>
|
||||
</data>
|
||||
<data name="LoginPage_WelcomeMessage.Text" xml:space="preserve">
|
||||
<value>Welcome back! Please sign in to continue.</value>
|
||||
</data>
|
||||
<data name="LoginPage_EmailLabel.Text" xml:space="preserve">
|
||||
<value>Email Address</value>
|
||||
</data>
|
||||
<data name="LoginPage_EmailTextBox.PlaceholderText" xml:space="preserve">
|
||||
<value>Enter your email</value>
|
||||
</data>
|
||||
<data name="LoginPage_PasswordLabel.Text" xml:space="preserve">
|
||||
<value>Password</value>
|
||||
</data>
|
||||
<data name="LoginPage_PasswordBox.PlaceholderText" xml:space="preserve">
|
||||
<value>Enter your password</value>
|
||||
</data>
|
||||
<data name="LoginPage_LoginButton.Content" xml:space="preserve">
|
||||
<value>Sign In</value>
|
||||
</data>
|
||||
<data name="LoginPage_LoginButtonText.Text" xml:space="preserve">
|
||||
<value>Sign In</value>
|
||||
</data>
|
||||
<data name="LoginPage_SigningInText.Text" xml:space="preserve">
|
||||
<value>Signing in...</value>
|
||||
</data>
|
||||
<data name="LoginPage_ForgotPasswordLink.Content" xml:space="preserve">
|
||||
<value>Forgot your password?</value>
|
||||
</data>
|
||||
<data name="LoginPage_NoAccountText.Text" xml:space="preserve">
|
||||
<value>Don't have an account?</value>
|
||||
</data>
|
||||
<data name="LoginPage_SignUpLink.Content" xml:space="preserve">
|
||||
<value>Sign up</value>
|
||||
</data>
|
||||
<data name="LoginPage.Error.EmailRequired" xml:space="preserve">
|
||||
<value>Email address is required.</value>
|
||||
</data>
|
||||
<data name="LoginPage.Error.PasswordRequired" xml:space="preserve">
|
||||
<value>Password is required.</value>
|
||||
</data>
|
||||
<data name="LoginPage.Error.LoginFailed" xml:space="preserve">
|
||||
<value>Login failed. Please check your credentials and try again.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -224,4 +224,51 @@
|
||||
<data name="SettingsPage_DesignSystemChange_Notice.Text" xml:space="preserve">
|
||||
<value>Los cambios del sistema de diseño se aplicarán la próxima vez que inicie la aplicación. Los cambios de tema de color se aplican inmediatamente.</value>
|
||||
</data>
|
||||
|
||||
<!-- Login Page -->
|
||||
<data name="LoginPage_Title.Text" xml:space="preserve">
|
||||
<value>Iniciar Sesión en Marechai</value>
|
||||
</data>
|
||||
<data name="LoginPage_WelcomeMessage.Text" xml:space="preserve">
|
||||
<value>¡Bienvenido de nuevo! Por favor, inicia sesión para continuar.</value>
|
||||
</data>
|
||||
<data name="LoginPage_EmailLabel.Text" xml:space="preserve">
|
||||
<value>Dirección de Correo Electrónico</value>
|
||||
</data>
|
||||
<data name="LoginPage_EmailTextBox.PlaceholderText" xml:space="preserve">
|
||||
<value>Ingrese su correo electrónico</value>
|
||||
</data>
|
||||
<data name="LoginPage_PasswordLabel.Text" xml:space="preserve">
|
||||
<value>Contraseña</value>
|
||||
</data>
|
||||
<data name="LoginPage_PasswordBox.PlaceholderText" xml:space="preserve">
|
||||
<value>Ingrese su contraseña</value>
|
||||
</data>
|
||||
<data name="LoginPage_LoginButton.Content" xml:space="preserve">
|
||||
<value>Iniciar Sesión</value>
|
||||
</data>
|
||||
<data name="LoginPage_LoginButtonText.Text" xml:space="preserve">
|
||||
<value>Iniciar Sesión</value>
|
||||
</data>
|
||||
<data name="LoginPage_SigningInText.Text" xml:space="preserve">
|
||||
<value>Iniciando sesión...</value>
|
||||
</data>
|
||||
<data name="LoginPage_ForgotPasswordLink.Content" xml:space="preserve">
|
||||
<value>¿Olvidó su contraseña?</value>
|
||||
</data>
|
||||
<data name="LoginPage_NoAccountText.Text" xml:space="preserve">
|
||||
<value>¿No tiene una cuenta?</value>
|
||||
</data>
|
||||
<data name="LoginPage_SignUpLink.Content" xml:space="preserve">
|
||||
<value>Registrarse</value>
|
||||
</data>
|
||||
<data name="LoginPage.Error.EmailRequired" xml:space="preserve">
|
||||
<value>La dirección de correo electrónico es obligatoria.</value>
|
||||
</data>
|
||||
<data name="LoginPage.Error.PasswordRequired" xml:space="preserve">
|
||||
<value>La contraseña es obligatoria.</value>
|
||||
</data>
|
||||
<data name="LoginPage.Error.LoginFailed" xml:space="preserve">
|
||||
<value>Error al iniciar sesión. Por favor, verifique sus credenciales e intente nuevamente.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -222,6 +222,53 @@
|
||||
<value>Système de Conception</value>
|
||||
</data>
|
||||
<data name="SettingsPage_DesignSystemChange_Notice.Text" xml:space="preserve">
|
||||
<value>Les modifications du système de conception seront appliquées au prochain démarrage de l'application. Les modifications du thème de couleur sont appliquées immédiatement.</value>
|
||||
<value>Les modifications du système de conception seront appliquées la prochaine fois que vous démarrerez l'application. Les modifications du thème de couleur sont appliquées immédiatement.</value>
|
||||
</data>
|
||||
|
||||
<!-- Login Page -->
|
||||
<data name="LoginPage_Title.Text" xml:space="preserve">
|
||||
<value>Se Connecter à Marechai</value>
|
||||
</data>
|
||||
<data name="LoginPage_WelcomeMessage.Text" xml:space="preserve">
|
||||
<value>Bienvenue ! Veuillez vous connecter pour continuer.</value>
|
||||
</data>
|
||||
<data name="LoginPage_EmailLabel.Text" xml:space="preserve">
|
||||
<value>Adresse E-mail</value>
|
||||
</data>
|
||||
<data name="LoginPage_EmailTextBox.PlaceholderText" xml:space="preserve">
|
||||
<value>Entrez votre e-mail</value>
|
||||
</data>
|
||||
<data name="LoginPage_PasswordLabel.Text" xml:space="preserve">
|
||||
<value>Mot de Passe</value>
|
||||
</data>
|
||||
<data name="LoginPage_PasswordBox.PlaceholderText" xml:space="preserve">
|
||||
<value>Entrez votre mot de passe</value>
|
||||
</data>
|
||||
<data name="LoginPage_LoginButton.Content" xml:space="preserve">
|
||||
<value>Se Connecter</value>
|
||||
</data>
|
||||
<data name="LoginPage_LoginButtonText.Text" xml:space="preserve">
|
||||
<value>Se Connecter</value>
|
||||
</data>
|
||||
<data name="LoginPage_SigningInText.Text" xml:space="preserve">
|
||||
<value>Connexion en cours...</value>
|
||||
</data>
|
||||
<data name="LoginPage_ForgotPasswordLink.Content" xml:space="preserve">
|
||||
<value>Mot de passe oublié ?</value>
|
||||
</data>
|
||||
<data name="LoginPage_NoAccountText.Text" xml:space="preserve">
|
||||
<value>Vous n'avez pas de compte ?</value>
|
||||
</data>
|
||||
<data name="LoginPage_SignUpLink.Content" xml:space="preserve">
|
||||
<value>S'inscrire</value>
|
||||
</data>
|
||||
<data name="LoginPage.Error.EmailRequired" xml:space="preserve">
|
||||
<value>L'adresse e-mail est requise.</value>
|
||||
</data>
|
||||
<data name="LoginPage.Error.PasswordRequired" xml:space="preserve">
|
||||
<value>Le mot de passe est requis.</value>
|
||||
</data>
|
||||
<data name="LoginPage.Error.LoginFailed" xml:space="preserve">
|
||||
<value>Échec de la connexion. Veuillez vérifier vos identifiants et réessayer.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -222,6 +222,53 @@
|
||||
<value>Sistema de Design</value>
|
||||
</data>
|
||||
<data name="SettingsPage_DesignSystemChange_Notice.Text" xml:space="preserve">
|
||||
<value>As alterações do sistema de design serão aplicadas na próxima vez que você iniciar o aplicativo. As alterações de tema de cor são aplicadas imediatamente.</value>
|
||||
<value>As alterações no sistema de design serão aplicadas na próxima vez que você iniciar o aplicativo. As alterações no tema de cores são aplicadas imediatamente.</value>
|
||||
</data>
|
||||
|
||||
<!-- Login Page -->
|
||||
<data name="LoginPage_Title.Text" xml:space="preserve">
|
||||
<value>Entrar no Marechai</value>
|
||||
</data>
|
||||
<data name="LoginPage_WelcomeMessage.Text" xml:space="preserve">
|
||||
<value>Bem-vindo de volta! Por favor, faça login para continuar.</value>
|
||||
</data>
|
||||
<data name="LoginPage_EmailLabel.Text" xml:space="preserve">
|
||||
<value>Endereço de E-mail</value>
|
||||
</data>
|
||||
<data name="LoginPage_EmailTextBox.PlaceholderText" xml:space="preserve">
|
||||
<value>Digite seu e-mail</value>
|
||||
</data>
|
||||
<data name="LoginPage_PasswordLabel.Text" xml:space="preserve">
|
||||
<value>Senha</value>
|
||||
</data>
|
||||
<data name="LoginPage_PasswordBox.PlaceholderText" xml:space="preserve">
|
||||
<value>Digite sua senha</value>
|
||||
</data>
|
||||
<data name="LoginPage_LoginButton.Content" xml:space="preserve">
|
||||
<value>Entrar</value>
|
||||
</data>
|
||||
<data name="LoginPage_LoginButtonText.Text" xml:space="preserve">
|
||||
<value>Entrar</value>
|
||||
</data>
|
||||
<data name="LoginPage_SigningInText.Text" xml:space="preserve">
|
||||
<value>Entrando...</value>
|
||||
</data>
|
||||
<data name="LoginPage_ForgotPasswordLink.Content" xml:space="preserve">
|
||||
<value>Esqueceu sua senha?</value>
|
||||
</data>
|
||||
<data name="LoginPage_NoAccountText.Text" xml:space="preserve">
|
||||
<value>Não tem uma conta?</value>
|
||||
</data>
|
||||
<data name="LoginPage_SignUpLink.Content" xml:space="preserve">
|
||||
<value>Cadastre-se</value>
|
||||
</data>
|
||||
<data name="LoginPage.Error.EmailRequired" xml:space="preserve">
|
||||
<value>O endereço de e-mail é obrigatório.</value>
|
||||
</data>
|
||||
<data name="LoginPage.Error.PasswordRequired" xml:space="preserve">
|
||||
<value>A senha é obrigatória.</value>
|
||||
</data>
|
||||
<data name="LoginPage.Error.LoginFailed" xml:space="preserve">
|
||||
<value>Falha no login. Por favor, verifique suas credenciais e tente novamente.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
Reference in New Issue
Block a user