MIF_E31230069/spk_mobile/lib/services/auth_service.dart

177 lines
4.8 KiB
Dart

import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:shared_preferences/shared_preferences.dart';
import '../config/app_config.dart';
import '../models/user.dart';
class AuthService {
// Singleton pattern
static final AuthService _instance = AuthService._internal();
factory AuthService() => _instance;
AuthService._internal();
String? _token;
User? _currentUser;
String? get token => _token;
User? get currentUser => _currentUser;
bool get isAuthenticated => _token != null;
// Load token from local storage
Future<void> loadToken() async {
final prefs = await SharedPreferences.getInstance();
_token = prefs.getString(AppConfig.tokenKey);
final userJson = prefs.getString(AppConfig.userKey);
if (userJson != null) {
_currentUser = User.fromJson(jsonDecode(userJson));
}
}
// Save token to local storage
Future<void> _saveToken(String token, User user) async {
final prefs = await SharedPreferences.getInstance();
await prefs.setString(AppConfig.tokenKey, token);
await prefs.setString(AppConfig.userKey, jsonEncode(user.toJson()));
_token = token;
_currentUser = user;
}
// Clear token (logout)
Future<void> clearToken() async {
final prefs = await SharedPreferences.getInstance();
await prefs.remove(AppConfig.tokenKey);
await prefs.remove(AppConfig.userKey);
_token = null;
_currentUser = null;
}
// Register
Future<Map<String, dynamic>> register({
required String name,
required String email,
required String password,
required String passwordConfirmation,
String? phone,
}) async {
try {
final response = await http.post(
Uri.parse('${AppConfig.baseUrl}/register'),
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
},
body: jsonEncode({
'name': name,
'email': email,
'password': password,
'password_confirmation': passwordConfirmation,
'phone': phone,
}),
);
final data = jsonDecode(response.body);
if (response.statusCode == 201 && data['success'] == true) {
final token = data['data']['token'];
final user = User.fromJson(data['data']['user']);
await _saveToken(token, user);
return {'success': true, 'message': data['message']};
} else {
return {
'success': false,
'message': data['message'] ?? 'Registrasi gagal',
'errors': data['errors'],
};
}
} catch (e) {
return {'success': false, 'message': 'Error: $e'};
}
}
// Login
Future<Map<String, dynamic>> login({
required String email,
required String password,
}) async {
try {
final response = await http.post(
Uri.parse('${AppConfig.baseUrl}/login'),
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
},
body: jsonEncode({'email': email, 'password': password}),
);
final data = jsonDecode(response.body);
if (response.statusCode == 200 && data['success'] == true) {
final token = data['data']['token'];
final user = User.fromJson(data['data']['user']);
await _saveToken(token, user);
return {'success': true, 'message': data['message']};
} else {
return {'success': false, 'message': data['message'] ?? 'Login gagal'};
}
} catch (e) {
return {'success': false, 'message': 'Error: $e'};
}
}
// Logout
Future<Map<String, dynamic>> logout() async {
try {
if (_token == null) {
await clearToken();
return {'success': true};
}
final response = await http.post(
Uri.parse('${AppConfig.baseUrl}/logout'),
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization': 'Bearer $_token',
},
);
await clearToken();
if (response.statusCode == 200) {
return {'success': true, 'message': 'Logout berhasil'};
} else {
return {'success': true}; // Still clear local token
}
} catch (e) {
await clearToken(); // Clear local token anyway
return {'success': true};
}
}
// Get current user
Future<User?> getCurrentUser() async {
if (_token == null) return null;
try {
final response = await http.get(
Uri.parse('${AppConfig.baseUrl}/user'),
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization': 'Bearer $_token',
},
);
if (response.statusCode == 200) {
final user = User.fromJson(jsonDecode(response.body));
_currentUser = user;
return user;
}
return null;
} catch (e) {
return null;
}
}
}