From 87ddf05e77d194b80389f6e5e64561310a72db9e Mon Sep 17 00:00:00 2001 From: Moe <moe@chocola.dev> Date: Mon, 23 May 2022 01:06:14 +0700 Subject: [PATCH] Add otp feature --- lib/components/login_form.dart | 18 ++++++---- lib/components/otp_body.dart | 63 ++++++++++++++++++++++++---------- lib/screens/otp.dart | 6 ++-- 3 files changed, 60 insertions(+), 27 deletions(-) diff --git a/lib/components/login_form.dart b/lib/components/login_form.dart index 4ee1e74..1194402 100644 --- a/lib/components/login_form.dart +++ b/lib/components/login_form.dart @@ -4,6 +4,7 @@ import 'package:flutter/material.dart'; import 'package:nekoya_flutter/api/api.dart'; import 'package:nekoya_flutter/components/menu.dart'; import 'package:nekoya_flutter/data/auth.dart'; +import 'package:nekoya_flutter/screens/otp.dart'; import 'package:nekoya_flutter/utils/utils.dart'; class LoginForm extends StatefulWidget { @@ -161,12 +162,17 @@ class LoginFormState extends State<LoginForm> { } else { submitForm(context).then((res) { if (res['statusCode'] == 200) { - addSession(res['data']['id'], res['data']['session_token']); - Navigator.pop(context); - Navigator.pushReplacement( - context, - MaterialPageRoute( - builder: (context) => const Menu(initialScreen: 2))); + if (!res['data']['otp']) { + addSession(res['data']['id'], res['data']['session_token']); + Navigator.pop(context); + Navigator.pushReplacement(context, MaterialPageRoute( + builder: (context) => const Menu(initialScreen: 2) + )); + } else { + Navigator.push(context, MaterialPageRoute( + builder: (context) => Otp(otpToken: res['data']['token']) + )); + } } else if (res['statusCode'] == 204) { showEmailNotRegister(context); } else if (res['statusCode'] == 205) { diff --git a/lib/components/otp_body.dart b/lib/components/otp_body.dart index 95dff1d..77d32d8 100644 --- a/lib/components/otp_body.dart +++ b/lib/components/otp_body.dart @@ -2,14 +2,41 @@ import 'package:lottie/lottie.dart'; import 'package:flutter/services.dart'; import 'package:flutter/material.dart'; +import 'package:nekoya_flutter/api/api.dart'; +import 'package:nekoya_flutter/components/menu.dart'; +import 'package:nekoya_flutter/data/auth.dart'; + class OtpBody extends StatefulWidget { - const OtpBody({Key? key}) : super(key: key); + const OtpBody({Key? key, required this.otpToken}) : super(key: key); + + final String otpToken; @override State<OtpBody> createState() => _OtpBodyState(); } class _OtpBodyState extends State<OtpBody> { + TextEditingController otpCode1 = TextEditingController(); + TextEditingController otpCode2 = TextEditingController(); + TextEditingController otpCode3 = TextEditingController(); + TextEditingController otpCode4 = TextEditingController(); + TextEditingController otpCode5 = TextEditingController(); + TextEditingController otpCode6 = TextEditingController(); + + Future submitForm(BuildContext context) async { + if (otpCode1.text.isEmpty || otpCode2.text.isEmpty || otpCode3.text.isEmpty || otpCode4.text.isEmpty || otpCode5.text.isEmpty || otpCode6.text.isEmpty) { + return 999; + } else { + Map<String, dynamic> data = { + "token": widget.otpToken, + "code": "${otpCode1.text}${otpCode2.text}${otpCode3.text}${otpCode4.text}${otpCode5.text}${otpCode6.text}" + }; + + var response = await otpPost(data); + return {'statusCode': response['statusCode'], 'data': response['data']}; + } + } + @override Widget build(BuildContext context) { return Container( @@ -41,6 +68,7 @@ class _OtpBodyState extends State<OtpBody> { height: 50, width: 50, child: TextFormField( + controller: otpCode1, onChanged: (value) { if (value.length == 1) { FocusScope.of(context).nextFocus(); @@ -72,6 +100,7 @@ class _OtpBodyState extends State<OtpBody> { height: 50, width: 50, child: TextFormField( + controller: otpCode2, onChanged: (value) { if (value.length == 1) { FocusScope.of(context).nextFocus(); @@ -103,6 +132,7 @@ class _OtpBodyState extends State<OtpBody> { height: 50, width: 50, child: TextFormField( + controller: otpCode3, onChanged: (value) { if (value.length == 1) { FocusScope.of(context).nextFocus(); @@ -134,6 +164,7 @@ class _OtpBodyState extends State<OtpBody> { height: 50, width: 50, child: TextFormField( + controller: otpCode4, onChanged: (value) { if (value.length == 1) { FocusScope.of(context).nextFocus(); @@ -165,6 +196,7 @@ class _OtpBodyState extends State<OtpBody> { height: 50, width: 50, child: TextFormField( + controller: otpCode5, onChanged: (value) { if (value.length == 1) { FocusScope.of(context).nextFocus(); @@ -196,6 +228,7 @@ class _OtpBodyState extends State<OtpBody> { height: 50, width: 50, child: TextFormField( + controller: otpCode6, onChanged: (value) { if (value.length == 1) { FocusScope.of(context).nextFocus(); @@ -222,23 +255,6 @@ class _OtpBodyState extends State<OtpBody> { ], ), )), - Container( - padding: const EdgeInsets.only(top: 15, bottom: 15), - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, - children: const [ - Text( - "Didn't get it?? \t", - style: TextStyle(color: Colors.white), - ), - Text( - 'Resend Code', - style: TextStyle(color: Colors.red), - ), - ], - ), - ), ElevatedButton( style: ButtonStyle( foregroundColor: @@ -250,7 +266,16 @@ class _OtpBodyState extends State<OtpBody> { borderRadius: BorderRadius.circular(18.0), side: const BorderSide(color: Colors.black)))), onPressed: () { - Navigator.pushNamed(context, '/login'); + submitForm(context).then((res) { + if (res['statusCode'] == 200) { + addSession(res['data']['id'], res['data']['session_token']); + Navigator.pop(context); + Navigator.pop(context); + Navigator.pushReplacement(context, MaterialPageRoute( + builder: (context) => const Menu(initialScreen: 2) + )); + } + }); }, child: const Text( 'Submit', diff --git a/lib/screens/otp.dart b/lib/screens/otp.dart index 0c6535b..4f8a3bf 100644 --- a/lib/screens/otp.dart +++ b/lib/screens/otp.dart @@ -3,7 +3,9 @@ import 'package:flutter/material.dart'; import 'package:nekoya_flutter/components/otp_body.dart'; class Otp extends StatefulWidget { - const Otp({Key? key}) : super(key: key); + const Otp({Key? key, required this.otpToken}) : super(key: key); + + final String otpToken; @override State<Otp> createState() => _OtpState(); @@ -19,7 +21,7 @@ class _OtpState extends State<Otp> { centerTitle: true, backgroundColor: const Color(0xff212226), ), - body: const OtpBody(), + body: OtpBody(otpToken: widget.otpToken,), ); } }