255 lines
7.1 KiB
Dart
255 lines
7.1 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;
|
|
}
|
|
}
|
|
|
|
// Update profile
|
|
Future<Map<String, dynamic>> updateProfile({
|
|
required String name,
|
|
required String email,
|
|
String? phone,
|
|
}) async {
|
|
try {
|
|
final response = await http.put(
|
|
Uri.parse('${AppConfig.baseUrl}/profile/update'),
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'Accept': 'application/json',
|
|
'Authorization': 'Bearer $_token',
|
|
},
|
|
body: jsonEncode({
|
|
'name': name,
|
|
'email': email,
|
|
'phone': phone,
|
|
}),
|
|
);
|
|
|
|
final data = jsonDecode(response.body);
|
|
|
|
if (response.statusCode == 200 && data['success'] == true) {
|
|
final user = User.fromJson(data['data']);
|
|
final prefs = await SharedPreferences.getInstance();
|
|
await prefs.setString(AppConfig.userKey, jsonEncode(user.toJson()));
|
|
_currentUser = user;
|
|
return {'success': true, 'message': data['message']};
|
|
} else {
|
|
return {
|
|
'success': false,
|
|
'message': data['message'] ?? 'Gagal update profil',
|
|
'errors': data['errors'],
|
|
};
|
|
}
|
|
} catch (e) {
|
|
return {'success': false, 'message': 'Error: $e'};
|
|
}
|
|
}
|
|
|
|
// Change password
|
|
Future<Map<String, dynamic>> changePassword({
|
|
required String password,
|
|
required String passwordConfirmation,
|
|
}) async {
|
|
try {
|
|
final response = await http.put(
|
|
Uri.parse('${AppConfig.baseUrl}/profile/update'),
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'Accept': 'application/json',
|
|
'Authorization': 'Bearer $_token',
|
|
},
|
|
body: jsonEncode({
|
|
'name': _currentUser?.name ?? '',
|
|
'email': _currentUser?.email ?? '',
|
|
'password': password,
|
|
'password_confirmation': passwordConfirmation,
|
|
}),
|
|
);
|
|
|
|
final data = jsonDecode(response.body);
|
|
|
|
if (response.statusCode == 200 && data['success'] == true) {
|
|
return {'success': true, 'message': 'Password berhasil diubah'};
|
|
} else {
|
|
return {
|
|
'success': false,
|
|
'message': data['message'] ?? 'Gagal mengubah password',
|
|
'errors': data['errors'],
|
|
};
|
|
}
|
|
} catch (e) {
|
|
return {'success': false, 'message': 'Error: $e'};
|
|
}
|
|
}
|
|
}
|