Merge pull request '🔀 add support for password, email and username modifications + const and fixes' (#3) from profile into master
continuous-integration/drone/push Build is passing Details

Reviewed-on: #3
pull/4/head
remrem 1 year ago
commit bc89324f2a

@ -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(),
);
}
}

@ -0,0 +1,55 @@
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';
import 'dart:convert';
import 'package:crypto/crypto.dart';
class ApiWrapper {
IDataStrategy api = RequestApi();
Future<bool> modifyUserInfo(String infoToModify, String value, String token,
InfoMessage infoManager) async {
if (infoToModify == 'email' && EmailValidator.validate(value) ||
infoToModify == 'password' ||
infoToModify == 'username') {
Tuple2<bool, String> 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;
}
}
Future<Tuple2<bool, String>> login(
String password, String email, InfoMessage infoManager) async {
String hash = sha256.convert(utf8.encode(password)).toString();
Tuple2<bool, String> 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 {
String capitalize() {
return "${this[0].toUpperCase()}${substring(1).toLowerCase()}";
}
}

@ -37,6 +37,6 @@ abstract class IDataStrategy {
Future<void> updateUsername(String token, String username);
*/
Future<Tuple2> modifAttribut(
Future<Tuple2<bool, String>> modifAttribut(
String token, String nameAttribut, String newValue);
}

@ -123,7 +123,7 @@ class RequestApi extends IDataStrategy {
}
@override
Future<Tuple2> modifAttribut(
Future<Tuple2<bool, String>> modifAttribut(
String token, String nameAttribut, String newValue) async {
final response = await http.put(Uri.parse('$urlApi/user/$nameAttribut'),
headers: <String, String>{
@ -133,8 +133,8 @@ class RequestApi extends IDataStrategy {
body: jsonEncode(<String, String>{nameAttribut: newValue}));
if (response.statusCode == 200) {
Map<String, dynamic> json = jsonDecode(response.body);
return Tuple2(true, json);
//Map<String, dynamic> json = jsonDecode(response.body);
return const Tuple2(true, "200 - OK");
}
if (response.statusCode == 400) {
return const Tuple2(false, "400 - BAD REQUEST");

@ -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;
}
}
}

@ -72,217 +72,214 @@ class _MobileLoginView extends State<MobileLoginView> {
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<bool, String> 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<bool, String> 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,
),
],
),
),
),

@ -91,230 +91,227 @@ class _MobileSignUpView extends State<MobileSignUpView> {
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<bool, String> 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<bool, String> 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,
),
],
),
),
),

@ -73,148 +73,144 @@ class _WebLoginView extends State<WebLoginView> {
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<bool, String> 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<bool, String> 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,
),
],
),
),
),

@ -90,159 +90,148 @@ class _WebSignUpView extends State<WebSignUpView> {
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<bool, String> 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,
),
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<bool, String> 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),
)
],
),
],
),
),
],
),
),
),

@ -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<ChangeEmailView> {
@override
@override
Widget build(BuildContext context) {
return ScreenTypeLayout.builder(
mobile: (_) => const MobileChangeEmailView(),

@ -1,9 +1,11 @@
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: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,12 +16,13 @@ class MobileChangeEmailView extends StatefulWidget {
class _MobileChangeEmailViewState extends State<MobileChangeEmailView> {
final TextEditingController controllerTextEmail = TextEditingController();
final TextEditingController controllerTextPassword = TextEditingController();
String oldUsername = "Ancien e-mail";
final InfoMessage infoManager = InfoMessage();
final ApiWrapper api = ApiWrapper();
@override
Widget build(BuildContext context) {
var media = MediaQuery.of(context).size;
String userEmail = context.watch<User>().email;
return Scaffold(
appBar: AppBar(
@ -44,16 +47,14 @@ class _MobileChangeEmailViewState extends State<MobileChangeEmailView> {
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 +76,7 @@ class _MobileChangeEmailViewState extends State<MobileChangeEmailView> {
),
),
Text(
oldUsername, // Utilisez votre ancien pseudo ici
userEmail,
style: TextStyle(
color: TColor.black,
fontSize: 16,
@ -91,7 +92,6 @@ class _MobileChangeEmailViewState extends State<MobileChangeEmailView> {
),
child: Column(
children: [
RoundTextField(
hitText: "Nouveau e-mail",
icon: "assets/img/user_text.svg",
@ -99,9 +99,28 @@ class _MobileChangeEmailViewState extends State<MobileChangeEmailView> {
controller: controllerTextEmail,
),
SizedBox(height: media.width * 0.07),
Visibility(
visible: infoManager.isVisible,
child: Text(infoManager.message,
style:
TextStyle(color: infoManager.messageColor))),
SizedBox(
height: media.width * 0.01,
),
RoundButton(
title: "Confirmer",
onPressed: () {}),
title: "Confirmer",
onPressed: () async {
bool res = await api.modifyUserInfo(
'email',
controllerTextEmail.text,
Provider.of<User>(context, listen: false).token,
infoManager);
if (res) {
Provider.of<User>(context, listen: false).email =
controllerTextEmail.text;
}
setState(() {});
}),
],
),
),
@ -112,4 +131,4 @@ class _MobileChangeEmailViewState extends State<MobileChangeEmailView> {
),
);
}
}
}

@ -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<MobileChangePasswordView> createState() => _MobileChangePasswordViewState();
State<MobileChangePasswordView> createState() =>
_MobileChangePasswordViewState();
}
class _MobileChangePasswordViewState extends State<MobileChangePasswordView> {
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<User>(context, listen: false);
return Scaffold(
appBar: AppBar(
@ -44,16 +53,14 @@ class _MobileChangePasswordViewState extends State<MobileChangePasswordView> {
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<MobileChangePasswordView> {
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<bool, String> 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<MobileChangePasswordView> {
),
);
}
}
}

@ -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<MobileChangeUsernameView> createState() => _MobileChangeUsernameViewState();
State<MobileChangeUsernameView> createState() =>
_MobileChangeUsernameViewState();
}
class _MobileChangeUsernameViewState extends State<MobileChangeUsernameView> {
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<User>().username;
return Scaffold(
appBar: AppBar(
@ -44,16 +48,14 @@ class _MobileChangeUsernameViewState extends State<MobileChangeUsernameView> {
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<MobileChangeUsernameView> {
),
),
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<MobileChangeUsernameView> {
),
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<User>(context, listen: false).token,
infoManager);
if (res) {
Provider.of<User>(context, listen: false)
.username = controllerTextUsername.text;
}
setState(() {});
}),
],
),
),
@ -112,4 +130,4 @@ class _MobileChangeUsernameViewState extends State<MobileChangeUsernameView> {
),
);
}
}
}

@ -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<MobileProfileView> {
];
@override
Widget build(BuildContext context) {
String username = context.watch<User>().username;
return Scaffold(
appBar: AppBar(
backgroundColor: TColor.white,
@ -106,7 +110,7 @@ class _MobileProfileView extends State<MobileProfileView> {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Benjelloun Othmane",
username,
style: TextStyle(
color: TColor.black,
fontSize: 14,
@ -214,21 +218,23 @@ class _MobileProfileView extends State<MobileProfileView> {
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<MobileProfileView> {
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 {

@ -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<WebChangeEmailView> {
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<User>().email;
return Scaffold(
appBar: AppBar(
@ -44,16 +47,14 @@ class _WebChangeEmailViewState extends State<WebChangeEmailView> {
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<WebChangeEmailView> {
Row(
children: [
Text(
"Ancien e-mail : ",
"Email actuel : ",
style: TextStyle(
color: TColor.black,
fontSize: 16,
@ -75,7 +76,7 @@ class _WebChangeEmailViewState extends State<WebChangeEmailView> {
),
),
Text(
oldUsername,
userEmail,
style: TextStyle(
color: TColor.black,
fontSize: 16,
@ -91,17 +92,33 @@ class _WebChangeEmailViewState extends State<WebChangeEmailView> {
),
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<User>(context, listen: false).token,
infoManager);
if (res) {
Provider.of<User>(context, listen: false).email =
controllerTextEmail.text;
}
setState(() {});
}),
],
),
),
@ -112,4 +129,4 @@ class _WebChangeEmailViewState extends State<WebChangeEmailView> {
),
);
}
}
}

@ -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<WebChangePasswordView> {
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<User>(context, listen: false);
return Scaffold(
appBar: AppBar(
@ -44,16 +52,14 @@ class _WebChangePasswordViewState extends State<WebChangePasswordView> {
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<WebChangePasswordView> {
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<bool, String> 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<WebChangePasswordView> {
),
);
}
}
}

@ -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<WebChangeUsernameView> {
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<User>().username;
return Scaffold(
appBar: AppBar(
@ -44,16 +47,14 @@ class _WebChangeUsernameViewState extends State<WebChangeUsernameView> {
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<WebChangeUsernameView> {
),
),
Text(
oldUsername, // Utilisez votre ancien pseudo ici
userUsername,
style: TextStyle(
color: TColor.black,
fontSize: 16,
@ -91,17 +92,35 @@ class _WebChangeUsernameViewState extends State<WebChangeUsernameView> {
),
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<User>(context, listen: false).token,
infoManager);
if (res) {
Provider.of<User>(context, listen: false)
.username = controllerTextUsername.text;
}
setState(() {});
}),
],
),
),
@ -112,4 +131,4 @@ class _WebChangeUsernameViewState extends State<WebChangeUsernameView> {
),
);
}
}
}

@ -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<WebProfileView> {
];
@override
Widget build(BuildContext context) {
String username = context.watch<User>().username;
return Scaffold(
appBar: AppBar(
backgroundColor: TColor.white,
@ -106,7 +110,7 @@ class _WebProfileView extends State<WebProfileView> {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Benjelloun Othmane",
username,
style: TextStyle(
color: TColor.black,
fontSize: 14,
@ -214,21 +218,23 @@ class _WebProfileView extends State<WebProfileView> {
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(),
),
);
}
@ -277,7 +283,7 @@ class _WebProfileView extends State<WebProfileView> {
),
Expanded(
child: Text(
"Pop-up Notification",
"Push Notifications",
style: TextStyle(
color: TColor.black,
fontSize: 12,
@ -286,9 +292,9 @@ class _WebProfileView extends State<WebProfileView> {
),
CustomAnimatedToggleSwitch<bool>(
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,
@ -296,7 +302,7 @@ class _WebProfileView extends State<WebProfileView> {
iconBuilder: (context, local, global) {
return const SizedBox();
},
cursors: ToggleCursors(
cursors: const ToggleCursors(
defaultCursor: SystemMouseCursors.click),
onTap: (_) =>
setState(() => positive = !positive),
@ -388,14 +394,15 @@ class _WebProfileView extends State<WebProfileView> {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const PrivacyPolicyView(),
builder: (context) =>
const PrivacyPolicyView(),
),
);
} else if (iObj["tag"] == "5") {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ContactUsView(),
builder: (context) => const ContactUsView(),
),
);
} else {

@ -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.

Loading…
Cancel
Save