0% found this document useful (0 votes)
2 views

code

The document is a Flutter Dart code for an OTP (One-Time Password) page in a mobile application. It includes functionality for inputting a 5-digit code, verifying it against a generated code, and navigating to a reset password page upon successful verification. The code also manages user input, error handling, and UI elements for the OTP input fields.

Uploaded by

meredo3985
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views

code

The document is a Flutter Dart code for an OTP (One-Time Password) page in a mobile application. It includes functionality for inputting a 5-digit code, verifying it against a generated code, and navigating to a reset password page upon successful verification. The code also manages user input, error handling, and UI elements for the OTP input fields.

Uploaded by

meredo3985
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 13

import 'dart:math';

import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:hexcolor/hexcolor.dart';
import 'package:my_tasklist/views/reset_password.dart';
import
'package:page_animation_transition/animations/right_to_left_faded_transition.dart';
import 'package:page_animation_transition/page_animation_transition.dart';
import 'package:shared_preferences/shared_preferences.dart';

import '../models/my_button_styles.dart';
import '../models/my_text_styles.dart';

class OtpPage extends StatefulWidget {


const OtpPage({super.key});

@override
State<OtpPage> createState() => _OtpPageState();
}

class _OtpPageState extends State<OtpPage> {


//
// Controllers
final TextEditingController _firstController = TextEditingController();
final TextEditingController _secondController = TextEditingController();
final TextEditingController _thirdController = TextEditingController();
final TextEditingController _fourthController = TextEditingController();
final TextEditingController _fifthController = TextEditingController();

// Errors
String? _firstFieldError,
_secondFieldError,
_thirdFieldError,
_fourthFieldError,
_fifthFieldError;

// FocusNode
final FocusNode _firstField = FocusNode();
final FocusNode _secondField = FocusNode();
final FocusNode _thirdField = FocusNode();
final FocusNode _fourthField = FocusNode();
final FocusNode _fifthField = FocusNode();

// Strings
String firstDigit = "",
secondDigit = "",
thirdDigit = "",
fourthDigit = "",
fifthDigit = "";

// int
int codeGenerated = 0;

// Form's key
final _formKey = GlobalKey<FormState>();
//String
String email = "";

// Get email
Future getEmail() async {
final prefs = await SharedPreferences.getInstance();
email = prefs.getString("email") ?? "example...@gmail.com";
}

// Send code
void sendCode() {
// Generate a code
setState(() {
Random random = Random();
codeGenerated = 10000 + random.nextInt(99999);
// Send this code generated by email

// debug
if (kDebugMode) {
return print("===> This the code generated : $codeGenerated <===");
}
});
}

// Verify code
void verifyCode() {
int codeTapped = 0;
setState(() {
// Check if the fields aren't empty
if (firstDigit.isEmpty &&
secondDigit.isEmpty &&
thirdDigit.isEmpty &&
fourthDigit.isEmpty &&
fifthDigit.isEmpty) {
// Enable errors
_firstFieldError = "";
_secondFieldError = "";
_thirdFieldError = "";
_fourthFieldError = "";
_fifthFieldError = "";
} else {
// Check each field to how which one is empty
if (firstDigit.isNotEmpty) {
if (secondDigit.isNotEmpty) {
if (thirdDigit.isNotEmpty) {
if (fourthDigit.isNotEmpty) {
if (fifthDigit.isNotEmpty) {
// Unable errors
_firstFieldError = null;
_secondFieldError = null;
_thirdFieldError = null;
_fourthFieldError = null;
_fifthFieldError = null;
// Get code tapped
codeTapped = int.parse(firstDigit +
secondDigit +
thirdDigit +
fourthDigit +
fifthDigit);
// Compare the number tapped and code generated
if (codeTapped == codeGenerated) {
// Go to the reset password page
Navigator.of(context).pushReplacement(
PageAnimationTransition(
page: const ResetPassword(),
pageAnimationType: RightToLeftFadedTransition()));
} else {
// Enable errors
_firstFieldError = "";
_secondFieldError = "";
_thirdFieldError = "";
_fourthFieldError = "";
_fifthFieldError = "";

// Show a error message through a snackbar


ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text(
"Sorry ! the number tapped is incorrect.",
style: MyTextStyles.bodyText.copyWith(
color: Colors.white,
fontSize: 14,
fontWeight: FontWeight.bold),
),
duration: const Duration(seconds: 2),
backgroundColor: Colors.red[900],
dismissDirection: DismissDirection.down,
));
}
} else {
// Enable error 5
_fifthFieldError = "";
}
} else {
// Enable error 4
_fourthFieldError = "";
}
} else {
// Enable error 3
_thirdFieldError = "";
}
} else {
// Enable error 2
_secondFieldError = "";
}
} else {
// Enable error 1
_firstFieldError = "";
}
}
});
}

@override
void initState() {
super.initState();
// Get email's user
getEmail();
}

@override
void dispose() {
super.dispose();
// Dispose controllers
// that means empty the fields memory
_firstController.dispose();
_secondController.dispose();
_thirdController.dispose();
_fourthController.dispose();
_fifthController.dispose();

// Dispose Focus
_firstField.dispose();
_secondField.dispose();
_thirdField.dispose();
_fourthField.dispose();
_fifthField.dispose();
}

//
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
extendBody: true,
body: GestureDetector(
// Disable the focus of all the fields
onTap: () => FocusScope.of(context).unfocus(),
//
child: SafeArea(
minimum:
const EdgeInsets.only(left: 30, top: 50, right: 30, bottom: 20),
child: SingleChildScrollView(
child: Column(
children: [
//
// Back IconButton
Row(
children: [
CircleAvatar(
backgroundColor: Colors.grey[300],
foregroundColor: Colors.grey,
radius: 23,
child: IconButton(
onPressed: () => Navigator.of(context).pop(),
icon: const Icon(
Icons.arrow_back_ios_new_rounded,
color: Colors.black,
size: 20,
),
),
),
],
),
//
// Space
const SizedBox(
height: 30,
),
// Forgot Password Page
Align(
alignment: Alignment.centerLeft,
child: Text(
"Check your email",
style: MyTextStyles.heading.copyWith(
color: Colors.black,
fontSize: 25,
),
),
),
//
// Subtitle
Padding(
padding: const EdgeInsets.only(top: 10),
child: Align(
alignment: Alignment.centerLeft,
child: Text.rich(
TextSpan(
text: "We send a reset link to ",
style: MyTextStyles.hintStyle.copyWith(
fontSize: 13, fontWeight: FontWeight.bold),
children: [
TextSpan(
text: email,
style: MyTextStyles.bodyText.copyWith(
color: Colors.black,
fontSize: 13,
fontWeight: FontWeight.bold)),
TextSpan(
text:
" enter 5 digit code that mentioned in the email.
",
style: MyTextStyles.hintStyle.copyWith(
fontSize: 13, fontWeight: FontWeight.bold),
),
TextSpan(
text: "This the code : $codeGenerated",
style: MyTextStyles.hintStyle.copyWith(
fontWeight: FontWeight.bold,
fontSize: 13,
color: HexColor("#2EE78A")))
],
),
),
),
),
//
// Space
const SizedBox(
height: 50,
),
//
// Form
Form(
key: _formKey,
// Row of field
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
//
// field 1
Padding(
padding: const EdgeInsets.all(5.0),
child: SizedBox(
height: 58,
width: 50,
child: TextFormField(
controller: _firstController,
focusNode: _firstField,
style: MyTextStyles.bodyText.copyWith(
color: HexColor("#253036"),
fontWeight: FontWeight.bold,
fontSize: 20),
textAlign: TextAlign.center,
decoration: InputDecoration(
hintText: "1",
hintStyle: MyTextStyles.hintStyle.copyWith(
fontSize: 20,
fontWeight: FontWeight.bold,
),
errorText: _firstFieldError,
errorStyle: MyTextStyles.errorStyle,
errorBorder: UnderlineInputBorder(
borderRadius: BorderRadius.circular(0),
borderSide: const BorderSide(
color: Colors.red,
width: 3,
),
),
focusedErrorBorder: UnderlineInputBorder(
borderRadius: BorderRadius.circular(0),
borderSide: const BorderSide(
color: Colors.red,
width: 3,
),
),
focusedBorder: UnderlineInputBorder(
borderRadius: BorderRadius.circular(0),
borderSide: BorderSide(
color: HexColor("#253036"),
width: 3,
),
),
// disabledBorder: OutlineInputBorder(
// borderRadius: BorderRadius.circular(15),
// borderSide: const BorderSide(
// color: Colors.grey,
// width: 3,
// ),
// ),
),
keyboardType: TextInputType.number,
inputFormatters: [
// To limit the caracter to 1
LengthLimitingTextInputFormatter(1),
// To force caracter to be only a digit
FilteringTextInputFormatter.digitsOnly,
],
onChanged: (value) => setState(() {
// check if value isn't empty
if (value.length == 1) {
//
firstDigit = value;
// if value isn't empty, focus the next field
FocusScope.of(context).nextFocus();
} else {
// if value is empty, focus the previous field
FocusScope.of(context).previousFocus();
}
}),
),
),
),
//
// Field 2
Padding(
padding: const EdgeInsets.all(5.0),
child: SizedBox(
height: 58,
width: 50,
child: TextFormField(
controller: _secondController,
focusNode: _secondField,
style: MyTextStyles.bodyText.copyWith(
color: HexColor("#253036"),
fontWeight: FontWeight.bold,
fontSize: 20),
textAlign: TextAlign.center,
decoration: InputDecoration(
hintText: "2",
hintStyle: MyTextStyles.hintStyle.copyWith(
fontSize: 20,
fontWeight: FontWeight.bold,
),
errorText: _secondFieldError,
errorStyle: MyTextStyles.errorStyle,
errorBorder: UnderlineInputBorder(
borderRadius: BorderRadius.circular(0),
borderSide: const BorderSide(
color: Colors.red,
width: 3,
),
),
focusedErrorBorder: UnderlineInputBorder(
borderRadius: BorderRadius.circular(0),
borderSide: const BorderSide(
color: Colors.red,
width: 3,
),
),
focusedBorder: UnderlineInputBorder(
borderRadius: BorderRadius.circular(0),
borderSide: BorderSide(
color: HexColor("#253036"),
width: 3,
),
),
// disabledBorder: OutlineInputBorder(
// borderRadius: BorderRadius.circular(15),
// borderSide: const BorderSide(
// color: Colors.grey,
// width: 3,
// ),
// ),
),
keyboardType: TextInputType.number,
inputFormatters: [
// To limit the caracter to 1
LengthLimitingTextInputFormatter(1),
// To force caracter to be only a digit
FilteringTextInputFormatter.digitsOnly,
],
onChanged: (value) => setState(() {
// check if value isn't empty
if (value.trim() != "" ||
value.trim().isNotEmpty) {
//
secondDigit = value;
// if value isn't empty, focus the next field
FocusScope.of(context).nextFocus();
} else {
// if value is empty, focus the previous field
FocusScope.of(context).previousFocus();
}
}),
),
),
),
//
// Field 3
Padding(
padding: const EdgeInsets.all(5.0),
child: SizedBox(
height: 58,
width: 50,
child: TextFormField(
controller: _thirdController,
focusNode: _thirdField,
style: MyTextStyles.bodyText.copyWith(
color: HexColor("#253036"),
fontWeight: FontWeight.bold,
fontSize: 20),
textAlign: TextAlign.center,
decoration: InputDecoration(
hintText: "3",
hintStyle: MyTextStyles.hintStyle.copyWith(
fontSize: 20,
fontWeight: FontWeight.bold,
),
errorText: _thirdFieldError,
errorStyle: MyTextStyles.errorStyle,
errorBorder: UnderlineInputBorder(
borderRadius: BorderRadius.circular(0),
borderSide: const BorderSide(
color: Colors.red,
width: 3,
),
),
focusedErrorBorder: UnderlineInputBorder(
borderRadius: BorderRadius.circular(0),
borderSide: const BorderSide(
color: Colors.red,
width: 3,
),
),
focusedBorder: UnderlineInputBorder(
borderRadius: BorderRadius.circular(0),
borderSide: BorderSide(
color: HexColor("#253036"),
width: 3,
),
),
// disabledBorder: OutlineInputBorder(
// borderRadius: BorderRadius.circular(15),
// borderSide: const BorderSide(
// color: Colors.grey,
// width: 3,
// ),
// ),
),
keyboardType: TextInputType.number,
inputFormatters: [
// To limit the caracter to 1
LengthLimitingTextInputFormatter(1),
// To force caracter to be only a digit
FilteringTextInputFormatter.digitsOnly,
],
onChanged: (value) => setState(() {
// check if value isn't empty
if (value.trim() != "" ||
value.trim().isNotEmpty) {
//
thirdDigit = value;
// if value isn't empty, focus the next field
FocusScope.of(context).nextFocus();
} else {
// if value is empty, focus the previous field
FocusScope.of(context).previousFocus();
}
}),
),
),
),
//
// Field 4
Padding(
padding: const EdgeInsets.all(5.0),
child: SizedBox(
height: 58,
width: 50,
child: TextFormField(
controller: _fourthController,
focusNode: _fourthField,
style: MyTextStyles.bodyText.copyWith(
color: HexColor("#253036"),
fontWeight: FontWeight.bold,
fontSize: 20),
textAlign: TextAlign.center,
decoration: InputDecoration(
hintText: "4",
hintStyle: MyTextStyles.hintStyle.copyWith(
fontSize: 20,
fontWeight: FontWeight.bold,
),
errorText: _fourthFieldError,
errorStyle: MyTextStyles.errorStyle,
errorBorder: UnderlineInputBorder(
borderRadius: BorderRadius.circular(0),
borderSide: const BorderSide(
color: Colors.red,
width: 3,
),
),
focusedErrorBorder: UnderlineInputBorder(
borderRadius: BorderRadius.circular(0),
borderSide: const BorderSide(
color: Colors.red,
width: 3,
),
),
focusedBorder: UnderlineInputBorder(
borderRadius: BorderRadius.circular(0),
borderSide: BorderSide(
color: HexColor("#253036"),
width: 3,
),
),
// disabledBorder: OutlineInputBorder(
// borderRadius: BorderRadius.circular(15),
// borderSide: const BorderSide(
// color: Colors.grey,
// width: 3,
// ),
// ),
),
keyboardType: TextInputType.number,
inputFormatters: [
// To limit the caracter to 1
LengthLimitingTextInputFormatter(1),
// To force caracter to be only a digit
FilteringTextInputFormatter.digitsOnly,
],
onChanged: (value) => setState(() {
// check if value isn't empty
if (value.trim() != "" ||
value.trim().isNotEmpty) {
//
fourthDigit = value;
// if value isn't empty, focus the next field
FocusScope.of(context).nextFocus();
} else {
// if value is empty, focus the previous field
FocusScope.of(context).previousFocus();
}
}),
),
),
),
//
// Field 5
Padding(
padding: const EdgeInsets.all(5.0),
child: SizedBox(
height: 58,
width: 50,
child: TextFormField(
controller: _fifthController,
focusNode: _fifthField,
style: MyTextStyles.bodyText.copyWith(
color: HexColor("#253036"),
fontWeight: FontWeight.bold,
fontSize: 20),
textAlign: TextAlign.center,
decoration: InputDecoration(
hintText: "5",
hintStyle: MyTextStyles.hintStyle.copyWith(
fontSize: 20,
fontWeight: FontWeight.bold,
),
errorText: _fifthFieldError,
errorStyle: MyTextStyles.errorStyle,
errorBorder: UnderlineInputBorder(
borderRadius: BorderRadius.circular(0),
borderSide: const BorderSide(
color: Colors.red,
width: 3,
),
),
focusedErrorBorder: UnderlineInputBorder(
borderRadius: BorderRadius.circular(0),
borderSide: const BorderSide(
color: Colors.red,
width: 3,
),
),
focusedBorder: UnderlineInputBorder(
borderRadius: BorderRadius.circular(0),
borderSide: BorderSide(
color: HexColor("#253036"),
width: 3,
),
),
// disabledBorder: OutlineInputBorder(
// borderRadius: BorderRadius.circular(15),
// borderSide: const BorderSide(
// color: Colors.grey,
// width: 3,
// ),
// ),
),
keyboardType: TextInputType.number,
inputFormatters: [
// To limit the caracter to 1
LengthLimitingTextInputFormatter(1),
// To force caracter to be only a digit
FilteringTextInputFormatter.digitsOnly,
],
onChanged: (value) => setState(() {
// check if value isn't empty
if (value.trim() != "" ||
value.trim().isNotEmpty) {
//
fifthDigit = value;
// if value isn't empty, unfocus
FocusScope.of(context).unfocus();
} else {
// if value is empty, focus this field
FocusScope.of(context).requestFocus();
}
}),
),
),
),
//
//
],
),
),
),

//
// Reset Password Button
Padding(
padding: const EdgeInsets.only(top: 50),
child: ElevatedButton(
onPressed: () => verifyCode(),
style: MyButtonStyles.primaryButton.copyWith(
minimumSize: const WidgetStatePropertyAll(
Size(double.infinity, 50)),
),
child: Text(
"Verify Code",
style: MyTextStyles.bodyText.copyWith(
color: Colors.white, fontWeight: FontWeight.bold),
),
),
),
//
// Heven't got the email yet ? Resend email
Padding(
padding: const EdgeInsets.all(10.0),
child: Text.rich(
TextSpan(
text: "Haven't got the email yet ? ",
style: MyTextStyles.bodyText
.copyWith(fontSize: 13, color: Colors.grey),
children: [
TextSpan(
text: "Resend email",
recognizer: TapGestureRecognizer()
..onTap = () => sendCode(),
style: MyTextStyles.bodyText.copyWith(
fontSize: 13,
color: HexColor("#2EE78A"),
fontWeight: FontWeight.bold),
),
],
),
),
),
],
),
),
),
),
);
}
}

You might also like