| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130 |
- import 'package:flutter/material.dart';
- import 'package:flutter_riverpod/flutter_riverpod.dart';
- import 'package:intl/intl.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<CatalogPage> createState() => _CatalogPageState();
- }
- class _CatalogPageState extends ConsumerState<CatalogPage> {
- 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)),
- ),
- ],
- ),
- ),
- ),
- );
- }
- }
|