import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import '../providers/app_state.dart'; import '../models/bean.dart'; import '../components/bean_dialog.dart'; import '../components/searchable_selection.dart'; class BeansScreen extends StatelessWidget { const BeansScreen({super.key}); @override Widget build(BuildContext context) { return Consumer( builder: (context, appState, child) { if (appState.isLoading) { return const Center(child: CircularProgressIndicator()); } return Scaffold( body: appState.beans.isEmpty ? const Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon(Icons.coffee, size: 64, color: Colors.grey), SizedBox(height: 16), Text('No beans in your collection yet'), Text('Tap the + button to browse and add beans'), ], ), ) : ListView.builder( padding: const EdgeInsets.all(16), itemCount: appState.beans.length, itemBuilder: (context, index) { final bean = appState.beans[index]; return _buildBeanCard(context, bean); }, ), floatingActionButton: FloatingActionButton( onPressed: () => _showAddBeanDialog(context), child: const Icon(Icons.add), ), ); }, ); } Widget _buildBeanCard(BuildContext context, Bean bean) { return Card( margin: const EdgeInsets.only(bottom: 16), child: Padding( padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Expanded( child: Text( bean.name, style: Theme.of(context).textTheme.headlineSmall, ), ), if (bean.preferred) const Icon(Icons.star, color: Colors.amber), PopupMenuButton( itemBuilder: (context) => [ const PopupMenuItem( value: 'edit', child: Row( children: [ Icon(Icons.edit), SizedBox(width: 8), Text('Edit'), ], ), ), const PopupMenuItem( value: 'delete', child: Row( children: [ Icon(Icons.delete, color: Colors.red), SizedBox(width: 8), Text('Delete', style: TextStyle(color: Colors.red)), ], ), ), ], onSelected: (value) { if (value == 'edit') { _showEditBeanDialog(context, bean); } else if (value == 'delete') { _showDeleteBeanDialog(context, bean); } }, ), ], ), const SizedBox(height: 8), Text('Varietal: ${bean.varietal}'), Text('Roast Level: ${bean.roastLevel.name}'), Text('Processing: ${bean.processingMethod}'), Text('Roasted: ${_formatDate(bean.roastDate)}'), Text('Origin: ${bean.origin}'), Text('Roaster: ${bean.roaster}'), const SizedBox(height: 12), Wrap( spacing: 4, children: bean.flavorNotes .map( (note) => Chip( label: Text( note.name, style: const TextStyle(fontSize: 12), ), backgroundColor: Theme.of( context, ).colorScheme.primary.withAlpha(51), ), ) .toList(), ), ], ), ), ); } String _formatDate(DateTime date) { return '${date.day}/${date.month}/${date.year}'; } void _showAddBeanDialog(BuildContext context) { _showBeanCatalog(context); } void _showBeanCatalog(BuildContext context) async { final appState = context.read(); // Get all available beans from catalog final availableBeans = await appState.getAllAvailableBeans(); if (availableBeans.isEmpty) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('No beans available in catalog')), ); return; } Navigator.of(context).push( MaterialPageRoute( builder: (context) => SearchableSelection( items: availableBeans, title: 'Browse Bean Catalog', displayText: (bean) => '${bean.name} - ${bean.origin}', searchHint: 'Search by name, varietal, or origin...', onItemSelected: (bean) async { Navigator.of(context).pop(); // Check if bean is already in user's collection if (appState.beans.any((b) => b.id == bean.id)) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('${bean.name} is already in your collection')), ); return; } // Add bean to user's collection try { await appState.addBean(bean); ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('${bean.name} added to your collection!')), ); } catch (e) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('Error adding bean: $e')), ); } }, onAddCustom: () { Navigator.of(context).pop(); showDialog( context: context, builder: (context) => const BeanDialog(), ); }, ), ), ); } void _showEditBeanDialog(BuildContext context, Bean bean) { showDialog( context: context, builder: (context) => BeanDialog(bean: bean), ); } void _showDeleteBeanDialog(BuildContext context, Bean bean) { showDialog( context: context, builder: (context) => AlertDialog( title: const Text('Delete Bean'), content: Text('Are you sure you want to delete "${bean.name}"?'), actions: [ TextButton( onPressed: () => Navigator.of(context).pop(), child: const Text('Cancel'), ), ElevatedButton( onPressed: () async { try { await Provider.of(context, listen: false) .deleteBean(bean.id); if (context.mounted) { Navigator.of(context).pop(); ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('Bean deleted successfully!')), ); } } catch (e) { if (context.mounted) { Navigator.of(context).pop(); ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('Error deleting bean: $e')), ); } } }, style: ElevatedButton.styleFrom(backgroundColor: Colors.red), child: const Text('Delete'), ), ], ), ); } }