import 'package:flutter/material.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:pad_scanner/models/scan_record.dart'; import 'package:pad_scanner/services/scanner_service.dart'; import 'package:pad_scanner/services/api_service.dart'; import 'package:pad_scanner/pages/settings_page.dart'; class ScanPage extends StatefulWidget { const ScanPage({super.key}); @override State createState() => _ScanPageState(); } class _ScanPageState extends State { final _scannerService = ScannerService(); final _apiService = ApiService(); final _records = []; String _status = 'Waiting for scan...'; @override void initState() { super.initState(); _startListening(); } void _startListening() { _scannerService.scanResults.listen((result) async { final record = ScanRecord( barcode: result.barcode, codeType: result.codeType, timestamp: DateTime.now(), ); setState(() { _records.insert(0, record); _status = 'Sending...'; }); final prefs = await SharedPreferences.getInstance(); final url = prefs.getString('api_url') ?? ''; if (url.isEmpty) { setState(() { record.status = SendStatus.failed; _status = 'No URL configured. Go to Settings.'; }); return; } final ok = await _apiService.sendScanData( url, barcode: record.barcode, codeType: record.codeType, ); if (mounted) { setState(() { record.status = ok ? SendStatus.success : SendStatus.failed; _status = ok ? 'Sent successfully' : 'Send failed'; }); } }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('PAD Scanner'), actions: [ IconButton( icon: const Icon(Icons.settings), onPressed: () => Navigator.push( context, MaterialPageRoute(builder: (_) => const SettingsPage()), ), ), ], ), body: Column( children: [ Container( width: double.infinity, padding: const EdgeInsets.all(16), color: Theme.of(context).colorScheme.surfaceContainerHighest, child: Text( _status, style: Theme.of(context).textTheme.titleMedium, textAlign: TextAlign.center, ), ), Expanded( child: _records.isEmpty ? const Center( child: Text( 'No scans yet.\nPress the scan button on the device.', textAlign: TextAlign.center)) : ListView.builder( itemCount: _records.length, itemBuilder: (context, index) { final r = _records[index]; return ListTile( title: Text(r.barcode), subtitle: Text( '${r.codeType} ${r.timestamp.toLocal().toIso8601String().substring(0, 19)}'), trailing: Icon( r.status == SendStatus.success ? Icons.check_circle : r.status == SendStatus.failed ? Icons.error : Icons.hourglass_empty, color: r.status == SendStatus.success ? Colors.green : r.status == SendStatus.failed ? Colors.red : Colors.orange, ), ); }, ), ), ], ), ); } }