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
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
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") ?? "[email protected]";
}

// 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