import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:frontend/features/room/service/game_room.dart'; import 'package:frontend/providers/auth.dart'; import 'package:go_router/go_router.dart'; import 'package:logging/logging.dart'; final logger = Logger('JoinRoomHome'); class JoinRoomHome extends ConsumerStatefulWidget { const JoinRoomHome({super.key}); @override ConsumerState<JoinRoomHome> createState() => _JoinRoomHomeState(); } class _JoinRoomHomeState extends ConsumerState<JoinRoomHome> { final _formKey = GlobalKey<FormState>(); final _codeController = TextEditingController(); final _nameController = TextEditingController(); bool _isLoading = false; @override void dispose() { _codeController.dispose(); _nameController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { final jwtBody = ref.watch(jwtBodyProvider); if (jwtBody != null) { logger.fine('Navigating to game room screen'); WidgetsBinding.instance.addPostFrameCallback( (_) => context.go('/room/${jwtBody.roomUuid}'), ); } return Scaffold( body: Padding( padding: const EdgeInsets.all(16.0), child: Form( key: _formKey, child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ TextFormField( controller: _codeController, textCapitalization: TextCapitalization.characters, style: const TextStyle( letterSpacing: 1.5, fontWeight: FontWeight.bold, ), decoration: const InputDecoration( labelText: 'Enter Room Code', hintText: 'ABCDEF', helperText: 'Enter 6 uppercase letters', border: OutlineInputBorder(), errorStyle: TextStyle(height: 0.8), counterText: '', // Hides the built-in counter ), maxLength: 6, textInputAction: TextInputAction.done, inputFormatters: [ // FilteringTextInputFormatter.allow(RegExp('[A-Z]')), UpperCaseTextFormatter(), ], validator: (value) { if (value == null || value.isEmpty) { return 'Room code is required'; } if (value.length != 6) { return 'Code must be exactly 6 characters'; } if (!RegExp(r'^[A-Z]{6}$').hasMatch(value)) { return 'Only uppercase letters are allowed'; } return null; }, onChanged: (value) { // Convert to uppercase while typing if (value != value.toUpperCase()) { _codeController.text = value.toUpperCase(); _codeController.selection = TextSelection.fromPosition( TextPosition(offset: _codeController.text.length), ); } }, ), const SizedBox(height: 16), TextFormField( controller: _nameController, decoration: const InputDecoration( labelText: 'Name', border: OutlineInputBorder(), ), keyboardType: TextInputType.text, maxLength: 20, validator: (value) { if (value == null || value.isEmpty) { return 'Please enter a name ya goof'; } return null; }, ), const SizedBox(height: 16), ElevatedButton( onPressed: _isLoading ? null : () async { if (_formKey.currentState!.validate()) { setState(() => _isLoading = true); try { ref.read( joinRoomProvider( username: _nameController.text, code: _codeController.text, ), ); } finally { setState(() => _isLoading = false); } } }, child: _isLoading ? const CircularProgressIndicator() : const Text('Join Room'), ), ], ), ), ), ); } } class UpperCaseTextFormatter extends TextInputFormatter { @override TextEditingValue formatEditUpdate( TextEditingValue oldValue, TextEditingValue newValue, ) { return TextEditingValue( text: newValue.text.toUpperCase(), selection: newValue.selection, ); } }