import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import '../providers/agent_provider.dart'; import '../providers/call_provider.dart'; import '../widgets/agent_status_toggle.dart'; import '../widgets/dialpad.dart'; import '../widgets/queue_card.dart'; import 'active_call_screen.dart'; import 'settings_screen.dart'; class DashboardScreen extends StatefulWidget { const DashboardScreen({super.key}); @override State createState() => _DashboardScreenState(); } class _DashboardScreenState extends State { @override void initState() { super.initState(); WidgetsBinding.instance.addPostFrameCallback((_) { context.read().refresh(); }); } void _showDialer(BuildContext context) { final numberController = TextEditingController(); String? selectedCallerId; showModalBottomSheet( context: context, isScrollControlled: true, shape: const RoundedRectangleBorder( borderRadius: BorderRadius.vertical(top: Radius.circular(16)), ), builder: (ctx) { final phoneNumbers = context.read().phoneNumbers; return StatefulBuilder( builder: (ctx, setSheetState) { return Padding( padding: EdgeInsets.only( bottom: MediaQuery.of(ctx).viewInsets.bottom, top: 16, left: 16, right: 16, ), child: Column( mainAxisSize: MainAxisSize.min, children: [ // Number display TextField( controller: numberController, keyboardType: TextInputType.phone, autofillHints: const [AutofillHints.telephoneNumber], textAlign: TextAlign.center, style: Theme.of(ctx).textTheme.headlineSmall, decoration: InputDecoration( hintText: 'Enter phone number', suffixIcon: IconButton( icon: const Icon(Icons.backspace_outlined), onPressed: () { final text = numberController.text; if (text.isNotEmpty) { numberController.text = text.substring(0, text.length - 1); numberController.selection = TextSelection.fromPosition( TextPosition(offset: numberController.text.length), ); } }, ), ), ), // Caller ID selector if (phoneNumbers.isNotEmpty) ...[ const SizedBox(height: 12), DropdownButtonFormField( initialValue: selectedCallerId, decoration: const InputDecoration( labelText: 'Caller ID', isDense: true, contentPadding: EdgeInsets.symmetric(horizontal: 12, vertical: 8), ), items: [ const DropdownMenuItem( value: null, child: Text('Default'), ), ...phoneNumbers.map((p) => DropdownMenuItem( value: p.phoneNumber, child: Text('${p.friendlyName} (${p.phoneNumber})'), )), ], onChanged: (value) { setSheetState(() { selectedCallerId = value; }); }, ), ], const SizedBox(height: 16), // Dialpad Dialpad( onDigit: (digit) { numberController.text += digit; numberController.selection = TextSelection.fromPosition( TextPosition(offset: numberController.text.length), ); }, onClose: () => Navigator.pop(ctx), ), const SizedBox(height: 8), // Call button ElevatedButton.icon( style: ElevatedButton.styleFrom( backgroundColor: Colors.green, foregroundColor: Colors.white, minimumSize: const Size(double.infinity, 48), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(24), ), ), icon: const Icon(Icons.call), label: const Text('Call'), onPressed: () { final number = numberController.text.trim(); if (number.isNotEmpty) { context.read().makeCall(number, callerId: selectedCallerId); Navigator.pop(ctx); } }, ), const SizedBox(height: 16), ], ), ); }, ); }, ); } @override Widget build(BuildContext context) { final agent = context.watch(); final call = context.watch(); // Navigate to active call screen when a call comes in if (call.callInfo.isActive) { WidgetsBinding.instance.addPostFrameCallback((_) { Navigator.of(context).pushAndRemoveUntil( MaterialPageRoute(builder: (_) => const ActiveCallScreen()), (route) => route.isFirst, ); }); } return Scaffold( appBar: AppBar( title: const Text('TWP Softphone'), actions: [ // SSE connection indicator Padding( padding: const EdgeInsets.only(right: 8), child: Icon( Icons.circle, size: 12, color: agent.sseConnected ? Colors.green : Colors.red, ), ), IconButton( icon: const Icon(Icons.settings), onPressed: () => Navigator.push(context, MaterialPageRoute(builder: (_) => const SettingsScreen())), ), ], ), floatingActionButton: FloatingActionButton( onPressed: () => _showDialer(context), child: const Icon(Icons.phone), ), body: RefreshIndicator( onRefresh: () => agent.refresh(), child: ListView( padding: const EdgeInsets.all(16), children: [ const AgentStatusToggle(), const SizedBox(height: 24), Text('Queues', style: Theme.of(context).textTheme.titleMedium), const SizedBox(height: 8), if (agent.queues.isEmpty) const Card( child: Padding( padding: EdgeInsets.all(24), child: Center(child: Text('No queues assigned')), ), ) else ...agent.queues.map((q) => Padding( padding: const EdgeInsets.only(bottom: 8), child: QueueCard(queue: q), )), ], ), ), ); } }