Max Mannstein 4478fa2457 Update visual assets and refactor codebase
This commit includes a complete replacement of the binary content of the image files, significantly updating the visual assets of the application to enhance user experience and align with new design standards.

Key changes include:
- Resetting session state for the subscription offer popup in `App.xaml.cs`.
- Replacing buttons with touch-friendly labels in `Step2ExternalControl.xaml` and `Step3Control.xaml`.
- Updating image sources and bindings in `WalkerListControl.xaml` to reflect premium subscription status.
- Adding a new converter class `PremiumToChatImageConverter` in `CommonConverters.cs`.
- Modifying various view models to manage premium user status and subscription offers.
- Enhancing UI layouts across multiple XAML files for improved visibility and functionality.
- Updating localized strings in `Text.Designer.cs` and incrementing the app version in `Info.plist`.

These changes aim to improve the overall functionality, maintainability, and user experience of the application.
2025-07-01 15:53:21 +02:00

521 lines
29 KiB
XML

<?xml version="1.0" encoding="utf-8" ?>
<controls:BaseContentPage
x:Class="gehGassiApp.Views.ProfileView"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:behaviors="clr-namespace:gehGassiApp.Behaviors"
xmlns:controls="clr-namespace:gehGassiApp.Controls"
xmlns:i="clr-namespace:gehGassiApp.Constants"
xmlns:ios="clr-namespace:Microsoft.Maui.Controls.PlatformConfiguration.iOSSpecific;assembly=Microsoft.Maui.Controls"
xmlns:res="clr-namespace:gehGassiApp.Resources"
xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
ControlTemplate="{StaticResource MenuPageTemplate}">
<controls:BaseContentPage.TitleView>
<controls:ShellTitleViewNoLogoControl
Initials="{Binding CurrentAppUser.Initials}"
Photo="{Binding CurrentAppUser.Photo}"
ViewModel="{Binding .}" />
</controls:BaseContentPage.TitleView>
<ContentPage.Content>
<Grid>
<ScrollView
x:Name="rootScrollView"
Padding="20"
HorizontalOptions="Fill"
IsVisible="{Binding IsNotLoading}">
<VerticalStackLayout
x:Name="rootVerticalStackLayout"
SizeChanged="rootVerticalStackLayout_SizeChanged"
Spacing="0">
<Grid
Margin="{StaticResource MarginBig}"
ColumnDefinitions="*,150,*"
VerticalOptions="Start">
<Border
Grid.Row="0"
Grid.Column="0"
Margin="10,10,0,0"
Padding="2"
BackgroundColor="{StaticResource Primary_DarkBlue}"
HorizontalOptions="Start"
IsVisible="{Binding AppUser.Verified}"
Stroke="{StaticResource Primary_White}"
StrokeShape="RoundRectangle 50"
VerticalOptions="Start">
<Image HeightRequest="32">
<Image.Source>
<FontImageSource
FontFamily="IconMoon"
Glyph="{x:Static i:IconsMoon.Icon_Check}"
Color="{StaticResource Primary_White}" />
</Image.Source>
</Image>
</Border>
<controls:RoundImageControl
Grid.Column="1"
Margin="0,15,0,0"
BorderBackgroundColor="{StaticResource Primary_White}"
BorderHeight="120"
BorderOpacity="1"
BorderStroke="{StaticResource Primary_White}"
BorderStrokeShape="RoundRectangle 12"
BorderStrokeThickness="2"
BorderWidth="120"
CornerRadius="12"
HorizontalOptions="Center"
ImageHeight="120"
ImageOpacity="1"
ImageSource="{Binding AppUser.Photo, Converter={StaticResource MissingPhotoConverter}, ConverterParameter='Human'}"
ImageWidth="120"
VerticalOptions="Start" />
<Button
Grid.Column="1"
Padding="0"
Background="{StaticResource Primary_DarkBlue_Brush}"
BorderColor="{StaticResource Primary_DarkBlue}"
BorderWidth="2"
Command="{Binding ChoosePhotoOptionCommand}"
ContentLayout="Left, 0"
CornerRadius="20"
HeightRequest="40"
HorizontalOptions="End"
Text=""
VerticalOptions="Start"
WidthRequest="40">
<Button.ImageSource>
<FontImageSource
FontFamily="IconFont"
Glyph="photo_camera"
Size="20"
Color="{StaticResource Primary_White}" />
</Button.ImageSource>
</Button>
<Button
Grid.Column="1"
Padding="0"
Background="{StaticResource Primary_DarkBlue}"
BorderColor="{StaticResource Primary_DarkBlue}"
BorderWidth="2"
Command="{Binding RotateRightCommand}"
ContentLayout="Left, 0"
CornerRadius="20"
HeightRequest="40"
HorizontalOptions="Start"
IsVisible="{Binding IsNewPhoto}"
Text=""
VerticalOptions="Start"
WidthRequest="40">
<Button.ImageSource>
<FontImageSource
FontFamily="IconMoon"
Glyph="{x:Static i:IconsMoon.Icon_Rotate_CW}"
Size="20"
Color="{StaticResource Primary_White}" />
</Button.ImageSource>
</Button>
<Button
Grid.Column="1"
Margin="0,15,0,0"
Padding="0"
Background="{StaticResource Primary_DarkBlue}"
BorderColor="{StaticResource Primary_DarkBlue}"
BorderWidth="2"
Command="{Binding FlipVerticalCommand}"
ContentLayout="Left, 0"
CornerRadius="20"
HeightRequest="40"
HorizontalOptions="Start"
IsVisible="{Binding IsNewPhoto}"
Text=""
VerticalOptions="Center"
WidthRequest="40">
<Button.ImageSource>
<FontImageSource
FontFamily="IconMoon"
Glyph="{x:Static i:IconsMoon.Icon_Reflect}"
Size="20"
Color="{StaticResource Primary_White}" />
</Button.ImageSource>
</Button>
<Button
Grid.Column="1"
Margin="0,0,0,-15"
Padding="0"
Background="{StaticResource Primary_DarkBlue}"
BorderColor="{StaticResource Primary_DarkBlue}"
BorderWidth="2"
Command="{Binding RotateLeftCommand}"
ContentLayout="Left, 0"
CornerRadius="20"
HeightRequest="40"
HorizontalOptions="Start"
IsVisible="{Binding IsNewPhoto}"
Text=""
VerticalOptions="End"
WidthRequest="40">
<Button.ImageSource>
<FontImageSource
FontFamily="IconMoon"
Glyph="{x:Static i:IconsMoon.Icon_Rotate_CCW}"
Size="18"
Color="{StaticResource Primary_White}" />
</Button.ImageSource>
</Button>
</Grid>
<VerticalStackLayout
HorizontalOptions="Fill"
Spacing="0"
VerticalOptions="Start">
<Label
Margin="{StaticResource MarginLabel}"
Style="{StaticResource Inter_Blue}"
Text="{x:Static res:Text.Profile_Name_Question}" />
<Border Margin="{StaticResource MarginSmall}" Style="{StaticResource EntryBorder}">
<Entry
x:Name="firstName"
Keyboard="Text"
Placeholder="{x:Static res:Text.Common_FirstName}"
Text="{Binding AppUser.FirstName, Converter={StaticResource NullToEmptyStringConverter}}">
<Entry.Behaviors>
<toolkit:TextValidationBehavior
x:Name="firstNameValidation"
Flags="ValidateOnValueChanged"
InvalidStyle="{StaticResource InvalidEntryStyle}"
MaximumLength="150"
MinimumLength="1" />
<behaviors:SelectAllFocusedEntryBehavior />
</Entry.Behaviors>
</Entry>
</Border>
<Border Margin="{StaticResource MarginBig}" Style="{StaticResource EntryBorder}">
<Entry
x:Name="lastName"
Keyboard="Text"
Placeholder="{x:Static res:Text.Common_LastName}"
Text="{Binding AppUser.LastName, Converter={StaticResource NullToEmptyStringConverter}}">
<Entry.Behaviors>
<toolkit:TextValidationBehavior
x:Name="lastNameValidation"
Flags="ValidateOnValueChanged"
InvalidStyle="{StaticResource InvalidEntryStyle}"
MaximumLength="150"
MinimumLength="1" />
<behaviors:SelectAllFocusedEntryBehavior />
</Entry.Behaviors>
</Entry>
</Border>
<Label
Margin="{StaticResource MarginLabel}"
Style="{StaticResource Inter_Blue}"
Text="{x:Static res:Text.Profile_Age_Question}" />
<Border Margin="{StaticResource MarginBig}" Style="{StaticResource EntryBorder}">
<Grid>
<Entry
Keyboard="Default"
Placeholder="{Binding BirthdateFormat}"
Text="{Binding BirthDay}">
<Entry.Behaviors>
<toolkit:TextValidationBehavior
Flags="ValidateOnValueChanged"
InvalidStyle="{StaticResource InvalidEntryStyle}"
MaximumLength="10"
MinimumLength="0" />
<behaviors:DateValidationBehavior
x:Name="birthdayValidation"
Flags="ValidateOnValueChanged"
InvalidStyle="{StaticResource InvalidEntryStyle}"
MaxDate="{Binding MaxDate}"
MinDate="01/01/1900" />
<behaviors:SelectAllFocusedEntryBehavior />
</Entry.Behaviors>
</Entry>
<Image HeightRequest="25" HorizontalOptions="End">
<Image.Source>
<FontImageSource
FontFamily="IconMoon"
Glyph="{x:Static i:IconsMoon.Icon_Calendar}"
Size="25"
Color="{StaticResource Primary_DarkBlue}" />
</Image.Source>
<Image.GestureRecognizers>
<TapGestureRecognizer Command="{Binding ShowBirthdayCalendarCommand}" CommandParameter="{x:Reference birthDatePicker}" />
</Image.GestureRecognizers>
</Image>
<DatePicker
x:Name="birthDatePicker"
Date="{Binding BirthDate}"
HeightRequest="0"
MaximumDate="{Binding MaxDate}"
MinimumDate="01/01/1900"
WidthRequest="0" />
</Grid>
</Border>
<Label
Margin="{StaticResource MarginLabel}"
Style="{StaticResource Inter_Blue}"
Text="{x:Static res:Text.Profile_Sex_Question}" />
<Border Margin="{StaticResource MarginBig}" Style="{StaticResource EntryBorder}">
<controls:PickerWithChevron
x:Name="sexPicker"
Title="{x:Static res:Text.Profile_Sex_Question}"
ios:Picker.UpdateMode="WhenFinished"
HorizontalOptions="Fill"
ItemDisplayBinding="{Binding Text}"
ItemsSource="{Binding SexItems}"
SelectedItem="{Binding SelectedSex}" />
</Border>
<Label
Margin="{StaticResource MarginLabel}"
Style="{StaticResource Inter_Blue}"
Text="{x:Static res:Text.Profile_Address_Question}" />
<Border Margin="{StaticResource MarginSmall}" Style="{StaticResource EntryBorder}">
<Entry
x:Name="addressLine1"
Keyboard="Text"
Placeholder="{x:Static res:Text.Common_Address_Line1}"
Text="{Binding AppUser.Address.AddressLine1, Converter={StaticResource NullToEmptyStringConverter}}">
<Entry.Behaviors>
<toolkit:TextValidationBehavior
x:Name="addressLine1Validation"
Flags="ValidateOnAttaching,ValidateOnValueChanged"
InvalidStyle="{StaticResource InvalidEntryStyle}"
MaximumLength="100"
MinimumLength="1" />
<behaviors:SelectAllFocusedEntryBehavior />
</Entry.Behaviors>
</Entry>
</Border>
<Border Margin="{StaticResource MarginSmall}" Style="{StaticResource EntryBorder}">
<Entry
x:Name="addressLine2"
Keyboard="Text"
Placeholder="{x:Static res:Text.Common_Address_Line2}"
Text="{Binding AppUser.Address.AddressLine2, Converter={StaticResource NullToEmptyStringConverter}}">
<Entry.Behaviors>
<toolkit:TextValidationBehavior
x:Name="addressLine2Validation"
Flags="ValidateOnAttaching,ValidateOnValueChanged"
InvalidStyle="{StaticResource InvalidEntryStyle}"
MaximumLength="100"
MinimumLength="0" />
<behaviors:SelectAllFocusedEntryBehavior />
</Entry.Behaviors>
</Entry>
</Border>
<Border Margin="{StaticResource MarginSmall}" Style="{StaticResource EntryBorder}">
<Entry
x:Name="zip"
Keyboard="Text"
Placeholder="{x:Static res:Text.Common_Address_Zip}"
Text="{Binding AppUser.Address.Zip, Converter={StaticResource NullToEmptyStringConverter}}">
<Entry.Behaviors>
<toolkit:TextValidationBehavior
x:Name="zipValidation"
Flags="ValidateOnAttaching,ValidateOnValueChanged"
InvalidStyle="{StaticResource InvalidEntryStyle}"
MaximumLength="20"
MinimumLength="1" />
<behaviors:SelectAllFocusedEntryBehavior />
</Entry.Behaviors>
</Entry>
</Border>
<Border Margin="{StaticResource MarginSmall}" Style="{StaticResource EntryBorder}">
<Entry
x:Name="city"
Keyboard="Text"
Placeholder="{x:Static res:Text.Common_Address_City}"
Text="{Binding AppUser.Address.City, Converter={StaticResource NullToEmptyStringConverter}}">
<Entry.Behaviors>
<toolkit:TextValidationBehavior
x:Name="cityValidation"
Flags="ValidateOnAttaching,ValidateOnValueChanged"
InvalidStyle="{StaticResource InvalidEntryStyle}"
MaximumLength="100"
MinimumLength="1" />
<behaviors:SelectAllFocusedEntryBehavior />
</Entry.Behaviors>
</Entry>
</Border>
<Border Margin="{StaticResource MarginSmall}" Style="{StaticResource EntryBorder}">
<controls:PickerWithChevron
Title="{x:Static res:Text.Common_SelectCountry}"
ios:Picker.UpdateMode="WhenFinished"
HorizontalOptions="Fill"
ItemDisplayBinding="{Binding Name}"
ItemsSource="{Binding Countries}"
SelectedItem="{Binding SelectedCountry}" />
</Border>
<Border Margin="{StaticResource MarginBig}" Style="{StaticResource EntryBorder}">
<controls:PickerWithChevron
Title="{x:Static res:Text.Common_SelectState}"
ios:Picker.UpdateMode="WhenFinished"
HorizontalOptions="Fill"
ItemDisplayBinding="{Binding Name}"
ItemsSource="{Binding States}"
SelectedItem="{Binding SelectedState}" />
</Border>
<Label
Margin="{StaticResource MarginLabel}"
Style="{StaticResource Inter_Blue}"
Text="{x:Static res:Text.Profile_Contact_Question}" />
<Border Margin="{StaticResource MarginSmall}" Style="{StaticResource EntryBorder}">
<Entry
x:Name="mobile"
Keyboard="Telephone"
Placeholder="{x:Static res:Text.Common_Contact_Mobile}"
Text="{Binding AppUser.Contact.Mobile, Converter={StaticResource NullToEmptyStringConverter}}">
<Entry.Behaviors>
<toolkit:TextValidationBehavior
x:Name="mobileValidation"
Flags="ValidateOnAttaching,ValidateOnValueChanged"
InvalidStyle="{StaticResource InvalidEntryStyle}"
MaximumLength="100"
MinimumLength="0" />
<behaviors:SelectAllFocusedEntryBehavior />
</Entry.Behaviors>
</Entry>
</Border>
<Border Margin="{StaticResource MarginBig}" Style="{StaticResource EntryBorder}">
<Entry
x:Name="phone"
Keyboard="Telephone"
Placeholder="{x:Static res:Text.Common_Contact_Phone}"
Text="{Binding AppUser.Contact.Phone, Converter={StaticResource NullToEmptyStringConverter}}">
<Entry.Behaviors>
<toolkit:TextValidationBehavior
x:Name="phoneValidation"
Flags="ValidateOnAttaching,ValidateOnValueChanged"
InvalidStyle="{StaticResource InvalidEntryStyle}"
MaximumLength="100"
MinimumLength="0" />
<behaviors:SelectAllFocusedEntryBehavior />
</Entry.Behaviors>
</Entry>
</Border>
<Label
Margin="{StaticResource MarginLabel}"
Style="{StaticResource Inter_Blue}"
Text="{x:Static res:Text.Profile_Nationality_Question}" />
<Border Margin="{StaticResource MarginBig}" Style="{StaticResource EntryBorder}">
<controls:PickerWithChevron
Title="{x:Static res:Text.Common_SelectCountry}"
ios:Picker.UpdateMode="WhenFinished"
HorizontalOptions="Fill"
ItemDisplayBinding="{Binding Name}"
ItemsSource="{Binding Nationalitites}"
SelectedItem="{Binding SelectedNationality}" />
</Border>
<Label
Margin="{StaticResource MarginLabel}"
Style="{StaticResource Inter_Blue}"
Text="{x:Static res:Text.Profile_MainResidence_Question}" />
<Border Margin="{StaticResource MarginBig}" Style="{StaticResource EntryBorder}">
<controls:PickerWithChevron
Title="{x:Static res:Text.Common_SelectCountry}"
ios:Picker.UpdateMode="WhenFinished"
HorizontalOptions="Fill"
ItemDisplayBinding="{Binding Name}"
ItemsSource="{Binding MainResidences}"
SelectedItem="{Binding SelectedMainResidence}" />
</Border>
<Grid Margin="{StaticResource MarginVerySmall}" ColumnDefinitions="*,*">
<Label
Grid.Column="0"
LineBreakMode="TailTruncation"
Style="{StaticResource BodySMedium_Blue}"
Text="{x:Static res:Text.Profile_AutoPayout}"
VerticalOptions="Center" />
<Switch
Grid.Column="1"
HorizontalOptions="End"
IsToggled="{Binding AppUser.AutoPayout}"
VerticalOptions="Center">
<Switch.IsEnabled>
<MultiBinding Converter="{StaticResource AllTrueMultiConverter}">
<Binding Converter="{StaticResource IsNotNullOrEmptyToBooleanConverter}" Path="AppUser.PaymentId" />
<Binding Converter="{StaticResource IsNotNullOrEmptyToBooleanConverter}" Path="AppUser.BankId" />
<Binding Path="AppUser.KycPassed" />
</MultiBinding>
</Switch.IsEnabled>
</Switch>
</Grid>
<Label
Margin="{StaticResource MarginBig}"
Style="{StaticResource BodyCaption_GreyDark}"
Text="{x:Static res:Text.Profile_AutoPayout_Desc}" />
<ActivityIndicator
HorizontalOptions="Center"
IsRunning="{Binding IsBusy}"
IsVisible="{Binding IsBusy}"
Scale="1"
VerticalOptions="Center" />
</VerticalStackLayout>
<ActivityIndicator
HorizontalOptions="Center"
IsRunning="{Binding IsSaving}"
IsVisible="{Binding IsSaving}"
Scale="1"
VerticalOptions="Center" />
<Button
x:Name="btnSave"
Command="{Binding SaveCommand}"
Text="{Static res:Text.Button_Done}">
<Button.IsEnabled>
<MultiBinding Converter="{StaticResource AllTrueMultiConverter}">
<Binding Path="IsValid" Source="{x:Reference firstNameValidation}" />
<Binding Path="IsValid" Source="{x:Reference lastNameValidation}" />
<Binding Path="IsValid" Source="{x:Reference birthdayValidation}" />
<Binding Path="IsValid" Source="{x:Reference addressLine1Validation}" />
<Binding Path="IsValid" Source="{x:Reference addressLine2Validation}" />
<Binding Path="IsValid" Source="{x:Reference zipValidation}" />
<Binding Path="IsValid" Source="{x:Reference cityValidation}" />
<Binding Path="IsValid" Source="{x:Reference mobileValidation}" />
<Binding Path="IsValid" Source="{x:Reference phoneValidation}" />
<Binding Path="AddressSelectionValid" />
<Binding Path="IsNotBusy" />
</MultiBinding>
</Button.IsEnabled>
</Button>
</VerticalStackLayout>
</ScrollView>
<VerticalStackLayout IsVisible="{Binding IsLoading}" VerticalOptions="Center">
<ActivityIndicator
HorizontalOptions="Center"
IsRunning="{Binding IsLoading}"
IsVisible="{Binding IsLoading}"
Scale="2"
VerticalOptions="Center" />
</VerticalStackLayout>
</Grid>
</ContentPage.Content>
</controls:BaseContentPage>