Update German localization for button labels and add photo requirement validation in Profile views
This commit is contained in:
parent
adf335d2be
commit
fe828683bd
145
.github/copilot-instructions.md
vendored
Normal file
145
.github/copilot-instructions.md
vendored
Normal file
@ -0,0 +1,145 @@
|
||||
# gehGassi App - AI Coding Agent Instructions
|
||||
|
||||
## Project Overview
|
||||
**gehGassi** is a .NET 9 MAUI cross-platform mobile app for a dog walking marketplace connecting dog owners with dog walkers. The app features dual user types (owners and walkers), real-time messaging, walk booking, payments, ratings, and a complex business workflow.
|
||||
|
||||
## Architecture & Key Patterns
|
||||
|
||||
### Project Structure (Clean Architecture)
|
||||
- **gehGassiApp** - Main MAUI app with Views, ViewModels, platform-specific code
|
||||
- **gehGassiApp.Core** - Business logic, services, interfaces
|
||||
- **gehGassiApp.Domain** - Entity models, value objects
|
||||
- **gehGassiApp.Data** - Entity Framework Core, SQLite database, repository pattern
|
||||
- **gehGassi.LocalNotifications** - Custom notification library
|
||||
- **gehGassi.Dto** - Shared DTOs with backend (external project reference)
|
||||
|
||||
### MVVM + DI Pattern
|
||||
- **BaseViewModel/MenuViewModel** - Inherit from these base classes for consistent patterns
|
||||
- **CommunityToolkit.Mvvm** - Uses `[ObservableProperty]` and `[RelayCommand]` attributes
|
||||
- **Dependency Injection** - All services registered in `MauiProgram.cs`, constructor injection throughout
|
||||
- **Page Lifecycle** - Override `InitializeAsync()` and `DisappearingAsync()` in ViewModels
|
||||
|
||||
### Service Layer Architecture
|
||||
All business services follow `IService<T>` interface with standard CRUD operations:
|
||||
```csharp
|
||||
// Example service injection in ViewModels
|
||||
public MyViewModel(IWalkService walkService, IDialogService dialogService) { }
|
||||
```
|
||||
|
||||
Key service types:
|
||||
- **Data Services** - Entity management (e.g., `IWalkService`, `IDogService`)
|
||||
- **Integration Services** - API communication (`ICommunicationService`)
|
||||
- **Platform Services** - Native features (`ILocationService`, `IDeviceInstallationService`)
|
||||
- **UI Services** - User interactions (`IDialogService`, `IPopupService`)
|
||||
|
||||
### Configuration Management
|
||||
Environment-specific settings in `MauiProgram.cs`:
|
||||
- **DEBUG** - Local development server (`192.168.0.172:8548`)
|
||||
- **STAGING/DEBUGSTAGING** - Staging environment
|
||||
- **RELEASE** - Production (`backend.gehgassi.com`)
|
||||
|
||||
Application ID changes per environment:
|
||||
- Debug/Staging: `com.gehgassi.local`
|
||||
- Release: `com.gehgassi.gehgassi`
|
||||
|
||||
## Critical Development Patterns
|
||||
|
||||
### XAML Resources System
|
||||
**ALWAYS verify resource existence before use** - the app has strict resource validation:
|
||||
- **Converters**: Defined in `Resources/Converters/Converters.xaml` (30+ available)
|
||||
- **Styles**: Defined in `Resources/Styles/Styles.xaml` (H5_Red, BodyCaption variants, etc.)
|
||||
- **Reference**: See `gehGassiApp_Converters_And_Styles.md` for complete list
|
||||
|
||||
Example of correct resource usage:
|
||||
```xml
|
||||
<!-- Correct - uses existing resources -->
|
||||
<Label Text="Error" Style="{StaticResource H5_Red}"
|
||||
IsVisible="{Binding HasError, Converter={StaticResource InvertedBoolConverter}}" />
|
||||
```
|
||||
|
||||
### Data Binding Patterns
|
||||
- **Validation**: Use multi-binding for button states:
|
||||
```xml
|
||||
<Button Text="Save">
|
||||
<Button.IsEnabled>
|
||||
<MultiBinding Converter="{StaticResource AllTrueMultiConverter}">
|
||||
<Binding Path="IsValid" />
|
||||
<Binding Path="HasPhoto" />
|
||||
</MultiBinding>
|
||||
</Button.IsEnabled>
|
||||
</Button>
|
||||
```
|
||||
|
||||
### Platform-Specific Code
|
||||
- **Android**: `Platforms/Android/` - Firebase services, permissions
|
||||
- **iOS**: `Platforms/iOS/` - Push notifications, App Store compliance
|
||||
- **Handlers**: Custom control behaviors in `MauiProgram.SetHandler()`
|
||||
|
||||
### Local Database (EF Core + SQLite)
|
||||
- **Context**: `LocalDbContext` with automatic migrations
|
||||
- **Repository Pattern**: `IUnitOfWork` coordinates multiple services
|
||||
- **Sync Pattern**: Many services implement `ISyncPushPullService<T>` for offline capability
|
||||
|
||||
## Build & Development
|
||||
|
||||
### Build Configurations
|
||||
- **Debug** - Local development, APK format
|
||||
- **DebugStaging** - Staging with debug symbols
|
||||
- **Release** - Production, AAB format with AOT compilation
|
||||
- **Staging** - Pre-production testing
|
||||
|
||||
### Build Commands
|
||||
```bash
|
||||
# Build for specific platform/config
|
||||
dotnet build -f net9.0-android -c Debug
|
||||
dotnet build -f net9.0-ios -c Release
|
||||
|
||||
# Platform-specific from main project directory
|
||||
dotnet build gehGassiApp/gehGassiApp.csproj -f net9.0-android
|
||||
```
|
||||
|
||||
### Critical Dependencies
|
||||
- **.NET 9** with MAUI 9.0.90
|
||||
- **Entity Framework Core 9.0.8**
|
||||
- **CommunityToolkit.Mvvm 8.4.0** - MVVM framework
|
||||
- **Microsoft.AspNetCore.SignalR.Client** - Real-time communication
|
||||
- **Platform packages**: Xamarin.Firebase.Messaging (Android), various AndroidX libraries
|
||||
|
||||
## Business Domain Knowledge
|
||||
|
||||
### User Types & Workflows
|
||||
- **Dog Owners** - Create walk requests, book walkers, manage dogs, rate walkers
|
||||
- **Dog Walkers** - Browse requests, offer services, execute walks, receive payments
|
||||
- **Dual Users** - Can switch between owner/walker modes
|
||||
|
||||
### Key Entities
|
||||
- **Walk** - Core business object with pickup/return addresses, timing, pricing
|
||||
- **PublicWalkRequest/Response** - Marketplace discovery system
|
||||
- **Rating** - Bidirectional rating system for quality assurance
|
||||
- **Conversation/Message** - In-app communication with SignalR real-time updates
|
||||
|
||||
### Complex Features
|
||||
- **Payment Flow** - Integration with external payment providers, wallet system
|
||||
- **Location Services** - GPS tracking during walks, geofenced operations
|
||||
- **Push Notifications** - Azure Notification Hub for engagement
|
||||
- **Offline Sync** - Local-first architecture with background synchronization
|
||||
|
||||
## Common Issues & Solutions
|
||||
|
||||
### Resource Not Found Errors
|
||||
Always check `Resources/Converters/Converters.xaml` and `Resources/Styles/Styles.xaml` before adding new resources.
|
||||
|
||||
### Navigation Patterns
|
||||
Use Shell-based navigation with query parameters:
|
||||
```csharp
|
||||
await Shell.Current.GoToAsync($"WalkView?walkId={walkId}");
|
||||
```
|
||||
|
||||
### Memory Management
|
||||
Custom image handler prevents crashes on Android - avoid modifying existing image loading patterns without testing.
|
||||
|
||||
### Platform Testing
|
||||
Test on both iOS and Android as business workflows have platform-specific behaviors (notifications, payments, camera).
|
||||
|
||||
---
|
||||
**Note**: This app serves a real marketplace with financial transactions. Always test payment flows, rating systems, and user safety features thoroughly.
|
||||
@ -268,7 +268,7 @@
|
||||
<value>Meine Hunde</value>
|
||||
</data>
|
||||
<data name="Button_Done" xml:space="preserve">
|
||||
<value>Fertig</value>
|
||||
<value>Speichern</value>
|
||||
</data>
|
||||
<data name="Button_EditOffer" xml:space="preserve">
|
||||
<value>Angebot bearbeiten</value>
|
||||
|
||||
@ -268,7 +268,7 @@
|
||||
<value>My dogs</value>
|
||||
</data>
|
||||
<data name="Button_Done" xml:space="preserve">
|
||||
<value>Done</value>
|
||||
<value>Save</value>
|
||||
</data>
|
||||
<data name="Button_EditOffer" xml:space="preserve">
|
||||
<value>Edit offer</value>
|
||||
|
||||
@ -75,6 +75,11 @@ namespace gehGassiApp.ViewModels
|
||||
[ObservableProperty]
|
||||
private bool _isNewPhoto;
|
||||
|
||||
/// <summary>
|
||||
/// Hat der Benutzer ein Profilbild?
|
||||
/// </summary>
|
||||
public bool HasPhoto => !string.IsNullOrWhiteSpace(AppUser?.Photo);
|
||||
|
||||
/// <summary>
|
||||
/// Liste der Länder
|
||||
/// </summary>
|
||||
@ -266,6 +271,7 @@ namespace gehGassiApp.ViewModels
|
||||
}
|
||||
|
||||
CheckForChanges();
|
||||
OnPropertyChanged(nameof(HasPhoto));
|
||||
}
|
||||
|
||||
partial void OnIsNewPhotoChanged(bool value)
|
||||
@ -648,6 +654,12 @@ namespace gehGassiApp.ViewModels
|
||||
private void OnAppUserPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
|
||||
{
|
||||
CheckForChanges();
|
||||
|
||||
// HasPhoto aktualisieren wenn sich die Photo Property ändert
|
||||
if (e.PropertyName == nameof(AppUser.Photo))
|
||||
{
|
||||
OnPropertyChanged(nameof(HasPhoto));
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@ -88,6 +88,11 @@ namespace gehGassiApp.ViewModels
|
||||
[ObservableProperty]
|
||||
private bool _isNewPhoto;
|
||||
|
||||
/// <summary>
|
||||
/// Hat der Benutzer ein Profilbild?
|
||||
/// </summary>
|
||||
public bool HasPhoto => !string.IsNullOrWhiteSpace(AppUser?.Photo);
|
||||
|
||||
/// <summary>
|
||||
/// Liste der Länder
|
||||
/// </summary>
|
||||
@ -324,6 +329,7 @@ namespace gehGassiApp.ViewModels
|
||||
}
|
||||
|
||||
CheckForChanges();
|
||||
OnPropertyChanged(nameof(HasPhoto));
|
||||
}
|
||||
|
||||
partial void OnWalkerProfileChanged(DogWalkerProfile value)
|
||||
@ -797,6 +803,12 @@ namespace gehGassiApp.ViewModels
|
||||
private void OnAppUserPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
|
||||
{
|
||||
CheckForChanges();
|
||||
|
||||
// HasPhoto aktualisieren wenn sich die Photo Property ändert
|
||||
if (e.PropertyName == nameof(AppUser.Photo))
|
||||
{
|
||||
OnPropertyChanged(nameof(HasPhoto));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@ -174,6 +174,14 @@
|
||||
|
||||
</Grid>
|
||||
|
||||
<Label
|
||||
Margin="{StaticResource MarginSmall}"
|
||||
HorizontalOptions="Center"
|
||||
IsVisible="{Binding HasPhoto, Converter={StaticResource InvertedBoolConverter}}"
|
||||
Style="{StaticResource H5_Red}"
|
||||
Text="Profilbild ist erforderlich"
|
||||
VerticalOptions="Start" />
|
||||
|
||||
<VerticalStackLayout
|
||||
HorizontalOptions="Fill"
|
||||
Spacing="0"
|
||||
@ -509,7 +517,7 @@
|
||||
<Button
|
||||
x:Name="btnSave"
|
||||
Margin="0,0,0,20"
|
||||
AbsoluteLayout.LayoutBounds="0.5,1,300,60"
|
||||
AbsoluteLayout.LayoutBounds="0.5,1,350,70"
|
||||
AbsoluteLayout.LayoutFlags="PositionProportional"
|
||||
Command="{Binding SaveCommand}"
|
||||
HorizontalOptions="Center"
|
||||
@ -528,6 +536,7 @@
|
||||
<Binding Path="IsValid" Source="{x:Reference mobileValidation}" />
|
||||
<Binding Path="IsValid" Source="{x:Reference phoneValidation}" />
|
||||
<Binding Path="AddressSelectionValid" />
|
||||
<Binding Path="HasPhoto" />
|
||||
<Binding Path="IsNotBusy" />
|
||||
</MultiBinding>
|
||||
</Button.IsEnabled>
|
||||
|
||||
@ -230,6 +230,14 @@
|
||||
|
||||
</Grid>
|
||||
|
||||
<Label
|
||||
Margin="{StaticResource MarginSmall}"
|
||||
HorizontalOptions="Center"
|
||||
IsVisible="{Binding HasPhoto, Converter={StaticResource InvertedBoolConverter}}"
|
||||
Style="{StaticResource H5_Red}"
|
||||
Text="Profilbild ist erforderlich"
|
||||
VerticalOptions="Start" />
|
||||
|
||||
<VerticalStackLayout
|
||||
Margin="{StaticResource MarginSection}"
|
||||
HorizontalOptions="Fill"
|
||||
@ -1016,7 +1024,7 @@
|
||||
<Button
|
||||
x:Name="btnSave"
|
||||
Margin="0,0,0,20"
|
||||
AbsoluteLayout.LayoutBounds="0.5,1,300,60"
|
||||
AbsoluteLayout.LayoutBounds="0.5,1,350,70"
|
||||
AbsoluteLayout.LayoutFlags="PositionProportional"
|
||||
Command="{Binding SaveCommand}"
|
||||
HorizontalOptions="Center"
|
||||
@ -1035,6 +1043,7 @@
|
||||
<Binding Path="IsValid" Source="{x:Reference mobileValidation}" />
|
||||
<Binding Path="IsValid" Source="{x:Reference phoneValidation}" />
|
||||
<Binding Path="AddressSelectionValid" />
|
||||
<Binding Path="HasPhoto" />
|
||||
<Binding Path="IsNotBusy" />
|
||||
</MultiBinding>
|
||||
</Button.IsEnabled>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user