Insparkspokalen-ui/lib/services/googleAuthService.dart

140 lines
4.6 KiB
Dart

import 'package:flutter/material.dart';
import 'package:google_sign_in/google_sign_in.dart';
import 'package:insparkspokalen_ui/login/startPage.dart';
// import 'package:shared_preferences/shared_preferences.dart';
import '../layout/adminHomePage.dart';
import '../layout/userHomePage.dart';
import 'userService.dart';
import 'package:insparkspokalen_ui/models/userModel.dart';
import 'package:insparkspokalen_ui/services/teamUserSyncService.dart';
/*
För att kräva login gör såhär:
Lägg till detta paket i klassen ->
import 'package:insparkspokalen_ui/services/googleAuthService.dart';
Sedan lägg till följande för alla knappar som kräver att användaren är inloggad ->
onPressed:() async {
final isAuthenticated = await GoogleAuthService.ensureLoggedIn(context);
if (!isAuthenticated) return;
},
Kör appen med detta kommando då vår konsol endast släpper in redirects från port 8080 via webben för tillfället
flutter run -d chrome --web-port=8080
*/
class GoogleAuthService {
// Singleton pattern for consistency
static final GoogleAuthService _instance = GoogleAuthService._internal();
factory GoogleAuthService() => _instance;
GoogleAuthService._internal();
// Current user state
static UserModel? _currentUser;
static UserModel? get currentUser => _currentUser;
// Team sync service integration
static final TeamUserSyncService _syncService = TeamUserSyncService();
static final GoogleSignIn _googleSignIn = GoogleSignIn(
clientId: '278095802777-40qt28sou07o3qb58pcoccl0eolas3k0.apps.googleusercontent.com', //web
// clientId: '278095802777-8tj05ph2nbb8117abl1k4nlnq4ukd7ao.apps.googleusercontent.com', //android
scopes: <String>['email', 'profile'],
);
// todo review this after final login solution is done
static String? accessToken;
// Getter for current user with null safety
static UserModel? getCurrentUser() {
return _currentUser;
}
// Set current user and sync with TeamUserSyncService
static void setCurrentUser(UserModel user) {
_currentUser = user;
// Also update the sync service to maintain consistency
_syncService.setCurrentUser(user);
}
static Future<void> signInWithGoogle(BuildContext context) async {
try {
await _googleSignIn.signOut(); // Optional: force fresh sign-in
final account = await _googleSignIn.signIn();
if (account == null) return;
final auth = await account.authentication;
accessToken = auth.accessToken;
if (accessToken == null) {
print("Missing access token.");
return;
}
// Create or fetch user from backend
await UserService.createOrFetchUser(account);
//Fetch role from backend
final email = account.email;
final role = await UserService.getUserRole(email);
// Creating a current user without photoURL
_currentUser = UserModel(
email,
account.displayName ?? "Unknown",
);
//Naviages to correct page based on role when you log in
if (role == 'ADMIN') {
Navigator.pushReplacement(context, MaterialPageRoute(builder: (_) => const AdminHomePage()));
} else if (role == 'USER') {
Navigator.pushReplacement(context, MaterialPageRoute(builder: (_) => const UserHomePage()));
} else {
print("Unknown role: $role");
}
} catch (e) {
print("Google Sign-In failed: $e");
// Show friendly error message to user
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Sign in failed. Please try again.')),
);
}
}
static Future<void> logout(BuildContext context) async {
await _googleSignIn.signOut();
// Clear cache when user logs out removed for now something went wrong with loading the cache
// final prefs = await SharedPreferences.getInstance();
// await prefs.remove('user');
Navigator.pushAndRemoveUntil(
context,
MaterialPageRoute(builder: (_) => const StartPage()), // Import StartPage
(route) => false,
);
accessToken = null;
}
static Future<bool> ensureLoggedIn(BuildContext context) async {
if (!isLoggedIn()) {
await signInWithGoogle(context);
}
return isLoggedIn();
}
static bool isLoggedIn() => accessToken != null;
// Public method to get current google account
static GoogleSignInAccount? getCurrentGoogleAccount() {
return _googleSignIn.currentUser;
}
// Method to refresh user data and team info
static Future<void> refreshUserData() async {
if (_currentUser != null) {
// Trigger team data refresh in the sync service
await _syncService.syncUserTeamData(_currentUser!.email);
}
}
}