206 lines
6.7 KiB
Dart
206 lines
6.7 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:flutter/services.dart';
|
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
|
import 'package:regroup/Common/CommonGlassmorphism.dart';
|
|
import 'package:regroup/Utils/Common/CommonAppbar.dart';
|
|
import 'package:regroup/Utils/Common/CustomNextButton.dart';
|
|
import 'package:regroup/Utils/Common/blureffect.dart';
|
|
import 'package:regroup/Utils/Common/sized_box.dart';
|
|
import 'package:regroup/Utils/dialogs.dart';
|
|
import 'package:regroup/Utils/texts.dart';
|
|
|
|
class VerifyCode extends StatefulWidget {
|
|
const VerifyCode({super.key});
|
|
|
|
@override
|
|
State<VerifyCode> createState() => _VerifyCodeState();
|
|
}
|
|
|
|
class _VerifyCodeState extends State<VerifyCode> {
|
|
final TextEditingController pincodeController = TextEditingController();
|
|
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Scaffold(
|
|
backgroundColor: const Color(0xFF222935),
|
|
appBar: CommonAppbar(titleTxt: ""),
|
|
body: Stack(
|
|
children: [
|
|
const CommonBlurLeftRed(),
|
|
const CommonBlurRightRed(),
|
|
const CommonBlurLeft(),
|
|
const CommonBlurRight(),
|
|
Positioned.fill(
|
|
child: Padding(
|
|
padding: EdgeInsets.symmetric(horizontal: 16.w),
|
|
child: SingleChildScrollView(
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
sizedBoxHeight(20.h),
|
|
text20700white("Check your email"),
|
|
sizedBoxHeight(10.h),
|
|
text14400whiteblur(
|
|
"Enter the verification code that we sent to loremipsum@gmail.com"),
|
|
sizedBoxHeight(30.h),
|
|
text16400white("Enter code"),
|
|
sizedBoxHeight(20.h),
|
|
commonGlassContainer(
|
|
width: double.infinity,
|
|
height: 50.h,
|
|
borderradius: 30.r,
|
|
border: 1,
|
|
customWidget: CustomPinCodeField(
|
|
controller: pincodeController,
|
|
onChanged: (value) {
|
|
print(value);
|
|
},
|
|
onCompleted: (value) {
|
|
print("Completed");
|
|
pincodeController.text = value;
|
|
},
|
|
),
|
|
),
|
|
sizedBoxHeight(70.h),
|
|
CustomButton(
|
|
text: 'Continue',
|
|
onPressed: () {
|
|
if (pincodeController.text.isEmpty) {
|
|
utils.showToast("Pin field is empty");
|
|
} else {
|
|
return;
|
|
}
|
|
},
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
class CustomPinCodeField extends StatefulWidget {
|
|
final TextEditingController controller;
|
|
final ValueChanged<String> onChanged;
|
|
final ValueChanged<String> onCompleted;
|
|
|
|
CustomPinCodeField({
|
|
required this.controller,
|
|
required this.onChanged,
|
|
required this.onCompleted,
|
|
});
|
|
|
|
@override
|
|
_CustomPinCodeFieldState createState() => _CustomPinCodeFieldState();
|
|
}
|
|
|
|
class _CustomPinCodeFieldState extends State<CustomPinCodeField> {
|
|
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
|
|
late List<TextEditingController> _controllers;
|
|
late List<FocusNode> _focusNodes;
|
|
String _currentText = "";
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
_controllers = List.generate(4, (_) => TextEditingController());
|
|
_focusNodes = List.generate(4, (_) => FocusNode());
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
_controllers.forEach((controller) => controller.dispose());
|
|
_focusNodes.forEach((focusNode) => focusNode.dispose());
|
|
super.dispose();
|
|
}
|
|
|
|
String? _validate(int index) {
|
|
// _currentText = _controllers.map((controller) => controller.text).join();
|
|
if (_currentText[index].isEmpty) {
|
|
return "Please Enter verification code";
|
|
} else if (_currentText.length < 4) {
|
|
return "OTP length should be at least 4";
|
|
}
|
|
return null;
|
|
}
|
|
|
|
void _onChanged(String value, int index) {
|
|
setState(() {
|
|
_currentText = _controllers.map((controller) => controller.text).join();
|
|
});
|
|
if (value.length == 1 && index != 3) {
|
|
FocusScope.of(context).nextFocus();
|
|
} else if (value.isEmpty && index != 0) {
|
|
FocusScope.of(context).previousFocus();
|
|
}
|
|
widget.onChanged(_currentText);
|
|
|
|
if (_currentText.length == 4) {
|
|
widget.onCompleted(_currentText);
|
|
}
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Form(
|
|
key: _formKey,
|
|
child: Row(
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
crossAxisAlignment: CrossAxisAlignment.center,
|
|
children: List.generate(4, (index) {
|
|
return Row(
|
|
crossAxisAlignment: CrossAxisAlignment.center,
|
|
children: [
|
|
Center(
|
|
child: Container(
|
|
width: 30,
|
|
height: 40,
|
|
// color: Colors.amber,
|
|
child: Center(
|
|
child: TextFormField(
|
|
controller: _controllers[index],
|
|
focusNode: _focusNodes[index],
|
|
keyboardType: TextInputType.number,
|
|
inputFormatters: [
|
|
FilteringTextInputFormatter.allow(RegExp('[0-9]')),
|
|
LengthLimitingTextInputFormatter(1),
|
|
],
|
|
textAlign: TextAlign.center,
|
|
style: TextStyle(
|
|
color: Colors.white,
|
|
fontSize: 20.sp,
|
|
fontFamily: 'Helvetica',
|
|
),
|
|
decoration: InputDecoration(
|
|
border: InputBorder.none,
|
|
errorStyle: TextStyle(height: 0),
|
|
),
|
|
onChanged: (value) => _onChanged(value, index),
|
|
validator: (value) {
|
|
if (index == 3) return _validate(index);
|
|
return null;
|
|
},
|
|
),
|
|
),
|
|
),
|
|
),
|
|
if (index != 3)
|
|
Container(
|
|
width: 12,
|
|
height: 2,
|
|
color: Colors.white,
|
|
margin: EdgeInsets.symmetric(horizontal: 10),
|
|
),
|
|
],
|
|
);
|
|
}),
|
|
),
|
|
);
|
|
}
|
|
}
|