import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:provider/provider.dart'; import '../models/device.dart'; import '../services/authentication_manager.dart'; import '../services/brandmeister_client.dart'; class LinkTalkgroupView extends StatefulWidget { final Device device; final VoidCallback onSuccess; const LinkTalkgroupView({ super.key, required this.device, required this.onSuccess, }); @override State createState() => _LinkTalkgroupViewState(); } class _LinkTalkgroupViewState extends State { final TextEditingController _talkgroupController = TextEditingController(); int _selectedTimeslot = 1; bool _isLoading = false; String? _errorMessage; @override void dispose() { _talkgroupController.dispose(); super.dispose(); } Future _linkTalkgroup() async { if (_talkgroupController.text.isEmpty) { setState(() { _errorMessage = 'Please enter a talkgroup ID'; }); return; } final talkgroupId = int.tryParse(_talkgroupController.text); if (talkgroupId == null) { setState(() { _errorMessage = 'Invalid talkgroup ID'; }); return; } setState(() { _isLoading = true; _errorMessage = null; }); try { final authManager = context.read(); await authManager.linkTalkgroup( talkgroupId: talkgroupId, dmrId: widget.device.id, timeslot: _selectedTimeslot, ); if (mounted) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('Talkgroup linked successfully')), ); widget.onSuccess(); } } on BrandmeisterError catch (e) { setState(() { _errorMessage = e.message; _isLoading = false; }); } catch (e) { setState(() { _errorMessage = e.toString(); _isLoading = false; }); } } @override Widget build(BuildContext context) { return Container( padding: const EdgeInsets.all(24), child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.stretch, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( 'Link Talkgroup', style: Theme.of(context).textTheme.titleLarge?.copyWith( fontWeight: FontWeight.bold, ), ), IconButton( icon: const Icon(Icons.close), onPressed: () => Navigator.pop(context), ), ], ), const SizedBox(height: 24), TextField( controller: _talkgroupController, keyboardType: TextInputType.number, inputFormatters: [FilteringTextInputFormatter.digitsOnly], decoration: InputDecoration( labelText: 'Talkgroup ID', hintText: 'Enter talkgroup ID', border: const OutlineInputBorder(), prefixIcon: const Icon(Icons.speaker_group), errorText: _errorMessage, ), enabled: !_isLoading, autofocus: true, ), const SizedBox(height: 24), Text( 'Timeslot', style: Theme.of(context).textTheme.titleMedium, ), const SizedBox(height: 8), SegmentedButton( segments: const [ ButtonSegment( value: 1, label: Text('TS1'), icon: Icon(Icons.looks_one), ), ButtonSegment( value: 2, label: Text('TS2'), icon: Icon(Icons.looks_two), ), ], selected: {_selectedTimeslot}, onSelectionChanged: _isLoading ? null : (Set newSelection) { setState(() { _selectedTimeslot = newSelection.first; }); }, ), const SizedBox(height: 24), ElevatedButton( onPressed: _isLoading ? null : _linkTalkgroup, style: ElevatedButton.styleFrom( padding: const EdgeInsets.symmetric(vertical: 16), ), child: _isLoading ? const SizedBox( height: 20, width: 20, child: CircularProgressIndicator(strokeWidth: 2), ) : const Text('Link Talkgroup'), ), ], ), ); } }