diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..ad32100 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,4 @@ +{ + "java.configuration.updateBuildConfiguration": "interactive", + "cmake.sourceDirectory": "C:/Users/akd24/Documents/GetWelPlus/flutter_app/linux" +} \ No newline at end of file diff --git a/flutter_app/android/app/build.gradle.kts b/flutter_app/android/app/build.gradle.kts index 343f129..7da92e3 100644 --- a/flutter_app/android/app/build.gradle.kts +++ b/flutter_app/android/app/build.gradle.kts @@ -1,10 +1,7 @@ plugins { id("com.android.application") id("kotlin-android") - // Add the Google services Gradle plugin - id("com.google.gms.google-services") - // The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins. id("dev.flutter.flutter-gradle-plugin") } @@ -27,10 +24,11 @@ android { applicationId = "com.example.flutter_app" // You can update the following values to match your application needs. // For more information, see: https://flutter.dev/to/review-gradle-config. - minSdk = flutter.minSdkVersion + minSdk = flutter.minSdkVersion // Required for Supabase targetSdk = flutter.targetSdkVersion versionCode = flutter.versionCode versionName = flutter.versionName + multiDexEnabled = true // Required for apps with many dependencies } buildTypes { @@ -47,15 +45,6 @@ flutter { } dependencies { - // Import the Firebase BoM - implementation(platform("com.google.firebase:firebase-bom:34.8.0")) - - - // TODO: Add the dependencies for Firebase products you want to use - // When using the BoM, don't specify versions in Firebase dependencies - implementation("com.google.firebase:firebase-analytics") - - - // Add the dependencies for any other desired Firebase products - // https://firebase.google.com/docs/android/setup#available-libraries + implementation("com.google.android.gms:play-services-auth:21.1.0") + implementation("androidx.multidex:multidex:2.0.1") } diff --git a/flutter_app/android/app/src/main/AndroidManifest.xml b/flutter_app/android/app/src/main/AndroidManifest.xml index 3eac92d..26ac042 100644 --- a/flutter_app/android/app/src/main/AndroidManifest.xml +++ b/flutter_app/android/app/src/main/AndroidManifest.xml @@ -1,4 +1,7 @@ + + + + + + + + + + + + @@ -41,5 +55,13 @@ + + + + + + + + diff --git a/flutter_app/android/app/src/main/res/xml/network_security_config.xml b/flutter_app/android/app/src/main/res/xml/network_security_config.xml new file mode 100644 index 0000000..c1484a2 --- /dev/null +++ b/flutter_app/android/app/src/main/res/xml/network_security_config.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + supabase.co + + + + + + diff --git a/flutter_app/android/build.gradle.kts b/flutter_app/android/build.gradle.kts index de12210..7687ef6 100644 --- a/flutter_app/android/build.gradle.kts +++ b/flutter_app/android/build.gradle.kts @@ -1,9 +1,5 @@ plugins { // ... - - // Add the dependency for the Google services Gradle plugin - id("com.google.gms.google-services") version "4.4.4" apply false - } allprojects { repositories { diff --git a/flutter_app/lib/auth/auth_provider.dart b/flutter_app/lib/auth/auth_provider.dart index f405280..d542765 100644 --- a/flutter_app/lib/auth/auth_provider.dart +++ b/flutter_app/lib/auth/auth_provider.dart @@ -1,13 +1,18 @@ import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:firebase_auth/firebase_auth.dart'; +import 'package:supabase_flutter/supabase_flutter.dart'; import 'auth_service.dart'; -// Give app access to AuthService +// Provide access to AuthService final authServiceProvider = Provider((ref) { return AuthService(); }); -// Listen to Firebase auth state -final authStateProvider = StreamProvider((ref) { - return ref.read(authServiceProvider).authstatechanges; -}); \ No newline at end of file +// Listen to Supabase auth state changes +final authStateProvider = StreamProvider((ref) { + return ref.read(authServiceProvider).authStateChanges; +}); + +// Get current user +final currentUserProvider = Provider((ref) { + return ref.read(authServiceProvider).currentUser; +}); diff --git a/flutter_app/lib/auth/auth_service.dart b/flutter_app/lib/auth/auth_service.dart index 91c7505..adfdb13 100644 --- a/flutter_app/lib/auth/auth_service.dart +++ b/flutter_app/lib/auth/auth_service.dart @@ -1,32 +1,160 @@ -import 'package:firebase_auth/firebase_auth.dart'; +import 'package:supabase_flutter/supabase_flutter.dart'; +import 'package:google_sign_in/google_sign_in.dart'; +class AuthService { + final SupabaseClient _supabase = Supabase.instance.client; + // Get current user + User? get currentUser => _supabase.auth.currentUser; -class AuthService { + // Listen to auth state changes + Stream get authStateChanges => _supabase.auth.onAuthStateChange; + + // Check if user is logged in + bool get isLoggedIn => currentUser != null; - final FirebaseAuth firebaseAuth = FirebaseAuth.instance; - User? get currentuser => firebaseAuth.currentUser; + // Sign up with email and password + Future signUp({ + required String email, + required String password, + required String name, + }) async { + try { + final response = await _supabase.auth.signUp( + email: email, + password: password, + data: {'name': name}, + ); - Stream get authstatechanges => firebaseAuth.authStateChanges(); + if (response.user != null) { + try { + await _supabase.from('users').insert({ + 'id': response.user!.id, + 'email': email, + 'name': name, + 'created_at': DateTime.now().toIso8601String(), + }); + } catch (dbError) { + // User already created in auth, profile creation can be retried later + } + } - Future login({ + return response; + } catch (e) { + rethrow; + } + } + + // Sign in with email and password + Future signIn({ required String email, required String password, + }) async { + try { + return await _supabase.auth.signInWithPassword( + email: email, + password: password, + ); + } catch (e) { + rethrow; + } + } + + // Sign in with Google + Future signInWithGoogle() async { + try { + const webClientId = + '632491342639-mq70dmjhr8udmps5t312gkcrc5d90a17.apps.googleusercontent.com'; - }) async{ - return await firebaseAuth.signInWithEmailAndPassword(email: email, password: password); + final GoogleSignIn googleSignIn = GoogleSignIn( + serverClientId: webClientId, + scopes: ['email', 'profile'], + ); + + final googleUser = await googleSignIn.signIn(); + if (googleUser == null) { + return false; + } + + final googleAuth = await googleUser.authentication; + final accessToken = googleAuth.accessToken; + final idToken = googleAuth.idToken; + + if (accessToken == null || idToken == null) { + throw 'Google authentication tokens not found'; + } + + final response = await _supabase.auth.signInWithIdToken( + provider: OAuthProvider.google, + idToken: idToken, + accessToken: accessToken, + ); + + // Create user profile if it doesn't exist + if (response.user != null) { + final existingUser = await _supabase + .from('users') + .select() + .eq('id', response.user!.id) + .maybeSingle(); + + if (existingUser == null) { + await _supabase.from('users').insert({ + 'id': response.user!.id, + 'email': response.user!.email, + 'name': googleUser.displayName ?? 'User', + 'created_at': DateTime.now().toIso8601String(), + }); + } + } + + return true; + } catch (e) { + rethrow; + } } - Future signup({ - required String email, - required String password, - }) async{ - return await firebaseAuth.createUserWithEmailAndPassword(email: email, password: password); + // Sign out + Future signOut() async { + try { + await _supabase.auth.signOut(); + } catch (e) { + rethrow; + } } - Future logout() async{ - await firebaseAuth.signOut(); + // Get user profile from database + Future?> getUserProfile(String userId) async { + try { + final response = await _supabase + .from('users') + .select() + .eq('id', userId) + .maybeSingle(); + return response; + } catch (e) { + rethrow; + } } + // Update user profile + Future updateUserProfile({ + required String userId, + required Map data, + }) async { + try { + await _supabase.from('users').update(data).eq('id', userId); + } catch (e) { + rethrow; + } + } -} \ No newline at end of file + // Reset password + Future resetPassword(String email) async { + try { + await _supabase.auth.resetPasswordForEmail(email); + } catch (e) { + rethrow; + } + } +} diff --git a/flutter_app/lib/auth/auth_wrapper.dart b/flutter_app/lib/auth/auth_wrapper.dart index 5771c45..8761a8a 100644 --- a/flutter_app/lib/auth/auth_wrapper.dart +++ b/flutter_app/lib/auth/auth_wrapper.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:firebase_auth/firebase_auth.dart'; +import 'package:supabase_flutter/supabase_flutter.dart'; import 'package:flutter_app/pages/homepage.dart'; import 'login_page.dart'; import 'signup_page.dart'; @@ -16,8 +16,8 @@ class _AuthWrapperState extends State { @override Widget build(BuildContext context) { - return StreamBuilder( - stream: FirebaseAuth.instance.authStateChanges(), + return StreamBuilder( + stream: Supabase.instance.client.auth.onAuthStateChange, builder: (context, snapshot) { // Loading if (snapshot.connectionState == ConnectionState.waiting) { @@ -26,8 +26,11 @@ class _AuthWrapperState extends State { ); } + // Check if user is logged in + final session = snapshot.hasData ? snapshot.data!.session : null; + // Logged in - if (snapshot.hasData) { + if (session != null) { return const HomePage(); } diff --git a/flutter_app/lib/auth/login_page.dart b/flutter_app/lib/auth/login_page.dart index e76587d..5e4e488 100644 --- a/flutter_app/lib/auth/login_page.dart +++ b/flutter_app/lib/auth/login_page.dart @@ -1,16 +1,14 @@ import 'package:flutter/material.dart'; import 'package:flutter_app/widgets/auth_button.dart'; import 'package:flutter_app/widgets/inputfield.dart'; -import 'package:firebase_auth/firebase_auth.dart'; +import 'package:flutter_app/auth/auth_service.dart'; +import 'package:supabase_flutter/supabase_flutter.dart'; + class LoginPage extends StatefulWidget { final VoidCallback onSwitch; - const LoginPage({super.key, - required this.onSwitch, - - }); + const LoginPage({super.key, required this.onSwitch}); @override - State createState() => _LoginPageState(); } @@ -18,7 +16,9 @@ class _LoginPageState extends State { final email = TextEditingController(); final pass = TextEditingController(); final formkey = GlobalKey(); + final authService = AuthService(); String? errorMessage; + bool isLoading = false; @override void dispose() { @@ -26,112 +26,178 @@ class _LoginPageState extends State { pass.dispose(); super.dispose(); } - Widget build(BuildContext context) { - return Scaffold( - // appBar: AppBar(), - body: SingleChildScrollView( - child: Padding( - padding: const EdgeInsets.all(27.0), - child: Form( - key: formkey, - child: Column( - children: [ - SizedBox(height: 140,), - RichText( - text: TextSpan( - style: const TextStyle( - fontSize: 60, - fontWeight: FontWeight.bold, - ), - children: const [ - TextSpan(text: "GetWel"), - TextSpan( - text: "+", - style: TextStyle(color: Color(0xFF4CAF50)), - ), - ], - ), - ), - - SizedBox(height: 30,), - Inputfield(hint_text: "Email",controller: email,), - SizedBox(height: 20,), - Inputfield(hint_text: "Password",controller: pass,hidetext: true,), - SizedBox(height: 20,), - AuthButton(label: "Log In", - onPressed: () async { - setState(() { - errorMessage = null; - }); - if (email.text.isEmpty || pass.text.isEmpty) { - setState(() { - errorMessage = 'Please enter email and password'; - }); - return; - } + Future _handleLogin() async { + setState(() { + errorMessage = null; + isLoading = true; + }); - try { - await FirebaseAuth.instance.signInWithEmailAndPassword( - email: email.text.trim(), - password: pass.text.trim(), - ); - } on FirebaseAuthException catch (e) { - setState(() { - if (e.code == 'user-not-found') { - errorMessage = 'User not found'; - } else if (e.code == 'wrong-password') { - errorMessage = 'Incorrect password'; - } else { - errorMessage = 'Login failed'; - } - }); - } - }, + if (email.text.isEmpty || pass.text.isEmpty) { + setState(() { + errorMessage = 'Please enter email and password'; + isLoading = false; + }); + return; + } - ), + try { + await authService.signIn( + email: email.text.trim(), + password: pass.text.trim(), + ); + // Navigation handled by AuthWrapper + } on AuthException catch (e) { + setState(() { + errorMessage = e.message; + isLoading = false; + }); + } catch (e) { + setState(() { + errorMessage = 'Login failed. Please try again.'; + isLoading = false; + }); + } + } - if (errorMessage != null) ...[ - const SizedBox(height: 20), - Text( - errorMessage!, - style: const TextStyle( - color: Colors.red, - fontSize: 14, - ), + Future _handleGoogleSignIn() async { + setState(() { + errorMessage = null; + isLoading = true; + }); + + try { + final success = await authService.signInWithGoogle(); + if (!success) { + setState(() { + errorMessage = 'Google sign-in was cancelled'; + isLoading = false; + }); + } + // Navigation handled by AuthWrapper + } on AuthException catch (e) { + setState(() { + errorMessage = 'Google sign-in failed: ${e.message}'; + isLoading = false; + }); + } catch (e) { + setState(() { + errorMessage = 'Google sign-in failed. Please try again.'; + isLoading = false; + }); + } + } + + @override + Widget build(BuildContext context) { + return Scaffold( + body: SingleChildScrollView( + child: Padding( + padding: const EdgeInsets.all(27.0), + child: Form( + key: formkey, + child: Column( + children: [ + const SizedBox(height: 140), + RichText( + text: const TextSpan( + style: TextStyle(fontSize: 60, fontWeight: FontWeight.bold), + children: [ + TextSpan(text: "GetWel"), + TextSpan( + text: "+", + style: TextStyle(color: Color(0xFF4CAF50)), ), ], - SizedBox(height: 20,), - GestureDetector( - onTap: () { - widget.onSwitch(); - }, - child: RichText(text: TextSpan( - text: 'Don\'t have an account?', - style: TextStyle( - fontSize: 17, - fontWeight: FontWeight.w700 - ), - children: [ - TextSpan(text: " Sign Up", - style: TextStyle( - fontWeight: FontWeight.bold, - color: Color(0xFF4CAF50) - ) - ) - - ] - )), ), - - - + ), + const SizedBox(height: 30), + Inputfield(hint_text: "Email", controller: email), + const SizedBox(height: 20), + Inputfield( + hint_text: "Password", + controller: pass, + hidetext: true, + ), + const SizedBox(height: 20), + isLoading + ? const CircularProgressIndicator() + : AuthButton(label: "Log In", onPressed: _handleLogin), + if (errorMessage != null) ...[ + const SizedBox(height: 20), + Text( + errorMessage!, + style: const TextStyle(color: Colors.red, fontSize: 14), + ), ], - ), + const SizedBox(height: 20), + const Text( + "OR", + style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600), + ), + const SizedBox(height: 20), + // Google Sign-In Button + isLoading + ? const SizedBox.shrink() + : OutlinedButton.icon( + onPressed: _handleGoogleSignIn, + style: OutlinedButton.styleFrom( + fixedSize: const Size(250, 50), + side: const BorderSide( + color: Color(0xFF4CAF50), + width: 2, + ), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + ), + icon: Image.asset( + 'assets/images/google_logo.png', + height: 24, + errorBuilder: (context, error, stackTrace) { + return const Icon( + Icons.g_mobiledata, + size: 28, + color: Color(0xFF4CAF50), + ); + }, + ), + label: const Text( + "Sign in with Google", + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w600, + color: Colors.black, + ), + ), + ), + const SizedBox(height: 20), + GestureDetector( + onTap: widget.onSwitch, + child: RichText( + text: const TextSpan( + text: 'Don\'t have an account?', + style: TextStyle( + fontSize: 17, + fontWeight: FontWeight.w700, + ), + children: [ + TextSpan( + text: " Sign Up", + style: TextStyle( + fontWeight: FontWeight.bold, + color: Color(0xFF4CAF50), + ), + ), + ], + ), + ), + ), + ], ), ), ), - + ), ); } -} \ No newline at end of file +} diff --git a/flutter_app/lib/auth/signup_page.dart b/flutter_app/lib/auth/signup_page.dart index 5bda9f6..8cbc4dd 100644 --- a/flutter_app/lib/auth/signup_page.dart +++ b/flutter_app/lib/auth/signup_page.dart @@ -1,17 +1,14 @@ import 'package:flutter/material.dart'; import 'package:flutter_app/widgets/auth_button.dart'; import 'package:flutter_app/widgets/inputfield.dart'; -import 'package:firebase_auth/firebase_auth.dart'; -import 'package:cloud_firestore/cloud_firestore.dart'; +import 'package:flutter_app/auth/auth_service.dart'; +import 'package:supabase_flutter/supabase_flutter.dart'; class SignupPage extends StatefulWidget { final VoidCallback onSwitch; - const SignupPage({super.key, - required this.onSwitch, - }); + const SignupPage({super.key, required this.onSwitch}); @override - State createState() => _SignupPageState(); } @@ -20,7 +17,9 @@ class _SignupPageState extends State { final email = TextEditingController(); final pass = TextEditingController(); final formkey = GlobalKey(); + final authService = AuthService(); String? errorMessage; + bool isLoading = false; @override void dispose() { @@ -29,131 +28,123 @@ class _SignupPageState extends State { pass.dispose(); super.dispose(); } - Widget build(BuildContext context) { - return Scaffold( - // appBar: AppBar(), - body: SingleChildScrollView( - child: Padding( - padding: const EdgeInsets.all(27.0), - child: Form( - key: formkey, - child: Column( - children: [ - SizedBox(height: 140,), - RichText( - text: TextSpan( - style: const TextStyle( - fontSize: 60, - fontWeight: FontWeight.bold, - ), - children: const [ - TextSpan(text: "GetWel"), - TextSpan( - text: "+", - style: TextStyle(color: Color(0xFF4CAF50)), - ), - ], - ), - ), - - SizedBox(height: 20,), - SizedBox(height: 10,), - Inputfield(hint_text: "Name",controller: name,), - SizedBox(height: 20,), - Inputfield(hint_text: "Email",controller: email,), - SizedBox(height: 20,), - Inputfield(hint_text: "Password",controller: pass,hidetext: true,), - SizedBox(height: 20,), - AuthButton( - label: "Sign Up", - onPressed: () async { - // clear old error - setState(() { - errorMessage = null; - }); - // manual validation (no TextField resize) - if (name.text.isEmpty || - email.text.isEmpty || - pass.text.isEmpty) { - setState(() { - errorMessage = 'Please fill all fields'; - }); - return; - } + Future _handleSignup() async { + setState(() { + errorMessage = null; + isLoading = true; + }); + + // Validate fields + if (name.text.isEmpty || email.text.isEmpty || pass.text.isEmpty) { + setState(() { + errorMessage = 'Please fill all fields'; + isLoading = false; + }); + return; + } + + // Validate password length + if (pass.text.length < 6) { + setState(() { + errorMessage = 'Password must be at least 6 characters'; + isLoading = false; + }); + return; + } + + try { + await authService.signUp( + email: email.text.trim(), + password: pass.text.trim(), + name: name.text.trim(), + ); + // Navigation handled by AuthWrapper + } on AuthException catch (e) { + setState(() { + errorMessage = e.message; + isLoading = false; + }); + } catch (e) { + setState(() { + errorMessage = 'Signup failed. Please try again.'; + isLoading = false; + }); + } + } - try { - await FirebaseAuth.instance.createUserWithEmailAndPassword( - email: email.text.trim(), - password: pass.text.trim(), - ); - final user = FirebaseAuth.instance.currentUser; - if (user != null) { - await FirebaseFirestore.instance - .collection('users') - .doc(user.uid) - .set({ - 'name': name.text.trim(), - 'email': user.email, - 'createdAt': FieldValue.serverTimestamp(), - }); - } - } on FirebaseAuthException catch (e) { - setState(() { - if (e.code == 'email-already-in-use') { - errorMessage = 'Email already in use'; - } else if (e.code == 'weak-password') { - errorMessage = 'Password is too weak'; - } else if (e.code == 'invalid-email') { - errorMessage = 'Invalid email address'; - } else { - errorMessage = 'Signup failed'; - } - }); - } - }, + @override + Widget build(BuildContext context) { + return Scaffold( + body: SingleChildScrollView( + child: Padding( + padding: const EdgeInsets.all(27.0), + child: Form( + key: formkey, + child: Column( + children: [ + const SizedBox(height: 140), + RichText( + text: const TextSpan( + style: TextStyle(fontSize: 60, fontWeight: FontWeight.bold), + children: [ + TextSpan(text: "GetWel"), + TextSpan( + text: "+", + style: TextStyle(color: Color(0xFF4CAF50)), + ), + ], ), - if (errorMessage != null) ...[ - const SizedBox(height: 20), - Text( - errorMessage!, - style: const TextStyle( - color: Colors.red, - fontSize: 14, + ), + const SizedBox(height: 20), + const SizedBox(height: 10), + Inputfield(hint_text: "Name", controller: name), + const SizedBox(height: 20), + Inputfield(hint_text: "Email", controller: email), + const SizedBox(height: 20), + Inputfield( + hint_text: "Password", + controller: pass, + hidetext: true, + ), + const SizedBox(height: 20), + isLoading + ? const CircularProgressIndicator() + : AuthButton(label: "Sign Up", onPressed: _handleSignup), + if (errorMessage != null) ...[ + const SizedBox(height: 20), + Text( + errorMessage!, + style: const TextStyle(color: Colors.red, fontSize: 14), + ), + ], + const SizedBox(height: 20), + GestureDetector( + onTap: widget.onSwitch, + child: RichText( + text: const TextSpan( + text: 'Already have an account?', + style: TextStyle( + fontSize: 17, + fontWeight: FontWeight.w700, ), - ), - ], - SizedBox(height: 20,), - GestureDetector( - onTap: () { - widget.onSwitch(); - }, - child: RichText(text: TextSpan( - text: 'Already have an account?', - style: TextStyle( - fontSize: 17, - fontWeight: FontWeight.w700 + children: [ + TextSpan( + text: " Log In", + style: TextStyle( + fontWeight: FontWeight.bold, + color: Color(0xFF4CAF50), + ), ), - children: [ - TextSpan(text: " Log In", - style: TextStyle( - fontWeight: FontWeight.bold, - color: Color(0xFF4CAF50) - ) - ) - - ] - )), + ], + ), ), - - - - ], - ), + ), + ], ), ), ), - + ), ); } -} \ No newline at end of file +} diff --git a/flutter_app/lib/core/theme/app_theme.dart b/flutter_app/lib/core/theme/app_theme.dart index b8889e8..d327081 100644 --- a/flutter_app/lib/core/theme/app_theme.dart +++ b/flutter_app/lib/core/theme/app_theme.dart @@ -1,8 +1,9 @@ +import 'package:flutter/src/material/theme_data.dart'; import 'light_theme.dart'; import 'dark_theme.dart'; class AppTheme { - static get light => LightTheme.theme; - static get dark => DarkTheme.theme; + static ThemeData get light => LightTheme.theme; + static ThemeData get dark => DarkTheme.theme; } diff --git a/flutter_app/lib/main.dart b/flutter_app/lib/main.dart index 0d347d8..7d02d22 100644 --- a/flutter_app/lib/main.dart +++ b/flutter_app/lib/main.dart @@ -2,19 +2,20 @@ import 'package:flutter/material.dart'; import 'package:flutter_app/auth/auth_wrapper.dart'; import 'core/theme/app_theme.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:firebase_core/firebase_core.dart'; - +import 'package:supabase_flutter/supabase_flutter.dart'; Future main() async { WidgetsFlutterBinding.ensureInitialized(); - await Firebase.initializeApp(); - runApp( - const ProviderScope( - child: MyApp(), - ), + + // Initialize Supabase + await Supabase.initialize( + url: 'https://prvbbbnsizxxfxreokov.supabase.co', + anonKey: + 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InBydmJiYm5zaXp4eGZ4cmVva292Iiwicm9sZSI6ImFub24iLCJpYXQiOjE3NzA4OTMwODgsImV4cCI6MjA4NjQ2OTA4OH0.GOqP5k0AnGzqse5loXuPz9BkfGCUdJgApUL9QBVw0es', ); -} + runApp(const ProviderScope(child: MyApp())); +} class MyApp extends StatelessWidget { const MyApp({super.key}); diff --git a/flutter_app/lib/pages/homepage.dart b/flutter_app/lib/pages/homepage.dart index 8922a10..bf8aeaa 100644 --- a/flutter_app/lib/pages/homepage.dart +++ b/flutter_app/lib/pages/homepage.dart @@ -1,206 +1,242 @@ import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:flutter_app/auth/auth_provider.dart'; -import 'package:cloud_firestore/cloud_firestore.dart'; -import 'package:firebase_auth/firebase_auth.dart'; +import 'package:supabase_flutter/supabase_flutter.dart'; + +// Services and Providers +import 'package:flutter_app/auth/auth_service.dart'; + +// Feature Pages +import 'package:flutter_app/pages/stress_check_page.dart'; +import 'package:flutter_app/pages/article_page.dart'; +import 'package:flutter_app/pages/mood_tracker.dart'; +import 'package:flutter_app/pages/ai_chat.dart'; + +// Widgets import 'package:flutter_app/widgets/feature_card.dart'; -class HomePage extends ConsumerWidget { +class HomePage extends ConsumerStatefulWidget { const HomePage({super.key}); - String getGreeting() { - final hour = DateTime.now().hour; - if (hour >= 5 && hour < 12) { - return 'Good Morning'; - } else if (hour >= 12 && hour < 17) { - return 'Good Afternoon'; - } else if (hour >= 17 && hour < 21) { - return 'Good Evening'; - } else { - return 'Good Night'; - } - } @override - Widget build(BuildContext context, WidgetRef ref) { - return Scaffold( - appBar: AppBar( - title: const Text('GetWel+',style: TextStyle( - fontSize: 31 - ),), - elevation: 4, - centerTitle: true, - actions: [ - IconButton( - icon: const Icon(Icons.notifications), - onPressed: () { - // open notifications page later - }, - ), - ], - ), - drawer: Drawer( - child: ListView( - padding: EdgeInsets.zero, - children: [ - DrawerHeader( - decoration: const BoxDecoration( - color: Color.fromARGB(255, 65, 151, 69), - ), - child: StreamBuilder( - stream: FirebaseFirestore.instance - .collection('users') - .doc(FirebaseAuth.instance.currentUser!.uid) - .snapshots(), - builder: (context, snapshot) { - if (!snapshot.hasData) { - return const Center( - child: CircularProgressIndicator(color: Colors.white), - ); - } + ConsumerState createState() => _HomePageState(); +} + +class _HomePageState extends ConsumerState { + final authService = AuthService(); + Map? userProfile; + bool isLoading = true; - final data = snapshot.data!; - final name = data['name'] ?? 'User'; + @override + void initState() { + super.initState(); + _loadUserProfile(); + } - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.end, - children: [ + Future _loadUserProfile() async { + try { + final userId = Supabase.instance.client.auth.currentUser?.id; + if (userId != null) { + final profile = await authService.getUserProfile(userId); + if (mounted) { + setState(() { + userProfile = profile; + isLoading = false; + }); + } + } + } catch (e) { + if (mounted) { + setState(() { + isLoading = false; + }); + } + } + } - Row( - children: [ - const CircleAvatar( - radius: 28, - backgroundColor: Colors.black, - child: Icon( - Icons.person, - size: 32, - color: Color(0xFF4CAF50), - ), + String getGreeting() { + final hour = DateTime.now().hour; + if (hour >= 5 && hour < 12) return 'Good Morning'; + if (hour >= 12 && hour < 17) return 'Good Afternoon'; + if (hour >= 17 && hour < 21) return 'Good Evening'; + return 'Good Night'; + } + + @override + Widget build(BuildContext context) { + final user = Supabase.instance.client.auth.currentUser; + final name = userProfile?['name'] ?? user?.userMetadata?['name'] ?? 'User'; + + return SafeArea( + child: Scaffold( + appBar: AppBar( + title: const Text('GetWel+', style: TextStyle(fontSize: 31)), + elevation: 4, + centerTitle: true, + actions: [ + IconButton( + icon: const Icon(Icons.notifications), + onPressed: () { + // Handle notifications + }, + ), + ], + ), + drawer: Drawer( + child: ListView( + padding: EdgeInsets.zero, + children: [ + DrawerHeader( + decoration: const BoxDecoration( + color: Color.fromARGB(255, 65, 151, 69), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Row( + children: [ + const CircleAvatar( + radius: 28, + backgroundColor: Colors.black, + child: Icon( + Icons.person, + size: 32, + color: Color(0xFF4CAF50), ), - const SizedBox(width: 12), - Text( + ), + const SizedBox(width: 12), + Expanded( + child: Text( name, style: const TextStyle( color: Colors.black, - fontSize: 44, - fontWeight: FontWeight.bold + fontSize: 32, // Adjusted for better fit + fontWeight: FontWeight.bold, ), + overflow: TextOverflow.ellipsis, ), - ], - ), - ], - ); + ), + ], + ), + ], + ), + ), + ListTile( + leading: const Icon(Icons.person), + title: const Text('Profile'), + onTap: () => Navigator.pop(context), + ), + ListTile( + leading: const Icon(Icons.settings), + title: const Text('Settings'), + onTap: () => Navigator.pop(context), + ), + const Divider(), + ListTile( + leading: const Icon(Icons.logout), + title: const Text('Logout'), + onTap: () async { + Navigator.pop(context); + await authService.signOut(); }, ), - ), - - - ListTile( - leading: const Icon(Icons.person), - title: const Text('Profile'), - onTap: () { - Navigator.pop(context); - // navigate to Profile page later - }, - ), - - ListTile( - leading: const Icon(Icons.settings), - title: const Text('Settings'), - onTap: () { - Navigator.pop(context); - // navigate to Settings page later - }, - ), - - const Divider(), - - ListTile( - leading: const Icon(Icons.logout), - title: const Text('Logout'), - onTap: () async { - Navigator.pop(context); - await FirebaseAuth.instance.signOut(); - }, - ), - ], + ], + ), ), - ), - - - body: Padding( - padding: const EdgeInsets.all(16.0), - child: Column( - children: [ - StreamBuilder( - stream: FirebaseFirestore.instance - .collection('users') - .doc(FirebaseAuth.instance.currentUser!.uid) - .snapshots(), - builder: (context, snapshot) { - if (!snapshot.hasData) { - return const Center(child: CircularProgressIndicator()); - } - - final data = snapshot.data!; - final name = data['name'] ?? 'User'; - final greeting = getGreeting(); - - return Column( + body: isLoading + ? const Center(child: CircularProgressIndicator()) + : SingleChildScrollView( + padding: const EdgeInsets.all(16.0), + child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - '$greeting, $name 👋', - style: Theme.of(context).textTheme.headlineSmall?.copyWith( - fontWeight: FontWeight.w600, - fontSize: 23, + '${getGreeting()}, $name 👋', + style: Theme.of(context).textTheme.headlineSmall + ?.copyWith(fontWeight: FontWeight.w600, fontSize: 23), + ), + const SizedBox(height: 20), + + // Feature List + FeatureCard( + imagePath: 'assets/images/online_call.jpg', + title: '1:1 Online Meet', + subtitle: 'Talk privately with a psychiatrist online', + onTap: () {}, + ), + FeatureCard( + imagePath: "assets/images/mood.jpg", + title: 'Track your mood', + subtitle: 'Log how you’re feeling today', + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (_) => const MoodTrackerPage(), + ), + ); + }, + ), + FeatureCard( + imagePath: 'assets/images/meditation.jpg', + title: 'Guided Meditation', + subtitle: 'Relax your mind in just a few minutes', + onTap: () {}, + ), + FeatureCard( + imagePath: 'assets/images/book_a_slot.jpg', + title: 'Book a Session', + subtitle: 'Meet a mental health professional offline', + onTap: () {}, + ), + FeatureCard( + imagePath: 'assets/images/stress.jpg', + title: 'Stress Check', + subtitle: 'Measure your stress level in minutes', + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (_) => const StressCheckPage(), + ), + ); + }, + ), + FeatureCard( + imagePath: 'assets/images/articles.jpg', + title: 'Psychology Articles', + subtitle: 'Read expert-written articles', + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (_) => const ArticlesPage(), ), + ); + }, + ), + FeatureCard( + imagePath: 'assets/images/music.jpg', + title: 'Calm Music', + subtitle: 'Soothing sounds to relax your mind', + onTap: () {}, ), ], - ); - }, - ), - SizedBox(height: 20,), - FeatureCard( - imagePath: "assets/images/mood.jpg", - title: 'Track your mood', - subtitle: 'Log how you’re feeling today', - onTap: () { - // navigate to mood tracker page - }, - ), - // SizedBox(height: 20,), - FeatureCard( - imagePath: 'assets/images/meditation.jpg', - title: 'Guided Meditation', - subtitle: 'Relax your mind in just a few minutes', - onTap: () { - // open meditation page - }, - ), - FeatureCard( - imagePath: 'assets/images/stress.jpg', - title: 'Stress Check', - subtitle: 'Measure your stress level in minutes', - onTap: () { - // open stress test page - }, - ), - FeatureCard( - imagePath: 'assets/images/music.jpg', - title: 'Calm Music', - subtitle: 'Soothing sounds to relax your mind', - onTap: () { - // open calm music / audio page - }, - ), - - ] + ), + ), + floatingActionButton: FloatingActionButton( + shape: const CircleBorder(), + foregroundColor: Colors.black, + backgroundColor: Colors.green, + onPressed: () { + Navigator.push( + context, + MaterialPageRoute(builder: (_) => const AiChatPage()), + ); + }, + child: const Text("AI", style: TextStyle(fontSize: 27)), ), ), - - - ); } } diff --git a/flutter_app/linux/flutter/generated_plugin_registrant.cc b/flutter_app/linux/flutter/generated_plugin_registrant.cc index e71a16d..3792af4 100644 --- a/flutter_app/linux/flutter/generated_plugin_registrant.cc +++ b/flutter_app/linux/flutter/generated_plugin_registrant.cc @@ -6,6 +6,14 @@ #include "generated_plugin_registrant.h" +#include +#include void fl_register_plugins(FlPluginRegistry* registry) { + g_autoptr(FlPluginRegistrar) gtk_registrar = + fl_plugin_registry_get_registrar_for_plugin(registry, "GtkPlugin"); + gtk_plugin_register_with_registrar(gtk_registrar); + g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar = + fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin"); + url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar); } diff --git a/flutter_app/linux/flutter/generated_plugins.cmake b/flutter_app/linux/flutter/generated_plugins.cmake index 2e1de87..5d07423 100644 --- a/flutter_app/linux/flutter/generated_plugins.cmake +++ b/flutter_app/linux/flutter/generated_plugins.cmake @@ -3,6 +3,8 @@ # list(APPEND FLUTTER_PLUGIN_LIST + gtk + url_launcher_linux ) list(APPEND FLUTTER_FFI_PLUGIN_LIST diff --git a/flutter_app/macos/Flutter/GeneratedPluginRegistrant.swift b/flutter_app/macos/Flutter/GeneratedPluginRegistrant.swift index 804ef2f..1075add 100644 --- a/flutter_app/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/flutter_app/macos/Flutter/GeneratedPluginRegistrant.swift @@ -5,12 +5,14 @@ import FlutterMacOS import Foundation -import cloud_firestore -import firebase_auth -import firebase_core +import app_links +import google_sign_in_ios +import shared_preferences_foundation +import url_launcher_macos func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { - FLTFirebaseFirestorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseFirestorePlugin")) - FLTFirebaseAuthPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseAuthPlugin")) - FLTFirebaseCorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCorePlugin")) + AppLinksMacosPlugin.register(with: registry.registrar(forPlugin: "AppLinksMacosPlugin")) + FLTGoogleSignInPlugin.register(with: registry.registrar(forPlugin: "FLTGoogleSignInPlugin")) + SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) + UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin")) } diff --git a/flutter_app/pubspec.lock b/flutter_app/pubspec.lock index b2d35d2..01eec87 100644 --- a/flutter_app/pubspec.lock +++ b/flutter_app/pubspec.lock @@ -9,14 +9,14 @@ packages: url: "https://pub.dev" source: hosted version: "91.0.0" - _flutterfire_internals: + adaptive_number: dependency: transitive description: - name: _flutterfire_internals - sha256: cd83f7d6bd4e4c0b0b4fef802e8796784032e1cc23d7b0e982cf5d05d9bbe182 + name: adaptive_number + sha256: "3a567544e9b5c9c803006f51140ad544aedc79604fd4f3f2c1380003f97c1d77" url: "https://pub.dev" source: hosted - version: "1.3.66" + version: "1.0.0" analyzer: dependency: transitive description: @@ -25,6 +25,38 @@ packages: url: "https://pub.dev" source: hosted version: "8.4.1" + app_links: + dependency: "direct main" + description: + name: app_links + sha256: "5f88447519add627fe1cbcab4fd1da3d4fed15b9baf29f28b22535c95ecee3e8" + url: "https://pub.dev" + source: hosted + version: "6.4.1" + app_links_linux: + dependency: transitive + description: + name: app_links_linux + sha256: f5f7173a78609f3dfd4c2ff2c95bd559ab43c80a87dc6a095921d96c05688c81 + url: "https://pub.dev" + source: hosted + version: "1.0.3" + app_links_platform_interface: + dependency: transitive + description: + name: app_links_platform_interface + sha256: "05f5379577c513b534a29ddea68176a4d4802c46180ee8e2e966257158772a3f" + url: "https://pub.dev" + source: hosted + version: "2.0.2" + app_links_web: + dependency: transitive + description: + name: app_links_web + sha256: af060ed76183f9e2b87510a9480e56a5352b6c249778d07bd2c95fc35632a555 + url: "https://pub.dev" + source: hosted + version: "1.0.4" args: dependency: transitive description: @@ -73,30 +105,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.1.2" - cloud_firestore: - dependency: "direct main" - description: - name: cloud_firestore - sha256: "54484b2fc49f41b46f35b60a54b12351181eeaad22c0e3def276a81e17ae7c9b" - url: "https://pub.dev" - source: hosted - version: "6.1.2" - cloud_firestore_platform_interface: - dependency: transitive - description: - name: cloud_firestore_platform_interface - sha256: dfaa8b2c0d0a824af289d4159816a5c78417feec264c2194081d645687195158 - url: "https://pub.dev" - source: hosted - version: "7.0.6" - cloud_firestore_web: - dependency: transitive - description: - name: cloud_firestore_web - sha256: "35d01f502b3b701d700470d32a8f82704dac8341a66e86c074900cde5bab343d" - url: "https://pub.dev" - source: hosted - version: "5.1.2" code_assets: dependency: transitive description: @@ -145,6 +153,22 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.8" + dart_jsonwebtoken: + dependency: transitive + description: + name: dart_jsonwebtoken + sha256: "0de65691c1d736e9459f22f654ddd6fd8368a271d4e41aa07e53e6301eff5075" + url: "https://pub.dev" + source: hosted + version: "3.3.1" + ed25519_edwards: + dependency: transitive + description: + name: ed25519_edwards + sha256: "6ce0112d131327ec6d42beede1e5dfd526069b18ad45dcf654f15074ad9276cd" + url: "https://pub.dev" + source: hosted + version: "0.3.1" fake_async: dependency: transitive description: @@ -169,54 +193,14 @@ packages: url: "https://pub.dev" source: hosted version: "7.0.1" - firebase_auth: - dependency: "direct main" - description: - name: firebase_auth - sha256: b20d1540460814c5984474c1e9dd833bdbcff6ecd8d6ad86cc9da8cfd581c172 - url: "https://pub.dev" - source: hosted - version: "6.1.4" - firebase_auth_platform_interface: - dependency: transitive - description: - name: firebase_auth_platform_interface - sha256: fd0225320b6bbc92460c86352d16b60aea15f9ef88292774cca97b0522ea9f72 - url: "https://pub.dev" - source: hosted - version: "8.1.6" - firebase_auth_web: - dependency: transitive - description: - name: firebase_auth_web - sha256: be7dccb263b89fbda2a564de9d8193118196e8481ffb937222a025cdfdf82c40 - url: "https://pub.dev" - source: hosted - version: "6.1.2" - firebase_core: - dependency: "direct main" - description: - name: firebase_core - sha256: "923085c881663ef685269b013e241b428e1fb03cdd0ebde265d9b40ff18abf80" - url: "https://pub.dev" - source: hosted - version: "4.4.0" - firebase_core_platform_interface: + fixnum: dependency: transitive description: - name: firebase_core_platform_interface - sha256: cccb4f572325dc14904c02fcc7db6323ad62ba02536833dddb5c02cac7341c64 + name: fixnum + sha256: b6dc7065e46c974bc7c5f143080a6764ec7a4be6da1285ececdc37be96de53be url: "https://pub.dev" source: hosted - version: "6.0.2" - firebase_core_web: - dependency: transitive - description: - name: firebase_core_web - sha256: "83e7356c704131ca4d8d8dd57e360d8acecbca38b1a3705c7ae46cc34c708084" - url: "https://pub.dev" - source: hosted - version: "3.4.0" + version: "1.1.1" flutter: dependency: "direct main" description: flutter @@ -256,6 +240,14 @@ packages: url: "https://pub.dev" source: hosted version: "4.0.0" + functions_client: + dependency: transitive + description: + name: functions_client + sha256: "94074d62167ae634127ef6095f536835063a7dc80f2b1aa306d2346ff9023996" + url: "https://pub.dev" + source: hosted + version: "2.5.0" glob: dependency: transitive description: @@ -272,6 +264,70 @@ packages: url: "https://pub.dev" source: hosted version: "8.0.0" + google_identity_services_web: + dependency: transitive + description: + name: google_identity_services_web + sha256: "5d187c46dc59e02646e10fe82665fc3884a9b71bc1c90c2b8b749316d33ee454" + url: "https://pub.dev" + source: hosted + version: "0.3.3+1" + google_sign_in: + dependency: "direct main" + description: + name: google_sign_in + sha256: d0a2c3bcb06e607bb11e4daca48bd4b6120f0bbc4015ccebbe757d24ea60ed2a + url: "https://pub.dev" + source: hosted + version: "6.3.0" + google_sign_in_android: + dependency: transitive + description: + name: google_sign_in_android + sha256: d5e23c56a4b84b6427552f1cf3f98f716db3b1d1a647f16b96dbb5b93afa2805 + url: "https://pub.dev" + source: hosted + version: "6.2.1" + google_sign_in_ios: + dependency: transitive + description: + name: google_sign_in_ios + sha256: "102005f498ce18442e7158f6791033bbc15ad2dcc0afa4cf4752e2722a516c96" + url: "https://pub.dev" + source: hosted + version: "5.9.0" + google_sign_in_platform_interface: + dependency: transitive + description: + name: google_sign_in_platform_interface + sha256: "5f6f79cf139c197261adb6ac024577518ae48fdff8e53205c5373b5f6430a8aa" + url: "https://pub.dev" + source: hosted + version: "2.5.0" + google_sign_in_web: + dependency: transitive + description: + name: google_sign_in_web + sha256: "460547beb4962b7623ac0fb8122d6b8268c951cf0b646dd150d60498430e4ded" + url: "https://pub.dev" + source: hosted + version: "0.12.4+4" + gotrue: + dependency: transitive + description: + name: gotrue + sha256: f7b52008311941a7c3e99f9590c4ee32dfc102a5442e43abf1b287d9f8cc39b2 + url: "https://pub.dev" + source: hosted + version: "2.18.0" + gtk: + dependency: transitive + description: + name: gtk + sha256: e8ce9ca4b1df106e4d72dad201d345ea1a036cc12c360f1a7d5a758f78ffa42c + url: "https://pub.dev" + source: hosted + version: "2.1.0" hooks: dependency: transitive description: @@ -320,6 +376,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.7.2" + jwt_decode: + dependency: transitive + description: + name: jwt_decode + sha256: d2e9f68c052b2225130977429d30f187aa1981d789c76ad104a32243cfdebfbb + url: "https://pub.dev" + source: hosted + version: "0.3.1" leak_tracker: dependency: transitive description: @@ -496,6 +560,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.8" + pointycastle: + dependency: transitive + description: + name: pointycastle + sha256: "92aa3841d083cc4b0f4709b5c74fd6409a3e6ba833ffc7dc6a8fee096366acf5" + url: "https://pub.dev" + source: hosted + version: "4.0.0" pool: dependency: transitive description: @@ -504,6 +576,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.5.2" + postgrest: + dependency: transitive + description: + name: postgrest + sha256: f4b6bb24b465c47649243ef0140475de8a0ec311dc9c75ebe573b2dcabb10460 + url: "https://pub.dev" + source: hosted + version: "2.6.0" pub_semver: dependency: transitive description: @@ -512,6 +592,22 @@ packages: url: "https://pub.dev" source: hosted version: "2.2.0" + realtime_client: + dependency: transitive + description: + name: realtime_client + sha256: "5268afc208d02fb9109854d262c1ebf6ece224cd285199ae1d2f92d2ff49dbf1" + url: "https://pub.dev" + source: hosted + version: "2.7.0" + retry: + dependency: transitive + description: + name: retry + sha256: "822e118d5b3aafed083109c72d5f484c6dc66707885e07c0fbcb8b986bba7efc" + url: "https://pub.dev" + source: hosted + version: "3.1.2" riverpod: dependency: transitive description: @@ -520,6 +616,70 @@ packages: url: "https://pub.dev" source: hosted version: "3.2.0" + rxdart: + dependency: transitive + description: + name: rxdart + sha256: "5c3004a4a8dbb94bd4bf5412a4def4acdaa12e12f269737a5751369e12d1a962" + url: "https://pub.dev" + source: hosted + version: "0.28.0" + shared_preferences: + dependency: transitive + description: + name: shared_preferences + sha256: "2939ae520c9024cb197fc20dee269cd8cdbf564c8b5746374ec6cacdc5169e64" + url: "https://pub.dev" + source: hosted + version: "2.5.4" + shared_preferences_android: + dependency: transitive + description: + name: shared_preferences_android + sha256: cbc40be9be1c5af4dab4d6e0de4d5d3729e6f3d65b89d21e1815d57705644a6f + url: "https://pub.dev" + source: hosted + version: "2.4.20" + shared_preferences_foundation: + dependency: transitive + description: + name: shared_preferences_foundation + sha256: "4e7eaffc2b17ba398759f1151415869a34771ba11ebbccd1b0145472a619a64f" + url: "https://pub.dev" + source: hosted + version: "2.5.6" + shared_preferences_linux: + dependency: transitive + description: + name: shared_preferences_linux + sha256: "580abfd40f415611503cae30adf626e6656dfb2f0cee8f465ece7b6defb40f2f" + url: "https://pub.dev" + source: hosted + version: "2.4.1" + shared_preferences_platform_interface: + dependency: transitive + description: + name: shared_preferences_platform_interface + sha256: "57cbf196c486bc2cf1f02b85784932c6094376284b3ad5779d1b1c6c6a816b80" + url: "https://pub.dev" + source: hosted + version: "2.4.1" + shared_preferences_web: + dependency: transitive + description: + name: shared_preferences_web + sha256: c49bd060261c9a3f0ff445892695d6212ff603ef3115edbb448509d407600019 + url: "https://pub.dev" + source: hosted + version: "2.4.3" + shared_preferences_windows: + dependency: transitive + description: + name: shared_preferences_windows + sha256: "94ef0f72b2d71bc3e700e025db3710911bd51a71cefb65cc609dd0d9a982e3c1" + url: "https://pub.dev" + source: hosted + version: "2.4.1" shelf: dependency: transitive description: @@ -597,6 +757,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.0" + storage_client: + dependency: transitive + description: + name: storage_client + sha256: "1c61b19ed9e78f37fdd1ca8b729ab8484e6c8fe82e15c87e070b861951183657" + url: "https://pub.dev" + source: hosted + version: "2.4.1" stream_channel: dependency: transitive description: @@ -613,6 +781,22 @@ packages: url: "https://pub.dev" source: hosted version: "1.4.1" + supabase: + dependency: transitive + description: + name: supabase + sha256: cc039f63a3168386b3a4f338f3bff342c860d415a3578f3fbe854024aee6f911 + url: "https://pub.dev" + source: hosted + version: "2.10.2" + supabase_flutter: + dependency: "direct main" + description: + name: supabase_flutter + sha256: "92b2416ecb6a5c3ed34cf6e382b35ce6cc8921b64f2a9299d5d28968d42b09bb" + url: "https://pub.dev" + source: hosted + version: "2.12.0" term_glyph: dependency: transitive description: @@ -653,6 +837,70 @@ packages: url: "https://pub.dev" source: hosted version: "1.4.0" + url_launcher: + dependency: transitive + description: + name: url_launcher + sha256: f6a7e5c4835bb4e3026a04793a4199ca2d14c739ec378fdfe23fc8075d0439f8 + url: "https://pub.dev" + source: hosted + version: "6.3.2" + url_launcher_android: + dependency: transitive + description: + name: url_launcher_android + sha256: "767344bf3063897b5cf0db830e94f904528e6dd50a6dfaf839f0abf509009611" + url: "https://pub.dev" + source: hosted + version: "6.3.28" + url_launcher_ios: + dependency: transitive + description: + name: url_launcher_ios + sha256: b1aca26728b7cc7a3af971bb6f601554a8ae9df2e0a006de8450ba06a17ad36a + url: "https://pub.dev" + source: hosted + version: "6.4.0" + url_launcher_linux: + dependency: transitive + description: + name: url_launcher_linux + sha256: d5e14138b3bc193a0f63c10a53c94b91d399df0512b1f29b94a043db7482384a + url: "https://pub.dev" + source: hosted + version: "3.2.2" + url_launcher_macos: + dependency: transitive + description: + name: url_launcher_macos + sha256: "368adf46f71ad3c21b8f06614adb38346f193f3a59ba8fe9a2fd74133070ba18" + url: "https://pub.dev" + source: hosted + version: "3.2.5" + url_launcher_platform_interface: + dependency: transitive + description: + name: url_launcher_platform_interface + sha256: "552f8a1e663569be95a8190206a38187b531910283c3e982193e4f2733f01029" + url: "https://pub.dev" + source: hosted + version: "2.3.2" + url_launcher_web: + dependency: transitive + description: + name: url_launcher_web + sha256: d0412fcf4c6b31ecfdb7762359b7206ffba3bbffd396c6d9f9c4616ece476c1f + url: "https://pub.dev" + source: hosted + version: "2.4.2" + url_launcher_windows: + dependency: transitive + description: + name: url_launcher_windows + sha256: "712c70ab1b99744ff066053cbe3e80c73332b38d46e5e945c98689b2e66fc15f" + url: "https://pub.dev" + source: hosted + version: "3.1.5" vector_math: dependency: transitive description: @@ -725,6 +973,14 @@ packages: url: "https://pub.dev" source: hosted version: "3.1.3" + yet_another_json_isolate: + dependency: transitive + description: + name: yet_another_json_isolate + sha256: fe45897501fa156ccefbfb9359c9462ce5dec092f05e8a56109db30be864f01e + url: "https://pub.dev" + source: hosted + version: "2.1.0" sdks: dart: ">=3.10.4 <4.0.0" flutter: ">=3.38.4" diff --git a/flutter_app/pubspec.yaml b/flutter_app/pubspec.yaml index 599bee3..2fbbe78 100644 --- a/flutter_app/pubspec.yaml +++ b/flutter_app/pubspec.yaml @@ -34,11 +34,11 @@ dependencies: # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: ^1.0.8 - firebase_core: ^4.4.0 # Latest core package for Firebase setup :contentReference[oaicite:0]{index=0} - firebase_auth: ^6.1.4 # Latest auth plugin :contentReference[oaicite:1]{index=1} - cloud_firestore: ^6.1.2 + supabase_flutter: ^2.8.0 flutter_riverpod: ^3.2.0 google_fonts: ^8.0.0 + google_sign_in: ^6.2.2 + app_links: ^6.4.1 dev_dependencies: flutter_test: diff --git a/flutter_app/windows/flutter/generated_plugin_registrant.cc b/flutter_app/windows/flutter/generated_plugin_registrant.cc index bf6d21a..785a046 100644 --- a/flutter_app/windows/flutter/generated_plugin_registrant.cc +++ b/flutter_app/windows/flutter/generated_plugin_registrant.cc @@ -6,15 +6,12 @@ #include "generated_plugin_registrant.h" -#include -#include -#include +#include +#include void RegisterPlugins(flutter::PluginRegistry* registry) { - CloudFirestorePluginCApiRegisterWithRegistrar( - registry->GetRegistrarForPlugin("CloudFirestorePluginCApi")); - FirebaseAuthPluginCApiRegisterWithRegistrar( - registry->GetRegistrarForPlugin("FirebaseAuthPluginCApi")); - FirebaseCorePluginCApiRegisterWithRegistrar( - registry->GetRegistrarForPlugin("FirebaseCorePluginCApi")); + AppLinksPluginCApiRegisterWithRegistrar( + registry->GetRegistrarForPlugin("AppLinksPluginCApi")); + UrlLauncherWindowsRegisterWithRegistrar( + registry->GetRegistrarForPlugin("UrlLauncherWindows")); } diff --git a/flutter_app/windows/flutter/generated_plugins.cmake b/flutter_app/windows/flutter/generated_plugins.cmake index b83b40a..8f8ee4f 100644 --- a/flutter_app/windows/flutter/generated_plugins.cmake +++ b/flutter_app/windows/flutter/generated_plugins.cmake @@ -3,9 +3,8 @@ # list(APPEND FLUTTER_PLUGIN_LIST - cloud_firestore - firebase_auth - firebase_core + app_links + url_launcher_windows ) list(APPEND FLUTTER_FFI_PLUGIN_LIST