Merge branch 'master' of https://codefirst.iut.uca.fr/git/justDEV/justMusic
continuous-integration/drone/push Build is passing Details

HISTORIC_CAPSULE_LDE
Emre KARTAL 2 years ago
commit 4474c95247

Binary file not shown.

After

Width:  |  Height:  |  Size: 983 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

@ -32,6 +32,7 @@ class CommentComponent extends StatelessWidget {
// Image radius // Image radius
child: FadeInImage.assetNetwork( child: FadeInImage.assetNetwork(
image: comment.user.pp, image: comment.user.pp,
fit: BoxFit.cover,
fadeInDuration: const Duration(milliseconds: 100), fadeInDuration: const Duration(milliseconds: 100),
placeholder: "assets/images/loadingPlaceholder.gif", placeholder: "assets/images/loadingPlaceholder.gif",
), ),

@ -0,0 +1,43 @@
import 'package:flutter/Material.dart';
class HistoricComponent extends StatefulWidget {
final int month;
const HistoricComponent({super.key, required this.month});
@override
State<HistoricComponent> createState() => _HistoricComponentState();
}
class _HistoricComponentState extends State<HistoricComponent> {
int getNumberOfDaysInMonth(int year, int month) {
if (month < 1 || month > 12) {
throw ArgumentError("Le numéro de mois doit être compris entre 1 et 12.");
}
return DateTime(year, month + 1, 0).day;
}
@override
Widget build(BuildContext context) {
return Wrap(
spacing: 14,
runSpacing: 14,
children: List.generate(getNumberOfDaysInMonth(DateTime.now().year, widget.month), (index) {
// Generate widgets
return LimitedBox(
maxWidth: MediaQuery.of(context).size.width - 40 / 5,
child: Container(
decoration: BoxDecoration(
gradient: LinearGradient(colors: [
Color(0xFF1E1E1E).withOpacity(0.7),
Color(0xFF1E1E1E).withOpacity(0),
], begin: Alignment.topCenter, end: Alignment.bottomCenter),
borderRadius: BorderRadius.circular(3)),
height: 60,
width: 60,
),
);
}),
);
}
}

@ -4,8 +4,9 @@ import 'package:flutter_screenutil/flutter_screenutil.dart';
class LoginButton extends StatefulWidget { class LoginButton extends StatefulWidget {
final Function callback; final Function callback;
final String text;
const LoginButton({Key? key, required this.callback}) : super(key: key); const LoginButton({Key? key, required this.callback, required this.text}) : super(key: key);
@override @override
State<LoginButton> createState() => _LoginButtonState(); State<LoginButton> createState() => _LoginButtonState();
@ -57,7 +58,7 @@ class _LoginButtonState extends State<LoginButton> {
), ),
alignment: Alignment.center, alignment: Alignment.center,
child: Text( child: Text(
"Se connecter", widget.text,
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: TextStyle(color: Colors.white, fontSize: 18), style: TextStyle(color: Colors.white, fontSize: 18),
), ),

@ -24,7 +24,7 @@ class ProfilPictureComponent extends StatelessWidget {
// Image radius // Image radius
child: FadeInImage.assetNetwork( child: FadeInImage.assetNetwork(
image: user.pp, image: user.pp,
fit: BoxFit.fill, fit: BoxFit.cover,
fadeInDuration: const Duration(milliseconds: 100), fadeInDuration: const Duration(milliseconds: 100),
placeholder: "assets/images/loadingPlaceholder.gif", placeholder: "assets/images/loadingPlaceholder.gif",
), ),

@ -1,5 +1,7 @@
import 'package:flutter/Material.dart'; import 'package:flutter/Material.dart';
import 'package:justmusic/screens/add_friend_screen.dart'; import 'package:justmusic/screens/add_friend_screen.dart';
import 'package:justmusic/screens/capsule_historic_screen.dart';
import 'package:justmusic/screens/change_password_screen.dart';
import 'package:justmusic/screens/feed_screen.dart'; import 'package:justmusic/screens/feed_screen.dart';
import 'package:justmusic/screens/profile_screen.dart'; import 'package:justmusic/screens/profile_screen.dart';
import 'package:justmusic/screens/user_screen.dart'; import 'package:justmusic/screens/user_screen.dart';
@ -71,3 +73,39 @@ Route routeUser(User user) {
}, },
); );
} }
Route routePassword() {
return PageRouteBuilder(
pageBuilder: (context, animation, secondaryAnimation) => const ChangePasswordScreen(),
transitionsBuilder: (context, animation, secondaryAnimation, child) {
const begin = Offset(1.0, 0.0);
const end = Offset.zero;
const curve = Curves.ease;
var tween = Tween(begin: begin, end: end).chain(CurveTween(curve: curve));
return SlideTransition(
position: animation.drive(tween),
child: child,
);
},
);
}
Route routeHistoric() {
return PageRouteBuilder(
pageBuilder: (context, animation, secondaryAnimation) => const CapsuleHistoricScreen(),
transitionsBuilder: (context, animation, secondaryAnimation, child) {
const begin = Offset(1.0, 0.0);
const end = Offset.zero;
const curve = Curves.ease;
var tween = Tween(begin: begin, end: end).chain(CurveTween(curve: curve));
return SlideTransition(
position: animation.drive(tween),
child: child,
);
},
);
}

@ -11,6 +11,7 @@ import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:justmusic/screens/add_friend_screen.dart'; import 'package:justmusic/screens/add_friend_screen.dart';
import 'package:justmusic/screens/explanations_screen.dart'; import 'package:justmusic/screens/explanations_screen.dart';
import 'package:justmusic/screens/feed_screen.dart'; import 'package:justmusic/screens/feed_screen.dart';
import 'package:justmusic/screens/forget_password_screen.dart';
import 'package:justmusic/screens/login_screen.dart'; import 'package:justmusic/screens/login_screen.dart';
import 'package:justmusic/screens/launching_rocker_screen.dart'; import 'package:justmusic/screens/launching_rocker_screen.dart';
import 'package:justmusic/screens/post_screen.dart'; import 'package:justmusic/screens/post_screen.dart';
@ -102,6 +103,7 @@ class _MyAppState extends State<MyApp> {
'/addFriend': (context) => const AddFriendScreen(), '/addFriend': (context) => const AddFriendScreen(),
'/launchingRocket': (context) => const LaunchingRocketScreen(), '/launchingRocket': (context) => const LaunchingRocketScreen(),
'/verifyEmail': (context) => const VerifyEmailScreen(), '/verifyEmail': (context) => const VerifyEmailScreen(),
'/forgetPassword': (context) => const ForgetPasswordScreen(),
}, },
debugShowCheckedModeBanner: false, debugShowCheckedModeBanner: false,
theme: ThemeData( theme: ThemeData(

@ -0,0 +1,94 @@
import 'package:flutter/Material.dart';
import 'package:google_fonts/google_fonts.dart';
import '../components/historic_component.dart';
import '../values/constants.dart';
class CapsuleHistoricScreen extends StatefulWidget {
const CapsuleHistoricScreen({super.key});
@override
State<CapsuleHistoricScreen> createState() => _CapsuleHistoricScreenState();
}
class _CapsuleHistoricScreenState extends State<CapsuleHistoricScreen> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: PreferredSize(
preferredSize: Size(double.infinity, 58),
child: Container(
height: double.infinity,
color: bgAppBar,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: defaultPadding),
child: Stack(
alignment: Alignment.centerLeft,
children: [
GestureDetector(
behavior: HitTestBehavior.translucent,
onTap: () {
Navigator.pop(context, true);
},
child: Container(
padding: EdgeInsets.symmetric(horizontal: 10),
height: 30,
width: 30,
child: Image(
image: AssetImage("assets/images/return_icon.png"),
height: 8,
),
)),
Align(
child: Text(
"Historique des capsules",
style: GoogleFonts.plusJakartaSans(color: Colors.white, fontSize: 14, fontWeight: FontWeight.bold),
),
)
],
),
),
),
),
body: Container(
width: double.infinity,
height: double.infinity,
color: bgColor,
child: SingleChildScrollView(
physics: const BouncingScrollPhysics(decelerationRate: ScrollDecelerationRate.fast),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: settingPadding),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: EdgeInsets.only(top: 30, bottom: 40),
child: SizedBox(
width: double.infinity,
child: Stack(
alignment: Alignment.center,
children: [
Container(
padding: EdgeInsets.symmetric(horizontal: 15),
constraints: BoxConstraints(maxWidth: 600),
child: Column(
children: [
HistoricComponent(
month: DateTime.now().month,
),
],
),
)
],
),
),
),
],
),
),
),
),
);
}
}

@ -0,0 +1,311 @@
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/Material.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/services.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:justmusic/main.dart';
import '../values/constants.dart';
class ChangePasswordScreen extends StatefulWidget {
const ChangePasswordScreen({super.key});
@override
State<ChangePasswordScreen> createState() => _ChangePasswordScreenState();
}
class _ChangePasswordScreenState extends State<ChangePasswordScreen> {
final _currentPasswordTextField = TextEditingController();
final _newPasswordTextField = TextEditingController();
final _confirmPasswordTextField = TextEditingController();
final _formKey = GlobalKey<FormState>();
Future<void> resetFullScreen() async {
await SystemChannels.platform.invokeMethod<void>(
'SystemChrome.restoreSystemUIOverlays',
);
}
handleChange() async {
print("test");
if (_formKey.currentState!.validate()) {
var error;
try {
await FirebaseAuth.instance.signInWithEmailAndPassword(
email: MyApp.userViewModel.userCurrent.mail,
password: _currentPasswordTextField.text,
);
if (_newPasswordTextField.text == _confirmPasswordTextField.text) {
await FirebaseAuth.instance.currentUser?.updatePassword(_confirmPasswordTextField.text);
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
"Mot de passe mis à jour",
style: GoogleFonts.plusJakartaSans(color: Colors.white, fontWeight: FontWeight.w400, fontSize: 15.h),
),
backgroundColor: primaryColor,
closeIconColor: Colors.white,
),
);
} else {
throw FirebaseAuthException(code: "not-same", message: "Les mots de passe ne correspondent pas");
}
} on FirebaseAuthException catch (e) {
if (e.code == "wrong-password") {
error = "Mot de passe incorrect";
} else if (e.code == "too-many-requests") {
error = "Trop de tentatives infructueuses. Veuillez réessayer plus tard";
} else if (e.code == "channel-error") {
error = "Impossible de vérifier le mot de passe";
} else if (e.code == "weak-password") {
error = "Le mot de passe doit contenir 6 caractères minimum";
}
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
error ?? e.message,
style: GoogleFonts.plusJakartaSans(color: Colors.white, fontWeight: FontWeight.w400, fontSize: 15.h),
),
backgroundColor: Colors.red,
closeIconColor: Colors.white,
),
);
}
setState(() {
_currentPasswordTextField.clear();
_newPasswordTextField.clear();
_confirmPasswordTextField.clear();
});
}
}
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
FocusScopeNode currentFocus = FocusScope.of(context);
if (!currentFocus.hasPrimaryFocus) {
currentFocus.unfocus();
resetFullScreen();
}
},
child: Scaffold(
appBar: PreferredSize(
preferredSize: Size(double.infinity, 58),
child: Container(
height: double.infinity,
color: bgAppBar,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: defaultPadding),
child: Stack(
alignment: Alignment.centerLeft,
children: [
GestureDetector(
behavior: HitTestBehavior.translucent,
onTap: () {
Navigator.pop(context, true);
},
child: Container(
padding: EdgeInsets.symmetric(horizontal: 10),
height: 30,
width: 30,
child: Image(
image: AssetImage("assets/images/return_icon.png"),
height: 8,
),
)),
Align(
child: Text(
"Mettre le mot de passe à jour",
style:
GoogleFonts.plusJakartaSans(color: Colors.white, fontSize: 14, fontWeight: FontWeight.bold),
),
)
],
),
),
),
),
body: Container(
width: double.infinity,
height: double.infinity,
color: bgColor,
child: SingleChildScrollView(
physics: const BouncingScrollPhysics(decelerationRate: ScrollDecelerationRate.fast),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: settingPadding),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: EdgeInsets.only(top: 30, bottom: 40),
child: SizedBox(
width: double.infinity,
child: Form(
key: _formKey,
child: Stack(
alignment: Alignment.center,
children: [
Container(
constraints: BoxConstraints(maxWidth: 600),
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Flexible(
child: Padding(
padding: const EdgeInsets.only(right: 10),
child: Text(
"Mot de passe actuel",
style: GoogleFonts.plusJakartaSans(
color: Colors.white, fontWeight: FontWeight.w800, fontSize: 16),
),
)),
Expanded(
child: TextFormField(
controller: _currentPasswordTextField,
decoration: InputDecoration(
enabledBorder: OutlineInputBorder(
borderSide: const BorderSide(color: Colors.transparent),
),
// Hides the border when you click the TextField
focusedBorder: OutlineInputBorder(
borderSide: const BorderSide(color: Colors.transparent),
),
// Hides the border when the TextField is disabled
disabledBorder: OutlineInputBorder(
borderSide: const BorderSide(color: Colors.transparent),
),
filled: true,
hintText: '6 caractères minimum',
hintStyle: GoogleFonts.plusJakartaSans(color: strokeTextField)),
maxLines: 1,
obscureText: true,
cursorColor: primaryColor,
style: GoogleFonts.plusJakartaSans(
color: grayText, fontWeight: FontWeight.w400, fontSize: 16),
),
),
],
),
SizedBox(
height: 10,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Flexible(
child: Padding(
padding: const EdgeInsets.only(right: 10),
child: Text(
"Nouveau mot de passe",
style: GoogleFonts.plusJakartaSans(
color: Colors.white, fontWeight: FontWeight.w800, fontSize: 16),
),
)),
Expanded(
child: TextField(
controller: _newPasswordTextField,
decoration: InputDecoration(
enabledBorder: OutlineInputBorder(
borderSide: const BorderSide(color: Colors.transparent),
),
// Hides the border when you click the TextField
focusedBorder: OutlineInputBorder(
borderSide: const BorderSide(color: Colors.transparent),
),
// Hides the border when the TextField is disabled
disabledBorder: OutlineInputBorder(
borderSide: const BorderSide(color: Colors.transparent),
),
filled: true,
hintText: '6 caractères minimum',
hintStyle: GoogleFonts.plusJakartaSans(color: strokeTextField)),
maxLines: 1,
obscureText: true,
cursorColor: primaryColor,
style: GoogleFonts.plusJakartaSans(
color: grayText, fontWeight: FontWeight.w400, fontSize: 16),
),
),
],
),
SizedBox(
height: 10,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Flexible(
child: Padding(
padding: const EdgeInsets.only(right: 10),
child: Text(
"Confirmer",
style: GoogleFonts.plusJakartaSans(
color: Colors.white, fontWeight: FontWeight.w800, fontSize: 16),
),
)),
Expanded(
child: TextField(
obscureText: true,
controller: _confirmPasswordTextField,
decoration: InputDecoration(
enabledBorder: OutlineInputBorder(
borderSide: const BorderSide(color: Colors.transparent),
),
// Hides the border when you click the TextField
focusedBorder: OutlineInputBorder(
borderSide: const BorderSide(color: Colors.transparent),
),
// Hides the border when the TextField is disabled
disabledBorder: OutlineInputBorder(
borderSide: const BorderSide(color: Colors.transparent),
),
filled: true,
hintText: '6 caractères minimum',
hintStyle: GoogleFonts.plusJakartaSans(color: strokeTextField)),
maxLines: 1,
cursorColor: primaryColor,
style: GoogleFonts.plusJakartaSans(
color: grayText, fontWeight: FontWeight.w400, fontSize: 16),
),
),
],
),
],
),
)
],
),
),
),
),
GestureDetector(
onTap: handleChange,
child: Align(
child: Container(
height: 35,
width: 160,
decoration:
BoxDecoration(color: primaryColor, borderRadius: BorderRadius.all(Radius.circular(10))),
child: Center(
child: Text(
"Mettre à jour",
style: GoogleFonts.plusJakartaSans(color: Colors.white),
),
),
),
),
)
],
),
),
),
),
),
);
}
}

@ -0,0 +1,234 @@
import 'dart:async';
import 'package:auto_size_text/auto_size_text.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/Material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:google_fonts/google_fonts.dart';
import '../components/login_button.dart';
import '../values/constants.dart';
class ForgetPasswordScreen extends StatefulWidget {
const ForgetPasswordScreen({Key? key}) : super(key: key);
@override
State<ForgetPasswordScreen> createState() => _ForgetPasswordScreenState();
}
class _ForgetPasswordScreenState extends State<ForgetPasswordScreen> {
bool canResendEmail = true;
Timer? timer;
final _formKey = GlobalKey<FormState>();
final _mailTextField = TextEditingController();
@override
void dispose() {
timer?.cancel();
super.dispose();
}
Future sendForgetPasswordEmail() async {
if (_formKey.currentState!.validate()) {
var error;
try {
await FirebaseAuth.instance
.sendPasswordResetEmail(email: _mailTextField.text);
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
"Un e-mail de réinitialisation a été envoyé. Veuillez patienter pendant 30 secondes avant la prochaine utilisation.",
style: GoogleFonts.plusJakartaSans(
color: Colors.white,
fontWeight: FontWeight.w400,
fontSize: 15.h),
),
backgroundColor: primaryColor,
),
);
setState(() => canResendEmail = false);
await Future.delayed(Duration(minutes: 1));
setState(() => canResendEmail = true);
} on FirebaseAuthException catch (e) {
if (e.code == "invalid-email") {
error = "Mail incorrect";
} else if (e.code == "user-not-found") {
error = "Format de mail incorrect";
} else if (e.code == "too-many-requests") {
error =
"Trop de tentatives. Veuillez réessayer plus tard";
}
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
error,
style: GoogleFonts.plusJakartaSans(
color: Colors.white,
fontWeight: FontWeight.w400,
fontSize: 20.h),
),
backgroundColor: Colors.red,
),
);
}
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: bgColor,
body: Form(
key: _formKey,
child: Stack(
children: [
SingleChildScrollView(
child: SizedBox(
width: double.infinity,
child: Column(
children: [
Padding(
padding: EdgeInsets.only(top: 185.h),
child: Align(
child: SizedBox(
width: 56.h,
child: Image(
image: AssetImage(
"assets/images/key_icon.png")),
),
)),
Padding(
padding: EdgeInsets.only(top: 28.h),
child: AutoSizeText(
"Mot de passe oublié",
style: GoogleFonts.plusJakartaSans(
color: Colors.white,
fontWeight: FontWeight.w600,
fontSize: 24.w),
maxLines: 1,
maxFontSize: 30,
overflow: TextOverflow.fade,
),
),
Padding(
padding:
EdgeInsets.symmetric(horizontal: defaultPadding),
child: Padding(
padding: EdgeInsets.only(bottom: 20.h),
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
SizedBox(
height: 15.h,
),
SizedBox(
width: 346.h,
child: AutoSizeText(
"Afin de procéder à la récupération de votre mot de passe, veuillez renseigner votre adresse mail correspondant a votre compte JustMusic.",
style: GoogleFonts.plusJakartaSans(
color: Colors.white,
fontWeight: FontWeight.w100,
fontSize: 16.w),
maxFontSize: 20,
textAlign: TextAlign.center,
),
),
],
),
),
),
ConstrainedBox(
constraints: BoxConstraints(maxWidth: 600),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Padding(
padding: EdgeInsets.only(
bottom: 68.h,
left: defaultPadding,
right: defaultPadding),
child: TextFormField(
controller: _mailTextField,
keyboardAppearance: Brightness.dark,
validator: (value) {
if (value == null || value.isEmpty) {
return 'entrez un email valide';
}
return null;
},
cursorColor: primaryColor,
keyboardType:
TextInputType.emailAddress,
style: GoogleFonts.plusJakartaSans(
color: primaryColor),
decoration: InputDecoration(
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
width: 1,
color: strokeTextField),
borderRadius: BorderRadius.all(
Radius.circular(10))),
prefix: const Padding(
padding: EdgeInsets.only(
left: 20.0)),
suffix: const Padding(
padding: EdgeInsets.only(
left: 20.0)),
fillColor: bgTextField,
filled: true,
focusColor: Color.fromRGBO(
255, 255, 255, 0.30),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
width: 1,
color: strokeTextField),
borderRadius: BorderRadius.all(
Radius.circular(10))),
hintText: 'Email',
hintStyle: GoogleFonts.plusJakartaSans(color: strokeTextField)),
)),
Padding(
padding: EdgeInsets.symmetric(
horizontal: defaultPadding),
child: SizedBox(
width: 600,
child: LoginButton(
callback: () {
canResendEmail
? sendForgetPasswordEmail()
: null;
},
text: "Envoyer",
)),
),
])),
Align(
child: GestureDetector(
behavior: HitTestBehavior.translucent,
onTap: () {
Navigator.pushNamed(context, '/login');
},
child: Padding(
padding: EdgeInsets.only(top: 101),
child: RichText(
textAlign: TextAlign.center,
text: TextSpan(
text: 'Revenir a létape précédente',
style: GoogleFonts.plusJakartaSans(
fontSize: 15,
fontWeight: FontWeight.w400,
color: primaryColor),
),
),
),
),
),
],
),
),
),
],
)));
}
}

@ -1,4 +1,3 @@
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
@ -27,14 +26,18 @@ class _LoginScreenState extends State<LoginScreen> {
handleLogin() async { handleLogin() async {
if (_formKey.currentState!.validate()) { if (_formKey.currentState!.validate()) {
try { try {
await MyApp.userViewModel.login(_userMailTextField.text, _passwordTextField.text); await MyApp.userViewModel
.login(_userMailTextField.text, _passwordTextField.text);
Navigator.pushNamed(context, '/feed'); Navigator.pushNamed(context, '/feed');
} catch (e) { } catch (e) {
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
SnackBar( SnackBar(
content: Text( content: Text(
e.toString() ?? "", e.toString(),
style: GoogleFonts.plusJakartaSans(color: Colors.white, fontWeight: FontWeight.w400, fontSize: 20.h), style: GoogleFonts.plusJakartaSans(
color: Colors.white,
fontWeight: FontWeight.w400,
fontSize: 20.h),
), ),
backgroundColor: Colors.red, backgroundColor: Colors.red,
), ),
@ -63,19 +66,25 @@ class _LoginScreenState extends State<LoginScreen> {
child: Form( child: Form(
key: _formKey, key: _formKey,
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment:
CrossAxisAlignment.center,
children: [ children: [
Flexible( Flexible(
flex: 4, flex: 4,
child: Padding( child: Padding(
padding: EdgeInsets.only(bottom: 60), padding: EdgeInsets.only(bottom: 60),
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.end, mainAxisAlignment:
MainAxisAlignment.end,
children: [ children: [
Text( Text(
"Te revoilà!", "Te revoilà!",
style: GoogleFonts.plusJakartaSans( style:
color: Colors.white, fontWeight: FontWeight.w600, fontSize: 38.h), GoogleFonts.plusJakartaSans(
color: Colors.white,
fontWeight:
FontWeight.w600,
fontSize: 38.h),
), ),
SizedBox( SizedBox(
height: 10, height: 10,
@ -84,8 +93,12 @@ class _LoginScreenState extends State<LoginScreen> {
width: 230.w, width: 230.w,
child: Text( child: Text(
"Bon retour parmis nous tu nous as manqué!", "Bon retour parmis nous tu nous as manqué!",
style: GoogleFonts.plusJakartaSans( style: GoogleFonts
color: Colors.white, fontWeight: FontWeight.w400, fontSize: 20.h), .plusJakartaSans(
color: Colors.white,
fontWeight:
FontWeight.w400,
fontSize: 20.h),
textAlign: TextAlign.center, textAlign: TextAlign.center,
), ),
), ),
@ -96,33 +109,51 @@ class _LoginScreenState extends State<LoginScreen> {
Expanded( Expanded(
flex: 5, flex: 5,
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.end, crossAxisAlignment:
mainAxisAlignment: MainAxisAlignment.center, CrossAxisAlignment.end,
mainAxisAlignment:
MainAxisAlignment.center,
children: [ children: [
TextFormField( TextFormField(
controller: _userMailTextField, controller: _userMailTextField,
keyboardAppearance: Brightness.dark, keyboardAppearance:
Brightness.dark,
validator: (value) { validator: (value) {
if (value == null || value.isEmpty) { if (value == null ||
value.isEmpty) {
return 'entrez un email valide'; return 'entrez un email valide';
} }
return null; return null;
}, },
cursorColor: primaryColor, cursorColor: primaryColor,
keyboardType: TextInputType.emailAddress, keyboardType:
style: GoogleFonts.plusJakartaSans(color: primaryColor), TextInputType.emailAddress,
style:
GoogleFonts.plusJakartaSans(
color: primaryColor),
decoration: InputDecoration( decoration: InputDecoration(
focusedBorder: OutlineInputBorder( focusedBorder: OutlineInputBorder(
borderSide: BorderSide(width: 1, color: strokeTextField), borderSide: BorderSide(
borderRadius: BorderRadius.all(Radius.circular(10))), width: 1,
prefix: const Padding(padding: EdgeInsets.only(left: 20.0)), color:
suffix: const Padding(padding: EdgeInsets.only(left: 20.0)), strokeTextField),
borderRadius: BorderRadius.all(
Radius.circular(10))),
prefix: const Padding(
padding: EdgeInsets.only(
left: 20.0)),
suffix: const Padding(
padding: EdgeInsets.only(
left: 20.0)),
fillColor: bgTextField, fillColor: bgTextField,
filled: true, filled: true,
errorStyle: TextStyle(fontSize: 9, height: 0.3), errorStyle: TextStyle(
focusColor: Color.fromRGBO(255, 255, 255, 0.30), fontSize: 9, height: 0.3),
focusColor: Color.fromRGBO(
255, 255, 255, 0.30),
enabledBorder: OutlineInputBorder( enabledBorder: OutlineInputBorder(
borderSide: BorderSide(width: 1, color: strokeTextField), borderSide:
BorderSide(width: 1, color: strokeTextField),
borderRadius: BorderRadius.all(Radius.circular(10))), borderRadius: BorderRadius.all(Radius.circular(10))),
hintText: 'Email', hintText: 'Email',
hintStyle: GoogleFonts.plusJakartaSans(color: strokeTextField)), hintStyle: GoogleFonts.plusJakartaSans(color: strokeTextField)),
@ -132,31 +163,55 @@ class _LoginScreenState extends State<LoginScreen> {
), ),
TextFormField( TextFormField(
controller: _passwordTextField, controller: _passwordTextField,
keyboardAppearance: Brightness.dark, keyboardAppearance:
Brightness.dark,
obscureText: passenable, obscureText: passenable,
validator: (value) { validator: (value) {
if (value == null || value.isEmpty) { if (value == null ||
value.isEmpty) {
return 'entrez un mot de passe valide'; return 'entrez un mot de passe valide';
} }
return null; return null;
}, },
cursorColor: primaryColor, cursorColor: primaryColor,
style: GoogleFonts.plusJakartaSans(color: primaryColor), style:
GoogleFonts.plusJakartaSans(
color: primaryColor),
decoration: InputDecoration( decoration: InputDecoration(
focusedBorder: OutlineInputBorder( focusedBorder:
borderSide: BorderSide(width: 1, color: strokeTextField), OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(10))), borderSide: BorderSide(
width: 1,
color:
strokeTextField),
borderRadius:
BorderRadius.all(
Radius.circular(
10))),
fillColor: bgTextField, fillColor: bgTextField,
filled: true, filled: true,
focusColor: Color.fromRGBO(255, 255, 255, 0.30), focusColor: Color.fromRGBO(
enabledBorder: OutlineInputBorder( 255, 255, 255, 0.30),
borderSide: BorderSide(width: 1, color: strokeTextField), enabledBorder:
borderRadius: BorderRadius.all(Radius.circular(10))), OutlineInputBorder(
borderSide: BorderSide(
width: 1,
color:
strokeTextField),
borderRadius:
BorderRadius.all(
Radius.circular(
10))),
hintText: 'Mot de passe', hintText: 'Mot de passe',
hintStyle: GoogleFonts.plusJakartaSans(color: strokeTextField), hintStyle:
prefix: const Padding(padding: EdgeInsets.only(left: 20.0)), GoogleFonts.plusJakartaSans(
color: strokeTextField),
prefix: const Padding(
padding: EdgeInsets.only(
left: 20.0)),
suffixIcon: Container( suffixIcon: Container(
padding: EdgeInsets.only(right: 10), padding: EdgeInsets.only(
right: 10),
margin: EdgeInsets.all(5), margin: EdgeInsets.all(5),
height: 3, height: 3,
child: InkWell( child: InkWell(
@ -170,25 +225,40 @@ class _LoginScreenState extends State<LoginScreen> {
}); });
}, },
// Image tapped // Image tapped
splashColor: Colors.white10, splashColor:
Colors.white10,
// Splash color over image // Splash color over image
child: Image( child: Image(
image: passenable image: passenable
? AssetImage("assets/images/show_icon.png") ? AssetImage(
: AssetImage("assets/images/hide_icon.png"), "assets/images/show_icon.png")
: AssetImage(
"assets/images/hide_icon.png"),
height: 2, height: 2,
), ),
)), )),
errorStyle: TextStyle(fontSize: 9, height: 0.3), errorStyle: TextStyle(
), fontSize: 9, height: 0.3),
),
Padding(
padding: EdgeInsets.only(top: 10),
child: Text(
"Mot de passe oublié?",
style: GoogleFonts.plusJakartaSans(color: Colors.white),
), ),
), ),
GestureDetector(
behavior:
HitTestBehavior.translucent,
onTap: () {
Navigator.pushNamed(
context, '/forgetPassword');
},
child: Padding(
padding:
EdgeInsets.only(top: 10),
child: Text(
"Mot de passe oublié?",
style: GoogleFonts
.plusJakartaSans(
color:
Colors.white),
),
)),
SizedBox( SizedBox(
height: defaultPadding, height: defaultPadding,
), ),
@ -196,30 +266,44 @@ class _LoginScreenState extends State<LoginScreen> {
width: 600, width: 600,
child: LoginButton( child: LoginButton(
callback: handleLogin, callback: handleLogin,
text: "Se connecter",
)), )),
Align( Align(
child: GestureDetector( child: GestureDetector(
behavior: HitTestBehavior.translucent, behavior:
HitTestBehavior.translucent,
onTap: () { onTap: () {
Navigator.pushNamed(context, '/register'); Navigator.pushNamed(
context, '/register');
}, },
child: Padding( child: Padding(
padding: EdgeInsets.only(top: 20), padding:
EdgeInsets.only(top: 20),
child: RichText( child: RichText(
textAlign: TextAlign.center, textAlign: TextAlign.center,
text: TextSpan( text: TextSpan(
text: 'Pas encore inscrit?', text:
style: GoogleFonts.plusJakartaSans( 'Pas encore inscrit?',
color: Colors.white, style: GoogleFonts
fontWeight: FontWeight.w400, .plusJakartaSans(
fontSize: 15), color:
Colors.white,
fontWeight:
FontWeight
.w400,
fontSize: 15),
children: <TextSpan>[ children: <TextSpan>[
TextSpan( TextSpan(
text: " Sinscire", text: " Sinscire",
style: GoogleFonts.plusJakartaSans( style: GoogleFonts
fontSize: 15, .plusJakartaSans(
fontWeight: FontWeight.w400, fontSize:
color: primaryColor)), 15,
fontWeight:
FontWeight
.w400,
color:
primaryColor)),
], ],
), ),
), ),
@ -234,38 +318,55 @@ class _LoginScreenState extends State<LoginScreen> {
child: Padding( child: Padding(
padding: EdgeInsets.only(top: 20), padding: EdgeInsets.only(top: 20),
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment:
crossAxisAlignment: CrossAxisAlignment.center, MainAxisAlignment.start,
crossAxisAlignment:
CrossAxisAlignment.center,
children: [ children: [
ConstrainedBox( ConstrainedBox(
constraints: BoxConstraints(maxWidth: 600), constraints: BoxConstraints(
maxWidth: 600),
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly, mainAxisAlignment:
MainAxisAlignment
.spaceEvenly,
children: [ children: [
Expanded( Expanded(
child: Container( child: Container(
color: Color(0xFF3D3D3D), color:
Color(0xFF3D3D3D),
height: 1, height: 1,
), ),
), ),
Padding( Padding(
padding: const EdgeInsets.only( padding: const EdgeInsets
left: defaultPadding, right: defaultPadding), .only(
left:
defaultPadding,
right:
defaultPadding),
child: Text( child: Text(
'Ou', 'Ou',
style: GoogleFonts.plusJakartaSans( style: GoogleFonts
color: Colors.white, fontWeight: FontWeight.bold), .plusJakartaSans(
color: Colors
.white,
fontWeight:
FontWeight
.bold),
), ),
), ),
Expanded( Expanded(
child: Container( child: Container(
height: 1, height: 1,
color: Color(0xFF3D3D3D), color:
Color(0xFF3D3D3D),
)), )),
], ],
), ),
), ),
SizedBox(height: defaultPadding), SizedBox(
height: defaultPadding),
SignInButton( SignInButton(
Buttons.Google, Buttons.Google,
text: "Login with Google", text: "Login with Google",

@ -26,10 +26,18 @@ class _ProfileScreenState extends State<ProfileScreen> {
Navigator.pushNamed(context, '/welcome'); Navigator.pushNamed(context, '/welcome');
} }
void _openHistoric() {
Navigator.of(context).push(routeHistoric());
}
void _openDetail() { void _openDetail() {
Navigator.of(context).push(routeUser(MyApp.userViewModel.userCurrent)); Navigator.of(context).push(routeUser(MyApp.userViewModel.userCurrent));
} }
void _openPassword() {
Navigator.of(context).push(routePassword());
}
return Scaffold( return Scaffold(
appBar: PreferredSize( appBar: PreferredSize(
preferredSize: Size(double.infinity, 58), preferredSize: Size(double.infinity, 58),
@ -103,16 +111,21 @@ class _ProfileScreenState extends State<ProfileScreen> {
label: 'Compte', label: 'Compte',
action: _openDetail, action: _openDetail,
), ),
const SettingPartComponent( SettingPartComponent(
icon: JustMusicIcon.history, icon: JustMusicIcon.history,
label: 'Historiques des capsules', label: 'Historiques des capsules',
action: null, action: _openHistoric,
), ),
const SettingPartComponent( const SettingPartComponent(
icon: JustMusicIcon.spotify, icon: JustMusicIcon.spotify,
label: 'Lier un compte Spotify', label: 'Lier un compte Spotify',
action: null, action: null,
), ),
SettingPartComponent(
icon: JustMusicIcon.password,
label: 'Modifier mon mot de passe',
action: _openPassword,
),
const SettingPartComponent( const SettingPartComponent(
icon: JustMusicIcon.trash, icon: JustMusicIcon.trash,
label: 'Supprimer mon compte', label: 'Supprimer mon compte',

@ -36,7 +36,7 @@ class _RegistrationScreenState extends State<RegistrationScreen> {
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
SnackBar( SnackBar(
content: Text( content: Text(
e.toString() ?? "", e.toString(),
style: GoogleFonts.plusJakartaSans(color: Colors.white, fontWeight: FontWeight.w400, fontSize: 20.h), style: GoogleFonts.plusJakartaSans(color: Colors.white, fontWeight: FontWeight.w400, fontSize: 20.h),
), ),
backgroundColor: Colors.red, backgroundColor: Colors.red,
@ -276,6 +276,7 @@ class _RegistrationScreenState extends State<RegistrationScreen> {
width: 600, width: 600,
child: LoginButton( child: LoginButton(
callback: handleRegister, callback: handleRegister,
text: "Continuer",
)), )),
), ),
Align( Align(

@ -1,5 +1,7 @@
import 'dart:io'; import 'dart:io';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/Material.dart'; import 'package:flutter/Material.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
@ -10,11 +12,11 @@ import 'package:image_picker/image_picker.dart';
import '../components/profile_component.dart'; import '../components/profile_component.dart';
import '../components/recap_component.dart'; import '../components/recap_component.dart';
import '../main.dart'; import '../main.dart';
import '../model/User.dart'; import '../model/User.dart' as UserJstMusic;
import '../values/constants.dart'; import '../values/constants.dart';
class UserScreen extends StatefulWidget { class UserScreen extends StatefulWidget {
final User user; final UserJstMusic.User user;
const UserScreen({super.key, required this.user}); const UserScreen({super.key, required this.user});
@override @override

@ -75,7 +75,7 @@ class _VerifyEmailScreenState extends State<VerifyEmailScreen> {
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
SnackBar( SnackBar(
content: Text( content: Text(
e.toString() ?? "", e.toString(),
style: GoogleFonts.plusJakartaSans(color: Colors.white, fontWeight: FontWeight.w400, fontSize: 20.h), style: GoogleFonts.plusJakartaSans(color: Colors.white, fontWeight: FontWeight.w400, fontSize: 20.h),
), ),
backgroundColor: Colors.red, backgroundColor: Colors.red,
@ -144,6 +144,7 @@ class _VerifyEmailScreenState extends State<VerifyEmailScreen> {
width: 600, width: 600,
child: LoginButton( child: LoginButton(
callback: checkEmailVerified, callback: checkEmailVerified,
text: "Continuer",
)), )),
), ),
Align( Align(

@ -5,7 +5,8 @@ enum JustMusicIcon {
cross, cross,
history, history,
theme, theme,
notification notification,
password,
} }
extension MyIconExtension on JustMusicIcon { extension MyIconExtension on JustMusicIcon {
@ -25,7 +26,8 @@ extension MyIconExtension on JustMusicIcon {
return 'assets/images/theme_icon.png'; return 'assets/images/theme_icon.png';
case JustMusicIcon.notification: case JustMusicIcon.notification:
return 'assets/images/notification_icon.png'; return 'assets/images/notification_icon.png';
case JustMusicIcon.password:
return 'assets/images/password_icon.png';
default: default:
throw 'assets/images/unknown.png'; throw 'assets/images/unknown.png';
} }

Loading…
Cancel
Save