feat: Phase 1 critical gaps — gamification API, Razorpay checkout, Google OAuth, notifications
- Fix gamification endpoints to use Node.js server (app.eventifyplus.com) - Replace 6 mock gamification methods with real API calls (dashboard, leaderboard, shop, redeem, submit) - Add booking models, service, payment service (Razorpay), checkout provider - Add 3-step CheckoutScreen with Razorpay native modal integration - Add Google OAuth login (Flutter + Django backend) - Add full notifications system (Django model + 3 endpoints + Flutter UI) - Register CheckoutProvider, NotificationProvider in main.dart MultiProvider - Wire notification bell in HomeScreen app bar - Add razorpay_flutter ^1.3.7 and google_sign_in ^6.2.2 packages
This commit is contained in:
@@ -1,10 +1,12 @@
|
||||
// lib/features/auth/services/auth_service.dart
|
||||
import 'package:flutter/foundation.dart' show kDebugMode, debugPrint;
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:google_sign_in/google_sign_in.dart';
|
||||
import '../../../core/api/api_client.dart';
|
||||
import '../../../core/api/api_endpoints.dart';
|
||||
import '../../../core/auth/auth_guard.dart';
|
||||
import '../../../core/storage/token_storage.dart';
|
||||
import '../../../core/analytics/posthog_service.dart';
|
||||
import '../models/user_model.dart';
|
||||
|
||||
class AuthService {
|
||||
@@ -58,6 +60,12 @@ class AuthService {
|
||||
// Save phone if provided (optional)
|
||||
if (res['phone_number'] != null) await prefs.setString('phone_number', res['phone_number'].toString());
|
||||
|
||||
PostHogService.instance.identify(savedEmail, properties: {
|
||||
'username': displayCandidate,
|
||||
'login_method': 'email',
|
||||
});
|
||||
PostHogService.instance.capture('user_logged_in');
|
||||
|
||||
return UserModel.fromJson(res);
|
||||
} catch (e) {
|
||||
if (kDebugMode) debugPrint('AuthService.login error: $e');
|
||||
@@ -130,6 +138,54 @@ class AuthService {
|
||||
}
|
||||
}
|
||||
|
||||
/// GOOGLE OAUTH LOGIN → returns UserModel
|
||||
Future<UserModel> googleLogin() async {
|
||||
try {
|
||||
final googleSignIn = GoogleSignIn(scopes: ['email']);
|
||||
final account = await googleSignIn.signIn();
|
||||
if (account == null) throw Exception('Google sign-in cancelled');
|
||||
|
||||
final auth = await account.authentication;
|
||||
final idToken = auth.idToken;
|
||||
if (idToken == null) throw Exception('Failed to get Google ID token');
|
||||
|
||||
final res = await _api.post(
|
||||
ApiEndpoints.googleLogin,
|
||||
body: {'id_token': idToken},
|
||||
requiresAuth: false,
|
||||
);
|
||||
|
||||
final token = res['token'];
|
||||
if (token == null) throw Exception('Token missing from response');
|
||||
|
||||
final serverEmail = (res['email'] as String?) ?? account.email;
|
||||
final displayName = (res['username'] as String?) ?? account.displayName ?? serverEmail;
|
||||
|
||||
AuthGuard.setGuest(false);
|
||||
await TokenStorage.saveToken(token.toString(), serverEmail);
|
||||
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
await prefs.setString('current_email', serverEmail);
|
||||
await prefs.setString('email', serverEmail);
|
||||
final perKey = 'display_name_$serverEmail';
|
||||
if ((prefs.getString(perKey) ?? '').isEmpty) {
|
||||
await prefs.setString(perKey, displayName);
|
||||
}
|
||||
if (res['phone_number'] != null) await prefs.setString('phone_number', res['phone_number'].toString());
|
||||
|
||||
PostHogService.instance.identify(serverEmail, properties: {
|
||||
'username': displayName,
|
||||
'login_method': 'google',
|
||||
});
|
||||
PostHogService.instance.capture('user_logged_in');
|
||||
|
||||
return UserModel.fromJson(res);
|
||||
} catch (e) {
|
||||
if (kDebugMode) debugPrint('AuthService.googleLogin error: $e');
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
/// Logout – clear auth token and current_email (keep per-account display_name entries so they persist)
|
||||
Future<void> logout() async {
|
||||
try {
|
||||
@@ -141,6 +197,8 @@ class AuthService {
|
||||
// Also remove canonical 'email' pointing to current user
|
||||
await prefs.remove('email');
|
||||
// Do not delete display_name_<email> entries — they are per-account and should remain on device.
|
||||
PostHogService.instance.capture('user_logged_out');
|
||||
PostHogService.instance.reset();
|
||||
} catch (e) {
|
||||
if (kDebugMode) debugPrint('AuthService.logout warning: $e');
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user