2025-11-28 10:14:30 +05:30
|
|
|
import 'dart:convert';
|
|
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
|
import 'package:shared_preferences/shared_preferences.dart';
|
|
|
|
|
import '../services/auth_service.dart';
|
|
|
|
|
|
|
|
|
|
class AuthProvider extends ChangeNotifier {
|
2025-12-03 11:57:05 +05:30
|
|
|
AuthService? _service;
|
2025-11-28 10:14:30 +05:30
|
|
|
|
|
|
|
|
bool _loading = false;
|
|
|
|
|
bool get loading => _loading;
|
|
|
|
|
|
2025-12-03 11:57:05 +05:30
|
|
|
bool initialized = false;
|
|
|
|
|
|
2025-11-28 10:14:30 +05:30
|
|
|
String? _token;
|
|
|
|
|
Map<String, dynamic>? _user;
|
|
|
|
|
|
|
|
|
|
String? get token => _token;
|
|
|
|
|
Map<String, dynamic>? get user => _user;
|
2025-12-03 11:57:05 +05:30
|
|
|
|
2025-11-28 10:14:30 +05:30
|
|
|
bool get isLoggedIn => _token != null && _token!.isNotEmpty;
|
|
|
|
|
|
2025-12-03 11:57:05 +05:30
|
|
|
// Inject context after provider initializes
|
|
|
|
|
void initContext(BuildContext context) {
|
|
|
|
|
_service = AuthService(context);
|
|
|
|
|
}
|
|
|
|
|
|
2025-11-28 10:14:30 +05:30
|
|
|
AuthProvider() {
|
|
|
|
|
_loadFromPrefs();
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-03 11:57:05 +05:30
|
|
|
// ---------------------- NEW FIX: SAFE INIT -----------------------
|
|
|
|
|
Future<void> init() async {
|
|
|
|
|
if (!initialized) {
|
|
|
|
|
await _loadFromPrefs();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ---------------------- LOAD FROM PREFS -----------------------
|
2025-11-28 10:14:30 +05:30
|
|
|
Future<void> _loadFromPrefs() async {
|
|
|
|
|
final prefs = await SharedPreferences.getInstance();
|
2025-12-03 11:57:05 +05:30
|
|
|
|
2025-11-28 10:14:30 +05:30
|
|
|
_token = prefs.getString('token');
|
2025-12-03 11:57:05 +05:30
|
|
|
|
2025-11-28 10:14:30 +05:30
|
|
|
final userJson = prefs.getString('user');
|
|
|
|
|
if (userJson != null) {
|
|
|
|
|
try {
|
|
|
|
|
_user = Map<String, dynamic>.from(jsonDecode(userJson));
|
|
|
|
|
} catch (_) {
|
|
|
|
|
_user = null;
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-12-03 11:57:05 +05:30
|
|
|
|
|
|
|
|
initialized = true;
|
2025-11-28 10:14:30 +05:30
|
|
|
notifyListeners();
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-03 11:57:05 +05:30
|
|
|
// -------------------------- LOGIN -----------------------------
|
|
|
|
|
Future<Map<String, dynamic>> login(
|
|
|
|
|
BuildContext context, String loginId, String password) async {
|
|
|
|
|
_service ??= AuthService(context);
|
|
|
|
|
|
2025-11-28 10:14:30 +05:30
|
|
|
_loading = true;
|
|
|
|
|
notifyListeners();
|
|
|
|
|
|
2025-12-03 11:57:05 +05:30
|
|
|
final res = await _service!.login(loginId, password);
|
2025-11-28 10:14:30 +05:30
|
|
|
|
|
|
|
|
_loading = false;
|
|
|
|
|
|
|
|
|
|
if (res['success'] == true) {
|
|
|
|
|
final token = res['token']?.toString();
|
2025-12-03 11:57:05 +05:30
|
|
|
final userMap =
|
|
|
|
|
res['user'] is Map ? Map<String, dynamic>.from(res['user']) : null;
|
2025-11-28 10:14:30 +05:30
|
|
|
|
|
|
|
|
if (token != null && userMap != null) {
|
2025-12-03 11:57:05 +05:30
|
|
|
final prefs = await SharedPreferences.getInstance();
|
|
|
|
|
await prefs.setString("saved_login_id", loginId);
|
|
|
|
|
await prefs.setString("saved_password", password);
|
|
|
|
|
|
2025-11-28 10:14:30 +05:30
|
|
|
await _saveSession(token, userMap);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
notifyListeners();
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-03 11:57:05 +05:30
|
|
|
// --------------------- SAVE SESSION ---------------------------
|
|
|
|
|
Future<void> _saveSession(
|
|
|
|
|
String token, Map<String, dynamic> userMap) async {
|
2025-11-28 10:14:30 +05:30
|
|
|
final prefs = await SharedPreferences.getInstance();
|
|
|
|
|
await prefs.setString('token', token);
|
|
|
|
|
await prefs.setString('user', jsonEncode(userMap));
|
2025-12-03 11:57:05 +05:30
|
|
|
|
2025-11-28 10:14:30 +05:30
|
|
|
_token = token;
|
|
|
|
|
_user = userMap;
|
2025-12-03 11:57:05 +05:30
|
|
|
notifyListeners();
|
2025-11-28 10:14:30 +05:30
|
|
|
}
|
|
|
|
|
|
2025-12-03 11:57:05 +05:30
|
|
|
// ----------------------- LOGOUT -------------------------------
|
|
|
|
|
Future<void> logout(BuildContext context) async {
|
|
|
|
|
_service ??= AuthService(context);
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
await _service!.logout();
|
|
|
|
|
} catch (_) {}
|
2025-11-28 10:14:30 +05:30
|
|
|
|
|
|
|
|
final prefs = await SharedPreferences.getInstance();
|
|
|
|
|
await prefs.remove('token');
|
|
|
|
|
await prefs.remove('user');
|
2025-12-03 11:57:05 +05:30
|
|
|
|
2025-11-28 10:14:30 +05:30
|
|
|
_token = null;
|
|
|
|
|
_user = null;
|
|
|
|
|
notifyListeners();
|
|
|
|
|
}
|
2025-12-03 11:57:05 +05:30
|
|
|
|
|
|
|
|
// -------------------- AUTO LOGIN ------------------------------
|
|
|
|
|
Future<bool> autoLoginFromSavedCredentials(BuildContext context) async {
|
|
|
|
|
final prefs = await SharedPreferences.getInstance();
|
|
|
|
|
final loginId = prefs.getString('saved_login_id');
|
|
|
|
|
final password = prefs.getString('saved_password');
|
|
|
|
|
|
|
|
|
|
if (loginId == null || password == null) return false;
|
|
|
|
|
|
|
|
|
|
final res = await login(context, loginId, password);
|
|
|
|
|
return res['success'] == true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// --------------------- REFRESH TOKEN --------------------------
|
|
|
|
|
Future<bool> tryRefreshToken(BuildContext context) async {
|
|
|
|
|
final prefs = await SharedPreferences.getInstance();
|
|
|
|
|
final oldToken = prefs.getString('token');
|
|
|
|
|
|
|
|
|
|
if (oldToken == null) return false;
|
|
|
|
|
|
|
|
|
|
_service ??= AuthService(context);
|
|
|
|
|
|
|
|
|
|
final res = await _service!.refreshToken(oldToken);
|
|
|
|
|
|
|
|
|
|
if (res['success'] == true && res['token'] != null) {
|
|
|
|
|
await prefs.setString('token', res['token']);
|
|
|
|
|
_token = res['token'];
|
|
|
|
|
notifyListeners();
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2025-11-28 10:14:30 +05:30
|
|
|
}
|