diff --git a/android/app/build.gradle b/android/app/build.gradle index b307593..872423c 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -24,6 +24,7 @@ if (flutterVersionName == null) { apply plugin: 'com.android.application' apply plugin: 'kotlin-android' apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" +apply plugin: 'com.google.gms.google-services' android { compileSdkVersion 29 @@ -39,7 +40,7 @@ android { defaultConfig { // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). applicationId "com.flutterflub.carify" - minSdkVersion 16 + minSdkVersion 21 targetSdkVersion 29 versionCode flutterVersionCode.toInteger() versionName flutterVersionName @@ -60,4 +61,6 @@ flutter { dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" + implementation platform('com.google.firebase:firebase-bom:26.1.1') + implementation 'com.google.firebase:firebase-analytics' } diff --git a/android/app/google-services.json b/android/app/google-services.json new file mode 100644 index 0000000..1492d2f --- /dev/null +++ b/android/app/google-services.json @@ -0,0 +1,47 @@ +{ + "project_info": { + "project_number": "500464888317", + "project_id": "carify-c8416", + "storage_bucket": "carify-c8416.appspot.com" + }, + "client": [ + { + "client_info": { + "mobilesdk_app_id": "1:500464888317:android:cb15c783bdac2f39cfd194", + "android_client_info": { + "package_name": "com.flutterflub.carify" + } + }, + "oauth_client": [ + { + "client_id": "500464888317-mde7nferub8gn37en1d6lpf79lqj9b0l.apps.googleusercontent.com", + "client_type": 1, + "android_info": { + "package_name": "com.flutterflub.carify", + "certificate_hash": "0d5b7dce11bceedb4b0ec3b4743c7eab87b42fb6" + } + }, + { + "client_id": "500464888317-51esjajj9e3q8hg2f5rjbmr1e427qgcr.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyAiooyasrTteWYmz84KVwVGkv2hhTrDLiU" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [ + { + "client_id": "500464888317-51esjajj9e3q8hg2f5rjbmr1e427qgcr.apps.googleusercontent.com", + "client_type": 3 + } + ] + } + } + } + ], + "configuration_version": "1" +} \ No newline at end of file diff --git a/android/build.gradle b/android/build.gradle index 3100ad2..9319192 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -8,6 +8,7 @@ buildscript { dependencies { classpath 'com.android.tools.build:gradle:3.5.0' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + classpath 'com.google.gms:google-services:4.3.4' } } diff --git a/assets/images/google_logo.png b/assets/images/google_logo.png new file mode 100644 index 0000000..b5b9bdd Binary files /dev/null and b/assets/images/google_logo.png differ diff --git a/lib/main.dart b/lib/main.dart index febdb35..f1e3eb7 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,11 +1,25 @@ import 'package:carify/screens/login_screen.dart'; +import 'package:carify/screens/profile_screen.dart'; import 'package:carify/screens/splash_screen.dart'; +import 'package:carify/screens/statusAuth.dart'; +import 'package:carify/utilities/user_authentication.dart'; +import 'package:firebase_auth/firebase_auth.dart'; import 'package:flutter/material.dart'; +import 'package:firebase_core/firebase_core.dart'; +import 'package:provider/provider.dart'; -void main() { - runApp(MaterialApp( - home: SplashScreen(), - debugShowCheckedModeBanner: false, - )); +Future main() async { + WidgetsFlutterBinding.ensureInitialized(); + await Firebase.initializeApp(); + runApp(MyApp()); +} + +class MyApp extends StatelessWidget { + @override + Widget build(BuildContext context) { + return MaterialApp( + home: SplashScreen(), + debugShowCheckedModeBanner: false, + ); + } } -//Hi diff --git a/lib/screens/login_screen.dart b/lib/screens/login_screen.dart index 36460cc..859a61b 100644 --- a/lib/screens/login_screen.dart +++ b/lib/screens/login_screen.dart @@ -1,5 +1,6 @@ import 'package:carify/screens/register_screen.dart'; import 'package:carify/utilities/constants.dart'; +import 'package:carify/utilities/loading.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; @@ -7,6 +8,10 @@ import 'package:flutter_svg/flutter_svg.dart'; import 'package:google_fonts/google_fonts.dart'; import 'package:carify/utilities/size_config.dart'; import 'package:carify/utilities/extracted_widget.dart'; +import 'package:carify/utilities/user_authentication.dart'; +import 'package:provider/provider.dart'; +import 'package:carify/screens/profile_screen.dart'; +import 'package:firebase_auth/firebase_auth.dart'; class LoginScreen extends StatefulWidget { @override @@ -15,199 +20,224 @@ class LoginScreen extends StatefulWidget { //TODO REFACTORING class _LoginScreenState extends State { - bool showPassword = true; + //Fields + bool showPassword = false; + String _email, _password; + AuthenticationService authenticationService = AuthenticationService(); + final GlobalKey _formKey = GlobalKey(); @override Widget build(BuildContext context) { SizeConfig().init(context); return SafeArea( child: Scaffold( - body: Column( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - Transform.scale( - scale: 1.15, - child: Transform.translate( - offset: Offset(0, -SizeConfig.safeBlockVertical * 7.5), - child: Container( - width: SizeConfig.safeBlockHorizontal * 100, - height: SizeConfig.safeBlockVertical * 40, - decoration: BoxDecoration( - image: DecorationImage( - image: AssetImage('assets/images/background_1.png'), - fit: BoxFit.cover), + body: SingleChildScrollView( + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Transform.scale( + scale: 1.15, + child: Transform.translate( + offset: Offset(0, -SizeConfig.safeBlockVertical * 7.5), + child: Container( + width: SizeConfig.safeBlockHorizontal * 100, + height: SizeConfig.safeBlockVertical * 40, + decoration: BoxDecoration( + image: DecorationImage( + image: AssetImage('assets/images/background_1.png'), + fit: BoxFit.cover), + ), + child: Stack( + children: [ + Positioned( + top: SizeConfig.safeBlockVertical * 12, + left: SizeConfig.safeBlockHorizontal * 30, + right: SizeConfig.safeBlockHorizontal * 30, + child: Column( + children: [ + SvgPicture.asset( + 'assets/images/carify_logo.svg', + // height: SizeConfig.safeBlockVertical * 12, + width: SizeConfig.safeBlockHorizontal * 40, + ), + Text( + 'Carify', //TODO Choose a font and add it into yaml file + Refactor the styles in the constant file + style: GoogleFonts.lemonada( + fontSize: + SizeConfig.safeBlockHorizontal * 7.5, + color: Colors.white, + fontWeight: FontWeight.w300), + ), + ], + ), + ), + Positioned( + top: SizeConfig.safeBlockVertical * 30, + left: SizeConfig.safeBlockHorizontal * 20, + right: SizeConfig.safeBlockHorizontal * 20, + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + 'DECIDE', + style: kSloganTextStyle, + ), + SizedBox( + width: 10.0, + ), + Text( + 'COMMIT', + style: kSloganTextStyle, + ), + SizedBox( + width: 10.0, + ), + Text( + 'SUCCEED', + style: kSloganTextStyle, + ), + ], + ), + ), + Positioned( + top: SizeConfig.safeBlockVertical * 35, + left: SizeConfig.safeBlockHorizontal * 35, + right: SizeConfig.safeBlockHorizontal * 35, + child: Center( + child: Text( + 'Login', + style: TextStyle( + fontSize: SizeConfig.safeBlockHorizontal * 8, + fontWeight: FontWeight.bold), + ), + ), + ), + ], + ), ), - child: Stack( + ), + ), + Container( + child: Form( + key: _formKey, + child: Column( children: [ - Positioned( - top: SizeConfig.safeBlockVertical * 10, - left: 50, - child: Icon( - Icons.chevron_left, - color: Colors.white, + Container( + width: SizeConfig.safeBlockHorizontal * 95, + height: SizeConfig.safeBlockVertical * 7, + decoration: kInputTextFieldDecoration, + child: InputFields( + hintText: 'Email', + prefixIcon: Icons.person_outline_sharp, + validatorFunction: (input) { + if (input.isEmpty) return 'Enter Email'; + }, + saveFunction: (input) => _email = input, ), ), - Positioned( - top: SizeConfig.safeBlockVertical * 12, - left: SizeConfig.safeBlockHorizontal * 30, - right: SizeConfig.safeBlockHorizontal * 30, - child: Column( - children: [ - SvgPicture.asset( - 'assets/images/carify_logo.svg', - // height: SizeConfig.safeBlockVertical * 12, - width: SizeConfig.safeBlockHorizontal * 40, - ), - Text( - 'Carify', //TODO Choose a font and add it into yaml file + Refactor the styles in the constant file - style: GoogleFonts.lemonada( - fontSize: - SizeConfig.safeBlockHorizontal * 7.5, - color: Colors.white, - fontWeight: FontWeight.w300), - ), - ], - ), + SizedBox( + height: SizeConfig.safeBlockVertical * 2, ), - Positioned( - top: SizeConfig.safeBlockVertical * 30, - left: SizeConfig.safeBlockHorizontal * 20, - right: SizeConfig.safeBlockHorizontal * 20, - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - 'DECIDE', - style: kSloganTextStyle, - ), - SizedBox( - width: 10.0, - ), - Text( - 'COMMIT', - style: kSloganTextStyle, - ), - SizedBox( - width: 10.0, - ), - Text( - 'SUCCEED', - style: kSloganTextStyle, - ), - ], + Container( + width: SizeConfig.safeBlockHorizontal * 95, + height: SizeConfig.safeBlockVertical * 7, + decoration: kInputTextFieldDecoration, + child: InputPasswordFields( + hintText: 'Password', + showPassword: !showPassword, + prefixIcon: Icons.lock_outline_sharp, + suffixIcon: showPassword + ? Icons.visibility + : Icons.visibility_off_rounded, + onPressed: () { + setState(() => showPassword = !showPassword); + }, + validatorFunction: (input) { + if (input.length < 6) + return 'Provide Minimum 6 Characters'; + }, + saveFunction: (input) => _password = input, ), ), - Positioned( - top: SizeConfig.safeBlockVertical * 35, - left: SizeConfig.safeBlockHorizontal * 35, - right: SizeConfig.safeBlockHorizontal * 35, - child: Center( - child: Text( - 'Login', - style: TextStyle( - fontSize: SizeConfig.safeBlockHorizontal * 8, - fontWeight: FontWeight.bold), - ), - ), + SizedBox( + height: SizeConfig.safeBlockVertical * 10, + ), + Container( + margin: EdgeInsets.symmetric( + horizontal: SizeConfig.safeBlockHorizontal * 7), + width: SizeConfig.safeBlockHorizontal * 95, + height: SizeConfig.safeBlockVertical * 7.5, + child: RoundedButton( + buttonText: 'Login', + fontSize: SizeConfig.safeBlockHorizontal * 5, + onPressed: () async { + if(_formKey.currentState.validate()){ + loading(context); + bool login = await authenticationService.signin(_email, _password); + if(login != null) { + Navigator.of(context).pop(); + if (!login) print( + 'email and password are wrong'); + } + } + // print(await authenticationService.user); + // final result = await authenticationService.signinAnonymously + // if(result != null ){ + // print("connected"); + // print(result); + // }else{ + // print("failure"); + // } + }), ), ], ), ), ), - ), - Container( - padding: EdgeInsets.symmetric(horizontal: 10.0), - width: SizeConfig.safeBlockHorizontal * 95, - height: SizeConfig.safeBlockVertical * 8, - child: InputFields( - hintText: 'Username', - prefixIcon: Icons.person_outline_sharp, + SizedBox( + height: SizeConfig.safeBlockVertical * 3, + ), + RichText( + text: TextSpan( + text: 'Want to create an account ? ', + style: TextStyle(color: kMidnightBlueCustom), + children: [ + TextSpan( + text: 'Sign Up', + style: kSignUpTextStyle, + recognizer: TapGestureRecognizer() + ..onTap = () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => RegisterScreen())); + }), + ]), ), - ), - SizedBox( - height: SizeConfig.safeBlockVertical * 2, - ), - Container( - padding: EdgeInsets.symmetric(horizontal: 10.0), - width: SizeConfig.safeBlockHorizontal * 95, - height: SizeConfig.safeBlockVertical * 8, - decoration: BoxDecoration(), - child: InputPasswordFields( - hintText: 'Password', - showPassword: !showPassword, - prefixIcon: Icons.lock_outline_sharp, - suffixIcon: showPassword - ? Icons.visibility - : Icons.visibility_off_rounded, - onPressed: () { - setState(() => showPassword = !showPassword); - }, + SizedBox( + height: SizeConfig.safeBlockVertical * 5, ), - ), - SizedBox( - height: SizeConfig.safeBlockVertical * 10, - ), - Container( - margin: EdgeInsets.symmetric( - horizontal: SizeConfig.safeBlockHorizontal * 7), - width: SizeConfig.safeBlockHorizontal * 95, - height: SizeConfig.safeBlockVertical * 7.5, - child: RawMaterialButton( - padding: EdgeInsets.only(left: 15.0, right: 15.0), - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(20.0)), - child: Text('Login'), - fillColor: kOrangeCustom, //TODO REFACTOR - textStyle: TextStyle( - color: Colors.white, - fontSize: SizeConfig.safeBlockHorizontal * 5, - fontWeight: FontWeight.bold, + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Container( + height: SizeConfig.safeBlockVertical * 0.15, + width: SizeConfig.safeBlockHorizontal * 40, + color: kMidnightBlueCustom, ), - onPressed: () {}), - ), - SizedBox( - height: SizeConfig.safeBlockVertical * 3, - ), - RichText( - text: TextSpan( - text: 'Want to create an account ? ', - style: TextStyle(color: kMidnightBlueCustom), - children: [ - TextSpan( - text: 'Sign Up', - style: kSignUpTextStyle, - recognizer: TapGestureRecognizer() - ..onTap = () { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => RegisterScreen())); - }), - ]), - ), - SizedBox( - height: SizeConfig.safeBlockVertical * 5, - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Container( - height: SizeConfig.safeBlockVertical * 0.15, - width: SizeConfig.safeBlockHorizontal * 40, - color: kMidnightBlueCustom, - ), - SvgPicture.asset( - 'assets/images/icon_clipboard.svg', - width: SizeConfig.safeBlockHorizontal * 15, - ), - Container( - height: SizeConfig.safeBlockVertical * 0.15, - width: SizeConfig.safeBlockHorizontal * 40, - color: kMidnightBlueCustom, - ), - ], - ), - ], + SvgPicture.asset( + 'assets/images/icon_clipboard.svg', + width: SizeConfig.safeBlockHorizontal * 15, + ), + Container( + height: SizeConfig.safeBlockVertical * 0.15, + width: SizeConfig.safeBlockHorizontal * 40, + color: kMidnightBlueCustom, + ), + ], + ), + ], + ), ), ), ); diff --git a/lib/screens/profile_screen.dart b/lib/screens/profile_screen.dart new file mode 100644 index 0000000..381a609 --- /dev/null +++ b/lib/screens/profile_screen.dart @@ -0,0 +1,51 @@ +import 'package:carify/screens/login_screen.dart'; +import 'package:carify/utilities/user_authentication.dart'; +import 'package:firebase_auth/firebase_auth.dart'; +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; + +class ProfileScreen extends StatefulWidget { + final User user; + ProfileScreen({this.user}); + + @override + _ProfileScreenState createState() => _ProfileScreenState(); +} + +class _ProfileScreenState extends State { + + User user; + AuthenticationService authenticationService = AuthenticationService(); + + Future getUser()async{ + final userResult = await authenticationService.user; + setState(() { + user = userResult; + }); + } + + + @override + Widget build(BuildContext context) { + getUser(); + return Scaffold( + body: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text('Welcome'), + if(user != null)Text('UID: ' + user.uid), + Container( + child: RaisedButton( + child: Text('bibi bye bye'), + onPressed: () { + authenticationService.signOut(); + setState(() {}); + }), + ), + ], + ), + ), + ); + } +} diff --git a/lib/screens/register_screen.dart b/lib/screens/register_screen.dart index d5b3dd9..73dd350 100644 --- a/lib/screens/register_screen.dart +++ b/lib/screens/register_screen.dart @@ -1,12 +1,252 @@ +import 'package:carify/utilities/constants.dart'; +import 'package:carify/utilities/extracted_widget.dart'; +import 'package:carify/utilities/size_config.dart'; +import 'package:cloud_firestore/cloud_firestore.dart'; +import 'package:firebase_auth/firebase_auth.dart'; +import 'package:firebase_core/firebase_core.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:google_fonts/google_fonts.dart'; +import 'package:carify/utilities/user_authentication.dart'; +import 'package:carify/screens/profile_screen.dart'; +import 'package:provider/provider.dart'; + +class RegisterScreen extends StatefulWidget { + @override + _RegisterScreenState createState() => _RegisterScreenState(); +} + +class _RegisterScreenState extends State { + //Fields + bool showPassword = false; + String _email, _password; + AuthenticationService authenticationService = AuthenticationService(); + final GlobalKey _formKey = GlobalKey(); -//TODO REGISTER SCREEN -class RegisterScreen extends StatelessWidget { @override Widget build(BuildContext context) { - return Scaffold( - body: Center( - child: Text('Register'), - )); + SizeConfig().init(context); + return SafeArea( + child: Scaffold( + body: Column(children: [ + Transform.scale( + scale: 1.15, + child: Transform.translate( + offset: Offset(0, -SizeConfig.safeBlockVertical * 7.5), + child: Container( + width: SizeConfig.safeBlockHorizontal * 100, + height: SizeConfig.safeBlockVertical * 40, + decoration: BoxDecoration( + image: DecorationImage( + image: AssetImage('assets/images/background_1.png'), + fit: BoxFit.cover), + ), + child: Stack( + children: [ + Positioned( + top: SizeConfig.safeBlockVertical * 10, + left: 50, + child: GestureDetector( + onTap: () { + Navigator.pop(context); + }, + child: Icon( + Icons.chevron_left, + color: Colors.white, + ), + ), + ), + Positioned( + top: SizeConfig.safeBlockVertical * 12, + left: SizeConfig.safeBlockHorizontal * 30, + right: SizeConfig.safeBlockHorizontal * 30, + child: Column( + children: [ + SvgPicture.asset( + 'assets/images/carify_logo.svg', + // height: SizeConfig.safeBlockVertical * 12, + width: SizeConfig.safeBlockHorizontal * 40, + ), + Text( + 'Carify', //TODO Choose a font and add it into yaml file + Refactor the styles in the constant file + style: GoogleFonts.lemonada( + fontSize: SizeConfig.safeBlockHorizontal * 7.5, + color: Colors.white, + fontWeight: FontWeight.w300), + ), + ], + ), + ), + Positioned( + top: SizeConfig.safeBlockVertical * 30, + left: SizeConfig.safeBlockHorizontal * 20, + right: SizeConfig.safeBlockHorizontal * 20, + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + 'DECIDE', + style: kSloganTextStyle, + ), + SizedBox( + width: 10.0, + ), + Text( + 'COMMIT', + style: kSloganTextStyle, + ), + SizedBox( + width: 10.0, + ), + Text( + 'SUCCEED', + style: kSloganTextStyle, + ), + ], + ), + ), + SizedBox( + height: 10.0, + ), + Positioned( + top: SizeConfig.safeBlockVertical * 35, + left: SizeConfig.safeBlockHorizontal * 35, + right: SizeConfig.safeBlockHorizontal * 35, + child: Center( + child: Text( + 'Register', + style: TextStyle( + fontSize: SizeConfig.safeBlockHorizontal * 7, + fontWeight: FontWeight.bold), + ), + ), + ), + ], + ), + ), + ), + ), + Container( + child: Form( + key: _formKey, + child: Container( + width: SizeConfig.safeBlockHorizontal * 95, + height: SizeConfig.safeBlockVertical * 7, + decoration: kInputTextFieldDecoration, + child: InputFields( + hintText: 'Email Address', + prefixIcon: Icons.person_outline_sharp, + validatorFunction: (input) { + if (input.isEmpty) return 'Enter Email'; + }, + saveFunction: (input) => _email = input, + ), + ), + ), + ), + SizedBox( + height: SizeConfig.safeBlockVertical * 2, + ), + Container( + width: SizeConfig.safeBlockHorizontal * 95, + height: SizeConfig.safeBlockVertical * 7, + decoration: kInputTextFieldDecoration, + child: InputPasswordFields( + hintText: 'Password', + showPassword: !showPassword, + prefixIcon: Icons.lock_outline_sharp, + suffixIcon: showPassword + ? Icons.visibility + : Icons.visibility_off_rounded, + onPressed: () { + setState(() => showPassword = !showPassword); + }, + validatorFunction: (input) { + if (input.length < 6) return 'Provide Minimum 6 Characters'; + }, + saveFunction: (input) => _password = input, + ), + ), + SizedBox( + height: SizeConfig.safeBlockVertical * 5, + ), + OutlineButton( + splashColor: kMidnightBlueCustom, + onPressed: () async { + authenticationService.googleSignIn(); + Navigator.of(context).pop(); + }, + shape: + RoundedRectangleBorder(borderRadius: BorderRadius.circular(40)), + highlightElevation: 0, + borderSide: BorderSide(color: kMidnightBlueCustom), + child: Padding( + padding: const EdgeInsets.fromLTRB(0, 10, 0, 10), + child: Row( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Image( + image: AssetImage("assets/images/google_logo.png"), + height: 35.0), + Padding( + padding: const EdgeInsets.only(left: 10), + child: Text( + 'Sign in with Google', + style: TextStyle( + fontSize: 20, + color: kMidnightBlueCustom, + ), + ), + ) + ], + ), + ), + ), + SizedBox( + height: SizeConfig.safeBlockVertical * 5, + ), + Container( + margin: EdgeInsets.symmetric( + horizontal: SizeConfig.safeBlockHorizontal * 7), + width: SizeConfig.safeBlockHorizontal * 95, + height: SizeConfig.safeBlockVertical * 7.5, + child: RoundedButton( + buttonText: 'Next', + fontSize: SizeConfig.safeBlockHorizontal * 5, + onPressed: () async { + if (_formKey.currentState.validate()) { + bool register = await authenticationService.signup(_email, _password); + if(register) Navigator.of(context).pop(); + } else { + print('not validated'); + } + }), + ), + SizedBox( + height: SizeConfig.safeBlockVertical * 5, + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Container( + height: SizeConfig.safeBlockVertical * 0.15, + width: SizeConfig.safeBlockHorizontal * 40, + color: kMidnightBlueCustom, + ), + SvgPicture.asset( + 'assets/images/icon_clipboard.svg', + width: SizeConfig.safeBlockHorizontal * 15, + ), + Container( + height: SizeConfig.safeBlockVertical * 0.15, + width: SizeConfig.safeBlockHorizontal * 40, + color: kMidnightBlueCustom, + ), + ], + ), + ]), + ), + ); } } diff --git a/lib/screens/splash_screen.dart b/lib/screens/splash_screen.dart index ed42496..7bdd62a 100644 --- a/lib/screens/splash_screen.dart +++ b/lib/screens/splash_screen.dart @@ -1,10 +1,16 @@ +import 'dart:async'; + import 'package:carify/screens/login_screen.dart'; +import 'package:carify/screens/profile_screen.dart'; +import 'package:carify/screens/statusAuth.dart'; +import 'package:carify/utilities/user_authentication.dart'; +import 'package:firebase_auth/firebase_auth.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:google_fonts/google_fonts.dart'; import 'package:carify/utilities/constants.dart'; -import 'dart:async'; +import 'package:provider/provider.dart'; class SplashScreen extends StatefulWidget { @override @@ -12,16 +18,27 @@ class SplashScreen extends StatefulWidget { } class _SplashScreenState extends State { + // final FirebaseAuth _auth = FirebaseAuth.instance; + // User user; @override void initState() { - Timer( - Duration(seconds: 3), - () => Navigator.pushReplacement( - context, MaterialPageRoute(builder: (context) => LoginScreen()))); - + displaySplash(); super.initState(); } + displaySplash() { + Timer(Duration(seconds: 3), () { + Navigator.pushReplacement(context, MaterialPageRoute(builder: (context) => Status())); + // if (_auth.currentUser != null) { + // Navigator.pushReplacement( + // context, MaterialPageRoute(builder: (context) => ProfileScreen())); + // } else { + // Navigator.pushReplacement( + // context, MaterialPageRoute(builder: (context) => LoginScreen())); + // } + }); + } + @override Widget build(BuildContext context) { return Scaffold( @@ -48,12 +65,6 @@ class _SplashScreenState extends State { color: Colors.white, fontWeight: FontWeight.w300), ), - // Divider( - // indent: 100.0, - // endIndent: 100.0, - // color: Colors.white60, - // thickness: 1.0, - // ), Row( mainAxisAlignment: MainAxisAlignment.center, children: [ diff --git a/lib/screens/statusAuth.dart b/lib/screens/statusAuth.dart new file mode 100644 index 0000000..f7720f4 --- /dev/null +++ b/lib/screens/statusAuth.dart @@ -0,0 +1,30 @@ +import 'package:carify/screens/login_screen.dart'; +import 'package:carify/screens/profile_screen.dart'; +import 'package:carify/utilities/user_authentication.dart'; +import 'package:flutter/material.dart'; +import 'package:firebase_auth/firebase_auth.dart'; + +class Status extends StatefulWidget { + @override + _StatusState createState() => _StatusState(); +} + +class _StatusState extends State { + + User user; + AuthenticationService authenticationService = AuthenticationService(); + + Future getUser()async{ + final userResult = await authenticationService.user; + setState(() { + user = userResult; + }); + } + + + @override + Widget build(BuildContext context) { + getUser(); + return user == null? LoginScreen():ProfileScreen(); + } +} diff --git a/lib/utilities/constants.dart b/lib/utilities/constants.dart index 92028fa..a033d19 100644 --- a/lib/utilities/constants.dart +++ b/lib/utilities/constants.dart @@ -34,7 +34,21 @@ const kInputTextDecoration = InputDecoration( borderSide: BorderSide(color: kMidnightBlueCustom, width: 2.5), ), enabledBorder: OutlineInputBorder( - borderSide: BorderSide(color: kDarkBlueCustom, width: 1.0), - borderRadius: BorderRadius.all(Radius.circular(32.0)), + borderSide: BorderSide(color: kDarkBlueCustom, width: 1.5), + borderRadius: BorderRadius.all(Radius.circular(25.0)), ), ); + +//Container Decorations +var kInputTextFieldDecoration = BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(25.0)), + color: Colors.white, + boxShadow: [ + BoxShadow( + color: Colors.grey.withOpacity(0.5), + spreadRadius: 2, + blurRadius: 3, + offset: Offset(0, 2), + ), + ], +); diff --git a/lib/utilities/extracted_widget.dart b/lib/utilities/extracted_widget.dart index 1893295..58198c0 100644 --- a/lib/utilities/extracted_widget.dart +++ b/lib/utilities/extracted_widget.dart @@ -1,24 +1,59 @@ import 'package:flutter/material.dart'; import 'package:carify/utilities/constants.dart'; -//TODO Extract the necessary widgets +//Input Field +class InputFields extends StatelessWidget { + final String hintText; + final IconData prefixIcon; + final Function validatorFunction; + final Function saveFunction; + + InputFields( + {@required this.hintText, + @required this.prefixIcon, + this.validatorFunction, + this.saveFunction}); + + @override + Widget build(BuildContext context) { + return TextFormField( + onChanged: saveFunction, + validator: validatorFunction, + showCursor: false, + decoration: kInputTextDecoration.copyWith( + hintText: hintText, + prefixIcon: Icon( + prefixIcon, + color: kDarkBlueCustom, + ), + )); + } +} + +//Input Password Field class InputPasswordFields extends StatelessWidget { final bool showPassword; final String hintText; final IconData prefixIcon; final IconData suffixIcon; final Function onPressed; + final Function validatorFunction; + final Function saveFunction; InputPasswordFields( {@required this.showPassword, @required this.hintText, @required this.prefixIcon, this.suffixIcon, - this.onPressed}); + this.onPressed, + this.validatorFunction, + this.saveFunction}); @override Widget build(BuildContext context) { - return TextField( + return TextFormField( + onChanged: saveFunction, + validator: validatorFunction, showCursor: false, obscureText: showPassword, decoration: kInputTextDecoration.copyWith( @@ -34,26 +69,31 @@ class InputPasswordFields extends StatelessWidget { )); } } +//Rounded Button -class InputFields extends StatelessWidget { - final String hintText; - final IconData prefixIcon; +class RoundedButton extends StatelessWidget { + final String buttonText; + final double fontSize; + final Function onPressed; - InputFields({ - @required this.hintText, - @required this.prefixIcon, - }); + RoundedButton( + {@required this.buttonText, + @required this.fontSize, + @required this.onPressed}); @override Widget build(BuildContext context) { - return TextField( - showCursor: false, - decoration: kInputTextDecoration.copyWith( - hintText: hintText, - prefixIcon: Icon( - prefixIcon, - color: kDarkBlueCustom, - ), - )); + return RawMaterialButton( + padding: EdgeInsets.only(left: 15.0, right: 15.0), + shape: + RoundedRectangleBorder(borderRadius: BorderRadius.circular(32.0)), + child: Text(buttonText), + fillColor: kOrangeCustom, + textStyle: TextStyle( + color: Colors.white, + fontSize: fontSize, + fontWeight: FontWeight.bold, + ), + onPressed: onPressed); } } diff --git a/lib/utilities/loading.dart b/lib/utilities/loading.dart new file mode 100644 index 0000000..50fba6f --- /dev/null +++ b/lib/utilities/loading.dart @@ -0,0 +1,14 @@ +import 'package:flutter/material.dart'; + +loading(context) => showDialog( + context: context, + barrierDismissible: false, + builder: (ctx) => Center( + child: Container( + width: 30, + height: 30, + child: CircularProgressIndicator( + valueColor: AlwaysStoppedAnimation(Colors.white), + ), + ), + )); diff --git a/lib/utilities/user_authentication.dart b/lib/utilities/user_authentication.dart new file mode 100644 index 0000000..bea9a03 --- /dev/null +++ b/lib/utilities/user_authentication.dart @@ -0,0 +1,115 @@ +import 'package:firebase_auth/firebase_auth.dart'; +import 'package:google_sign_in/google_sign_in.dart'; + +class AuthenticationService { + //Fields + final FirebaseAuth auth = FirebaseAuth.instance; + + Future siginAnonymous() async { + try{ + final result = await auth.signInAnonymously(); + return result.user; + }catch(e){ + print(e); + return null; + } + } + + Future get user async{ + final user = FirebaseAuth.instance.currentUser; + return user; + } + + Future signup(String email, String pass) async { + try{ + final result = await auth.createUserWithEmailAndPassword(email: email, password: pass); + if(result.user != null) return true; + return false; + }catch(e){ + return false; + } + } + + Future signin(String email, String pass) async { + try{ + final result = await auth.signInWithEmailAndPassword(email: email, password: pass); + if(result.user != null) return true; + return false; + }catch(e){ + return false; + } + } + + Future googleSignIn() async{ + GoogleSignInAccount signInAccount = await GoogleSignIn().signIn(); + GoogleSignInAuthentication authentication = await signInAccount.authentication; + AuthCredential authCredential = GoogleAuthProvider.credential( + idToken: authentication.idToken, + accessToken: authentication.accessToken, + ); + await auth.signInWithCredential(authCredential); + } + + + Future signOut() async { + try{ + return auth.signOut(); + }catch(e){ + return null; + } + } + +//Google Sign in Method +// Future googleSignIn() async { +// final GoogleSignInAccount googleSignInAccount = +// await googleSignInstance.signIn(); +// +// final GoogleSignInAuthentication googleSignInAuthentication = +// await googleSignInAccount.authentication; +// +// final GoogleAuthCredential credential = GoogleAuthProvider.credential( +// idToken: googleSignInAuthentication.idToken, +// accessToken: googleSignInAuthentication.accessToken); +// +// return await _auth.signInWithCredential(credential); +// } + +//Function SignUp with email +// Future signUp({String email, String password}) async { +// UserCredential userCredential; +// try { +// userCredential = await _auth.createUserWithEmailAndPassword( +// email: email, password: password); +// } on FirebaseAuthException catch (e) { +// if (e.code == 'email-already-in-use') +// print('the account already exists for the email.'); +// } catch (e) { +// print(e); +// } +// return Future.value(userCredential); +// } + + // Future login({String email, String password}) async { + // UserCredential userCredential; + // try { + // userCredential = await _auth.signInWithEmailAndPassword( + // email: email, password: password); + // } on FirebaseAuthException catch (e) { + // if (e.code == 'user-not-found') { + // print('No user found for that email.'); + // } else if (e.code == 'wrong-password') { + // print('Wrong password provided for that user.'); + // } + // } + // return Future.value(userCredential); + // } + + // Sign Out +// Future signOutUser() async { +// User user = _auth.currentUser; +// if (user.providerData[1].providerId == 'google.com') { +// await googleSignInstance.disconnect(); +// } +// await _auth.signOut(); +// } +} diff --git a/pubspec.lock b/pubspec.lock index dd676a1..3e72f20 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1,6 +1,20 @@ # Generated by pub # See https://dart.dev/tools/pub/glossary#lockfile packages: + archive: + dependency: transitive + description: + name: archive + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.13" + args: + dependency: transitive + description: + name: args + url: "https://pub.dartlang.org" + source: hosted + version: "1.6.0" async: dependency: transitive description: @@ -36,6 +50,27 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.1.0-nullsafety.1" + cloud_firestore: + dependency: "direct main" + description: + name: cloud_firestore + url: "https://pub.dartlang.org" + source: hosted + version: "0.14.4" + cloud_firestore_platform_interface: + dependency: transitive + description: + name: cloud_firestore_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "2.2.1" + cloud_firestore_web: + dependency: transitive + description: + name: cloud_firestore_web + url: "https://pub.dartlang.org" + source: hosted + version: "0.2.1+2" collection: dependency: transitive description: @@ -85,6 +120,48 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "5.2.1" + firebase_auth: + dependency: "direct main" + description: + name: firebase_auth + url: "https://pub.dartlang.org" + source: hosted + version: "0.18.4" + firebase_auth_platform_interface: + dependency: transitive + description: + name: firebase_auth_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.4" + firebase_auth_web: + dependency: transitive + description: + name: firebase_auth_web + url: "https://pub.dartlang.org" + source: hosted + version: "0.3.2+2" + firebase_core: + dependency: "direct main" + description: + name: firebase_core + url: "https://pub.dartlang.org" + source: hosted + version: "0.5.3" + firebase_core_platform_interface: + dependency: transitive + description: + name: firebase_core_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" + firebase_core_web: + dependency: transitive + description: + name: firebase_core_web + url: "https://pub.dartlang.org" + source: hosted + version: "0.2.1+1" flutter: dependency: "direct main" description: flutter @@ -102,6 +179,11 @@ packages: description: flutter source: sdk version: "0.0.0" + flutter_web_plugins: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" google_fonts: dependency: "direct main" description: @@ -109,6 +191,27 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.1.1" + google_sign_in: + dependency: "direct main" + description: + name: google_sign_in + url: "https://pub.dartlang.org" + source: hosted + version: "4.5.6" + google_sign_in_platform_interface: + dependency: transitive + description: + name: google_sign_in_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.2" + google_sign_in_web: + dependency: transitive + description: + name: google_sign_in_web + url: "https://pub.dartlang.org" + source: hosted + version: "0.9.2" http: dependency: transitive description: @@ -130,6 +233,27 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.16.1" + js: + dependency: transitive + description: + name: js + url: "https://pub.dartlang.org" + source: hosted + version: "0.6.2" + logging: + dependency: transitive + description: + name: logging + url: "https://pub.dartlang.org" + source: hosted + version: "0.11.4" + lottie: + dependency: "direct main" + description: + name: lottie + url: "https://pub.dartlang.org" + source: hosted + version: "0.7.0+1" matcher: dependency: transitive description: @@ -144,6 +268,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.3.0-nullsafety.3" + nested: + dependency: transitive + description: + name: nested + url: "https://pub.dartlang.org" + source: hosted + version: "0.0.4" path: dependency: transitive description: @@ -235,6 +366,20 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "3.0.13" + provider: + dependency: "direct main" + description: + name: provider + url: "https://pub.dartlang.org" + source: hosted + version: "4.3.2+3" + quiver: + dependency: transitive + description: + name: quiver + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.5" sky_engine: dependency: transitive description: flutter diff --git a/pubspec.yaml b/pubspec.yaml index d7eb34e..f67065a 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -26,6 +26,12 @@ dependencies: cupertino_icons: ^1.0.0 google_fonts: ^1.1.1 flutter_svg: ^0.19.0 + firebase_core: ^0.5.3 + firebase_auth: ^0.18.4 + cloud_firestore: ^0.14.4 + google_sign_in: ^4.5.6 + provider: ^4.3.2+3 + lottie: ^0.7.0+1 dev_dependencies: flutter_test: diff --git a/test/widget_test.dart b/test/widget_test.dart index f8b742b..543b0a3 100644 --- a/test/widget_test.dart +++ b/test/widget_test.dart @@ -13,7 +13,7 @@ import 'package:carify/main.dart'; void main() { testWidgets('Counter increments smoke test', (WidgetTester tester) async { // Build our app and trigger a frame. - await tester.pumpWidget(MaterialApp()); + await tester.pumpWidget(MyApp()); // Verify that our counter starts at 0. expect(find.text('0'), findsOneWidget);