import 'dart:convert'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:teso/Classes/API%20Clasess/ResetClass.dart'; import 'package:teso/Pages/PageWidgets/Login/validation.dart'; import 'package:teso/util/consts.dart'; import 'dart:math' as math; import 'Pages/PageWidgets/Login/passwordSignUP.dart'; import 'package:http/http.dart' as http; class ResetPassword extends StatefulWidget { final String resetID; const ResetPassword({Key key, this.resetID}) : super(key: key); @override _ResetPasswordState createState() => _ResetPasswordState(); } class _ResetPasswordState extends State with TickerProviderStateMixin { TextEditingController password = new TextEditingController(); AnimationController _controller; Animation _fabScale; bool eightChars = false; bool specialChar = false; bool upperCaseChar = false; bool lowerCaseChar = false; bool number = false; bool changing = false; @override void dispose() { super.dispose(); } changePassword(context) async { setState(() { changing = true; }); Map requestHeaders = { 'Content-type': 'application/json', }; var register2 = serverLocation + 'resetpassword/reset'; ResetClass resetClass = ResetClass(password: password.text, resetGuid: widget.resetID); var client1 = await http.post( Uri.parse(register2), body: json.encode(resetClass), headers: requestHeaders, ); if (client1.statusCode == 200) { await tesoSuccessDialog(context); setState(() { changing = false; }); Future.delayed(const Duration(seconds: 5), () { Navigator.of(context).pop(); Navigator.of(context).pop(); }); } else if (client1.statusCode == 400 && client1.body == "expired") { tesoErrorDialog(context); } else { tesoErrorDialog(context); } } tesoSuccessDialog(context) { showDialog( context: context, builder: (BuildContext bc) { return AlertDialog( title: Text( "Success", style: TextStyle(color: Colors.green[400]), ), actions: [ TextButton( child: Text( 'OK', style: TextStyle(color: Colors.green[400]), ), onPressed: () { Navigator.of(context).pop(true); }, ), ], //title: Text("Alert Dialog"), content: Text( "Password changed successfully", style: TextStyle(color: Colors.green[400]), ), ); }); } tesoErrorDialog(context) { showDialog( context: context, builder: (BuildContext bc) { return AlertDialog( title: Text( "Error Occurred", style: TextStyle(color: Colors.red[400]), ), actions: [ TextButton( child: Text( 'OK', style: TextStyle(color: Colors.red[400]), ), onPressed: () { Navigator.of(context).pop(); }, ), ], //title: Text("Alert Dialog"), content: Text( "An error occurred while changing password, please try again!", style: TextStyle(color: Colors.red[400]), ), ); }); } tesoExpiredDialog(context) { showDialog( context: context, builder: (BuildContext bc) { return AlertDialog( title: Text( "Link Expired", style: TextStyle(color: Colors.red[400]), ), actions: [ TextButton( child: Text( 'OK', style: TextStyle(color: Colors.red[400]), ), onPressed: () { Navigator.of(context).pop(); }, ), ], //title: Text("Alert Dialog"), content: Text( "Password reset link expired, please try again with a new link!", style: TextStyle(color: Colors.red[400]), ), ); }); } bool _allValid() { return eightChars && number && specialChar && upperCaseChar && lowerCaseChar; } @override void initState() { super.initState(); password.addListener(() { setState(() { eightChars = password.text.length >= 8; number = password.text.contains(RegExp(r'\d'), 0); upperCaseChar = password.text.contains(new RegExp(r'[A-Z]'), 0); lowerCaseChar = password.text.contains(new RegExp(r'[a-z]'), 0); specialChar = password.text.isNotEmpty && !password.text.contains(RegExp(r'^[\w&.-]+$'), 0); }); if (_allValid()) { _controller.forward(); } else { _controller.reverse(); } }); _controller = AnimationController( vsync: this, duration: const Duration(milliseconds: 500)); _fabScale = Tween(begin: 0, end: 1) .animate(CurvedAnimation(parent: _controller, curve: Curves.bounceOut)); _fabScale.addListener(() { setState(() {}); }); } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.white, appBar: AppBar( backgroundColor: Colors.white, title: Text("Reset your Teso password"), automaticallyImplyLeading: false, ), body: Container( height: MediaQuery.of(context).size.height * 0.9, child: SingleChildScrollView( scrollDirection: Axis.vertical, child: new Column( children: [ Container( padding: EdgeInsets.all(10), width: double.infinity, margin: EdgeInsets.only( bottom: MediaQuery.of(context).size.height * 0.02, top: MediaQuery.of(context).size.height * 0.02, ), child: Center( child: Text( "Enter a password with a minimum of 8 characters and the password must have at least an uppercase letter, a lowercase letter, " + "a digit and a non-alphanumeric character", textAlign: TextAlign.center, style: TextStyle( color: Colors.grey, ), ), ), ), Container( padding: EdgeInsets.symmetric( horizontal: (MediaQuery.of(context).size.width) * 0.01), child: _validationStack()), SizedBox( height: 50, ), createPassword(context, password), SizedBox(height: MediaQuery.of(context).size.height * 0.002), Visibility( visible: !changing, child: Container( margin: EdgeInsets.only(top: 20), width: MediaQuery.of(context).size.width * 0.6, height: 40.0, decoration: BoxDecoration( gradient: LinearGradient( begin: Alignment.topCenter, end: Alignment.bottomCenter, colors: [ accentMain, darkAccent, ], // stops: [0.1, 0.4, 0.7, 0.8], ), boxShadow: [ BoxShadow( color: Colors.grey[500], offset: Offset(0.0, 1.5), blurRadius: 1.5, ), ]), child: Material( shape: RoundedRectangleBorder( borderRadius: BorderRadius.all( Radius.circular(25.0), ), ), color: Colors.transparent, child: InkWell( onTap: () async { if (_allValid()) { await changePassword(context); } }, child: Center( child: Text( "Reset Password", style: TextStyle( fontSize: 18, color: Colors.white, ), ), )), ), ), ), Visibility( visible: changing, child: Container( width: MediaQuery.of(context).size.width, height: MediaQuery.of(context).size.height, child: Center( child: CupertinoActivityIndicator( animating: true, radius: 15, ), ), ), ), ], ), ), ), ); } Widget _separator() { return Container( height: 1, decoration: BoxDecoration(color: Colors.blue.withAlpha(100)), ); } Stack _validationStack() { return Stack( alignment: Alignment.bottomLeft, children: [ Card( shape: CircleBorder(), color: Colors.black12, child: Container( height: 150, width: 150, ), ), Padding( padding: const EdgeInsets.only(bottom: 32.0, left: 10), child: Transform.rotate( angle: -math.pi / 20, child: Icon( Icons.lock, color: Colors.pink, size: 60, ), ), ), Padding( padding: const EdgeInsets.only(left: 50.0, right: 60), child: Transform.rotate( angle: -math.pi / -60, child: Card( shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(5)), elevation: 4, color: Colors.yellow.shade800, child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ Padding( padding: const EdgeInsets.fromLTRB(8, 8, 0, 4), child: Container( alignment: Alignment.centerLeft, child: Icon( Icons.brightness_1, color: Colors.deepPurple, )), ), Padding( padding: const EdgeInsets.fromLTRB(8, 4, 0, 4), child: Container( alignment: Alignment.centerLeft, child: Icon( Icons.brightness_1, color: Colors.deepPurple, )), ), Padding( padding: const EdgeInsets.fromLTRB(8, 4, 0, 4), child: Container( alignment: Alignment.centerLeft, child: Icon( Icons.brightness_1, color: Colors.deepPurple, )), ), Padding( padding: const EdgeInsets.fromLTRB(8, 4, 0, 8), child: Container( alignment: Alignment.centerLeft, child: Icon( Icons.brightness_1, color: Colors.deepPurple, )), ), ], ), ), ), ), Padding( padding: const EdgeInsets.only(left: 74), child: Transform.rotate( angle: math.pi / -45, child: Card( elevation: 6, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(5)), child: Stack( alignment: Alignment.bottomRight, children: [ IntrinsicWidth( child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ ValidationItem("8 or more Characters", eightChars), _separator(), ValidationItem("1 Special character", specialChar), _separator(), ValidationItem("1 Upper case", upperCaseChar), _separator(), ValidationItem("1 Lower case", lowerCaseChar), _separator(), ValidationItem("1 Number", number) ], ), ), Padding( padding: const EdgeInsets.all(8.0), child: Transform.scale( scale: _fabScale.value, child: Card( shape: CircleBorder(), color: Colors.green, child: Padding( padding: const EdgeInsets.all(8.0), child: Icon( Icons.check, color: Colors.white, ), ), ), ), ) ], ), ), ), ) ], ); } }