From 44c38bbdb7c34983627725df756873f4e2955785 Mon Sep 17 00:00:00 2001 From: RemRem Date: Tue, 21 Nov 2023 15:44:09 +0100 Subject: [PATCH 1/6] :pencil2: add const + fix typo --- lib/view/profile/web/web_profile_view.dart | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/lib/view/profile/web/web_profile_view.dart b/lib/view/profile/web/web_profile_view.dart index 7da5b1d..f16e4b8 100644 --- a/lib/view/profile/web/web_profile_view.dart +++ b/lib/view/profile/web/web_profile_view.dart @@ -206,14 +206,16 @@ class _WebProfileView extends State { Navigator.push( context, MaterialPageRoute( - builder: (context) => ChangeUsernameView(), + builder: (context) => + const ChangeUsernameView(), ), ); } else if (iObj["tag"] == "2") { Navigator.push( context, MaterialPageRoute( - builder: (context) => ChangePasswordView(), + builder: (context) => + const ChangePasswordView(), ), ); } else { @@ -264,7 +266,7 @@ class _WebProfileView extends State { ), Expanded( child: Text( - "Pop-up Notification", + "Push Notifications", style: TextStyle( color: TColor.black, fontSize: 12, @@ -273,9 +275,9 @@ class _WebProfileView extends State { ), CustomAnimatedToggleSwitch( current: positive, - values: [false, true], + values: const [false, true], spacing: 0.0, - indicatorSize: Size.square(25.0), + indicatorSize: const Size.square(25.0), animationDuration: const Duration(milliseconds: 200), animationCurve: Curves.linear, @@ -283,7 +285,7 @@ class _WebProfileView extends State { iconBuilder: (context, local, global) { return const SizedBox(); }, - cursors: ToggleCursors( + cursors: const ToggleCursors( defaultCursor: SystemMouseCursors.click), onTap: (_) => setState(() => positive = !positive), From 2aa6c43f5dbcf6278d847ff2df3d92d54c21a06e Mon Sep 17 00:00:00 2001 From: RemRem Date: Tue, 21 Nov 2023 16:15:33 +0100 Subject: [PATCH 2/6] :coffin: remove useless SingleChidScrollView on login and signup --- lib/view/login/mobile/android_login_view.dart | 389 ++++++++-------- .../login/mobile/android_signup_view.dart | 419 +++++++++--------- lib/view/login/web/web_login_view.dart | 262 ++++++----- lib/view/login/web/web_signup_view.dart | 285 ++++++------ 4 files changed, 670 insertions(+), 685 deletions(-) diff --git a/lib/view/login/mobile/android_login_view.dart b/lib/view/login/mobile/android_login_view.dart index 0d825f4..39b5da0 100644 --- a/lib/view/login/mobile/android_login_view.dart +++ b/lib/view/login/mobile/android_login_view.dart @@ -72,217 +72,214 @@ class _MobileLoginView extends State { var media = MediaQuery.of(context).size; return Scaffold( backgroundColor: TColor.white, - body: SingleChildScrollView( - child: SafeArea( - child: Container( - height: media.height * 0.9, - padding: const EdgeInsets.symmetric(horizontal: 20), - child: Column( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Text( - "Bienvenue", - style: TextStyle(color: TColor.gray, fontSize: 16), - ), - Text( - "Se connecter", - style: TextStyle( - color: TColor.black, - fontSize: 20, - fontWeight: FontWeight.w700), - ), - SizedBox( - height: media.width * 0.05, - ), - SizedBox( - height: media.width * 0.04, - ), - RoundTextField( - hitText: "Email", - icon: "assets/img/email.svg", - keyboardType: TextInputType.emailAddress, - controller: controllerTextEmail, - ), - SizedBox( - height: media.width * 0.04, - ), - RoundTextField( - controller: controllerTextPassword, - hitText: "Mot de passe", - icon: "assets/img/lock.svg", - obscureText: _obscureText, - rigtIcon: TextButton( - onPressed: _toggle, - child: Container( - alignment: Alignment.center, + body: SafeArea( + child: Container( + height: media.height * 0.9, + padding: const EdgeInsets.symmetric(horizontal: 20), + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Text( + "Bienvenue", + style: TextStyle(color: TColor.gray, fontSize: 16), + ), + Text( + "Se connecter", + style: TextStyle( + color: TColor.black, + fontSize: 20, + fontWeight: FontWeight.w700), + ), + SizedBox( + height: media.width * 0.05, + ), + SizedBox( + height: media.width * 0.04, + ), + RoundTextField( + hitText: "Email", + icon: "assets/img/email.svg", + keyboardType: TextInputType.emailAddress, + controller: controllerTextEmail, + ), + SizedBox( + height: media.width * 0.04, + ), + RoundTextField( + controller: controllerTextPassword, + hitText: "Mot de passe", + icon: "assets/img/lock.svg", + obscureText: _obscureText, + rigtIcon: TextButton( + onPressed: _toggle, + child: Container( + alignment: Alignment.center, + width: 20, + height: 20, + child: SvgPicture.asset( + "assets/img/show_password.svg", width: 20, height: 20, - child: SvgPicture.asset( - "assets/img/show_password.svg", - width: 20, - height: 20, - fit: BoxFit.contain, - ))), - ), - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - "Mot de passe oublié ?", - style: TextStyle( - color: TColor.gray, - fontSize: 15, - decoration: TextDecoration.underline), - ), - ], - ), - SizedBox( - height: media.width * 0.04, - ), - Visibility( - visible: _errorLogin, - child: Text("Error - $_msgError", - style: TextStyle(color: TColor.red))), - const Spacer(), - RoundButton( - title: "Se connecter", - onPressed: () async { - if (!emailValidate || !passwordValidate) { - _printMsgError( - "Les champs renseigné ne sont pas valide"); - return; - } - Tuple2 result = - await util.checkLoginAndPassword( - controllerTextEmail.text, - controllerTextPassword.text); - - if (result.item1 == true) { - Tuple2 infoUser = await util.getUserInfo(result.item2); + fit: BoxFit.contain, + ))), + ), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + "Mot de passe oublié ?", + style: TextStyle( + color: TColor.gray, + fontSize: 15, + decoration: TextDecoration.underline), + ), + ], + ), + SizedBox( + height: media.width * 0.04, + ), + Visibility( + visible: _errorLogin, + child: Text("Error - $_msgError", + style: TextStyle(color: TColor.red))), + const Spacer(), + RoundButton( + title: "Se connecter", + onPressed: () async { + if (!emailValidate || !passwordValidate) { + _printMsgError("Les champs renseigné ne sont pas valide"); + return; + } + Tuple2 result = + await util.checkLoginAndPassword( + controllerTextEmail.text, + controllerTextPassword.text); - if (infoUser.item1 == false) { - //print("Erreur - Impossible de récupéré les données de l'utilisateur"); - _printMsgError( - "Impossible de récupéré les données de l'utilisateur - {$infoUser.item2}"); - } else { - util.fillUser(context, infoUser.item2, result.item2); + if (result.item1 == true) { + Tuple2 infoUser = await util.getUserInfo(result.item2); - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => const MainTabView())); - } + if (infoUser.item1 == false) { + //print("Erreur - Impossible de récupéré les données de l'utilisateur"); + _printMsgError( + "Impossible de récupéré les données de l'utilisateur - {$infoUser.item2}"); } else { - _printMsgError("Connexion refuser - ${result.item2}"); + util.fillUser(context, infoUser.item2, result.item2); + + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => const MainTabView())); } - }), - SizedBox( - height: media.width * 0.04, - ), - Row( - // crossAxisAlignment: CrossAxisAlignment., - children: [ - Expanded( - child: Container( - height: 1, - color: TColor.gray.withOpacity(0.5), - )), - Text( - " Or ", - style: TextStyle(color: TColor.black, fontSize: 12), - ), - Expanded( - child: Container( - height: 1, - color: TColor.gray.withOpacity(0.5), - )), - ], - ), - SizedBox( - height: media.width * 0.04, - ), - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - GestureDetector( - onTap: () {}, + } else { + _printMsgError("Connexion refuser - ${result.item2}"); + } + }), + SizedBox( + height: media.width * 0.04, + ), + Row( + // crossAxisAlignment: CrossAxisAlignment., + children: [ + Expanded( child: Container( - width: 50, - height: 50, - alignment: Alignment.center, - decoration: BoxDecoration( - color: TColor.white, - border: Border.all( - width: 1, - color: TColor.gray.withOpacity(0.4), - ), - borderRadius: BorderRadius.circular(15), - ), - child: Image.asset( - "assets/img/google.png", - width: 20, - height: 20, + height: 1, + color: TColor.gray.withOpacity(0.5), + )), + Text( + " Or ", + style: TextStyle(color: TColor.black, fontSize: 12), + ), + Expanded( + child: Container( + height: 1, + color: TColor.gray.withOpacity(0.5), + )), + ], + ), + SizedBox( + height: media.width * 0.04, + ), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + GestureDetector( + onTap: () {}, + child: Container( + width: 50, + height: 50, + alignment: Alignment.center, + decoration: BoxDecoration( + color: TColor.white, + border: Border.all( + width: 1, + color: TColor.gray.withOpacity(0.4), ), + borderRadius: BorderRadius.circular(15), + ), + child: Image.asset( + "assets/img/google.png", + width: 20, + height: 20, ), ), - SizedBox( - width: media.width * 0.04, - ), - GestureDetector( - onTap: () {}, - child: Container( - width: 50, - height: 50, - alignment: Alignment.center, - decoration: BoxDecoration( - color: TColor.white, - border: Border.all( - width: 1, - color: TColor.gray.withOpacity(0.4), - ), - borderRadius: BorderRadius.circular(15), - ), - child: Image.asset( - "assets/img/suunto.png", - width: 35, - height: 35, + ), + SizedBox( + width: media.width * 0.04, + ), + GestureDetector( + onTap: () {}, + child: Container( + width: 50, + height: 50, + alignment: Alignment.center, + decoration: BoxDecoration( + color: TColor.white, + border: Border.all( + width: 1, + color: TColor.gray.withOpacity(0.4), ), + borderRadius: BorderRadius.circular(15), ), - ) - ], - ), - SizedBox( - height: media.width * 0.04, - ), - TextButton( - onPressed: () { - Navigator.pop(context); - }, - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Text( - "Vous n'avez pas toujours pas de compte ? ", - style: TextStyle( + child: Image.asset( + "assets/img/suunto.png", + width: 35, + height: 35, + ), + ), + ) + ], + ), + SizedBox( + height: media.width * 0.04, + ), + TextButton( + onPressed: () { + Navigator.pop(context); + }, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Text( + "Vous n'avez pas toujours pas de compte ? ", + style: TextStyle( + color: TColor.black, + fontSize: 14, + ), + ), + Text( + "Créer un compte", + style: TextStyle( color: TColor.black, fontSize: 14, - ), - ), - Text( - "Créer un compte", - style: TextStyle( - color: TColor.black, - fontSize: 14, - fontWeight: FontWeight.w700), - ) - ], - ), - ), - SizedBox( - height: media.width * 0.04, + fontWeight: FontWeight.w700), + ) + ], ), - ], - ), + ), + SizedBox( + height: media.width * 0.04, + ), + ], ), ), ), diff --git a/lib/view/login/mobile/android_signup_view.dart b/lib/view/login/mobile/android_signup_view.dart index 094a5f6..a62a9db 100644 --- a/lib/view/login/mobile/android_signup_view.dart +++ b/lib/view/login/mobile/android_signup_view.dart @@ -91,230 +91,227 @@ class _MobileSignUpView extends State { var media = MediaQuery.of(context).size; return Scaffold( backgroundColor: TColor.white, - body: SingleChildScrollView( - child: SafeArea( - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 20), - child: Column( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Text( - "Bienvenue,", - style: TextStyle(color: TColor.gray, fontSize: 16), - ), - Text( - "Créer un compte", - style: TextStyle( - color: TColor.black, - fontSize: 20, - fontWeight: FontWeight.w700), - ), - SizedBox( - height: media.width * 0.05, - ), - RoundTextField( - hitText: "Prénom", - icon: "assets/img/user_text.svg", - controller: controllerUsername, - ), - SizedBox( - height: media.width * 0.04, - ), - RoundTextField( - hitText: "Email", - icon: "assets/img/email.svg", - keyboardType: TextInputType.emailAddress, - controller: controllerTextEmail, - ), - SizedBox( - height: media.width * 0.04, - ), - RoundTextField( - hitText: "Mot de passe", - icon: "assets/img/lock.svg", - obscureText: _obscureText, - controller: controllerTextPassword, - rigtIcon: TextButton( - onPressed: _toggle, - child: Container( - alignment: Alignment.center, + body: SafeArea( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 20), + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Text( + "Bienvenue,", + style: TextStyle(color: TColor.gray, fontSize: 16), + ), + Text( + "Créer un compte", + style: TextStyle( + color: TColor.black, + fontSize: 20, + fontWeight: FontWeight.w700), + ), + SizedBox( + height: media.width * 0.05, + ), + RoundTextField( + hitText: "Prénom", + icon: "assets/img/user_text.svg", + controller: controllerUsername, + ), + SizedBox( + height: media.width * 0.04, + ), + RoundTextField( + hitText: "Email", + icon: "assets/img/email.svg", + keyboardType: TextInputType.emailAddress, + controller: controllerTextEmail, + ), + SizedBox( + height: media.width * 0.04, + ), + RoundTextField( + hitText: "Mot de passe", + icon: "assets/img/lock.svg", + obscureText: _obscureText, + controller: controllerTextPassword, + rigtIcon: TextButton( + onPressed: _toggle, + child: Container( + alignment: Alignment.center, + width: 20, + height: 20, + child: SvgPicture.asset( + "assets/img/show_password.svg", width: 20, height: 20, - child: SvgPicture.asset( - "assets/img/show_password.svg", - width: 20, - height: 20, - fit: BoxFit.contain, - ))), - ), - Row( - // crossAxisAlignment: CrossAxisAlignment., - children: [ - IconButton( - onPressed: () { - _check(); - }, - icon: Icon( - _isCheck - ? Icons.check_box_outlined - : Icons.check_box_outline_blank_outlined, - color: TColor.gray, - size: 20, - ), + fit: BoxFit.contain, + ))), + ), + Row( + // crossAxisAlignment: CrossAxisAlignment., + children: [ + IconButton( + onPressed: () { + _check(); + }, + icon: Icon( + _isCheck + ? Icons.check_box_outlined + : Icons.check_box_outline_blank_outlined, + color: TColor.gray, + size: 20, ), - Padding( - padding: const EdgeInsets.only(top: 8), - child: Text( - "En continuant, vous acceptez notre Politique de\nconfidentialité et nos Conditions d'utilisation.", - style: TextStyle(color: TColor.gray, fontSize: 10), - ), - ) - ], - ), - SizedBox( - height: media.width * 0.05, - ), - Visibility( - visible: _errorCreateUser, - child: Text("Error - $_msgError", - style: TextStyle(color: TColor.red))), - SizedBox( - height: media.width * 0.4, - ), - RoundButton( - title: "Créer un compte", - onPressed: () async { - if (!emailValidate || - !passwordValidate || - !usernameValidate) { - _printMsgError( - "Les champs renseigné ne sont pas valide"); - return; - } - - Tuple2 result = await util.createUser( - controllerTextEmail.text, - controllerUsername.text, - controllerTextPassword.text); - if (result.item1) { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => const LoginView())); - } else { - _printMsgError(result.item2); - } - }), - SizedBox( - height: media.width * 0.04, - ), - Row( - // crossAxisAlignment: CrossAxisAlignment., - children: [ - Expanded( - child: Container( - height: 1, - color: TColor.gray.withOpacity(0.5), - )), - Text( - " Ou ", - style: TextStyle(color: TColor.black, fontSize: 12), + ), + Padding( + padding: const EdgeInsets.only(top: 8), + child: Text( + "En continuant, vous acceptez notre Politique de\nconfidentialité et nos Conditions d'utilisation.", + style: TextStyle(color: TColor.gray, fontSize: 10), ), - Expanded( - child: Container( - height: 1, - color: TColor.gray.withOpacity(0.5), - )), - ], - ), - SizedBox( - height: media.width * 0.04, - ), - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - GestureDetector( - onTap: () {}, + ) + ], + ), + SizedBox( + height: media.width * 0.05, + ), + Visibility( + visible: _errorCreateUser, + child: Text("Error - $_msgError", + style: TextStyle(color: TColor.red))), + SizedBox( + height: media.width * 0.4, + ), + RoundButton( + title: "Créer un compte", + onPressed: () async { + if (!emailValidate || + !passwordValidate || + !usernameValidate) { + _printMsgError("Les champs renseigné ne sont pas valide"); + return; + } + + Tuple2 result = await util.createUser( + controllerTextEmail.text, + controllerUsername.text, + controllerTextPassword.text); + if (result.item1) { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => const LoginView())); + } else { + _printMsgError(result.item2); + } + }), + SizedBox( + height: media.width * 0.04, + ), + Row( + // crossAxisAlignment: CrossAxisAlignment., + children: [ + Expanded( child: Container( - width: 50, - height: 50, - alignment: Alignment.center, - decoration: BoxDecoration( - color: TColor.white, - border: Border.all( - width: 1, - color: TColor.gray.withOpacity(0.4), - ), - borderRadius: BorderRadius.circular(15), - ), - child: Image.asset( - "assets/img/google.png", - width: 20, - height: 20, + height: 1, + color: TColor.gray.withOpacity(0.5), + )), + Text( + " Ou ", + style: TextStyle(color: TColor.black, fontSize: 12), + ), + Expanded( + child: Container( + height: 1, + color: TColor.gray.withOpacity(0.5), + )), + ], + ), + SizedBox( + height: media.width * 0.04, + ), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + GestureDetector( + onTap: () {}, + child: Container( + width: 50, + height: 50, + alignment: Alignment.center, + decoration: BoxDecoration( + color: TColor.white, + border: Border.all( + width: 1, + color: TColor.gray.withOpacity(0.4), ), + borderRadius: BorderRadius.circular(15), + ), + child: Image.asset( + "assets/img/google.png", + width: 20, + height: 20, ), ), - SizedBox( - width: media.width * 0.04, - ), - GestureDetector( - onTap: () {}, - child: Container( - width: 50, - height: 50, - alignment: Alignment.center, - decoration: BoxDecoration( - color: TColor.white, - border: Border.all( - width: 1, - color: TColor.gray.withOpacity(0.4), - ), - borderRadius: BorderRadius.circular(15), - ), - child: Image.asset( - "assets/img/suunto.png", - width: 35, - height: 35, + ), + SizedBox( + width: media.width * 0.04, + ), + GestureDetector( + onTap: () {}, + child: Container( + width: 50, + height: 50, + alignment: Alignment.center, + decoration: BoxDecoration( + color: TColor.white, + border: Border.all( + width: 1, + color: TColor.gray.withOpacity(0.4), ), + borderRadius: BorderRadius.circular(15), ), - ) - ], - ), - SizedBox( - height: media.width * 0.04, - ), - TextButton( - onPressed: () { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => const LoginView())); - }, - child: Row( - mainAxisSize: MainAxisSize.min, - children: [ - Text( - "Vous avez déjà un compte ? ", - style: TextStyle( + child: Image.asset( + "assets/img/suunto.png", + width: 35, + height: 35, + ), + ), + ) + ], + ), + SizedBox( + height: media.width * 0.04, + ), + TextButton( + onPressed: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => const LoginView())); + }, + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Text( + "Vous avez déjà un compte ? ", + style: TextStyle( + color: TColor.black, + fontSize: 14, + ), + ), + Text( + "Se connecter", + style: TextStyle( color: TColor.black, fontSize: 14, - ), - ), - Text( - "Se connecter", - style: TextStyle( - color: TColor.black, - fontSize: 14, - fontWeight: FontWeight.w700), - ) - ], - ), - ), - SizedBox( - height: media.width * 0.04, + fontWeight: FontWeight.w700), + ) + ], ), - ], - ), + ), + SizedBox( + height: media.width * 0.04, + ), + ], ), ), ), diff --git a/lib/view/login/web/web_login_view.dart b/lib/view/login/web/web_login_view.dart index 83d83ca..0c4833e 100644 --- a/lib/view/login/web/web_login_view.dart +++ b/lib/view/login/web/web_login_view.dart @@ -73,148 +73,144 @@ class _WebLoginView extends State { var media = MediaQuery.of(context).size; return Scaffold( backgroundColor: TColor.white, - body: SingleChildScrollView( - child: SafeArea( - child: Container( - padding: const EdgeInsets.symmetric(horizontal: 300), - height: media.height, - child: Column( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - SizedBox( - height: media.width * 0.03, - ), - Text( - "Bienvenue", - style: TextStyle(color: TColor.gray, fontSize: 16), - ), - Text( - "Se connecter", - style: TextStyle( - color: TColor.black, - fontSize: 20, - fontWeight: FontWeight.w700), - ), - SizedBox( - height: media.width * 0.04, - ), - RoundTextField( - hitText: "Email", - icon: "assets/img/email.svg", - keyboardType: TextInputType.emailAddress, - controller: controllerTextEmail, - ), - SizedBox( - height: media.width * 0.04, - ), - RoundTextField( - controller: controllerTextPassword, - hitText: "Mot de passe", - icon: "assets/img/lock.svg", - obscureText: _obscureText, - rigtIcon: TextButton( - onPressed: _toggle, - child: Container( - alignment: Alignment.center, + body: SafeArea( + child: Container( + padding: const EdgeInsets.symmetric(horizontal: 300), + height: media.height, + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + SizedBox( + height: media.width * 0.03, + ), + Text( + "Bienvenue sur SmartFit", + style: TextStyle(color: TColor.gray, fontSize: 16), + ), + Text( + "Se connecter", + style: TextStyle( + color: TColor.black, + fontSize: 20, + fontWeight: FontWeight.w700), + ), + SizedBox( + height: media.width * 0.04, + ), + RoundTextField( + hitText: "Email", + icon: "assets/img/email.svg", + keyboardType: TextInputType.emailAddress, + controller: controllerTextEmail, + ), + SizedBox( + height: media.width * 0.04, + ), + RoundTextField( + controller: controllerTextPassword, + hitText: "Mot de passe", + icon: "assets/img/lock.svg", + obscureText: _obscureText, + rigtIcon: TextButton( + onPressed: _toggle, + child: Container( + alignment: Alignment.center, + width: 20, + height: 20, + child: SvgPicture.asset( + "assets/img/show_password.svg", width: 20, height: 20, - child: SvgPicture.asset( - "assets/img/show_password.svg", - width: 20, - height: 20, - fit: BoxFit.contain, - ))), - ), - SizedBox( - height: media.width * 0.01, - ), - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - "Mot de passe oublié ?", - style: TextStyle( - color: TColor.gray, - fontSize: 15, - decoration: TextDecoration.underline), - ), - ], - ), - SizedBox( - height: media.width * 0.04, - ), - Visibility( - visible: _errorLogin, - child: Text("Error - $_msgError", - style: TextStyle(color: TColor.red))), - const Spacer(), - RoundButton( - title: "Se connecter", - onPressed: () async { - if (!emailValidate || !passwordValidate) { - _printMsgError( - "Les champs renseigné ne sont pas valide"); - return; - } - Tuple2 result = - await util.checkLoginAndPassword( - controllerTextEmail.text, - controllerTextPassword.text); + fit: BoxFit.contain, + ))), + ), + SizedBox( + height: media.width * 0.01, + ), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + "Mot de passe oublié ?", + style: TextStyle( + color: TColor.gray, + fontSize: 15, + decoration: TextDecoration.underline), + ), + ], + ), + SizedBox( + height: media.width * 0.04, + ), + Visibility( + visible: _errorLogin, + child: Text("Error - $_msgError", + style: TextStyle(color: TColor.red))), + const Spacer(), + RoundButton( + title: "Se connecter", + onPressed: () async { + if (!emailValidate || !passwordValidate) { + _printMsgError("Les champs renseigné ne sont pas valide"); + return; + } + Tuple2 result = + await util.checkLoginAndPassword( + controllerTextEmail.text, + controllerTextPassword.text); - if (result.item1 == true) { - Tuple2 infoUser = await util.getUserInfo(result.item2); + if (result.item1 == true) { + Tuple2 infoUser = await util.getUserInfo(result.item2); - if (infoUser.item1 == false) { - //print("Erreur - Impossible de récupéré les données de l'utilisateur"); - _printMsgError( - "Impossible de récupéré les données de l'utilisateur - {$infoUser.item2}"); - } else { - util.fillUser(context, infoUser.item2, result.item2); - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => const MainTabView())); - } + if (infoUser.item1 == false) { + //print("Erreur - Impossible de récupéré les données de l'utilisateur"); + _printMsgError( + "Impossible de récupéré les données de l'utilisateur - {$infoUser.item2}"); } else { - _printMsgError("Connexion refuser - ${result.item2}"); + util.fillUser(context, infoUser.item2, result.item2); + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => const MainTabView())); } - }), - SizedBox( - height: media.width * 0.04, - ), - - SizedBox( - height: media.width * 0.04, - ), - TextButton( - onPressed: () { - Navigator.pop(context); - }, - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Text( - "Vous n'avez pas toujours pas de compte ? ", - style: TextStyle( + } else { + _printMsgError("Connexion refuser - ${result.item2}"); + } + }), + SizedBox( + height: media.width * 0.04, + ), + SizedBox( + height: media.width * 0.04, + ), + TextButton( + onPressed: () { + Navigator.pop(context); + }, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Text( + "Vous n'avez pas toujours pas de compte ? ", + style: TextStyle( + color: TColor.black, + fontSize: 14, + ), + ), + Text( + "Créer un compte", + style: TextStyle( color: TColor.black, fontSize: 14, - ), - ), - Text( - "Créer un compte", - style: TextStyle( - color: TColor.black, - fontSize: 14, - fontWeight: FontWeight.w700), - ) - ], - ), - ), - SizedBox( - height: media.width * 0.04, + fontWeight: FontWeight.w700), + ) + ], ), - ], - ), + ), + SizedBox( + height: media.width * 0.04, + ), + ], ), ), ), diff --git a/lib/view/login/web/web_signup_view.dart b/lib/view/login/web/web_signup_view.dart index 1f457f8..e197a9a 100644 --- a/lib/view/login/web/web_signup_view.dart +++ b/lib/view/login/web/web_signup_view.dart @@ -90,159 +90,154 @@ class _WebSignUpView extends State { var media = MediaQuery.of(context).size; return Scaffold( backgroundColor: TColor.white, - body: SingleChildScrollView( - child: SafeArea( - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 300), - child: Column( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - SizedBox( - height: media.width * 0.04, - ), - Text( - "Bienvenue,", - style: TextStyle(color: TColor.gray, fontSize: 16), - ), - Text( - "Créer un compte", - style: TextStyle( - color: TColor.black, - fontSize: 20, - fontWeight: FontWeight.w700), - ), - SizedBox( - height: media.width * 0.05, - ), - RoundTextField( - hitText: "Prénom", - icon: "assets/img/user_text.svg", - controller: controllerUsername, - ), - SizedBox( - height: media.width * 0.04, - ), - RoundTextField( - hitText: "Email", - icon: "assets/img/email.svg", - keyboardType: TextInputType.emailAddress, - controller: controllerTextEmail, - ), - SizedBox( - height: media.width * 0.04, - ), - RoundTextField( - hitText: "Mot de passe", - icon: "assets/img/lock.svg", - obscureText: _obscureText, - controller: controllerTextPassword, - rigtIcon: TextButton( - onPressed: _toggle, - child: Container( - alignment: Alignment.center, + body: SafeArea( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 300), + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + SizedBox( + height: media.width * 0.04, + ), + Text( + "Bienvenue,", + style: TextStyle(color: TColor.gray, fontSize: 16), + ), + Text( + "Créer un compte", + style: TextStyle( + color: TColor.black, + fontSize: 20, + fontWeight: FontWeight.w700), + ), + SizedBox( + height: media.width * 0.05, + ), + RoundTextField( + hitText: "Prénom", + icon: "assets/img/user_text.svg", + controller: controllerUsername, + ), + SizedBox( + height: media.width * 0.04, + ), + RoundTextField( + hitText: "Email", + icon: "assets/img/email.svg", + keyboardType: TextInputType.emailAddress, + controller: controllerTextEmail, + ), + SizedBox( + height: media.width * 0.04, + ), + RoundTextField( + hitText: "Mot de passe", + icon: "assets/img/lock.svg", + obscureText: _obscureText, + controller: controllerTextPassword, + rigtIcon: TextButton( + onPressed: _toggle, + child: Container( + alignment: Alignment.center, + width: 20, + height: 20, + child: SvgPicture.asset( + "assets/img/show_password.svg", width: 20, height: 20, - child: SvgPicture.asset( - "assets/img/show_password.svg", - width: 20, - height: 20, - fit: BoxFit.contain, - ))), - ), - Row( - // crossAxisAlignment: CrossAxisAlignment., + fit: BoxFit.contain, + ))), + ), + Row( + // crossAxisAlignment: CrossAxisAlignment., + children: [ + IconButton( + onPressed: () { + _check(); + }, + icon: Icon( + _isCheck + ? Icons.check_box_outlined + : Icons.check_box_outline_blank_outlined, + color: TColor.gray, + size: 20, + ), + ), + Padding( + padding: const EdgeInsets.only(top: 8), + child: Text( + "En continuant, vous acceptez notre Politique de\nconfidentialité et nos Conditions d'utilisation.", + style: TextStyle(color: TColor.gray, fontSize: 10), + ), + ) + ], + ), + Visibility( + visible: _errorCreateUser, + child: Text("Error - $_msgError", + style: TextStyle(color: TColor.red))), + SizedBox( + height: media.width * 0.05, + ), + RoundButton( + title: "Créer un compte", + onPressed: () async { + if (!emailValidate || + !passwordValidate || + !usernameValidate) { + _printMsgError("Les champs renseigné ne sont pas valide"); + return; + } + Tuple2 result = await util.createUser( + controllerTextEmail.text, + controllerUsername.text, + controllerTextPassword.text); + if (result.item1) { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => const LoginView())); + } else { + _printMsgError(result.item2); + } + }), + SizedBox( + height: media.width * 0.04, + ), + SizedBox( + height: media.width * 0.04, + ), + TextButton( + onPressed: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => const LoginView())); + }, + child: Row( + mainAxisSize: MainAxisSize.min, children: [ - IconButton( - onPressed: () { - _check(); - }, - icon: Icon( - _isCheck - ? Icons.check_box_outlined - : Icons.check_box_outline_blank_outlined, - color: TColor.gray, - size: 20, + Text( + "Vous avez déjà un compte ? ", + style: TextStyle( + color: TColor.black, + fontSize: 14, ), ), - Padding( - padding: const EdgeInsets.only(top: 8), - child: Text( - "En continuant, vous acceptez notre Politique de\nconfidentialité et nos Conditions d'utilisation.", - style: TextStyle(color: TColor.gray, fontSize: 10), - ), - ) - ], - ), - - Visibility( - visible: _errorCreateUser, - child: Text("Error - $_msgError", - style: TextStyle(color: TColor.red))), - SizedBox( - height: media.width * 0.05, - ), - RoundButton( - title: "Créer un compte", - onPressed: () async { - if (!emailValidate || - !passwordValidate || - !usernameValidate) { - _printMsgError( - "Les champs renseigné ne sont pas valide"); - return; - } - Tuple2 result = await util.createUser( - controllerTextEmail.text, - controllerUsername.text, - controllerTextPassword.text); - if (result.item1) { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => const LoginView())); - } else { - _printMsgError(result.item2); - } - }), - SizedBox( - height: media.width * 0.04, - ), - - SizedBox( - height: media.width * 0.04, - ), - TextButton( - onPressed: () { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => const LoginView())); - }, - child: Row( - mainAxisSize: MainAxisSize.min, - children: [ - Text( - "Vous avez déjà un compte ? ", - style: TextStyle( + Text( + "Se connecter", + style: TextStyle( color: TColor.black, fontSize: 14, - ), - ), - Text( - "Se connecter", - style: TextStyle( - color: TColor.black, - fontSize: 14, - fontWeight: FontWeight.w700), - ) - ], - ), - ), - SizedBox( - height: media.width * 0.04, + fontWeight: FontWeight.w700), + ) + ], ), - ], - ), + ), + SizedBox( + height: media.width * 0.04, + ), + ], ), ), ), From 67864dd09cca08d30c57be54342913f7c01c8890 Mon Sep 17 00:00:00 2001 From: RemRem Date: Thu, 23 Nov 2023 21:55:14 +0100 Subject: [PATCH 3/6] :sparkles: add email change on web + class InfoMessage and ApiWrapper --- lib/main.dart | 2 +- lib/modele/api/api_wrapper.dart | 38 ++++++++++++++ lib/modele/api/i_data_strategy.dart | 2 +- lib/modele/api/request_api.dart | 6 +-- lib/modele/utile/info_message.dart | 17 +++++++ lib/view/login/web/web_signup_view.dart | 6 --- lib/view/profile/change_email.dart | 5 +- .../profile/mobile/mobile_change_email.dart | 21 +++----- lib/view/profile/web/web_change_email.dart | 49 +++++++++++++------ lib/view/profile/web/web_profile_view.dart | 9 +++- pubspec.yaml | 1 + 11 files changed, 110 insertions(+), 46 deletions(-) create mode 100644 lib/modele/api/api_wrapper.dart create mode 100644 lib/modele/utile/info_message.dart diff --git a/lib/main.dart b/lib/main.dart index e1b9afd..9452bdc 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -35,8 +35,8 @@ class MyApp extends StatelessWidget { // tested with just a hot reload. primaryColor: TColor.primaryColor1, fontFamily: "Poppins"), - //home: const StartedView(), home: const SignUpView(), + //home: const ProfileView(), ); } } diff --git a/lib/modele/api/api_wrapper.dart b/lib/modele/api/api_wrapper.dart new file mode 100644 index 0000000..0202fc8 --- /dev/null +++ b/lib/modele/api/api_wrapper.dart @@ -0,0 +1,38 @@ +import 'package:smartfit_app_mobile/modele/api/i_data_strategy.dart'; +import 'package:smartfit_app_mobile/modele/api/request_api.dart'; +import 'package:smartfit_app_mobile/modele/utile/info_message.dart'; +import 'package:email_validator/email_validator.dart'; +import 'package:tuple/tuple.dart'; + +class ApiWrapper { + IDataStrategy api = RequestApi(); + + Future modifyUserInfo(String infoToModify, String value, String token, + InfoMessage infoManager) async { + if (infoToModify == 'email' && EmailValidator.validate(value) || + infoToModify == 'password' || + infoToModify == 'username') { + Tuple2 res = + await api.modifAttribut(token, infoToModify, value); + if (res.item1 == true) { + infoManager.displayMessage( + "${infoToModify.capitalize()} modified succesfully !", false); + return true; + } else { + infoManager.displayMessage( + "An error occured :/ Please try again.", true); + return false; + } + } else { + infoManager.displayMessage( + "This is not a valid $infoToModify :/ Please try again.", true); + return false; + } + } +} + +extension StringExtension on String { + String capitalize() { + return "${this[0].toUpperCase()}${substring(1).toLowerCase()}"; + } +} diff --git a/lib/modele/api/i_data_strategy.dart b/lib/modele/api/i_data_strategy.dart index 49c4940..8e620a6 100644 --- a/lib/modele/api/i_data_strategy.dart +++ b/lib/modele/api/i_data_strategy.dart @@ -37,6 +37,6 @@ abstract class IDataStrategy { Future updateUsername(String token, String username); */ - Future modifAttribut( + Future> modifAttribut( String token, String nameAttribut, String newValue); } diff --git a/lib/modele/api/request_api.dart b/lib/modele/api/request_api.dart index 8d0756f..a8ce3c9 100644 --- a/lib/modele/api/request_api.dart +++ b/lib/modele/api/request_api.dart @@ -123,7 +123,7 @@ class RequestApi extends IDataStrategy { } @override - Future modifAttribut( + Future> modifAttribut( String token, String nameAttribut, String newValue) async { final response = await http.put(Uri.parse('$urlApi/user/$nameAttribut'), headers: { @@ -133,8 +133,8 @@ class RequestApi extends IDataStrategy { body: jsonEncode({nameAttribut: newValue})); if (response.statusCode == 200) { - Map json = jsonDecode(response.body); - return Tuple2(true, json); + //Map json = jsonDecode(response.body); + return const Tuple2(true, "200 - OK"); } if (response.statusCode == 400) { return const Tuple2(false, "400 - BAD REQUEST"); diff --git a/lib/modele/utile/info_message.dart b/lib/modele/utile/info_message.dart new file mode 100644 index 0000000..7d9f459 --- /dev/null +++ b/lib/modele/utile/info_message.dart @@ -0,0 +1,17 @@ +import 'package:flutter/material.dart'; + +class InfoMessage { + String message = ""; + Color messageColor = Colors.transparent; + bool isVisible = false; + + void displayMessage(String message, bool isError) { + this.message = message; + isVisible = true; + if (isError) { + messageColor = Colors.red; + } else { + messageColor = Colors.green; + } + } +} diff --git a/lib/view/login/web/web_signup_view.dart b/lib/view/login/web/web_signup_view.dart index e197a9a..29b57c4 100644 --- a/lib/view/login/web/web_signup_view.dart +++ b/lib/view/login/web/web_signup_view.dart @@ -204,9 +204,6 @@ class _WebSignUpView extends State { SizedBox( height: media.width * 0.04, ), - SizedBox( - height: media.width * 0.04, - ), TextButton( onPressed: () { Navigator.push( @@ -234,9 +231,6 @@ class _WebSignUpView extends State { ], ), ), - SizedBox( - height: media.width * 0.04, - ), ], ), ), diff --git a/lib/view/profile/change_email.dart b/lib/view/profile/change_email.dart index 9b61eae..757c28d 100644 --- a/lib/view/profile/change_email.dart +++ b/lib/view/profile/change_email.dart @@ -1,10 +1,7 @@ import 'package:flutter/material.dart'; import 'package:responsive_builder/responsive_builder.dart'; import 'package:smartfit_app_mobile/view/profile/mobile/mobile_change_email.dart'; -import 'package:smartfit_app_mobile/view/profile/mobile/mobile_change_username.dart'; import 'package:smartfit_app_mobile/view/profile/web/web_change_email.dart'; -import 'package:smartfit_app_mobile/view/profile/web/web_change_username.dart'; - class ChangeEmailView extends StatefulWidget { const ChangeEmailView({super.key}); @@ -14,7 +11,7 @@ class ChangeEmailView extends StatefulWidget { } class _ChangeEmailViewState extends State { - @override + @override Widget build(BuildContext context) { return ScreenTypeLayout.builder( mobile: (_) => const MobileChangeEmailView(), diff --git a/lib/view/profile/mobile/mobile_change_email.dart b/lib/view/profile/mobile/mobile_change_email.dart index f623052..99f8fef 100644 --- a/lib/view/profile/mobile/mobile_change_email.dart +++ b/lib/view/profile/mobile/mobile_change_email.dart @@ -1,10 +1,10 @@ import 'package:flutter/material.dart'; -import 'package:flutter_svg/svg.dart'; +import 'package:smartfit_app_mobile/modele/user.dart'; +import 'package:provider/provider.dart'; import 'package:smartfit_app_mobile/common/colo_extension.dart'; import 'package:smartfit_app_mobile/common_widget/button/round_button.dart'; import 'package:smartfit_app_mobile/common_widget/text_field/round_text_field.dart'; - class MobileChangeEmailView extends StatefulWidget { const MobileChangeEmailView({super.key}); @@ -15,11 +15,11 @@ class MobileChangeEmailView extends StatefulWidget { class _MobileChangeEmailViewState extends State { final TextEditingController controllerTextEmail = TextEditingController(); final TextEditingController controllerTextPassword = TextEditingController(); - String oldUsername = "Ancien e-mail"; @override Widget build(BuildContext context) { var media = MediaQuery.of(context).size; + String userEmail = context.watch().email; return Scaffold( appBar: AppBar( @@ -44,16 +44,14 @@ class _MobileChangeEmailViewState extends State { height: 15, fit: BoxFit.contain, ), - ), - ), - title: Text( + title: Text( "Changer son e-mail", style: TextStyle( color: TColor.black, fontSize: 16, fontWeight: FontWeight.w700), ), - ), + ), backgroundColor: TColor.white, body: Column( children: [ @@ -75,7 +73,7 @@ class _MobileChangeEmailViewState extends State { ), ), Text( - oldUsername, // Utilisez votre ancien pseudo ici + userEmail, // Utilisez votre ancien pseudo ici style: TextStyle( color: TColor.black, fontSize: 16, @@ -91,7 +89,6 @@ class _MobileChangeEmailViewState extends State { ), child: Column( children: [ - RoundTextField( hitText: "Nouveau e-mail", icon: "assets/img/user_text.svg", @@ -99,9 +96,7 @@ class _MobileChangeEmailViewState extends State { controller: controllerTextEmail, ), SizedBox(height: media.width * 0.07), - RoundButton( - title: "Confirmer", - onPressed: () {}), + RoundButton(title: "Confirmer", onPressed: () {}), ], ), ), @@ -112,4 +107,4 @@ class _MobileChangeEmailViewState extends State { ), ); } -} \ No newline at end of file +} diff --git a/lib/view/profile/web/web_change_email.dart b/lib/view/profile/web/web_change_email.dart index 797c08d..6a7fe3c 100644 --- a/lib/view/profile/web/web_change_email.dart +++ b/lib/view/profile/web/web_change_email.dart @@ -1,9 +1,11 @@ import 'package:flutter/material.dart'; -import 'package:flutter_svg/svg.dart'; +import 'package:provider/provider.dart'; +import 'package:smartfit_app_mobile/modele/api/api_wrapper.dart'; +import 'package:smartfit_app_mobile/modele/user.dart'; import 'package:smartfit_app_mobile/common/colo_extension.dart'; import 'package:smartfit_app_mobile/common_widget/button/round_button.dart'; import 'package:smartfit_app_mobile/common_widget/text_field/round_text_field.dart'; - +import 'package:smartfit_app_mobile/modele/utile/info_message.dart'; class WebChangeEmailView extends StatefulWidget { const WebChangeEmailView({super.key}); @@ -14,12 +16,13 @@ class WebChangeEmailView extends StatefulWidget { class _WebChangeEmailViewState extends State { final TextEditingController controllerTextEmail = TextEditingController(); - final TextEditingController controllerTextPassword = TextEditingController(); - String oldUsername = "Ancien e-mail"; + final ApiWrapper apiWrapper = ApiWrapper(); + final InfoMessage infoManager = InfoMessage(); @override Widget build(BuildContext context) { var media = MediaQuery.of(context).size; + String userEmail = context.watch().email; return Scaffold( appBar: AppBar( @@ -44,16 +47,14 @@ class _WebChangeEmailViewState extends State { height: 15, fit: BoxFit.contain, ), - ), - ), - title: Text( - "Changer son e-mail", + title: Text( + "Changer son email", style: TextStyle( color: TColor.black, fontSize: 16, fontWeight: FontWeight.w700), ), - ), + ), backgroundColor: TColor.white, body: Column( children: [ @@ -67,7 +68,7 @@ class _WebChangeEmailViewState extends State { Row( children: [ Text( - "Ancien e-mail : ", + "Email actuel : ", style: TextStyle( color: TColor.black, fontSize: 16, @@ -75,7 +76,7 @@ class _WebChangeEmailViewState extends State { ), ), Text( - oldUsername, + userEmail, style: TextStyle( color: TColor.black, fontSize: 16, @@ -91,17 +92,33 @@ class _WebChangeEmailViewState extends State { ), child: Column( children: [ - RoundTextField( hitText: "Nouveau email", icon: "assets/img/user_text.svg", keyboardType: TextInputType.text, controller: controllerTextEmail, ), - SizedBox(height: media.width * 0.04), + SizedBox(height: media.width * 0.01), + Visibility( + visible: infoManager.isVisible, + child: Text(infoManager.message, + style: + TextStyle(color: infoManager.messageColor))), + SizedBox(height: media.width * 0.03), RoundButton( - title: "Confirmer", - onPressed: () {}), + title: "Confirmer", + onPressed: () async { + bool res = await apiWrapper.modifyUserInfo( + 'email', + controllerTextEmail.text, + Provider.of(context, listen: false).token, + infoManager); + if (res) { + Provider.of(context, listen: false).email = + controllerTextEmail.text; + } + setState(() {}); + }), ], ), ), @@ -112,4 +129,4 @@ class _WebChangeEmailViewState extends State { ), ); } -} \ No newline at end of file +} diff --git a/lib/view/profile/web/web_profile_view.dart b/lib/view/profile/web/web_profile_view.dart index 598e01e..23b2ca2 100644 --- a/lib/view/profile/web/web_profile_view.dart +++ b/lib/view/profile/web/web_profile_view.dart @@ -1,5 +1,7 @@ import 'package:flutter/material.dart'; import 'package:animated_toggle_switch/animated_toggle_switch.dart'; +import 'package:provider/provider.dart'; +import 'package:smartfit_app_mobile/modele/user.dart'; import 'package:smartfit_app_mobile/common/colo_extension.dart'; import 'package:smartfit_app_mobile/common_widget/button/round_button.dart'; import 'package:smartfit_app_mobile/common_widget/setting_row.dart'; @@ -48,6 +50,8 @@ class _WebProfileView extends State { ]; @override Widget build(BuildContext context) { + String _username = context.watch().username; + return Scaffold( appBar: AppBar( backgroundColor: TColor.white, @@ -106,7 +110,7 @@ class _WebProfileView extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - "Benjelloun Othmane", + _username, style: TextStyle( color: TColor.black, fontSize: 14, @@ -390,7 +394,8 @@ class _WebProfileView extends State { Navigator.push( context, MaterialPageRoute( - builder: (context) => const PrivacyPolicyView(), + builder: (context) => + const PrivacyPolicyView(), ), ); } else if (iObj["tag"] == "5") { diff --git a/pubspec.yaml b/pubspec.yaml index 8581686..25c6942 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -35,6 +35,7 @@ dependencies: file_picker: ^6.1.1 csv: ^5.1.1 fit_tool: ^1.0.5 + email_validator: '^2.1.16' # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. From 73dfc4e76f29958872df21c380f4563224cff24b Mon Sep 17 00:00:00 2001 From: RemRem Date: Fri, 24 Nov 2023 10:30:16 +0100 Subject: [PATCH 4/6] :sparkles: add change email on mobile --- .../profile/mobile/mobile_change_email.dart | 30 +++++++++++++++++-- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/lib/view/profile/mobile/mobile_change_email.dart b/lib/view/profile/mobile/mobile_change_email.dart index 99f8fef..b887896 100644 --- a/lib/view/profile/mobile/mobile_change_email.dart +++ b/lib/view/profile/mobile/mobile_change_email.dart @@ -1,9 +1,11 @@ import 'package:flutter/material.dart'; +import 'package:smartfit_app_mobile/modele/api/api_wrapper.dart'; import 'package:smartfit_app_mobile/modele/user.dart'; import 'package:provider/provider.dart'; import 'package:smartfit_app_mobile/common/colo_extension.dart'; import 'package:smartfit_app_mobile/common_widget/button/round_button.dart'; import 'package:smartfit_app_mobile/common_widget/text_field/round_text_field.dart'; +import 'package:smartfit_app_mobile/modele/utile/info_message.dart'; class MobileChangeEmailView extends StatefulWidget { const MobileChangeEmailView({super.key}); @@ -14,7 +16,8 @@ class MobileChangeEmailView extends StatefulWidget { class _MobileChangeEmailViewState extends State { final TextEditingController controllerTextEmail = TextEditingController(); - final TextEditingController controllerTextPassword = TextEditingController(); + final InfoMessage infoManager = InfoMessage(); + final ApiWrapper api = ApiWrapper(); @override Widget build(BuildContext context) { @@ -73,7 +76,7 @@ class _MobileChangeEmailViewState extends State { ), ), Text( - userEmail, // Utilisez votre ancien pseudo ici + userEmail, style: TextStyle( color: TColor.black, fontSize: 16, @@ -96,7 +99,28 @@ class _MobileChangeEmailViewState extends State { controller: controllerTextEmail, ), SizedBox(height: media.width * 0.07), - RoundButton(title: "Confirmer", onPressed: () {}), + Visibility( + visible: infoManager.isVisible, + child: Text(infoManager.message, + style: + TextStyle(color: infoManager.messageColor))), + SizedBox( + height: media.width * 0.01, + ), + RoundButton( + title: "Confirmer", + onPressed: () async { + bool res = await api.modifyUserInfo( + 'email', + controllerTextEmail.text, + Provider.of(context, listen: false).token, + infoManager); + if (res) { + Provider.of(context, listen: false).email = + controllerTextEmail.text; + } + setState(() {}); + }), ], ), ), From 94b5470cb557cec98d0ab5d555d16811d19ee635 Mon Sep 17 00:00:00 2001 From: RemRem Date: Fri, 24 Nov 2023 10:58:34 +0100 Subject: [PATCH 5/6] :sparkles: add username change + add consts in profile pages --- .../mobile/mobile_change_username.dart | 50 +++++++++++++------ .../profile/mobile/mobile_profile_view.dart | 19 ++++--- lib/view/profile/web/web_change_username.dart | 49 ++++++++++++------ lib/view/profile/web/web_profile_view.dart | 8 +-- 4 files changed, 85 insertions(+), 41 deletions(-) diff --git a/lib/view/profile/mobile/mobile_change_username.dart b/lib/view/profile/mobile/mobile_change_username.dart index 66f2abb..3aa1367 100644 --- a/lib/view/profile/mobile/mobile_change_username.dart +++ b/lib/view/profile/mobile/mobile_change_username.dart @@ -1,25 +1,29 @@ +import 'package:provider/provider.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_svg/svg.dart'; +import 'package:smartfit_app_mobile/modele/api/api_wrapper.dart'; +import 'package:smartfit_app_mobile/modele/user.dart'; import 'package:smartfit_app_mobile/common/colo_extension.dart'; import 'package:smartfit_app_mobile/common_widget/button/round_button.dart'; import 'package:smartfit_app_mobile/common_widget/text_field/round_text_field.dart'; - +import 'package:smartfit_app_mobile/modele/utile/info_message.dart'; class MobileChangeUsernameView extends StatefulWidget { const MobileChangeUsernameView({super.key}); @override - State createState() => _MobileChangeUsernameViewState(); + State createState() => + _MobileChangeUsernameViewState(); } class _MobileChangeUsernameViewState extends State { - final TextEditingController controllerTextEmail = TextEditingController(); - final TextEditingController controllerTextPassword = TextEditingController(); - String oldUsername = "Ancien pseudo"; + final TextEditingController controllerTextUsername = TextEditingController(); + final InfoMessage infoManager = InfoMessage(); + final ApiWrapper api = ApiWrapper(); @override Widget build(BuildContext context) { var media = MediaQuery.of(context).size; + String userUsername = context.watch().username; return Scaffold( appBar: AppBar( @@ -44,16 +48,14 @@ class _MobileChangeUsernameViewState extends State { height: 15, fit: BoxFit.contain, ), - ), - ), - title: Text( + title: Text( "Changer son pseudo", style: TextStyle( color: TColor.black, fontSize: 16, fontWeight: FontWeight.w700), ), - ), + ), backgroundColor: TColor.white, body: Column( children: [ @@ -75,7 +77,7 @@ class _MobileChangeUsernameViewState extends State { ), ), Text( - oldUsername, // Utilisez votre ancien pseudo ici + userUsername, // Utilisez votre ancien pseudo ici style: TextStyle( color: TColor.black, fontSize: 16, @@ -91,17 +93,33 @@ class _MobileChangeUsernameViewState extends State { ), child: Column( children: [ - RoundTextField( hitText: "Nouveau pseudo", icon: "assets/img/user_text.svg", keyboardType: TextInputType.text, - controller: controllerTextEmail, + controller: controllerTextUsername, ), SizedBox(height: media.width * 0.07), + Visibility( + visible: infoManager.isVisible, + child: Text(infoManager.message, + style: + TextStyle(color: infoManager.messageColor))), + SizedBox(height: media.width * 0.02), RoundButton( - title: "Confirmer", - onPressed: () {}), + title: "Confirmer", + onPressed: () async { + bool res = await api.modifyUserInfo( + 'username', + controllerTextUsername.text, + Provider.of(context, listen: false).token, + infoManager); + if (res) { + Provider.of(context, listen: false) + .username = controllerTextUsername.text; + } + setState(() {}); + }), ], ), ), @@ -112,4 +130,4 @@ class _MobileChangeUsernameViewState extends State { ), ); } -} \ No newline at end of file +} diff --git a/lib/view/profile/mobile/mobile_profile_view.dart b/lib/view/profile/mobile/mobile_profile_view.dart index b60212f..97dbbf9 100644 --- a/lib/view/profile/mobile/mobile_profile_view.dart +++ b/lib/view/profile/mobile/mobile_profile_view.dart @@ -1,5 +1,7 @@ +import 'package:smartfit_app_mobile/modele/user.dart'; import 'package:flutter/material.dart'; import 'package:animated_toggle_switch/animated_toggle_switch.dart'; +import 'package:provider/provider.dart'; import 'package:smartfit_app_mobile/common/colo_extension.dart'; import 'package:smartfit_app_mobile/common_widget/button/round_button.dart'; import 'package:smartfit_app_mobile/common_widget/setting_row.dart'; @@ -48,6 +50,8 @@ class _MobileProfileView extends State { ]; @override Widget build(BuildContext context) { + String username = context.watch().username; + return Scaffold( appBar: AppBar( backgroundColor: TColor.white, @@ -106,7 +110,7 @@ class _MobileProfileView extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - "Benjelloun Othmane", + username, style: TextStyle( color: TColor.black, fontSize: 14, @@ -214,21 +218,23 @@ class _MobileProfileView extends State { Navigator.push( context, MaterialPageRoute( - builder: (context) => ChangeUsernameView(), + builder: (context) => + const ChangeUsernameView(), ), ); } else if (iObj["tag"] == "2") { Navigator.push( context, MaterialPageRoute( - builder: (context) => ChangePasswordView(), + builder: (context) => + const ChangePasswordView(), ), ); } else { Navigator.push( context, MaterialPageRoute( - builder: (context) => ChangeEmailView(), + builder: (context) => const ChangeEmailView(), ), ); } @@ -388,14 +394,15 @@ class _MobileProfileView extends State { Navigator.push( context, MaterialPageRoute( - builder: (context) => PrivacyPolicyView(), + builder: (context) => + const PrivacyPolicyView(), ), ); } else if (iObj["tag"] == "5") { Navigator.push( context, MaterialPageRoute( - builder: (context) => ContactUsView(), + builder: (context) => const ContactUsView(), ), ); } else { diff --git a/lib/view/profile/web/web_change_username.dart b/lib/view/profile/web/web_change_username.dart index 53f99ce..f00c301 100644 --- a/lib/view/profile/web/web_change_username.dart +++ b/lib/view/profile/web/web_change_username.dart @@ -1,9 +1,11 @@ import 'package:flutter/material.dart'; -import 'package:flutter_svg/svg.dart'; +import 'package:smartfit_app_mobile/modele/user.dart'; +import 'package:provider/provider.dart'; import 'package:smartfit_app_mobile/common/colo_extension.dart'; import 'package:smartfit_app_mobile/common_widget/button/round_button.dart'; import 'package:smartfit_app_mobile/common_widget/text_field/round_text_field.dart'; - +import 'package:smartfit_app_mobile/modele/api/api_wrapper.dart'; +import 'package:smartfit_app_mobile/modele/utile/info_message.dart'; class WebChangeUsernameView extends StatefulWidget { const WebChangeUsernameView({super.key}); @@ -13,13 +15,14 @@ class WebChangeUsernameView extends StatefulWidget { } class _WebChangeUsernameViewState extends State { - final TextEditingController controllerTextEmail = TextEditingController(); - final TextEditingController controllerTextPassword = TextEditingController(); - String oldUsername = "Ancien pseudo"; + final TextEditingController controllerTextUsername = TextEditingController(); + final InfoMessage infoManager = InfoMessage(); + final ApiWrapper api = ApiWrapper(); @override Widget build(BuildContext context) { var media = MediaQuery.of(context).size; + String userUsername = context.watch().username; return Scaffold( appBar: AppBar( @@ -44,16 +47,14 @@ class _WebChangeUsernameViewState extends State { height: 15, fit: BoxFit.contain, ), - ), - ), - title: Text( + title: Text( "Changer son pseudo", style: TextStyle( color: TColor.black, fontSize: 16, fontWeight: FontWeight.w700), ), - ), + ), backgroundColor: TColor.white, body: Column( children: [ @@ -75,7 +76,7 @@ class _WebChangeUsernameViewState extends State { ), ), Text( - oldUsername, // Utilisez votre ancien pseudo ici + userUsername, style: TextStyle( color: TColor.black, fontSize: 16, @@ -91,17 +92,35 @@ class _WebChangeUsernameViewState extends State { ), child: Column( children: [ - RoundTextField( hitText: "Nouveau pseudo", icon: "assets/img/user_text.svg", keyboardType: TextInputType.text, - controller: controllerTextEmail, + controller: controllerTextUsername, ), + SizedBox( + height: media.width * 0.01, + ), + Visibility( + visible: infoManager.isVisible, + child: Text(infoManager.message, + style: + TextStyle(color: infoManager.messageColor))), SizedBox(height: media.width * 0.04), RoundButton( - title: "Confirmer", - onPressed: () {}), + title: "Confirmer", + onPressed: () async { + bool res = await api.modifyUserInfo( + 'username', + controllerTextUsername.text, + Provider.of(context, listen: false).token, + infoManager); + if (res) { + Provider.of(context, listen: false) + .username = controllerTextUsername.text; + } + setState(() {}); + }), ], ), ), @@ -112,4 +131,4 @@ class _WebChangeUsernameViewState extends State { ), ); } -} \ No newline at end of file +} diff --git a/lib/view/profile/web/web_profile_view.dart b/lib/view/profile/web/web_profile_view.dart index 23b2ca2..9b11d17 100644 --- a/lib/view/profile/web/web_profile_view.dart +++ b/lib/view/profile/web/web_profile_view.dart @@ -50,7 +50,7 @@ class _WebProfileView extends State { ]; @override Widget build(BuildContext context) { - String _username = context.watch().username; + String username = context.watch().username; return Scaffold( appBar: AppBar( @@ -110,7 +110,7 @@ class _WebProfileView extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - _username, + username, style: TextStyle( color: TColor.black, fontSize: 14, @@ -234,7 +234,7 @@ class _WebProfileView extends State { Navigator.push( context, MaterialPageRoute( - builder: (context) => ChangeEmailView(), + builder: (context) => const ChangeEmailView(), ), ); } @@ -402,7 +402,7 @@ class _WebProfileView extends State { Navigator.push( context, MaterialPageRoute( - builder: (context) => ContactUsView(), + builder: (context) => const ContactUsView(), ), ); } else { From d755378672075478e5e30b9074e0de1f1b18ea54 Mon Sep 17 00:00:00 2001 From: rem Date: Mon, 27 Nov 2023 14:04:31 +0100 Subject: [PATCH 6/6] :sparkles: add support for password modification --- lib/modele/api/api_wrapper.dart | 17 +++++ .../mobile/mobile_change_password.dart | 65 ++++++++++++----- lib/view/profile/web/web_change_password.dart | 69 ++++++++++++++----- 3 files changed, 113 insertions(+), 38 deletions(-) diff --git a/lib/modele/api/api_wrapper.dart b/lib/modele/api/api_wrapper.dart index 0202fc8..67174a1 100644 --- a/lib/modele/api/api_wrapper.dart +++ b/lib/modele/api/api_wrapper.dart @@ -3,6 +3,8 @@ import 'package:smartfit_app_mobile/modele/api/request_api.dart'; import 'package:smartfit_app_mobile/modele/utile/info_message.dart'; import 'package:email_validator/email_validator.dart'; import 'package:tuple/tuple.dart'; +import 'dart:convert'; +import 'package:crypto/crypto.dart'; class ApiWrapper { IDataStrategy api = RequestApi(); @@ -29,6 +31,21 @@ class ApiWrapper { return false; } } + + Future> login( + String password, String email, InfoMessage infoManager) async { + String hash = sha256.convert(utf8.encode(password)).toString(); + Tuple2 res = await api.connexion(email, hash); + + if (res.item1) { + return Tuple2(true, res.item2); // return token + } else { + infoManager.displayMessage( + "Authentification failed! Enter your actual password carefully.", + true); + return const Tuple2(false, "An error occured during connexion!"); + } // need to be better + } } extension StringExtension on String { diff --git a/lib/view/profile/mobile/mobile_change_password.dart b/lib/view/profile/mobile/mobile_change_password.dart index 2bb37a4..a170eb2 100644 --- a/lib/view/profile/mobile/mobile_change_password.dart +++ b/lib/view/profile/mobile/mobile_change_password.dart @@ -1,25 +1,34 @@ +import 'dart:convert'; +import 'package:crypto/crypto.dart'; +import 'package:smartfit_app_mobile/modele/user.dart'; +import 'package:smartfit_app_mobile/modele/api/api_wrapper.dart'; +import 'package:smartfit_app_mobile/modele/utile/info_message.dart'; +import 'package:tuple/tuple.dart'; +import 'package:provider/provider.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_svg/svg.dart'; import 'package:smartfit_app_mobile/common/colo_extension.dart'; import 'package:smartfit_app_mobile/common_widget/button/round_button.dart'; import 'package:smartfit_app_mobile/common_widget/text_field/round_text_field.dart'; - class MobileChangePasswordView extends StatefulWidget { const MobileChangePasswordView({super.key}); @override - State createState() => _MobileChangePasswordViewState(); + State createState() => + _MobileChangePasswordViewState(); } class _MobileChangePasswordViewState extends State { - final TextEditingController controllerTextEmail = TextEditingController(); - final TextEditingController controllerTextPassword = TextEditingController(); - + final TextEditingController controllerActualPasswd = TextEditingController(); + final TextEditingController controllerNewPasswd = TextEditingController(); + final TextEditingController controllerNewPasswd2 = TextEditingController(); + final InfoMessage infoManager = InfoMessage(); + final ApiWrapper api = ApiWrapper(); @override Widget build(BuildContext context) { var media = MediaQuery.of(context).size; + User providerUser = Provider.of(context, listen: false); return Scaffold( appBar: AppBar( @@ -44,16 +53,14 @@ class _MobileChangePasswordViewState extends State { height: 15, fit: BoxFit.contain, ), - ), - ), - title: Text( + title: Text( "Changer son Mot de passe", style: TextStyle( color: TColor.black, fontSize: 16, fontWeight: FontWeight.w700), ), - ), + ), backgroundColor: TColor.white, body: Column( children: [ @@ -77,29 +84,49 @@ class _MobileChangePasswordViewState extends State { obscureText: true, icon: "assets/img/lock.svg", keyboardType: TextInputType.text, - controller: controllerTextEmail, + controller: controllerActualPasswd, ), SizedBox(height: media.width * 0.07), RoundTextField( - controller: controllerTextPassword, + controller: controllerNewPasswd, hitText: "Nouveau mot de passe", icon: "assets/img/lock.svg", obscureText: true, - ), SizedBox(height: media.width * 0.07), RoundTextField( - controller: controllerTextPassword, + controller: controllerNewPasswd2, hitText: "Confirmer nouveau mot de passe", icon: "assets/img/lock.svg", obscureText: true, - ), SizedBox(height: media.width * 0.07), RoundButton( - title: "Confirmer", - onPressed: () {}), - + title: "Confirmer", + onPressed: () async { + Tuple2 res = await api.login( + controllerActualPasswd.text, + providerUser.email, + infoManager); + if (res.item1) { + if (controllerNewPasswd.text == + controllerNewPasswd2.text) { + await api.modifyUserInfo( + 'password', + sha256 + .convert(utf8 + .encode(controllerNewPasswd.text)) + .toString(), + providerUser.token, + infoManager); + } else { + infoManager.displayMessage( + 'Passwords does not match each other! Enter them carefully.', + true); + } + } + setState(() {}); + }), ], ), ), @@ -110,4 +137,4 @@ class _MobileChangePasswordViewState extends State { ), ); } -} \ No newline at end of file +} diff --git a/lib/view/profile/web/web_change_password.dart b/lib/view/profile/web/web_change_password.dart index bb080e2..00ff54e 100644 --- a/lib/view/profile/web/web_change_password.dart +++ b/lib/view/profile/web/web_change_password.dart @@ -1,9 +1,14 @@ +import 'dart:convert'; +import 'package:crypto/crypto.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_svg/svg.dart'; +import 'package:tuple/tuple.dart'; +import 'package:provider/provider.dart'; +import 'package:smartfit_app_mobile/modele/user.dart'; import 'package:smartfit_app_mobile/common/colo_extension.dart'; -import 'package:smartfit_app_mobile/common_widget/button/round_button.dart'; import 'package:smartfit_app_mobile/common_widget/text_field/round_text_field.dart'; - +import 'package:smartfit_app_mobile/modele/utile/info_message.dart'; +import 'package:smartfit_app_mobile/modele/api/api_wrapper.dart'; +import 'package:smartfit_app_mobile/common_widget/button/round_button.dart'; class WebChangePasswordView extends StatefulWidget { const WebChangePasswordView({super.key}); @@ -13,13 +18,16 @@ class WebChangePasswordView extends StatefulWidget { } class _WebChangePasswordViewState extends State { - final TextEditingController controllerTextEmail = TextEditingController(); - final TextEditingController controllerTextPassword = TextEditingController(); - + final TextEditingController controllerActualPasswd = TextEditingController(); + final TextEditingController controllerNewPasswd = TextEditingController(); + final TextEditingController controllerNewPasswd2 = TextEditingController(); + final InfoMessage infoManager = InfoMessage(); + final ApiWrapper api = ApiWrapper(); @override Widget build(BuildContext context) { var media = MediaQuery.of(context).size; + User providerUser = Provider.of(context, listen: false); return Scaffold( appBar: AppBar( @@ -44,16 +52,14 @@ class _WebChangePasswordViewState extends State { height: 15, fit: BoxFit.contain, ), - ), - ), - title: Text( + title: Text( "Changer son Mot de passe", style: TextStyle( color: TColor.black, fontSize: 16, fontWeight: FontWeight.w700), ), - ), + ), backgroundColor: TColor.white, body: Column( children: [ @@ -76,29 +82,54 @@ class _WebChangePasswordViewState extends State { obscureText: true, icon: "assets/img/lock.svg", keyboardType: TextInputType.text, - controller: controllerTextEmail, + controller: controllerActualPasswd, ), SizedBox(height: media.width * 0.02), RoundTextField( - controller: controllerTextPassword, + controller: controllerNewPasswd, hitText: "Nouveau mot de passe", icon: "assets/img/lock.svg", obscureText: true, - ), SizedBox(height: media.width * 0.02), RoundTextField( - controller: controllerTextPassword, + controller: controllerNewPasswd2, hitText: "Confirmer nouveau mot de passe", icon: "assets/img/lock.svg", obscureText: true, - ), + Visibility( + visible: infoManager.isVisible, + child: Text(infoManager.message, + style: + TextStyle(color: infoManager.messageColor))), SizedBox(height: media.width * 0.04), RoundButton( - title: "Confirmer", - onPressed: () {}), - + title: "Confirmer", + onPressed: () async { + Tuple2 res = await api.login( + controllerActualPasswd.text, + providerUser.email, + infoManager); + if (res.item1) { + if (controllerNewPasswd.text == + controllerNewPasswd2.text) { + await api.modifyUserInfo( + 'password', + sha256 + .convert(utf8 + .encode(controllerNewPasswd.text)) + .toString(), + providerUser.token, + infoManager); + } else { + infoManager.displayMessage( + 'Passwords does not match each other! Enter them carefully.', + true); + } + } + setState(() {}); + }), ], ), ), @@ -109,4 +140,4 @@ class _WebChangePasswordViewState extends State { ), ); } -} \ No newline at end of file +}