import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../../../database/database.dart'; import '../../../providers/article_provider.dart'; import '../../widgets/article_image.dart'; import '../../widgets/empty_state.dart'; import '../../widgets/search_bar.dart' as sw; import '../../../core/responsive.dart'; class CatalogPage extends ConsumerStatefulWidget { const CatalogPage({super.key}); @override ConsumerState createState() => _CatalogPageState(); } class _CatalogPageState extends ConsumerState { String _filter = ''; final _searchCtrl = TextEditingController(); @override void dispose() { _searchCtrl.dispose(); super.dispose(); } @override Widget build(BuildContext context) { final articlesAsync = ref.watch(activeArticleSearchProvider(_filter)); return Scaffold( appBar: AppBar(title: const Text('Catalogo')), body: SafeArea( child: Column( children: [ sw.SearchBarWidget( controller: _searchCtrl, hint: 'Cerca articolo...', onChanged: (v) => setState(() => _filter = v), onClear: () { _searchCtrl.clear(); setState(() => _filter = ''); }, ), Expanded( child: articlesAsync.when( data: (articles) { if (articles.isEmpty) return const EmptyState( icon: Icons.inventory_2_outlined, title: 'Nessun articolo'); if (ResponsiveBreakpoints.isPhone(context)) { return ListView.builder( itemCount: articles.length, itemBuilder: (_, i) => _ArticleListItem(article: articles[i]), ); } return GridView.builder( padding: const EdgeInsets.all(8), gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 3, childAspectRatio: 1.2, crossAxisSpacing: 8, mainAxisSpacing: 8, ), itemCount: articles.length, itemBuilder: (_, i) => _ArticleGridItem(article: articles[i]), ); }, loading: () => const Center(child: CircularProgressIndicator()), error: (e, _) => Center(child: Text('Errore: $e')), ), ), ], ), ), ); } } class _ArticleListItem extends StatelessWidget { final Articolo article; const _ArticleListItem({required this.article}); @override Widget build(BuildContext context) { return Card( margin: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), child: ListTile( leading: ArticleImage( idArticolo: article.idArticolo, codArticolo: article.codArticolo), title: Text(article.descrizione ?? ''), subtitle: Text(article.codArticolo ?? ''), trailing: article.nonDisponibile == 1 ? Container( padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 2), decoration: BoxDecoration( color: Colors.red.shade100, borderRadius: BorderRadius.circular(8)), child: const Text('N.D.', style: TextStyle(color: Colors.red, fontSize: 12)), ) : null, ), ); } } class _ArticleGridItem extends StatelessWidget { final Articolo article; const _ArticleGridItem({required this.article}); @override Widget build(BuildContext context) { return Card( child: InkWell( borderRadius: BorderRadius.circular(12), child: Padding( padding: const EdgeInsets.all(8), child: Column( mainAxisSize: MainAxisSize.min, children: [ ArticleImage( idArticolo: article.idArticolo, codArticolo: article.codArticolo, size: 64), const SizedBox(height: 8), Text(article.descrizione ?? '', maxLines: 2, overflow: TextOverflow.ellipsis, style: Theme.of(context).textTheme.bodySmall), Text(article.codArticolo ?? '', style: Theme.of(context) .textTheme .labelSmall ?.copyWith(color: Theme.of(context).colorScheme.outline)), if (article.nonDisponibile == 1) Container( padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 1), decoration: BoxDecoration( color: Colors.red.shade100, borderRadius: BorderRadius.circular(8)), child: const Text('N.D.', style: TextStyle(color: Colors.red, fontSize: 10)), ), ], ), ), ), ); } }