import 'package:dio/dio.dart'; import 'package:flutter/material.dart'; import 'package:qpay/auth_state.dart'; import 'package:qpay/http/http.dart'; import 'package:qpay/models/api_response.dart'; import 'package:shared_preferences/shared_preferences.dart'; class LoginScreenModel { String username = ""; String password = ""; String status = "PENDING"; bool isLoading = false; String? errorMessage; } class LoginController extends ChangeNotifier { final Http http = Http(); final model = LoginScreenModel(); late SharedPreferences prefs; BuildContext context; bool _disposed = false; LoginController(this.context); @override void dispose() { _disposed = true; super.dispose(); } void _safeNotifyListeners() { if (!_disposed) { notifyListeners(); } } Future> login( String username, String password, ) async { try { model.isLoading = true; _safeNotifyListeners(); prefs = await SharedPreferences.getInstance(); dynamic response = await http.post('/auth/login', { 'username': username, 'password': password, }); logger.i(response.toString()); model.isLoading = false; _safeNotifyListeners(); if (response.containsKey('token')) { model.status = 'SUCCESS'; prefs.setString('token', response['token']); prefs.setString('username', username); prefs.setString('email', response['email']); prefs.setString('firstName', response['firstName']); prefs.setString('lastName', response['lastName'] ?? ''); prefs.setString('phone', response['phone']); prefs.setString('userId', response['uuid']); prefs.setString( 'initials', response['firstName'].substring(0, 1) + (response['lastName'] != null && response['lastName'].isNotEmpty ? response['lastName'].substring(0, 1) : ''), ); // Notify the router that the user is now signed in so any // auth-gated redirects (e.g. the groups flow) are re-evaluated // and the user is sent to their originally requested page. await authState.refresh(); return ApiResponse.success(model); } else { model.errorMessage = response['errorMessage'] ?? "Problem with the operation. Please try again or contact support"; return ApiResponse.failure(model.errorMessage!); } } on DioException catch (e, s) { logger.e(s); model.isLoading = false; _safeNotifyListeners(); return ApiResponse.failure( e.response?.data['errors'][0] ?? "Unknown error", ); } catch (e, s) { logger.e(s); model.isLoading = false; _safeNotifyListeners(); return ApiResponse.failure( "Problem processing that operation. Please try again or contact support", ); } } }