import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import '../../../core/auth/auth_bloc.dart'; class OtpScreen extends StatefulWidget { final String phone; const OtpScreen({super.key, required this.phone}); @override State createState() => _OtpScreenState(); } class _OtpScreenState extends State { final List _controllers = List.generate(6, (_) => TextEditingController()); final List _focusNodes = List.generate(6, (_) => FocusNode()); @override void dispose() { for (final c in _controllers) { c.dispose(); } for (final f in _focusNodes) { f.dispose(); } super.dispose(); } String get _otp => _controllers.map((c) => c.text).join(); void _onChanged(int index, String value) { if (value.length == 1 && index < 5) { _focusNodes[index + 1].requestFocus(); } if (_otp.length == 6) { _submit(); } } void _onKeyDown(int index, KeyEvent event) { if (event is KeyDownEvent && event.logicalKey == LogicalKeyboardKey.backspace && _controllers[index].text.isEmpty && index > 0) { _controllers[index - 1].clear(); _focusNodes[index - 1].requestFocus(); } } void _submit() { final otp = _otp; if (otp.length != 6) return; final state = context.read().state; final verificationId = state is AuthOtpSent ? state.verificationId : ''; context.read().add(OtpVerified(verificationId, otp)); } @override Widget build(BuildContext context) { return BlocListener( listener: (context, state) { if (state is AuthError) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text(state.message)), ); // Clear fields on error for (final c in _controllers) { c.clear(); } _focusNodes[0].requestFocus(); } }, child: Scaffold( appBar: AppBar(title: const Text('Masukkan OTP')), body: Padding( padding: const EdgeInsets.all(24), child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ Text( 'Kode OTP telah dikirim ke ${widget.phone}', textAlign: TextAlign.center, ), const SizedBox(height: 32), Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: List.generate(6, (index) { return SizedBox( width: 48, child: KeyboardListener( focusNode: FocusNode(), onKeyEvent: (event) => _onKeyDown(index, event), child: TextField( controller: _controllers[index], focusNode: _focusNodes[index], textAlign: TextAlign.center, keyboardType: TextInputType.number, maxLength: 1, style: const TextStyle( fontSize: 24, fontWeight: FontWeight.bold, ), decoration: const InputDecoration( counterText: '', border: OutlineInputBorder(), contentPadding: EdgeInsets.symmetric(vertical: 14), ), inputFormatters: [ FilteringTextInputFormatter.digitsOnly, ], onChanged: (value) => _onChanged(index, value), ), ), ); }), ), const SizedBox(height: 32), BlocBuilder( builder: (context, state) => ElevatedButton( onPressed: state is AuthLoading ? null : _submit, child: state is AuthLoading ? const CircularProgressIndicator() : const Text('Verifikasi'), ), ), ], ), ), ), ); } }