diff --git a/lib/src/controller/login_controller.dart b/lib/src/controller/login_controller.dart index 6b1b673..0f375ce 100644 --- a/lib/src/controller/login_controller.dart +++ b/lib/src/controller/login_controller.dart @@ -18,15 +18,13 @@ class LoginController implements LoginInterface { LoginController(this._api); Widget build(BuildContext context) { - return Provider( + return ChangeNotifierProvider( create: (context) => LoginProvider(""), child: LoginScreen(this), ); } void sendOtp(BuildContext context) async { - Scaffold.of(context).hideCurrentSnackBar(); - this._sendOtpLock.synchronized(() async { if (this._sendOtpClicked) { return; @@ -34,10 +32,10 @@ class LoginController implements LoginInterface { this._sendOtpClicked = true; } - try { - LoginProvider loginProvider = - Provider.of(context, listen: false); + LoginProvider loginProvider = + Provider.of(context, listen: false); + try { RegExp regExp = new RegExp( r"^\+62\d{10,12}", caseSensitive: false, @@ -45,9 +43,7 @@ class LoginController implements LoginInterface { ); if (regExp.hasMatch(loginProvider.phoneNumber()) == false) { - Scaffold.of(context).showSnackBar(SnackBar( - content: Text("Nomor telfon tidak valid"), - )); + loginProvider.setErrorString("Nomor telfon tidak valid"); return; } @@ -58,17 +54,15 @@ class LoginController implements LoginInterface { print(otpSerializer.phoneNumber.toString()); print(otpSerializer.sentTime.toString()); + loginProvider.setErrorString(""); Navigator.of(context).pushNamed('/otp', arguments: otpSerializer); } on APIException catch (e, backtrace) { - Scaffold.of(context).hideCurrentSnackBar(); - Scaffold.of(context).showSnackBar(SnackBar( - content: Text(e.error.firstError().detail), - )); - + loginProvider.setErrorString(e.error.firstError().detail); print("API ERROR: " + e.toString()); print("STACKTRACE: " + backtrace.toString()); } catch (e, backtrace) { + loginProvider.setErrorString("Telah terjadi error pad aplikasi"); print("ERROR: " + e.toString()); print("STACKTRACE: " + backtrace.toString()); } finally { diff --git a/lib/src/controller/otp_controller.dart b/lib/src/controller/otp_controller.dart index 1c3919f..3987223 100644 --- a/lib/src/controller/otp_controller.dart +++ b/lib/src/controller/otp_controller.dart @@ -22,7 +22,7 @@ class OTPController implements OTPInterface { Widget build(BuildContext context) { this._otpSerializer = ModalRoute.of(context).settings.arguments; - return Provider( + return ChangeNotifierProvider( create: (context) => OTPProvider(), child: OTPScreen(this), ); @@ -36,25 +36,21 @@ class OTPController implements OTPInterface { Scaffold.of(context).hideCurrentSnackBar(); this._submitOTPLock.synchronized(() async { - try { - if (this._submitOTPClicked) { - return; - } else { - this._submitOTPClicked = true; - } + if (this._submitOTPClicked) { + return; + } else { + this._submitOTPClicked = true; + } - OTPProvider otpProvider = - Provider.of(context, listen: false); + OTPProvider otpProvider = + Provider.of(context, listen: false); + try { if (otpProvider.otpString().length < 4) { - Scaffold.of(context).showSnackBar(SnackBar( - content: Text("Kode OTP tidak valid"), - )); + otpProvider.setErrorString("Kode OTP tidak valid"); return; } - print("OTP STRING: " + otpProvider.otpString()); - LoginSerializer loginSerializer = await this._api.auth().login( context, phoneNumber: this._otpSerializer.phoneNumber, @@ -69,19 +65,20 @@ class OTPController implements OTPInterface { Provider.of(context, listen: false); await authProvider.authorize(loginSerializer); + otpProvider.setErrorString(""); + Navigator.of(context).pushNamedAndRemoveUntil( '/timeline', (Route route) => false); } on APIException catch (e, backtrace) { - Scaffold.of(context).hideCurrentSnackBar(); - Scaffold.of(context).showSnackBar(SnackBar( - content: Text(e.error.firstError().detail), - )); + otpProvider.setErrorString(e.error.firstError().detail); print("API ERROR: " + e.toString()); print("API STATUS CODE: " + e.statusCode.toString()); print("DETAIL: " + e.error.firstError().detail); print("STACKTRACE: " + backtrace.toString()); } catch (e, backtrace) { + otpProvider.setErrorString("Telah terjadi kesalahan pada aplikasi"); + print("ERROR: " + e.toString()); print("STACKTRACE: " + backtrace.toString()); } finally { diff --git a/lib/src/provider/login_provider.dart b/lib/src/provider/login_provider.dart index c153ad2..db34409 100644 --- a/lib/src/provider/login_provider.dart +++ b/lib/src/provider/login_provider.dart @@ -1,13 +1,20 @@ -class LoginProvider { +import 'package:flutter/widgets.dart'; + +class LoginProvider with ChangeNotifier { LoginProvider(this._phoneNumber); String _phoneNumber; + String phoneNumber() => _phoneNumber; - String phoneNumber() { - return "+62" + this._phoneNumber; - } + String _errorString; + String errorString() => _errorString; void setPhoneNumber(String phoneNumber) { - this._phoneNumber = phoneNumber; + this._phoneNumber = "+62" + phoneNumber; + } + + void setErrorString(String errorString) { + this._errorString = errorString; + notifyListeners(); } } diff --git a/lib/src/provider/otp_provider.dart b/lib/src/provider/otp_provider.dart index 5674458..beba39a 100644 --- a/lib/src/provider/otp_provider.dart +++ b/lib/src/provider/otp_provider.dart @@ -1,6 +1,16 @@ -class OTPProvider { +import 'package:flutter/widgets.dart'; + +class OTPProvider with ChangeNotifier { final List _otp = List(4); + String _errorString; + String errorString() => _errorString; + + void setErrorString(String errorString) { + this._errorString = errorString; + notifyListeners(); + } + void setOTP(String digit, int index) { this._otp[index] = digit; } diff --git a/lib/src/screen/component/alert_text.dart b/lib/src/screen/component/alert_text.dart new file mode 100644 index 0000000..327c5a3 --- /dev/null +++ b/lib/src/screen/component/alert_text.dart @@ -0,0 +1,19 @@ +import 'package:flutter/material.dart'; + +class AlertText extends StatelessWidget { + final String text; + + AlertText(this.text); + + @override + Widget build(BuildContext context) { + return Text( + this.text, + style: TextStyle( + fontFamily: 'Hind', + fontSize: 14, + color: Colors.red, + ), + ); + } +} diff --git a/lib/src/screen/login_screen.dart b/lib/src/screen/login_screen.dart index 58770ac..40c8d87 100644 --- a/lib/src/screen/login_screen.dart +++ b/lib/src/screen/login_screen.dart @@ -1,6 +1,8 @@ import 'package:coronator/src/core/color.dart'; import 'package:coronator/src/interface/login_interface.dart'; import 'package:coronator/src/provider/login_provider.dart'; +import 'package:coronator/src/screen/component/alert_text.dart'; +import 'package:coronator/src/screen/component/button.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:provider/provider.dart'; @@ -73,45 +75,29 @@ class LoginScreen extends StatelessWidget { style: TextStyle(fontFamily: 'Hind', fontSize: 16), ), SizedBox( - height: 75, + height: 10, + ), + Consumer( + builder: (_, loginProvider, __) { + if (loginProvider.errorString() == null) { + return Container(); + } + + return AlertText(loginProvider.errorString()); + }, + ), + SizedBox( + height: 10, ), Row( mainAxisAlignment: MainAxisAlignment.end, children: [ - Stack( - children: [ - Container( - padding: EdgeInsets.all(15), - child: Text( - "KIRIM OTP", - textAlign: TextAlign.center, - style: TextStyle( - color: Colors.white, - ), - ), - width: 150, - decoration: BoxDecoration( - color: CustomColor.redTheme.withAlpha(255), - borderRadius: - BorderRadius.all(Radius.circular(50)), - ), - ), - Positioned.fill( - child: Material( - color: Colors.transparent, - borderRadius: - BorderRadius.all(Radius.circular(50)), - child: InkWell( - borderRadius: - BorderRadius.all(Radius.circular(50)), - splashColor: CustomColor.wewak, - onTap: () { - this.interface.sendOtp(context); - }, - ), - ), - ) - ], + Button( + buttonText: "KIRIM OTP", + onTap: () { + this.interface.sendOtp(context); + }, + width: 150, ), ], ), diff --git a/lib/src/screen/otp_screen.dart b/lib/src/screen/otp_screen.dart index 9ca6ddb..7c3fb5f 100644 --- a/lib/src/screen/otp_screen.dart +++ b/lib/src/screen/otp_screen.dart @@ -1,6 +1,8 @@ import 'package:coronator/src/core/color.dart'; import 'package:coronator/src/interface/otp_interface.dart'; import 'package:coronator/src/provider/otp_provider.dart'; +import 'package:coronator/src/screen/component/alert_text.dart'; +import 'package:coronator/src/screen/component/button.dart'; import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import 'package:provider/provider.dart'; @@ -78,6 +80,23 @@ class OTPScreen extends StatelessWidget { SizedBox( height: 30, ), + Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Consumer( + builder: (_, otpProvider, __) { + if (otpProvider.errorString() == null) { + return Container(); + } + + return AlertText(otpProvider.errorString()); + }, + ), + ], + ), + SizedBox( + height: 10, + ), Row( mainAxisAlignment: MainAxisAlignment.end, children: [ @@ -101,40 +120,11 @@ class OTPScreen extends StatelessWidget { Row( mainAxisAlignment: MainAxisAlignment.end, children: [ - Stack( - children: [ - Container( - padding: EdgeInsets.all(15), - child: Text( - "SUBMIT", - textAlign: TextAlign.center, - style: TextStyle( - color: Colors.white, - ), - ), - width: 150, - decoration: BoxDecoration( - color: CustomColor.redTheme.withAlpha(255), - borderRadius: - BorderRadius.all(Radius.circular(50)), - ), - ), - Positioned.fill( - child: Material( - color: Colors.transparent, - borderRadius: - BorderRadius.all(Radius.circular(50)), - child: InkWell( - borderRadius: - BorderRadius.all(Radius.circular(50)), - splashColor: CustomColor.wewak, - onTap: () { - this.interface.submitOTP(context); - }, - ), - ), - ) - ], + Button( + buttonText: "SUBMIT", + onTap: () { + this.interface.submitOTP(context); + }, ), ], ),