531 lines
30 KiB
XML
531 lines
30 KiB
XML
<UserControl xmlns="https://github.com/avaloniaui"
|
|
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="clr-namespace:Clario.ViewModels"
|
|
mc:Ignorable="d" d:DesignWidth="1180" d:DesignHeight="800"
|
|
x:Class="Clario.Views.SettingsView"
|
|
x:DataType="vm:SettingsViewModel">
|
|
<Design.DataContext>
|
|
<vm:SettingsViewModel />
|
|
</Design.DataContext>
|
|
|
|
<ScrollViewer VerticalScrollBarVisibility="Auto"
|
|
HorizontalScrollBarVisibility="Disabled">
|
|
<StackPanel Margin="32,28,32,48"
|
|
Spacing="0"
|
|
MaxWidth="720">
|
|
|
|
<!-- ── Page header ─────────────────────────── -->
|
|
<StackPanel Margin="0,0,0,28">
|
|
<TextBlock Text="Settings"
|
|
FontSize="26"
|
|
FontWeight="Bold"
|
|
Foreground="{DynamicResource TextPrimary}" />
|
|
<TextBlock Text="Manage your account and preferences"
|
|
FontSize="13"
|
|
Foreground="{DynamicResource TextMuted}"
|
|
Margin="0,4,0,0" />
|
|
</StackPanel>
|
|
|
|
<!-- ── Global success / error banner ─────────── -->
|
|
<Border Background="{DynamicResource IconBgGreen}"
|
|
BorderBrush="{DynamicResource AccentGreen}"
|
|
BorderThickness="1"
|
|
CornerRadius="12"
|
|
Padding="14,10"
|
|
Margin="0,0,0,14"
|
|
IsVisible="{Binding HasSuccess}">
|
|
<Grid ColumnDefinitions="Auto,*">
|
|
<Svg Grid.Column="0"
|
|
Path="../Assets/Icons/circle-check.svg"
|
|
Width="14" Height="14"
|
|
Css="{DynamicResource SvgGreen}"
|
|
VerticalAlignment="Center"
|
|
Margin="0,0,10,0" />
|
|
<TextBlock Grid.Column="1"
|
|
Text="{Binding SuccessMessage}"
|
|
FontSize="13"
|
|
Foreground="{DynamicResource AccentGreen}"
|
|
VerticalAlignment="Center" />
|
|
</Grid>
|
|
</Border>
|
|
|
|
<Border Background="{DynamicResource BadgeBgRed}"
|
|
BorderBrush="{DynamicResource AccentRed}"
|
|
BorderThickness="1"
|
|
CornerRadius="12"
|
|
Padding="14,10"
|
|
Margin="0,0,0,14"
|
|
IsVisible="{Binding HasError}">
|
|
<Grid ColumnDefinitions="Auto,*">
|
|
<Svg Grid.Column="0"
|
|
Path="../Assets/Icons/circle-alert.svg"
|
|
Width="14" Height="14"
|
|
Css="path, circle, rect, ellipse, line, polyline, polygon, text, use { stroke: #FF5E5E; }"
|
|
VerticalAlignment="Center"
|
|
Margin="0,0,10,0" />
|
|
<TextBlock Grid.Column="1"
|
|
Text="{Binding ErrorMessage}"
|
|
FontSize="13"
|
|
Foreground="{DynamicResource AccentRed}"
|
|
VerticalAlignment="Center"
|
|
TextWrapping="Wrap" />
|
|
</Grid>
|
|
</Border>
|
|
|
|
<!-- ══════════════════════════════════════════════
|
|
SECTION: Profile
|
|
══════════════════════════════════════════════ -->
|
|
<TextBlock Text="PROFILE"
|
|
Classes="label"
|
|
Margin="0,0,0,10" />
|
|
|
|
<Border Background="{DynamicResource BgSurface}"
|
|
BorderBrush="{DynamicResource BorderSubtle}"
|
|
BorderThickness="1"
|
|
CornerRadius="16"
|
|
Padding="22"
|
|
Margin="0,0,0,24">
|
|
<StackPanel Spacing="20">
|
|
|
|
<!-- Avatar -->
|
|
<Grid ColumnDefinitions="Auto,*">
|
|
<StackPanel Grid.Column="0"
|
|
Spacing="8"
|
|
Margin="0,0,20,0">
|
|
<!-- Avatar circle -->
|
|
<Panel Width="80" Height="80"
|
|
HorizontalAlignment="Center">
|
|
<!-- Image (if has avatar) -->
|
|
<Border CornerRadius="40"
|
|
ClipToBounds="True"
|
|
Width="80" Height="80"
|
|
IsVisible="{Binding HasAvatar}">
|
|
<Image Source="{Binding AvatarImage}"
|
|
Stretch="UniformToFill" />
|
|
</Border>
|
|
<!-- Initials fallback -->
|
|
<Border CornerRadius="40"
|
|
Width="80" Height="80"
|
|
Background="{DynamicResource BorderAccent}"
|
|
IsVisible="{Binding !HasAvatar}">
|
|
<TextBlock Text="{Binding DisplayName[0]}"
|
|
FontSize="28"
|
|
FontWeight="Bold"
|
|
Foreground="{DynamicResource AccentBlue}"
|
|
HorizontalAlignment="Center"
|
|
VerticalAlignment="Center" />
|
|
</Border>
|
|
<!-- Upload spinner overlay -->
|
|
<Border CornerRadius="40"
|
|
Width="80" Height="80"
|
|
Background="#80000000"
|
|
IsVisible="{Binding IsUploadingAvatar}">
|
|
<TextBlock Text="..."
|
|
Foreground="White"
|
|
HorizontalAlignment="Center"
|
|
VerticalAlignment="Center" />
|
|
</Border>
|
|
</Panel>
|
|
|
|
<!-- Avatar actions -->
|
|
<StackPanel Spacing="4">
|
|
<Button Classes="base"
|
|
HorizontalAlignment="Stretch"
|
|
HorizontalContentAlignment="Center"
|
|
Padding="0,7"
|
|
FontSize="12"
|
|
IsEnabled="{Binding !IsUploadingAvatar}"
|
|
Command="{Binding UploadAvatarCommand}">
|
|
<StackPanel Orientation="Horizontal" Spacing="6">
|
|
<Svg Path="../Assets/Icons/upload.svg"
|
|
Width="12" Height="12"
|
|
Css="{DynamicResource SvgMuted}" />
|
|
<TextBlock Text="Upload" FontSize="12" VerticalAlignment="Center" />
|
|
</StackPanel>
|
|
</Button>
|
|
<Button Background="Transparent"
|
|
BorderThickness="0"
|
|
HorizontalAlignment="Stretch"
|
|
HorizontalContentAlignment="Center"
|
|
Padding="0,4"
|
|
FontSize="11"
|
|
Foreground="{DynamicResource AccentRed}"
|
|
IsVisible="{Binding HasAvatar}"
|
|
IsEnabled="{Binding !IsUploadingAvatar}"
|
|
Command="{Binding RemoveAvatarCommand}"
|
|
Content="Remove" />
|
|
</StackPanel>
|
|
</StackPanel>
|
|
|
|
<!-- Profile fields -->
|
|
<StackPanel Grid.Column="1" Spacing="16">
|
|
|
|
<!-- Display name -->
|
|
<StackPanel Spacing="6">
|
|
<TextBlock Text="DISPLAY NAME" Classes="label" />
|
|
<TextBox Text="{Binding DisplayName, Mode=TwoWay}"
|
|
Watermark="Your name"
|
|
FontSize="13"
|
|
Height="38"
|
|
Padding="12,0"
|
|
VerticalContentAlignment="Center" />
|
|
</StackPanel>
|
|
|
|
<!-- Currency + Theme -->
|
|
<Grid ColumnDefinitions="*,16,*">
|
|
<StackPanel Grid.Column="0" Spacing="6">
|
|
<TextBlock Text="CURRENCY" Classes="label" />
|
|
<ComboBox ItemsSource="{Binding Currencies}"
|
|
SelectedItem="{Binding SelectedCurrency, Mode=TwoWay}"
|
|
HorizontalAlignment="Stretch"
|
|
Padding="10,8"
|
|
FontSize="13" />
|
|
</StackPanel>
|
|
<StackPanel Grid.Column="2" Spacing="6">
|
|
<TextBlock Text="THEME" Classes="label" />
|
|
<ComboBox ItemsSource="{Binding ThemeLabels}"
|
|
SelectedIndex="{Binding SelectedThemeIndex, Mode=TwoWay}"
|
|
HorizontalAlignment="Stretch"
|
|
Padding="10,8"
|
|
FontSize="13" />
|
|
</StackPanel>
|
|
</Grid>
|
|
|
|
<!-- Language -->
|
|
<StackPanel Spacing="6">
|
|
<TextBlock Text="LANGUAGE" Classes="label" />
|
|
<ComboBox ItemsSource="{Binding LanguageLabels}"
|
|
SelectedIndex="{Binding SelectedLanguageIndex, Mode=TwoWay}"
|
|
HorizontalAlignment="Stretch"
|
|
Padding="10,8"
|
|
FontSize="13" />
|
|
</StackPanel>
|
|
|
|
</StackPanel>
|
|
</Grid>
|
|
|
|
<Separator />
|
|
|
|
<!-- Save button -->
|
|
<Button Classes="accented"
|
|
HorizontalAlignment="Right"
|
|
Padding="20,9"
|
|
IsEnabled="{Binding !IsSaving}"
|
|
Command="{Binding SaveProfileCommand}">
|
|
<StackPanel Orientation="Horizontal" Spacing="8">
|
|
<Svg Path="../Assets/Icons/check.svg"
|
|
Width="13" Height="13"
|
|
Css="path, circle, rect, ellipse, line, polyline, polygon, text, use { stroke: #0D0F14; }" />
|
|
<Panel>
|
|
<TextBlock Text="{Binding IsSaving, Converter={StaticResource BoolToStringConverter}, ConverterParameter='Saving...|Save Changes'}"
|
|
FontSize="13"
|
|
FontWeight="SemiBold"
|
|
Foreground="{DynamicResource BgBase}"
|
|
VerticalAlignment="Center" />
|
|
</Panel>
|
|
</StackPanel>
|
|
</Button>
|
|
|
|
</StackPanel>
|
|
</Border>
|
|
|
|
<!-- ══════════════════════════════════════════════
|
|
SECTION: Account Security
|
|
══════════════════════════════════════════════ -->
|
|
<TextBlock Text="ACCOUNT & SECURITY"
|
|
Classes="label"
|
|
Margin="0,0,0,10" />
|
|
|
|
<Border Background="{DynamicResource BgSurface}"
|
|
BorderBrush="{DynamicResource BorderSubtle}"
|
|
BorderThickness="1"
|
|
CornerRadius="16"
|
|
Padding="0"
|
|
Margin="0,0,0,24">
|
|
<StackPanel Spacing="0">
|
|
|
|
<!-- ── Email row ───────────────────────────── -->
|
|
<Border BorderBrush="{DynamicResource BorderSubtle}"
|
|
BorderThickness="0,0,0,1"
|
|
Padding="20,0">
|
|
<Panel>
|
|
<!-- Normal email display -->
|
|
<Grid IsVisible="{Binding !IsChangingEmail}"
|
|
ColumnDefinitions="*,Auto"
|
|
MinHeight="58">
|
|
<StackPanel Grid.Column="0"
|
|
VerticalAlignment="Center"
|
|
Spacing="2">
|
|
<TextBlock Text="EMAIL ADDRESS"
|
|
Classes="label" />
|
|
<TextBlock Text="{Binding MaskedEmail}"
|
|
FontSize="13"
|
|
Foreground="{DynamicResource TextPrimary}"
|
|
FontWeight="SemiBold" />
|
|
</StackPanel>
|
|
<Button Grid.Column="1"
|
|
Background="Transparent"
|
|
BorderThickness="0"
|
|
Padding="0"
|
|
Cursor="Hand"
|
|
VerticalAlignment="Center"
|
|
Command="{Binding StartChangeEmailCommand}">
|
|
<StackPanel Orientation="Horizontal" Spacing="6">
|
|
<Svg Path="../Assets/Icons/pencil.svg"
|
|
Width="13" Height="13"
|
|
Css="{DynamicResource SvgMuted}" />
|
|
<TextBlock Text="Change"
|
|
FontSize="12"
|
|
Foreground="{DynamicResource AccentBlue}" />
|
|
</StackPanel>
|
|
</Button>
|
|
</Grid>
|
|
|
|
<!-- Change email form -->
|
|
<StackPanel IsVisible="{Binding IsChangingEmail}"
|
|
Spacing="12"
|
|
Margin="0,16,0,16">
|
|
<TextBlock Text="CHANGE EMAIL ADDRESS"
|
|
Classes="label" />
|
|
|
|
<!-- Email success / error -->
|
|
<Border Background="{DynamicResource IconBgGreen}"
|
|
BorderBrush="{DynamicResource AccentGreen}"
|
|
BorderThickness="1"
|
|
CornerRadius="10"
|
|
Padding="12,8"
|
|
IsVisible="{Binding HasEmailSuccess}">
|
|
<TextBlock Text="{Binding EmailSuccessMessage}"
|
|
FontSize="12"
|
|
Foreground="{DynamicResource AccentGreen}"
|
|
TextWrapping="Wrap" />
|
|
</Border>
|
|
<Border Background="{DynamicResource BadgeBgRed}"
|
|
BorderBrush="{DynamicResource AccentRed}"
|
|
BorderThickness="1"
|
|
CornerRadius="10"
|
|
Padding="12,8"
|
|
IsVisible="{Binding HasEmailError}">
|
|
<TextBlock Text="{Binding EmailErrorMessage}"
|
|
FontSize="12"
|
|
Foreground="{DynamicResource AccentRed}"
|
|
TextWrapping="Wrap" />
|
|
</Border>
|
|
|
|
<Grid ColumnDefinitions="*,16,*">
|
|
<StackPanel Grid.Column="0" Spacing="6">
|
|
<TextBlock Text="NEW EMAIL" Classes="label" />
|
|
<TextBox Text="{Binding NewEmail, Mode=TwoWay}"
|
|
Watermark="new@email.com"
|
|
FontSize="13"
|
|
Height="38"
|
|
Padding="12,0"
|
|
VerticalContentAlignment="Center" />
|
|
</StackPanel>
|
|
<StackPanel Grid.Column="2" Spacing="6">
|
|
<TextBlock Text="CONFIRM WITH PASSWORD" Classes="label" />
|
|
<TextBox Text="{Binding EmailConfirmPassword, Mode=TwoWay}"
|
|
Watermark="Current password"
|
|
PasswordChar="•"
|
|
FontSize="13"
|
|
Height="38"
|
|
Padding="12,0"
|
|
VerticalContentAlignment="Center" />
|
|
</StackPanel>
|
|
</Grid>
|
|
|
|
<StackPanel Orientation="Horizontal"
|
|
Spacing="8"
|
|
HorizontalAlignment="Right">
|
|
<Button Classes="base"
|
|
Padding="16,8"
|
|
FontSize="13"
|
|
Content="Cancel"
|
|
Command="{Binding CancelChangeEmailCommand}" />
|
|
<Button Classes="accented"
|
|
Padding="16,8"
|
|
IsEnabled="{Binding !IsSaving}"
|
|
Command="{Binding ConfirmChangeEmailCommand}">
|
|
<TextBlock Text="Update Email"
|
|
FontSize="13"
|
|
FontWeight="SemiBold"
|
|
Foreground="{DynamicResource BgBase}" />
|
|
</Button>
|
|
</StackPanel>
|
|
</StackPanel>
|
|
</Panel>
|
|
</Border>
|
|
|
|
<!-- ── Password row ───────────────────────── -->
|
|
<Border Padding="20,0">
|
|
<!-- Normal password display -->
|
|
<Panel>
|
|
<Grid IsVisible="{Binding !IsChangingPassword}"
|
|
ColumnDefinitions="*,Auto"
|
|
MinHeight="58">
|
|
<StackPanel Grid.Column="0"
|
|
VerticalAlignment="Center"
|
|
Spacing="2">
|
|
<TextBlock Text="PASSWORD"
|
|
Classes="label" />
|
|
<TextBlock Text="••••••••••••"
|
|
FontSize="16"
|
|
Foreground="{DynamicResource TextMuted}"
|
|
LetterSpacing="2" />
|
|
</StackPanel>
|
|
<Button Grid.Column="1"
|
|
Background="Transparent"
|
|
BorderThickness="0"
|
|
Padding="0"
|
|
Cursor="Hand"
|
|
VerticalAlignment="Center"
|
|
Command="{Binding StartChangePasswordCommand}">
|
|
<StackPanel Orientation="Horizontal" Spacing="6">
|
|
<Svg Path="../Assets/Icons/pencil.svg"
|
|
Width="13" Height="13"
|
|
Css="{DynamicResource SvgMuted}" />
|
|
<TextBlock Text="Change"
|
|
FontSize="12"
|
|
Foreground="{DynamicResource AccentBlue}" />
|
|
</StackPanel>
|
|
</Button>
|
|
</Grid>
|
|
|
|
<!-- Change password form -->
|
|
<StackPanel IsVisible="{Binding IsChangingPassword}"
|
|
Spacing="12"
|
|
Margin="0,16,0,16">
|
|
<TextBlock Text="CHANGE PASSWORD" Classes="label" />
|
|
|
|
<!-- Password success / error -->
|
|
<Border Background="{DynamicResource IconBgGreen}"
|
|
BorderBrush="{DynamicResource AccentGreen}"
|
|
BorderThickness="1"
|
|
CornerRadius="10"
|
|
Padding="12,8"
|
|
IsVisible="{Binding HasPasswordSuccess}">
|
|
<TextBlock Text="{Binding PasswordSuccessMessage}"
|
|
FontSize="12"
|
|
Foreground="{DynamicResource AccentGreen}"
|
|
TextWrapping="Wrap" />
|
|
</Border>
|
|
<Border Background="{DynamicResource BadgeBgRed}"
|
|
BorderBrush="{DynamicResource AccentRed}"
|
|
BorderThickness="1"
|
|
CornerRadius="10"
|
|
Padding="12,8"
|
|
IsVisible="{Binding HasPasswordError}">
|
|
<TextBlock Text="{Binding PasswordErrorMessage}"
|
|
FontSize="12"
|
|
Foreground="{DynamicResource AccentRed}"
|
|
TextWrapping="Wrap" />
|
|
</Border>
|
|
|
|
<StackPanel Spacing="6">
|
|
<TextBlock Text="CURRENT PASSWORD" Classes="label" />
|
|
<TextBox Text="{Binding CurrentPassword, Mode=TwoWay}"
|
|
Watermark="Enter current password"
|
|
PasswordChar="•"
|
|
FontSize="13"
|
|
Height="38"
|
|
Padding="12,0"
|
|
VerticalContentAlignment="Center" />
|
|
</StackPanel>
|
|
<Grid ColumnDefinitions="*,16,*">
|
|
<StackPanel Grid.Column="0" Spacing="6">
|
|
<TextBlock Text="NEW PASSWORD" Classes="label" />
|
|
<TextBox Text="{Binding NewPassword, Mode=TwoWay}"
|
|
Watermark="Min. 8 characters"
|
|
PasswordChar="•"
|
|
FontSize="13"
|
|
Height="38"
|
|
Padding="12,0"
|
|
VerticalContentAlignment="Center" />
|
|
</StackPanel>
|
|
<StackPanel Grid.Column="2" Spacing="6">
|
|
<TextBlock Text="CONFIRM NEW PASSWORD" Classes="label" />
|
|
<TextBox Text="{Binding ConfirmNewPassword, Mode=TwoWay}"
|
|
Watermark="Repeat new password"
|
|
PasswordChar="•"
|
|
FontSize="13"
|
|
Height="38"
|
|
Padding="12,0"
|
|
VerticalContentAlignment="Center" />
|
|
</StackPanel>
|
|
</Grid>
|
|
|
|
<StackPanel Orientation="Horizontal"
|
|
Spacing="8"
|
|
HorizontalAlignment="Right">
|
|
<Button Classes="base"
|
|
Padding="16,8"
|
|
FontSize="13"
|
|
Content="Cancel"
|
|
Command="{Binding CancelChangePasswordCommand}" />
|
|
<Button Classes="accented"
|
|
Padding="16,8"
|
|
IsEnabled="{Binding !IsSaving}"
|
|
Command="{Binding ConfirmChangePasswordCommand}">
|
|
<TextBlock Text="Update Password"
|
|
FontSize="13"
|
|
FontWeight="SemiBold"
|
|
Foreground="{DynamicResource BgBase}" />
|
|
</Button>
|
|
</StackPanel>
|
|
</StackPanel>
|
|
</Panel>
|
|
</Border>
|
|
|
|
</StackPanel>
|
|
</Border>
|
|
|
|
<!-- ══════════════════════════════════════════════
|
|
SECTION: Danger zone
|
|
══════════════════════════════════════════════ -->
|
|
<TextBlock Text="SESSION"
|
|
Classes="label"
|
|
Margin="0,0,0,10" />
|
|
|
|
<Border Background="{DynamicResource BgSurface}"
|
|
BorderBrush="{DynamicResource BorderSubtle}"
|
|
BorderThickness="1"
|
|
CornerRadius="16"
|
|
Padding="20">
|
|
<Grid ColumnDefinitions="*,Auto">
|
|
<StackPanel Grid.Column="0"
|
|
VerticalAlignment="Center"
|
|
Spacing="2">
|
|
<TextBlock Text="Sign Out"
|
|
FontSize="14"
|
|
FontWeight="SemiBold"
|
|
Foreground="{DynamicResource TextPrimary}" />
|
|
<TextBlock Text="You will be returned to the login screen."
|
|
FontSize="12"
|
|
Foreground="{DynamicResource TextMuted}" />
|
|
</StackPanel>
|
|
<Button Grid.Column="1"
|
|
Background="#2A0D0D"
|
|
BorderBrush="#3A1515"
|
|
BorderThickness="1"
|
|
CornerRadius="{DynamicResource RadiusControl}"
|
|
Padding="16,9"
|
|
Command="{Binding SignOutCommand}">
|
|
<StackPanel Orientation="Horizontal" Spacing="8">
|
|
<Svg Path="../Assets/Icons/log-out.svg"
|
|
Width="13" Height="13"
|
|
Css="path, circle, rect, ellipse, line, polyline, polygon, text, use { stroke: #FF5E5E; }" />
|
|
<TextBlock Text="Sign Out"
|
|
FontSize="13"
|
|
FontWeight="SemiBold"
|
|
Foreground="#FF5E5E"
|
|
VerticalAlignment="Center" />
|
|
</StackPanel>
|
|
</Button>
|
|
</Grid>
|
|
</Border>
|
|
|
|
</StackPanel>
|
|
</ScrollViewer>
|
|
</UserControl> |