implemented RMV public transit module including trip search, station departures, and nearby stop lookup, added "Marianum Connect" API integration with bearer token authentication and auto-refresh logic, integrated geolocator for location-based station search, added persistent storage for favorite stations and recent trip queries, and implemented comprehensive UI for journey details, trip results, and disruption alerts
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
/// Hand-rolled to be tolerant of the actual server payload: only [token] is
|
||||
/// load-bearing. `expiresAt` may be `null` (server-issued tokens without an
|
||||
/// explicit expiry); every other field shape is also tolerated so a stray
|
||||
/// rename on the backend does not break login for everyone.
|
||||
class LoginResponse {
|
||||
final String token;
|
||||
final String? tokenId;
|
||||
|
||||
/// `null` when the backend did not provide an expiry. In that case the
|
||||
/// token is treated as long-lived; callers should refresh on 401.
|
||||
final DateTime? expiresAt;
|
||||
final ConnectUserDto? user;
|
||||
|
||||
LoginResponse({
|
||||
required this.token,
|
||||
required this.tokenId,
|
||||
required this.expiresAt,
|
||||
required this.user,
|
||||
});
|
||||
|
||||
factory LoginResponse.fromJson(Map<String, dynamic> json) {
|
||||
final token = json['token'];
|
||||
if (token is! String || token.isEmpty) {
|
||||
throw const FormatException('login response missing "token" string');
|
||||
}
|
||||
final expiresRaw = json['expiresAt'];
|
||||
final expires = expiresRaw is String ? DateTime.tryParse(expiresRaw) : null;
|
||||
final userJson = json['user'];
|
||||
return LoginResponse(
|
||||
token: token,
|
||||
tokenId: json['tokenId']?.toString(),
|
||||
expiresAt: expires,
|
||||
user: userJson is Map<String, dynamic>
|
||||
? ConnectUserDto.fromJson(userJson)
|
||||
: null,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class ConnectUserDto {
|
||||
final String? id;
|
||||
final String? username;
|
||||
final String? firstName;
|
||||
final String? lastName;
|
||||
final String? userType;
|
||||
final String? className;
|
||||
|
||||
ConnectUserDto({
|
||||
this.id,
|
||||
this.username,
|
||||
this.firstName,
|
||||
this.lastName,
|
||||
this.userType,
|
||||
this.className,
|
||||
});
|
||||
|
||||
factory ConnectUserDto.fromJson(Map<String, dynamic> json) => ConnectUserDto(
|
||||
id: json['id']?.toString(),
|
||||
username: json['username']?.toString(),
|
||||
firstName: json['firstName']?.toString(),
|
||||
lastName: json['lastName']?.toString(),
|
||||
userType: json['userType']?.toString(),
|
||||
className: json['className']?.toString(),
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user