import 'dart:async'; import 'package:english_learning/core/widgets/custom_snackbar.dart'; import 'package:english_learning/features/auth/provider/user_provider.dart'; import 'package:english_learning/features/auth/provider/validator_provider.dart'; import 'package:english_learning/features/auth/screens/signin/signin_screen.dart'; import 'package:english_learning/core/widgets/form_field/custom_field_widget.dart'; import 'package:english_learning/core/widgets/global_button.dart'; import 'package:english_learning/core/utils/styles/theme.dart'; import 'package:english_learning/features/auth/widgets/dialog/signup_verification.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; class SignupScreen extends StatefulWidget { SignupScreen({super.key}); @override State createState() => _SignupScreenState(); } class _SignupScreenState extends State { final TextEditingController _emailController = TextEditingController(); final TextEditingController _passwordController = TextEditingController(); final TextEditingController _nisnController = TextEditingController(); final TextEditingController _nameController = TextEditingController(); bool isLoading = false; @override Widget build(BuildContext context) { final userProvider = Provider.of(context, listen: false); Provider.of(context, listen: false); final mediaQuery = MediaQuery.of(context); final screenHeight = mediaQuery.size.height; Future handleRegistration( BuildContext context, ValidatorProvider validatorProvider, ) async { if (isLoading) return; // Prevent multiple submissions setState(() { isLoading = true; }); try { // Attempt registration with timeout final isSuccess = await userProvider .register( name: _nameController.text, email: _emailController.text, nisn: _nisnController.text, password: _passwordController.text, confirmPassword: _passwordController.text, ) .timeout( const Duration(seconds: 30), onTimeout: () { throw TimeoutException( 'Registration request timed out. Please try again.'); }, ); // Remove loading dialog Navigator.of(context).pop(); if (isSuccess) { // Show success verification dialog if (!context.mounted) return; await showDialog( context: context, barrierDismissible: false, builder: (BuildContext dialogContext) { return PopScope( canPop: false, child: SignupVerification( onSubmit: () { // Clear the form fields _emailController.clear(); _passwordController.clear(); _nisnController.clear(); _nameController.clear(); validatorProvider.resetFields(); // Navigate to login screen Navigator.of(dialogContext).pushAndRemoveUntil( MaterialPageRoute( builder: (context) => SigninScreen(), ), (Route route) => false, ); }, ), ); }, ); } else { if (!context.mounted) return; CustomSnackBar.show( context, message: 'Registration failed. Please try again.', isError: true, ); } } catch (e) { // Remove loading dialog if it's showing if (Navigator.canPop(context)) { Navigator.of(context).pop(); } if (!context.mounted) return; CustomSnackBar.show( context, message: 'An error occurred: ${e.toString()}', isError: true, ); } finally { setState(() { isLoading = false; }); } } return Scaffold( backgroundColor: AppColors.whiteColor, body: Center( child: Container( margin: const EdgeInsets.symmetric(horizontal: 16), child: SingleChildScrollView( child: Consumer( builder: (context, validatorProvider, child) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ SizedBox(height: screenHeight * 0.05), Text( '👋 Hi!, you here!', style: AppTextStyles.blueTextStyle.copyWith( fontSize: 24, fontWeight: FontWeight.w900, ), ), const SizedBox(height: 4), Text( 'Let\'s start by creating your account first', style: AppTextStyles.greyTextStyle.copyWith( fontSize: 14, fontWeight: FontWeight.w400, ), ), const SizedBox(height: 49), CustomFieldWidget( controller: _nisnController, fieldName: 'nisn', isRequired: true, textInputAction: TextInputAction.next, labelText: 'NISN', hintText: 'Enter Your NISN', keyboardType: TextInputType.number, validator: validatorProvider.nisnValidator, onChanged: (value) { validatorProvider.validateField('nisn', value, validator: validatorProvider.nisnValidator); }, errorText: validatorProvider.getError('nisn'), ), const SizedBox(height: 14), CustomFieldWidget( controller: _nameController, fieldName: 'name', isRequired: true, textInputAction: TextInputAction.next, labelText: 'Full Name', hintText: 'Enter Your Full Name', keyboardType: TextInputType.text, validator: validatorProvider.fullNameValidator, onChanged: (value) { validatorProvider.validateField( 'fullname', value, validator: validatorProvider.fullNameValidator, ); }, errorText: validatorProvider.getError('name'), ), const SizedBox(height: 14), CustomFieldWidget( controller: _emailController, fieldName: 'email', isRequired: true, textInputAction: TextInputAction.next, labelText: 'Email Address', hintText: 'Enter Your Email Address', keyboardType: TextInputType.emailAddress, validator: validatorProvider.emailValidator, onChanged: (value) { validatorProvider.validateField( 'email', value, validator: validatorProvider.emailValidator, ); }, errorText: validatorProvider.getError('email'), ), const SizedBox(height: 14), CustomFieldWidget( controller: _passwordController, fieldName: 'password', isRequired: true, textInputAction: TextInputAction.next, labelText: 'Password', hintText: 'Create a Strong Password', obscureText: validatorProvider.isObscure('password'), keyboardType: TextInputType.visiblePassword, validator: validatorProvider.passwordValidator, onChanged: (value) { validatorProvider.validateField( 'password', value, validator: validatorProvider.passwordValidator, ); }, onSuffixIconTap: () => validatorProvider.toggleVisibility('password'), errorText: validatorProvider.getError('password'), ), const SizedBox(height: 14), CustomFieldWidget( fieldName: 'confirmPassword', isRequired: true, textInputAction: TextInputAction.next, labelText: 'Confirm Password', hintText: 'Retype Your Password', obscureText: validatorProvider.isObscure('confirmPassword'), keyboardType: TextInputType.visiblePassword, validator: validatorProvider.confirmPasswordValidator, onChanged: (value) { validatorProvider.validateField( 'confirmPassword', value, validator: validatorProvider.confirmPasswordValidator, ); }, onSuffixIconTap: () => validatorProvider.toggleVisibility('confirmPassword'), errorText: validatorProvider.getError('confirmPassword'), ), const SizedBox(height: 24), GlobalButton( text: 'Sign Up', isLoading: isLoading, onPressed: isLoading ? null : () { validatorProvider.validateField( 'nisn', _nisnController.text, validator: validatorProvider.nisnValidator); validatorProvider.validateField( 'name', _nameController.text, validator: validatorProvider.fullNameValidator); validatorProvider.validateField( 'email', _emailController.text, validator: validatorProvider.emailValidator); validatorProvider.validateField( 'password', _passwordController.text, validator: validatorProvider.passwordValidator); validatorProvider.validateField( 'confirmPassword', _passwordController.text, validator: validatorProvider .confirmPasswordValidator); // If no error, proceed with registration if (validatorProvider.getError('nisn') == null && validatorProvider.getError('name') == null && validatorProvider.getError('email') == null && validatorProvider.getError('password') == null && validatorProvider .getError('confirmPassword') == null) { handleRegistration(context, validatorProvider); } }, ), const SizedBox(height: 8), Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Text( 'Already have an account?', style: AppTextStyles.blackTextStyle .copyWith(fontSize: 14), ), GestureDetector( onTap: () { context.read().resetFields(); Navigator.push( context, MaterialPageRoute( builder: (context) => SigninScreen()), ); }, child: Text( ' Login Here', style: AppTextStyles.blueTextStyle.copyWith( fontSize: 14, fontWeight: FontWeight.bold, ), ), ), ], ), ], ); }, ), ), ), ), ); } }