feat(app): add evaluation history, bot control panel, simulation visualizer, and vendored signalr_core

This commit is contained in:
2026-08-24 21:37:43 +02:00
parent 676496b77d
commit 0894c40f07
113 changed files with 12413 additions and 3613 deletions
@@ -36,11 +36,16 @@ class AuthRepository {
'password': password,
});
if (res.statusCode == 200 && res.data != null) {
final token = res.data['token']?.toString() ?? '';
if (res.data['requiresPasswordChange'] == true) {
// The backend already issues a valid JWT even when a password change is required, so it must be
// persisted here: the subsequent change-initial-password call is an [Authorize]-protected endpoint
// and has no other way to authenticate itself.
await storageService.saveToken(token);
throw RequiresPasswordChangeException(res.data['userId']?.toString() ?? '');
}
final token = res.data['token']?.toString() ?? '';
final user = UserModel.fromJson(res.data, token: token);
await storageService.saveToken(token);
await storageService.saveUserEmail(user.email);
@@ -50,23 +55,6 @@ class AuthRepository {
}
}
Future<UserModel> register(String email, String password, String fullName) async {
final res = await apiClient.post('/api/v1/auth/register', data: {
'email': email,
'password': password,
'fullName': fullName,
});
if (res.statusCode == 200 && res.data != null) {
final token = res.data['token']?.toString() ?? '';
final user = UserModel.fromJson(res.data, token: token);
await storageService.saveToken(token);
await storageService.saveUserEmail(user.email);
return user;
} else {
throw Exception('Registrierung fehlgeschlagen');
}
}
Future<bool> changeInitialPassword(String userId, String newPassword) async {
final res = await apiClient.post('/api/v1/auth/change-initial-password', data: {
'userId': userId,