Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implemented Skip button functionality, added adaptive WillPopScope, and enhanced Signup/Login page UI. #120

Merged
merged 1 commit into from
Nov 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -212,3 +212,42 @@ To know more [Click Here](LICENSE.md)
</a>
</div>

<h1>Firebase Setup Guide</h1>
<ol>
<li>
<strong>Login to Firebase Console</strong>
<p>Go to the <a href="https://console.firebase.google.com/" target="_blank">Firebase Console</a> and log in with your Google account.</p>
</li>
<li>
<strong>Setup for Android Version</strong>
<p>In the Firebase Console, create a new project and follow the instructions to set up Firebase for Android.</p>
</li>
<li>
<strong>Download google-services.json</strong>
<p>Download the <code>google-services.json</code> file from the Firebase console and add it under the <code>android/app</code> folder in your Flutter project.</p>
</li>
<li>
<strong>Configure build.gradle</strong>
<p>Open the <code>android/build.gradle</code> file and add the following classpath under the <code>dependencies</code> section:</p>
<pre>
classpath 'com.google.gms:google-services:4.3.15' <!-- or the latest version -->
</pre>
<p>Then, open the <code>android/app/build.gradle</code> file and add the following line at the bottom:</p>
<pre>
apply plugin: 'com.google.gms.google-services'
</pre>
</li>
<li>
<strong>Setup Firestore for Database</strong>
<p>In the Firebase console, go to the Firestore section and create a Firestore database for your project. Follow the on-screen instructions to choose between production or test mode.</p>
</li>
<li>
<strong>Setup Authentication</strong>
<p>In the Firebase console, go to the Authentication section and enable the following sign-in methods:</p>
<ul>
<li>Email/Password</li>
<li>Google</li>
</ul>
<p>Make sure to configure the necessary credentials and settings for both sign-in methods.</p>
</li>
</ol>
4 changes: 4 additions & 0 deletions android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,7 @@ android {
flutter {
source = "../.."
}

dependencies {
implementation platform('com.google.firebase:firebase-bom:33.5.1')
}
32 changes: 25 additions & 7 deletions android/app/google-services.json
Original file line number Diff line number Diff line change
@@ -1,26 +1,44 @@
{
"project_info": {
"project_number": "445023469277",
"project_id": "donor-connect-project",
"storage_bucket": "donor-connect-project.appspot.com"
"project_number": "255205177926",
"project_id": "donorconnect-40490",
"storage_bucket": "donorconnect-40490.firebasestorage.app"
},
"client": [
{
"client_info": {
"mobilesdk_app_id": "1:445023469277:android:867d6fc40fb1d859a52534",
"mobilesdk_app_id": "1:255205177926:android:eae013c60c9efa933c6847",
"android_client_info": {
"package_name": "com.example.donorconnect"
}
},
"oauth_client": [],
"oauth_client": [
{
"client_id": "255205177926-q7chqmo3b2sh6pmcnnfketcledt3d9jb.apps.googleusercontent.com",
"client_type": 1,
"android_info": {
"package_name": "com.example.donorconnect",
"certificate_hash": "c645004972e2e67b6e8fb81cdbff026bad48ab47"
}
},
{
"client_id": "255205177926-hd9rrs0i3ti9s2s4bchij1tk8263k8u3.apps.googleusercontent.com",
"client_type": 3
}
],
"api_key": [
{
"current_key": "AIzaSyDprpAsw0AkuQmFG1Iczpb9N2gghyAFmqo"
"current_key": "AIzaSyAaf-WvXzjym1yZ2umggxp5nuWyWM3OcJ0"
}
],
"services": {
"appinvite_service": {
"other_platform_oauth_client": []
"other_platform_oauth_client": [
{
"client_id": "255205177926-hd9rrs0i3ti9s2s4bchij1tk8263k8u3.apps.googleusercontent.com",
"client_type": 3
}
]
}
}
}
Expand Down
39 changes: 37 additions & 2 deletions android/build.gradle
Original file line number Diff line number Diff line change
@@ -1,15 +1,50 @@
// allprojects {
// repositories {
// google()
// mavenCentral()
// }
// dependencies {
// // classpath 'com.android.tools.build:gradle:7.0.0' // Use the correct Android Gradle Plugin version here
// classpath 'com.google.gms:google-services:4.4.2'
// }
// }



// rootProject.buildDir = "../build"
// subprojects {
// project.buildDir = "${rootProject.buildDir}/${project.name}"
// }
// subprojects {
// project.evaluationDependsOn(":app")
// }

// tasks.register("clean", Delete) {
// delete rootProject.buildDir
// }

buildscript {
repositories {
google()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:7.0.0' // Ensure you are using the correct version
classpath 'com.google.gms:google-services:4.4.2'
}
}

allprojects {
repositories {
google()
mavenCentral()
}
}

// Configure root project build directory and tasks
rootProject.buildDir = "../build"
subprojects {
project.buildDir = "${rootProject.buildDir}/${project.name}"
}
subprojects {
project.evaluationDependsOn(":app")
}

Expand Down
95 changes: 51 additions & 44 deletions lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import 'package:donorconnect/language/cubit/language_cubit.dart';
import 'package:donorconnect/language/helper/language.dart';
import 'package:donorconnect/language/services/language_repositoty.dart';
import 'package:donorconnect/services/blood_bank_service.dart';
import 'package:donorconnect/views/pages/login/login.dart';
import 'package:donorconnect/views/pages/main_home/homepage.dart';
import 'package:donorconnect/views/pages/onboarding/onboarding.dart';
import 'package:donorconnect/views/pages/welcome/welcome_screen.dart';
Expand All @@ -18,86 +19,92 @@ import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:get/get_navigation/src/root/get_material_app.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:jwt_decoder/jwt_decoder.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
// import 'package:riverpod/riverpod.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';

void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);

try {
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
} catch (e) {
print("Firebase initialization error: $e");
}

await LanguageRepository.init();
SharedPreferences prefs = await SharedPreferences.getInstance();
ErrorWidget.builder = (FlutterErrorDetails details) {
return const Material();
};
await dotenv.load(fileName: '.env');

// Check if the user has completed onboarding and if they are logged in
bool onboardingCompleted = prefs.getBool('onboardingCompleted') ?? false;
String? token = prefs.getString('token');
bool isLoggedIn = token != null && !JwtDecoder.isExpired(token);

// Lock orientation
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
DeviceOrientation.portraitDown,
]);

// Initialize the app
runApp(MyApp(
token: prefs.getString('token'),
token: isLoggedIn ? token : null,
onboardingCompleted: onboardingCompleted,
));
}

class MyApp extends StatelessWidget {
final String? token;
final bool onboardingCompleted;

const MyApp({
required this.token,
required this.onboardingCompleted,
super.key,
});

@override
Widget build(BuildContext context) {
return MultiBlocProvider(
providers: [
BlocProvider(create: (context) => ProfileCubit()),
BlocProvider(
create: (context) => ProfileCubit(),
),
BlocProvider(
create: (context) => AuthCubit(
FirebaseAuth.instance,
FirebaseFirestore.instance,
),
),
BlocProvider(
create: (context) => LocateBloodBanksCubit(BloodBankService()),
),
BlocProvider(
create: (context) => LanguageCubit()..initilize(),
),
create: (context) =>
AuthCubit(FirebaseAuth.instance, FirebaseFirestore.instance)),
BlocProvider(
create: (context) => ThemeCubit()..setInitialTheme(),
),
create: (context) => LocateBloodBanksCubit(BloodBankService())),
BlocProvider(create: (context) => LanguageCubit()..initilize()),
BlocProvider(create: (context) => ThemeCubit()..setInitialTheme()),
],
child: BlocBuilder<ThemeCubit, Themestate>(
builder: (context, themeState) {
return BlocBuilder<LanguageCubit, Language>(
builder: (context, languageState) {
return GetMaterialApp(
localizationsDelegates: AppLocalizations.localizationsDelegates,
supportedLocales: AppLocalizations.supportedLocales,
locale: Locale(languageState.languageCode),
//theme
// themeMode: themeState.themeData,
theme: themeState.themeData,
darkTheme: ThemeData.dark(),
debugShowCheckedModeBanner: false,
// Main route selection
home: (token != null && !JwtDecoder.isExpired(token!))
? HomePage(token: token!)
: const OnBoardingScreen(),
// You can add routes for the verification form
routes: {
'/verification': (context) =>
const VerificationForm(), // Add route for verification form
},
);
});
builder: (context, languageState) {
return GetMaterialApp(
localizationsDelegates: AppLocalizations.localizationsDelegates,
supportedLocales: AppLocalizations.supportedLocales,
locale: Locale(languageState.languageCode),
theme: themeState.themeData,
darkTheme: ThemeData.dark(),
debugShowCheckedModeBanner: false,
home: onboardingCompleted
? (token != null
? HomePage(
token:
token!) // Directly navigate to home page if logged in
: const LoginPage()) // Navigate to login if not logged in
: const OnBoardingScreen(), // Navigate to onboarding if not completed
routes: {
'/verification': (context) => const VerificationForm(),
},
);
},
);
},
),
);
Expand Down
75 changes: 36 additions & 39 deletions lib/views/controllers/onboarding/onboarding_controller.dart
Original file line number Diff line number Diff line change
@@ -1,55 +1,52 @@

import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:get/get.dart';
import 'package:flutter/material.dart';
import 'package:donorconnect/views/pages/login/login.dart'; // Import LoginPage
import 'package:get_storage/get_storage.dart';

import '../../pages/login/login.dart';

import 'package:flutter/foundation.dart';

class OnBoardingController extends GetxController {
static OnBoardingController get instance => Get.find();
// Page controller for the PageView
var pageController = PageController();

/// Variable
final pageController = PageController();
// final currentPageIndex = 0.obs; alternate method below
// Observable to track the current page index
Rx<int> currentPageIndex = 0.obs;
/// Update Current Index when page Scroll
void updatePageIndicator(index) => currentPageIndex.value = index;

/// Jump to the specific dot selected page.
void dotNavigationClick(index) {
currentPageIndex.value = index;
pageController.jumpTo(index);
}
// Update the page indicator when the page changes
void updatePageIndicator(int index) {
currentPageIndex.value = index;
}

/// Update Current Index & jump to next page
void nextPage() {
if(currentPageIndex.value == 2){
final storage = GetStorage();
// Method to navigate to a specific page based on dot navigation
void dotNavigationClick(int index) {
currentPageIndex.value = index;
pageController.jumpToPage(index);
}

if(kDebugMode){
print('===================== GET STORAGE ==============');
print(storage.read('IsFirstTime'));
}
// Method to navigate to the next page or to the login page if it's the last page
void nextPage() {
if (currentPageIndex.value == 2) {
final storage = GetStorage();

storage.write('IsFirstTime', false);
// Update the storage to indicate the user has completed onboarding
storage.write('IsFirstTime', false);

if(kDebugMode){
print('===================== GET STORAGE ==============');
print(storage.read('IsFirstTime'));
// Navigate to the LoginPage
Get.offAll(const LoginPage());
} else {
// Move to the next page
int nextPage = currentPageIndex.value + 1;
pageController.jumpToPage(nextPage);
}
}

Get.offAll(const LoginPage());
} else{
int page = currentPageIndex.value + 1;
pageController.jumpToPage(page);
// Skip the onboarding process and jump to the last page (LoginPage)
void skipPage() {
currentPageIndex.value = 2;
pageController.jumpToPage(2);
}
}

/// Update current index & jump to the last Page
void skipPage() {
currentPageIndex.value = 2;
pageController.jumpTo(2);
// Method to go to the login page directly
void goToLoginPage() {
Get.to(() => const LoginPage()); // Navigate to LoginPage
}
}
}
Loading