You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
cloudsolutions-atoms/lib/modules/applicationDemo/widgets/otp_verification_bottom_she...

176 lines
5.8 KiB
Dart

import 'package:flutter/material.dart';
import 'package:pinput/pinput.dart';
import 'package:test_sa/extensions/int_extensions.dart';
import 'package:test_sa/extensions/widget_extensions.dart';
import 'package:test_sa/new_views/app_style/app_color.dart';
import 'package:test_sa/views/widgets/item_views/info_header_widget.dart';
import 'package:test_sa/views/widgets/item_views/info_text_widget.dart';
class OtpVerificationBottomSheet extends StatefulWidget {
final String otpMethod;
final Function(String otp) onOtpVerified;
final VoidCallback? onResend;
final VoidCallback? onChangeMethod;
const OtpVerificationBottomSheet({
Key? key,
required this.otpMethod,
required this.onOtpVerified,
this.onResend,
this.onChangeMethod,
}) : super(key: key);
@override
State<OtpVerificationBottomSheet> createState() => _OtpVerificationBottomSheetState();
}
class _OtpVerificationBottomSheetState extends State<OtpVerificationBottomSheet> {
final ValueNotifier<String> _timerNotifier = ValueNotifier("2:00");
bool _canResend = false;
@override
void initState() {
super.initState();
_startTimer();
}
void _startTimer() {
int seconds = 120; // 2 minutes
_canResend = false;
Future.doWhile(() async {
await Future.delayed(const Duration(seconds: 1));
if (!mounted) return false;
seconds--;
if (seconds <= 0) {
_timerNotifier.value = "0:00";
_canResend = true;
return false;
}
final minutes = seconds ~/ 60;
final secs = seconds % 60;
_timerNotifier.value = "$minutes:${secs.toString().padLeft(2, '0')}";
return true;
});
}
@override
void dispose() {
_timerNotifier.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
final defaultPinTheme = PinTheme(
width: 51.toScreenWidth,
height: 63.toScreenHeight,
textStyle: TextStyle(fontSize: 24, color: AppColor.headingTextColor(context)),
decoration: BoxDecoration(
color: AppColor.background(context),
borderRadius: BorderRadius.circular(10),
border: Border.all(color: AppColor.border2Color(context)),
),
);
return WillPopScope(
onWillPop: () async => false, // Prevent dismiss by back button
child: SingleChildScrollView(
padding: EdgeInsets.zero,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
InfoTextWidget(
label: 'OTP has been sent to your ${widget.otpMethod.toLowerCase()}',
isMsg: true,
showEmptyValue: true,
),
Center(
child: Pinput(
length: 4,
defaultPinTheme: defaultPinTheme,
focusedPinTheme: defaultPinTheme.copyWith(
decoration: defaultPinTheme.decoration?.copyWith(
border: Border.all(color: AppColor.primary10),
),
),
onCompleted: (pin) async {
// Call the verification callback
widget.onOtpVerified(pin);
},
),
).paddingOnly(top: 24, bottom: 24),
Row(
children: [
InfoTextWidget(label: 'Resend in', isMsg: true, showEmptyValue: true),
6.width,
ValueListenableBuilder<String>(
valueListenable: _timerNotifier,
builder: (context, value, _) {
return InfoTextWidget(label: value, isMsg: true, showEmptyValue: true);
},
),
6.width,
InkWell(
onTap: _canResend
? () {
if (widget.onResend != null) {
widget.onResend!();
_startTimer();
}
}
: null,
child: Text(
'Resend',
style: TextStyle(
color: _canResend ? AppColor.primary10 : AppColor.white50,
fontWeight: FontWeight.w500,
fontSize: 12.toScreenWidth,
decorationColor: _canResend ? AppColor.primary10 : AppColor.white50,
decoration: TextDecoration.underline,
),
),
),
],
),
],
).toShadowContainer(context),
16.height,
Column(
crossAxisAlignment: CrossAxisAlignment.start,
spacing: 4,
children: [
InfoHeader16Widget('Having trouble receiving OTP?'),
InkWell(
onTap: () {
Navigator.pop(context);
if (widget.onChangeMethod != null) {
widget.onChangeMethod!();
}
},
child: Text(
'Check out other methods',
style: TextStyle(
color: AppColor.primary10,
fontSize: 16.toScreenWidth,
fontWeight: FontWeight.w500,
decoration: TextDecoration.underline,
decorationColor: AppColor.primary10,
),
),
),
],
),
],
),
),
);
}
}