import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; /// Widget to display the most recent scan result with tap to edit functionality class ScanResultDisplay extends StatelessWidget { final String? barcode; final VoidCallback? onTap; final VoidCallback? onCopy; const ScanResultDisplay({ required this.barcode, this.onTap, this.onCopy, super.key, }); @override Widget build(BuildContext context) { return Container( width: double.infinity, padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: Theme.of(context).colorScheme.surfaceVariant, border: Border( top: BorderSide( color: Theme.of(context).dividerColor, width: 1, ), bottom: BorderSide( color: Theme.of(context).dividerColor, width: 1, ), ), ), child: barcode != null ? _buildScannedResult(context) : _buildEmptyState(context), ); } /// Build widget when barcode is scanned Widget _buildScannedResult(BuildContext context) { return Material( color: Colors.transparent, child: InkWell( onTap: onTap, borderRadius: BorderRadius.circular(8), child: Container( padding: const EdgeInsets.all(12), decoration: BoxDecoration( color: Theme.of(context).colorScheme.surface, borderRadius: BorderRadius.circular(8), border: Border.all( color: Theme.of(context).colorScheme.primary.withOpacity(0.3), width: 1, ), ), child: Row( children: [ // Barcode icon Container( padding: const EdgeInsets.all(8), decoration: BoxDecoration( color: Theme.of(context).colorScheme.primary.withOpacity(0.1), borderRadius: BorderRadius.circular(6), ), child: Icon( Icons.qr_code, size: 24, color: Theme.of(context).colorScheme.primary, ), ), const SizedBox(width: 12), // Barcode text and label Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ Text( 'Last Scanned', style: Theme.of(context).textTheme.labelSmall?.copyWith( color: Theme.of(context).colorScheme.onSurfaceVariant, ), ), const SizedBox(height: 2), Text( barcode!, style: Theme.of(context).textTheme.titleMedium?.copyWith( fontFamily: 'monospace', fontWeight: FontWeight.bold, ), maxLines: 2, overflow: TextOverflow.ellipsis, ), if (onTap != null) ...[ const SizedBox(height: 4), Text( 'Tap to edit', style: Theme.of(context).textTheme.bodySmall?.copyWith( color: Theme.of(context).colorScheme.primary, fontWeight: FontWeight.w500, ), ), ], ], ), ), // Action buttons Row( mainAxisSize: MainAxisSize.min, children: [ // Copy button IconButton( icon: Icon( Icons.copy, size: 20, color: Theme.of(context).colorScheme.onSurfaceVariant, ), onPressed: () => _copyToClipboard(context), tooltip: 'Copy to clipboard', visualDensity: VisualDensity.compact, ), // Edit button (if tap is enabled) if (onTap != null) Icon( Icons.arrow_forward_ios, size: 16, color: Theme.of(context).colorScheme.onSurfaceVariant, ), ], ), ], ), ), ), ); } /// Build empty state when no barcode is scanned Widget _buildEmptyState(BuildContext context) { return Container( padding: const EdgeInsets.all(16), child: Row( children: [ // Placeholder icon Container( padding: const EdgeInsets.all(8), decoration: BoxDecoration( color: Theme.of(context).colorScheme.onSurfaceVariant.withOpacity(0.1), borderRadius: BorderRadius.circular(6), ), child: Icon( Icons.qr_code_scanner, size: 24, color: Theme.of(context).colorScheme.onSurfaceVariant, ), ), const SizedBox(width: 12), // Placeholder text Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ Text( 'No barcode scanned', style: Theme.of(context).textTheme.titleMedium?.copyWith( color: Theme.of(context).colorScheme.onSurfaceVariant, ), ), const SizedBox(height: 2), Text( 'Point camera at barcode to scan', style: Theme.of(context).textTheme.bodySmall?.copyWith( color: Theme.of(context).colorScheme.onSurfaceVariant, ), ), ], ), ), // Scan animation (optional visual feedback) _buildScanAnimation(context), ], ), ); } /// Build scanning animation indicator Widget _buildScanAnimation(BuildContext context) { return TweenAnimationBuilder( duration: const Duration(seconds: 2), tween: Tween(begin: 0.0, end: 1.0), builder: (context, value, child) { return Opacity( opacity: (1.0 - value).clamp(0.3, 1.0), child: Container( width: 4, height: 24, decoration: BoxDecoration( color: Theme.of(context).colorScheme.primary, borderRadius: BorderRadius.circular(2), ), ), ); }, onEnd: () { // Restart animation (this creates a continuous effect) }, ); } /// Copy barcode to clipboard void _copyToClipboard(BuildContext context) { if (barcode != null) { Clipboard.setData(ClipboardData(text: barcode!)); // Show feedback ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text('Copied "$barcode" to clipboard'), duration: const Duration(seconds: 2), behavior: SnackBarBehavior.floating, action: SnackBarAction( label: 'OK', onPressed: () { ScaffoldMessenger.of(context).hideCurrentSnackBar(); }, ), ), ); } // Call custom onCopy callback if provided onCopy?.call(); } }