import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; import '../../../backend/models/collection.dart'; import '../../../shared/widgets/adaptive_scaffold.dart'; import '../../../shared/widgets/confirm_dialog.dart'; import '../../../shared/widgets/empty_view.dart'; import '../../../shared/widgets/error_view.dart'; import 'collection_form_dialog.dart'; import 'collections_controller.dart'; class CollectionsScreen extends ConsumerWidget { const CollectionsScreen({super.key}); @override Widget build(BuildContext context, WidgetRef ref) { final collections = ref.watch(collectionsControllerProvider); return AdaptiveScaffold( title: 'Collections', actions: [ IconButton( tooltip: 'New collection', icon: const Icon(Icons.add_rounded), onPressed: () => showCollectionFormDialog(context, ref), ), ], body: collections.when( loading: () => const Center(child: CircularProgressIndicator()), error: (error, _) => ErrorView(message: error.toString()), data: (items) => items.isEmpty ? const EmptyView(title: 'No collections yet') : GridView.builder( padding: const EdgeInsets.all(16), gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent( maxCrossAxisExtent: 320, mainAxisSpacing: 12, crossAxisSpacing: 12, childAspectRatio: 1.35, ), itemCount: items.length, itemBuilder: (context, index) { final item = items[index]; return _CollectionCard( collection: item, onOpen: () => context.go('/collections/${item.id}'), onEdit: () => showCollectionFormDialog( context, ref, collection: item, ), onDelete: () async { final ok = await showConfirmDialog( context, title: 'Delete collection', message: 'Remove ${item.name}?', ); if (ok) { await ref .read(collectionsControllerProvider.notifier) .delete(item.id); } }, ); }, ), ), ); } } class _CollectionCard extends StatelessWidget { const _CollectionCard({ required this.collection, required this.onOpen, required this.onEdit, required this.onDelete, }); final Collection collection; final VoidCallback onOpen; final VoidCallback onEdit; final VoidCallback onDelete; @override Widget build(BuildContext context) { final scheme = Theme.of(context).colorScheme; return Card( clipBehavior: Clip.antiAlias, child: InkWell( onTap: onOpen, child: Stack( children: [ Positioned.fill( child: Padding( padding: const EdgeInsets.fromLTRB(16, 16, 16, 14), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ SizedBox( height: 54, child: Align( alignment: Alignment.centerLeft, child: DecoratedBox( decoration: BoxDecoration( color: scheme.primaryContainer.withValues(alpha: 0.56), borderRadius: BorderRadius.circular(12), ), child: const Padding( padding: EdgeInsets.all(12), child: Icon( Icons.collections_bookmark_rounded, size: 28, ), ), ), ), ), const Spacer(), Text( collection.name, maxLines: 1, overflow: TextOverflow.ellipsis, style: Theme.of(context).textTheme.titleLarge, ), const SizedBox(height: 4), Text( collection.description ?? 'No description', maxLines: 2, overflow: TextOverflow.ellipsis, style: Theme.of(context).textTheme.bodyMedium?.copyWith( color: scheme.onSurfaceVariant, ), ), ], ), ), ), Positioned( top: 6, right: 6, child: PopupMenuButton( tooltip: 'Collection actions', icon: const Icon(Icons.more_horiz_rounded), onSelected: (value) { if (value == 'edit') onEdit(); if (value == 'delete') onDelete(); }, itemBuilder: (context) => const [ PopupMenuItem( value: 'edit', child: ListTile( dense: true, leading: Icon(Icons.edit_rounded), title: Text('Edit'), ), ), PopupMenuItem( value: 'delete', child: ListTile( dense: true, leading: Icon(Icons.delete_rounded), title: Text('Delete'), ), ), ], ), ), ], ), ), ); } }