import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import '../models/device.dart'; import '../models/user_info.dart'; import '../services/authentication_manager.dart'; import '../services/brandmeister_client.dart'; import 'device_detail_view.dart'; class DevicesView extends StatefulWidget { const DevicesView({super.key}); @override State createState() => _DevicesViewState(); } class _DevicesViewState extends State { List _devices = []; bool _isLoadingDevices = false; String? _errorMessage; @override void initState() { super.initState(); _loadDevices(); } Future _loadDevices() async { setState(() { _isLoadingDevices = true; _errorMessage = null; }); try { final authManager = context.read(); final devices = await authManager.getDevices(); setState(() { _devices = devices; _isLoadingDevices = false; }); } on BrandmeisterError catch (e) { setState(() { _errorMessage = e.message; _isLoadingDevices = false; }); } catch (e) { setState(() { _errorMessage = e.toString(); _isLoadingDevices = false; }); } } @override Widget build(BuildContext context) { final authManager = context.watch(); final userInfo = authManager.userInfo; return Scaffold( appBar: AppBar( title: const Text('Devices'), ), body: RefreshIndicator( onRefresh: _loadDevices, child: _buildBody(userInfo), ), ); } Widget _buildBody(UserInfo? userInfo) { if (_isLoadingDevices && _devices.isEmpty) { return const Center( child: CircularProgressIndicator(), ); } if (_errorMessage != null) { return Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon( Icons.error_outline, size: 64, color: Colors.red[300], ), const SizedBox(height: 16), Text( 'Error', style: Theme.of(context).textTheme.titleLarge, ), const SizedBox(height: 8), Padding( padding: const EdgeInsets.symmetric(horizontal: 32), child: Text( _errorMessage!, textAlign: TextAlign.center, style: TextStyle(color: Colors.grey[600]), ), ), const SizedBox(height: 24), ElevatedButton.icon( onPressed: _loadDevices, icon: const Icon(Icons.refresh), label: const Text('Retry'), ), ], ), ); } if (_devices.isEmpty) { return Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon( Icons.devices_other, size: 64, color: Colors.grey[400], ), const SizedBox(height: 16), Text( 'No devices found', style: Theme.of(context).textTheme.titleLarge, ), const SizedBox(height: 8), Text( 'You don\'t have any devices registered', style: TextStyle(color: Colors.grey[600]), ), ], ), ); } return ListView( children: [ if (userInfo != null) Container( padding: const EdgeInsets.all(16), color: Theme.of(context).colorScheme.primaryContainer, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( userInfo.displayName, style: Theme.of(context).textTheme.titleLarge?.copyWith( color: Theme.of(context).colorScheme.onPrimaryContainer, ), ), const SizedBox(height: 4), Text( _devices.isNotEmpty ? 'DMR ID: ${_devices.first.id}' : 'No devices', style: Theme.of(context).textTheme.bodyMedium?.copyWith( color: Theme.of(context) .colorScheme .onPrimaryContainer .withValues(alpha: 0.7), ), ), ], ), ), ..._devices.map((device) => _DeviceRow( device: device, onTap: () { Navigator.push( context, MaterialPageRoute( builder: (context) => DeviceDetailView(device: device), ), ); }, )), ], ); } } class _DeviceRow extends StatelessWidget { final Device device; final VoidCallback onTap; const _DeviceRow({ required this.device, required this.onTap, }); @override Widget build(BuildContext context) { return ListTile( leading: CircleAvatar( backgroundColor: Theme.of(context).colorScheme.primaryContainer, child: Icon( Icons.radio, color: Theme.of(context).colorScheme.onPrimaryContainer, ), ), title: Text(device.callsign ?? 'Unknown'), subtitle: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('ID: ${device.id}'), if (device.name != null) Text(device.name!), Text(device.displayLocation), ], ), isThreeLine: true, trailing: const Icon(Icons.chevron_right), onTap: onTap, ); } }