193 lines
5.5 KiB
Dart
193 lines
5.5 KiB
Dart
import 'package:firebase_auth/firebase_auth.dart';
|
|
import 'package:flutter/foundation.dart';
|
|
import 'package:mobile_monitoring/data/models/service_result.dart';
|
|
|
|
/// Model untuk user profile info
|
|
class UserProfileInfo {
|
|
final String? displayName;
|
|
final String? email;
|
|
final String initials;
|
|
|
|
UserProfileInfo({
|
|
required this.displayName,
|
|
required this.email,
|
|
required this.initials,
|
|
});
|
|
}
|
|
|
|
/// Service untuk Profile Page - Backend Logic
|
|
/// Tidak ada dependency ke UI (no BuildContext, no widgets)
|
|
class ProfileService {
|
|
final FirebaseAuth _auth = FirebaseAuth.instance;
|
|
|
|
/// Get current user profile info
|
|
UserProfileInfo? getCurrentUserProfile() {
|
|
final user = _auth.currentUser;
|
|
if (user == null) {
|
|
debugPrint('[ProfileService] No current user');
|
|
return null;
|
|
}
|
|
|
|
debugPrint('[ProfileService] getCurrentUserProfile()');
|
|
debugPrint(' Name: ${user.displayName}');
|
|
debugPrint(' Email: ${user.email}');
|
|
|
|
return UserProfileInfo(
|
|
displayName: user.displayName,
|
|
email: user.email,
|
|
initials: _generateInitials(user.displayName),
|
|
);
|
|
}
|
|
|
|
/// Get current user
|
|
User? getCurrentUser() {
|
|
return _auth.currentUser;
|
|
}
|
|
|
|
/// Generate initials dari nama
|
|
/// Business logic untuk format display initials
|
|
String _generateInitials(String? name) {
|
|
if (name == null || name.isEmpty) return 'U';
|
|
final parts = name.trim().split(' ');
|
|
if (parts.length >= 2) {
|
|
return '${parts[0][0]}${parts[1][0]}'.toUpperCase();
|
|
}
|
|
return name[0].toUpperCase();
|
|
}
|
|
|
|
/// Generate initials - exposed untuk public use
|
|
String generateInitials(String? name) {
|
|
return _generateInitials(name);
|
|
}
|
|
|
|
/// Update user profile name
|
|
/// Backend logic untuk update nama user
|
|
Future<ServiceResult<void>> updateUserName(String newName) async {
|
|
try {
|
|
final user = _auth.currentUser;
|
|
if (user == null) {
|
|
debugPrint('[ProfileService] No current user');
|
|
return ServiceResult.failure(
|
|
message: 'Silakan login terlebih dahulu',
|
|
errorCode: 'no_user',
|
|
);
|
|
}
|
|
|
|
debugPrint('[ProfileService] updateUserName() - new name: "$newName"');
|
|
|
|
// Validasi input
|
|
if (newName.trim().isEmpty) {
|
|
return ServiceResult.failure(
|
|
message: 'Nama tidak boleh kosong',
|
|
errorCode: 'empty_name',
|
|
);
|
|
}
|
|
|
|
// Update display name
|
|
await user.updateDisplayName(newName.trim());
|
|
await user.reload();
|
|
|
|
debugPrint('[ProfileService] ✓ Name updated successfully');
|
|
|
|
return ServiceResult.success(
|
|
message: 'Nama berhasil diperbarui',
|
|
);
|
|
} catch (e) {
|
|
debugPrint('[ProfileService] ✗ Failed to update name: $e');
|
|
return ServiceResult.failure(
|
|
message: 'Gagal memperbarui nama: $e',
|
|
errorCode: 'update_failed',
|
|
);
|
|
}
|
|
}
|
|
|
|
/// Validate password change
|
|
/// Business logic untuk validate password lama dan ganti dengan yang baru
|
|
Future<ServiceResult<void>> validateAndUpdatePassword(
|
|
String oldPassword,
|
|
String newPassword,
|
|
) async {
|
|
try {
|
|
final user = _auth.currentUser;
|
|
if (user == null || user.email == null) {
|
|
debugPrint('[ProfileService] No current user or email');
|
|
return ServiceResult.failure(
|
|
message: 'Silakan login terlebih dahulu',
|
|
errorCode: 'no_user',
|
|
);
|
|
}
|
|
|
|
debugPrint('[ProfileService] validateAndUpdatePassword()');
|
|
debugPrint(' Email: ${user.email}');
|
|
|
|
// Validasi input
|
|
if (oldPassword.isEmpty || newPassword.isEmpty) {
|
|
return ServiceResult.failure(
|
|
message: 'Password tidak boleh kosong',
|
|
errorCode: 'empty_password',
|
|
);
|
|
}
|
|
|
|
if (newPassword.length < 6) {
|
|
return ServiceResult.failure(
|
|
message: 'Password baru minimal 6 karakter',
|
|
errorCode: 'weak_password',
|
|
);
|
|
}
|
|
|
|
// Reauthenticate dengan password lama
|
|
debugPrint('[ProfileService] Reauthenticating...');
|
|
final credential = EmailAuthProvider.credential(
|
|
email: user.email!,
|
|
password: oldPassword,
|
|
);
|
|
|
|
try {
|
|
await user.reauthenticateWithCredential(credential);
|
|
debugPrint('[ProfileService] ✓ Reauthentication successful');
|
|
} on FirebaseAuthException catch (e) {
|
|
debugPrint('[ProfileService] ✗ Reauthentication failed: ${e.code}');
|
|
if (e.code == 'wrong-password') {
|
|
return ServiceResult.failure(
|
|
message: 'Password lama Anda salah',
|
|
errorCode: 'wrong_password',
|
|
);
|
|
}
|
|
return ServiceResult.failure(
|
|
message: 'Gagal memverifikasi password lama',
|
|
errorCode: e.code,
|
|
);
|
|
}
|
|
|
|
// Update password
|
|
debugPrint('[ProfileService] Updating password...');
|
|
await user.updatePassword(newPassword);
|
|
|
|
debugPrint('[ProfileService] ✓ Password updated successfully');
|
|
|
|
return ServiceResult.success(
|
|
message: 'Password berhasil diubah',
|
|
);
|
|
} catch (e) {
|
|
debugPrint('[ProfileService] ✗ Failed to update password: $e');
|
|
return ServiceResult.failure(
|
|
message: 'Gagal mengubah password: $e',
|
|
errorCode: 'update_failed',
|
|
);
|
|
}
|
|
}
|
|
|
|
/// Validate email
|
|
bool isValidEmail(String email) {
|
|
return email.isNotEmpty && email.contains('@');
|
|
}
|
|
|
|
/// Check if user is authenticated
|
|
bool isUserAuthenticated() {
|
|
final user = _auth.currentUser;
|
|
final isAuth = user != null && user.uid.isNotEmpty;
|
|
debugPrint('[ProfileService] isUserAuthenticated: $isAuth');
|
|
return isAuth;
|
|
}
|
|
}
|