import 'package:flutter/material.dart'; import 'package:fluttertoast/fluttertoast.dart'; import 'package:get/get.dart'; import 'package:otp_timer_button/otp_timer_button.dart'; import 'package:sms_autofill/sms_autofill.dart'; import '../../controllers/authentication/auth_controller.dart'; class VerificationUiPage extends StatefulWidget { final String phoneNumber; final bool isNewUser; // true if new user, false if existing const VerificationUiPage({ super.key, required this.phoneNumber, required this.isNewUser, }); @override State createState() => _VerificationUiPageState(); } class _VerificationUiPageState extends State with CodeAutoFill { String? otpCode; final AuthController authController = Get.find(); // ✅ Reuses existing instance with isNewUser state // final AuthController authController = Get.put(AuthController()); // ✅ Controller instance final OtpTimerButtonController otpTimerController = OtpTimerButtonController(); @override void initState() { super.initState(); listenForCode(); } @override void codeUpdated() { setState(() { otpCode = code; }); // Auto-verify when OTP is received if (otpCode != null && otpCode!.length == 6) { authController.validateOtp(otpCode!, context); } } @override void dispose() { cancel(); super.dispose(); } @override Widget build(BuildContext context) { Size screenSize = MediaQuery.of(context).size; return Scaffold( backgroundColor: const Color(0xFF662582), body: Stack( alignment: Alignment.bottomCenter, children: [ /// Top Section Container( width: double.infinity, padding: EdgeInsets.only( top: screenSize.height * 0.07, left: screenSize.width * 0.06, right: screenSize.width * 0.06, ), decoration: const BoxDecoration( gradient: LinearGradient( colors: [Color(0xFF662582), Color(0xFF8546A6)], begin: Alignment.topLeft, end: Alignment.bottomRight, ), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text( "Groceries, Essentials & More – Delivered in Minutes!", style: TextStyle( color: Colors.white, fontWeight: FontWeight.bold, fontSize: 26, height: 1.3, ), ), SizedBox(height: screenSize.height * 0.02), const Text( "Sign in to enjoy lightning-fast delivery!", style: TextStyle( color: Colors.white70, fontSize: 16, ), ), Align( alignment: Alignment.centerRight, child: Image.asset( "assets/images/loginImage.png", height: screenSize.height * 0.35, fit: BoxFit.contain, ), ), ], ), ), /// Bottom OTP Section SingleChildScrollView( child: Container( width: screenSize.width, padding: EdgeInsets.all(screenSize.width * 0.07), decoration: const BoxDecoration( color: Colors.white, borderRadius: BorderRadius.vertical(top: Radius.circular(24)), boxShadow: [ BoxShadow( color: Colors.black12, blurRadius: 10, spreadRadius: 2, offset: Offset(0, -3), ), ], ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ /// Title const Text( "Verify with OTP", style: TextStyle( color: Colors.black87, fontWeight: FontWeight.w700, fontSize: 22, ), ), SizedBox(height: screenSize.height * 0.01), Text( "6 digit OTP has been sent to your number", style: TextStyle( color: Colors.grey[600], fontSize: 16, ), ), SizedBox(height: screenSize.height * 0.02), /// Number + Change Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( widget.phoneNumber, style: const TextStyle( color: Colors.black87, fontWeight: FontWeight.bold, fontSize: 18, ), ), Row( children: [ const Text( "Not Yours?", style: TextStyle( color: Colors.black54, fontWeight: FontWeight.w500, fontSize: 15, ), ), const SizedBox(width: 6), InkWell( onTap: () => Navigator.of(context).pop(), child: const Text( "Change", style: TextStyle( color: Color(0xFF662582), fontWeight: FontWeight.bold, fontSize: 15, ), ), ), ], ), ], ), SizedBox(height: screenSize.height * 0.04), /// OTP Input Center( child: PinFieldAutoFill( codeLength: 6, decoration: BoxLooseDecoration( strokeColorBuilder: FixedColorBuilder(Colors.grey.shade400), bgColorBuilder: FixedColorBuilder(Colors.grey.shade100), gapSpace: 12, radius: const Radius.circular(10), textStyle: const TextStyle( fontSize: 20, fontWeight: FontWeight.bold, color: Colors.black87, ), ), onCodeChanged: (code) { otpCode = code; if (code != null && code.length == 6) { authController.validateOtp(otpCode!, context, widget.isNewUser); } }, ), ), SizedBox(height: screenSize.height * 0.04), /// Resend OTP Center( child: Column( children: [ Text( "Didn’t receive an OTP?", style: TextStyle( color: Colors.grey[600], fontSize: 15, ), ), OtpTimerButton( controller: otpTimerController, onPressed: () async { await authController.receiveSmsOtp(); // ✅ Resend OTP Fluttertoast.showToast( msg: "A new OTP has been sent to your number", toastLength: Toast.LENGTH_SHORT, gravity: ToastGravity.TOP, backgroundColor: Colors.green.withOpacity(0.8), textColor: Colors.white, fontSize: 15, ); }, text: const Text( "Resend Again", style: TextStyle( fontSize: 15, fontWeight: FontWeight.bold, color: Color(0xFF662582), ), ), duration: 60, buttonType: ButtonType.text_button, ), ], ), ), SizedBox(height: screenSize.height * 0.04), /// Verify Button SizedBox( width: double.infinity, child: ElevatedButton( style: ElevatedButton.styleFrom( backgroundColor: const Color(0xFF662582), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), ), padding: const EdgeInsets.symmetric(vertical: 14), ), onPressed: () { if (otpCode != null && otpCode!.length == 6) { authController.validateOtp(otpCode!, context); } else { Fluttertoast.showToast( msg: "Enter a valid OTP", toastLength: Toast.LENGTH_SHORT, gravity: ToastGravity.TOP, backgroundColor: Colors.green.withOpacity(0.8), textColor: Colors.white, fontSize: 15, ); } }, child: const Text( "Verify OTP", style: TextStyle( fontSize: 18, fontWeight: FontWeight.bold, color: Colors.white, ), ), ), ), SizedBox(height: screenSize.height * 0.03), /// Terms RichText( textAlign: TextAlign.center, text: TextSpan( style: TextStyle( color: Colors.grey[600], fontSize: 12, ), children: const [ TextSpan(text: "By continuing, you agree to the "), TextSpan( text: "Terms & Privacy Policy", style: TextStyle( color: Colors.blue, fontWeight: FontWeight.bold, ), ), ], ), ), SizedBox(height: screenSize.height * 0.02), ], ), ), ), ], ), ); } }