develop #1

Merged
akhdanre merged 104 commits from develop into main 2025-07-10 12:38:53 +07:00
6 changed files with 82 additions and 17 deletions
Showing only changes of commit 488479befa - Show all commits

View File

@ -39,4 +39,11 @@ class UserController extends GetxController {
userImage.value = userEntity.picUrl;
email.value = userEntity.email;
}
void clearUser() {
userData = null;
userName.value = "";
userImage.value = "";
email.value = '';
}
}

View File

@ -0,0 +1,35 @@
import 'package:google_sign_in/google_sign_in.dart';
class GoogleAuthService {
final GoogleSignIn _googleSignIn = GoogleSignIn(
scopes: ['email', 'profile', 'openid'],
);
Future<GoogleSignInAccount?> signIn() async {
try {
return await _googleSignIn.signIn();
} catch (e) {
rethrow;
}
}
Future<void> signOut() async {
try {
await _googleSignIn.signOut();
} catch (e) {
rethrow;
}
}
Future<String?> getIdToken() async {
final account = await _googleSignIn.signIn();
if (account == null) return null;
final auth = await account.authentication;
return auth.idToken;
}
Future<bool> isSignedIn() async {
return await _googleSignIn.isSignedIn();
}
}

View File

@ -2,13 +2,15 @@ import 'package:get/get_core/get_core.dart';
import 'package:get/get_instance/get_instance.dart';
import 'package:quiz_app/data/controllers/user_controller.dart';
import 'package:quiz_app/data/services/auth_service.dart';
import 'package:quiz_app/data/services/google_auth_service.dart';
import 'package:quiz_app/data/services/user_storage_service.dart';
import 'package:quiz_app/feature/login/controllers/login_controller.dart';
class LoginBinding extends Bindings {
@override
void dependencies() {
Get.lazyPut<GoogleAuthService>(() => GoogleAuthService());
Get.lazyPut(() => AuthService());
Get.lazyPut(() => LoginController(Get.find<AuthService>(), Get.find<UserStorageService>(), Get.find<UserController>()));
Get.lazyPut(() => LoginController(Get.find<AuthService>(), Get.find<UserStorageService>(), Get.find<UserController>(), Get.find<GoogleAuthService>()));
}
}

View File

@ -1,6 +1,5 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:google_sign_in/google_sign_in.dart';
import 'package:quiz_app/app/routes/app_pages.dart';
import 'package:quiz_app/component/global_button.dart';
import 'package:quiz_app/core/utils/logger.dart';
@ -9,14 +8,21 @@ import 'package:quiz_app/data/entity/user/user_entity.dart';
import 'package:quiz_app/data/models/login/login_request_model.dart';
import 'package:quiz_app/data/models/login/login_response_model.dart';
import 'package:quiz_app/data/services/auth_service.dart';
import 'package:quiz_app/data/services/google_auth_service.dart';
import 'package:quiz_app/data/services/user_storage_service.dart';
class LoginController extends GetxController {
final AuthService _authService;
final UserStorageService _userStorageService;
final UserController _userController;
final GoogleAuthService _googleAuthService;
LoginController(this._authService, this._userStorageService, this._userController);
LoginController(
this._authService,
this._userStorageService,
this._userController,
this._googleAuthService,
);
final TextEditingController emailController = TextEditingController();
final TextEditingController passwordController = TextEditingController();
@ -25,10 +31,6 @@ class LoginController extends GetxController {
final RxBool isPasswordHidden = true.obs;
final RxBool isLoading = false.obs;
final GoogleSignIn _googleSignIn = GoogleSignIn(
scopes: ['email', 'profile', 'openid'],
);
@override
void onInit() {
super.onInit();
@ -81,22 +83,19 @@ class LoginController extends GetxController {
/// **🔹 Login via Google**
Future<void> loginWithGoogle() async {
try {
final GoogleSignInAccount? googleUser = await _googleSignIn.signIn();
if (googleUser == null) {
final user = await _googleAuthService.signIn();
if (user == null) {
Get.snackbar("Error", "Google Sign-In canceled");
return;
}
final GoogleSignInAuthentication googleAuth = await googleUser.authentication;
final idToken = googleAuth.idToken;
final idToken = await user.authentication.then((auth) => auth.idToken);
if (idToken == null || idToken.isEmpty) {
Get.snackbar("Error", "Google sign-in failed. No ID Token received.");
Get.snackbar("Error", "No ID Token received.");
return;
}
final LoginResponseModel response = await _authService.loginWithGoogle(idToken);
final userEntity = _convertLoginResponseToUserEntity(response);
await _userStorageService.saveUser(userEntity);

View File

@ -1,9 +1,12 @@
import 'package:get/get.dart';
import 'package:quiz_app/data/services/google_auth_service.dart';
import 'package:quiz_app/data/services/user_storage_service.dart';
import 'package:quiz_app/feature/profile/controller/profile_controller.dart';
class ProfileBinding extends Bindings {
@override
void dependencies() {
Get.lazyPut(() => ProfileController());
Get.lazyPut<GoogleAuthService>(() => GoogleAuthService());
Get.lazyPut(() => ProfileController(Get.find<UserStorageService>(), Get.find<GoogleAuthService>()));
}
}

View File

@ -1,10 +1,18 @@
import 'package:get/get.dart';
import 'package:quiz_app/app/routes/app_pages.dart';
import 'package:quiz_app/core/utils/logger.dart';
import 'package:quiz_app/data/controllers/user_controller.dart';
import 'package:quiz_app/data/services/google_auth_service.dart';
import 'package:quiz_app/data/services/user_storage_service.dart';
class ProfileController extends GetxController {
final UserController _userController = Get.find<UserController>();
final UserStorageService _userStorageService;
final GoogleAuthService _googleAuthService;
ProfileController(this._userStorageService, this._googleAuthService);
Rx<String> get userName => _userController.userName;
Rx<String> get email => _userController.email;
Rx<String?> get userImage => _userController.userImage;
@ -12,8 +20,19 @@ class ProfileController extends GetxController {
final totalQuizzes = 12.obs;
final avgScore = 85.obs;
void logout() {
logC.i("Logout pressed");
void logout() async {
try {
await _googleAuthService.signOut();
await _userStorageService.clearUser();
_userController.clearUser();
_userStorageService.isLogged = false;
Get.offAllNamed(AppRoutes.loginPage);
} catch (e, stackTrace) {
logC.e("Google Sign-Out Error: $e", stackTrace: stackTrace);
Get.snackbar("Error", "Gagal logout dari Google");
}
}
void editProfile() {