import 'package:flutter/material.dart'; import '../main.dart'; import '../services/collection_service.dart'; import '../theme/app_colors.dart'; import 'garage_screen.dart'; import 'manage_collection_screen.dart'; /// Lists all collections the current user is a member of. class CollectionsScreen extends StatefulWidget { const CollectionsScreen({super.key}); @override State createState() => CollectionsScreenState(); } class CollectionsScreenState extends State { List _collections = []; bool _isLoading = true; String? _error; @override void initState() { super.initState(); _load(); } /// Public so other tabs can trigger a refresh. void refresh() => _load(); Future _load() async { setState(() { _isLoading = true; _error = null; }); try { final list = await CollectionService.getMyCollections(); if (!mounted) return; setState(() { _collections = list; _isLoading = false; }); } catch (e) { if (!mounted) return; setState(() { _error = e.toString(); _isLoading = false; }); } } Future _createCollection() async { final nameCtrl = TextEditingController(); final descCtrl = TextEditingController(); final result = await showDialog( context: context, builder: (_) => AlertDialog( icon: Container( padding: const EdgeInsets.all(12), decoration: const BoxDecoration( gradient: AppColors.brandGradient, shape: BoxShape.circle, ), child: const Icon(Icons.add, color: Colors.white, size: 28), ), title: const Text('New Collection'), content: Column( mainAxisSize: MainAxisSize.min, children: [ TextField( controller: nameCtrl, autofocus: true, decoration: const InputDecoration( labelText: 'Name', hintText: 'e.g. Hot Wheels, Matchbox…', ), ), const SizedBox(height: 12), TextField( controller: descCtrl, decoration: const InputDecoration( labelText: 'Description (optional)', hintText: 'What is this collection for?', ), ), ], ), actions: [ TextButton( onPressed: () => Navigator.pop(context), child: const Text('Cancel'), ), ElevatedButton( onPressed: () { if (nameCtrl.text.trim().isEmpty) return; Navigator.pop(context, true); }, child: const Text('Create'), ), ], ), ); if (result != true) return; try { await CollectionService.create( name: nameCtrl.text.trim(), description: descCtrl.text.trim(), ); showGlobalSnackBar('Collection created!'); _load(); } catch (e) { showGlobalSnackBar('Failed: $e', isError: true); } } void _openCollection(Collection c) { navigatorKey.currentState!.push( MaterialPageRoute( builder: (_) => GarageScreen( collectionId: c.id, collectionName: c.name, isOwner: c.isOwner, ), ), ).then((_) => _load()); // refresh counts when coming back } void _manageCollection(Collection c) { navigatorKey.currentState!.push( MaterialPageRoute( builder: (_) => ManageCollectionScreen(collection: c), ), ).then((_) => _load()); } @override Widget build(BuildContext context) { return Scaffold( body: CustomScrollView( slivers: [ // ── Header ── SliverAppBar( expandedHeight: 140, pinned: true, flexibleSpace: FlexibleSpaceBar( titlePadding: const EdgeInsets.only(left: 20, bottom: 16), title: Text( 'Collections', style: TextStyle( fontFamily: 'Poppins', fontWeight: FontWeight.w700, fontSize: 22, color: Colors.white, shadows: [ Shadow( color: Colors.black.withValues(alpha: 0.3), blurRadius: 4, ), ], ), ), background: Container( decoration: const BoxDecoration( gradient: AppColors.brandGradient, ), child: Align( alignment: Alignment.centerRight, child: Padding( padding: const EdgeInsets.only(right: 24), child: Icon( Icons.collections_bookmark, size: 72, color: Colors.white.withValues(alpha: 0.15), ), ), ), ), ), ), // ── Content ── if (_isLoading) const SliverFillRemaining( child: Center(child: CircularProgressIndicator()), ) else if (_error != null) SliverFillRemaining( child: Center( child: Column( mainAxisSize: MainAxisSize.min, children: [ const Icon(Icons.error_outline, size: 56, color: AppColors.error), const SizedBox(height: 16), Text(_error!, textAlign: TextAlign.center, style: const TextStyle(color: AppColors.textSecondary)), const SizedBox(height: 16), ElevatedButton.icon( onPressed: _load, icon: const Icon(Icons.refresh), label: const Text('Retry'), ), ], ), ), ) else if (_collections.isEmpty) SliverFillRemaining( child: Center( child: Padding( padding: const EdgeInsets.all(40), child: Column( mainAxisSize: MainAxisSize.min, children: [ Icon(Icons.collections_bookmark_outlined, size: 64, color: AppColors.textHint), const SizedBox(height: 16), const Text( 'No collections yet', style: TextStyle( fontSize: 18, fontWeight: FontWeight.w600, color: AppColors.textSecondary, ), ), const SizedBox(height: 8), const Text( 'Create your first collection to start tracking!', textAlign: TextAlign.center, style: TextStyle(color: AppColors.textHint), ), const SizedBox(height: 24), ElevatedButton.icon( onPressed: _createCollection, icon: const Icon(Icons.add), label: const Text('Create Collection'), ), ], ), ), ), ) else SliverPadding( padding: const EdgeInsets.fromLTRB(16, 16, 16, 100), sliver: SliverList( delegate: SliverChildBuilderDelegate( (context, index) { final c = _collections[index]; return _CollectionCard( collection: c, onTap: () => _openCollection(c), onManage: () => _manageCollection(c), ); }, childCount: _collections.length, ), ), ), ], ), floatingActionButton: _collections.isNotEmpty ? FloatingActionButton( onPressed: _createCollection, child: const Icon(Icons.add), ) : null, ); } } // ── Collection Card ────────────────────────────────────────────────── class _CollectionCard extends StatelessWidget { final Collection collection; final VoidCallback onTap; final VoidCallback onManage; const _CollectionCard({ required this.collection, required this.onTap, required this.onManage, }); @override Widget build(BuildContext context) { final c = collection; return Card( margin: const EdgeInsets.only(bottom: 12), child: InkWell( onTap: onTap, borderRadius: BorderRadius.circular(16), child: Padding( padding: const EdgeInsets.all(16), child: Row( children: [ // Icon Container( width: 56, height: 56, decoration: BoxDecoration( gradient: c.isOwner ? AppColors.brandGradient : const LinearGradient( colors: [AppColors.navy, AppColors.navyLight], ), borderRadius: BorderRadius.circular(14), ), child: Icon( c.isOwner ? Icons.collections_bookmark : Icons.group, color: Colors.white, size: 28, ), ), const SizedBox(width: 16), // Info Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( c.name, style: const TextStyle( fontSize: 17, fontWeight: FontWeight.w600, ), ), const SizedBox(height: 4), Row( children: [ _MiniStat( icon: Icons.directions_car, value: '${c.itemCount}'), const SizedBox(width: 16), _MiniStat( icon: Icons.people, value: '${c.memberCount}'), const SizedBox(width: 16), Container( padding: const EdgeInsets.symmetric( horizontal: 8, vertical: 2), decoration: BoxDecoration( color: c.isOwner ? AppColors.orange.withValues(alpha: 0.15) : AppColors.navy.withValues(alpha: 0.1), borderRadius: BorderRadius.circular(6), ), child: Text( c.isOwner ? 'Owner' : 'Member', style: TextStyle( fontSize: 11, fontWeight: FontWeight.w600, color: c.isOwner ? AppColors.orange : AppColors.navy, ), ), ), ], ), ], ), ), // Manage button IconButton( icon: const Icon(Icons.settings_outlined, color: AppColors.textHint), onPressed: onManage, ), ], ), ), ), ); } } class _MiniStat extends StatelessWidget { final IconData icon; final String value; const _MiniStat({required this.icon, required this.value}); @override Widget build(BuildContext context) { return Row( mainAxisSize: MainAxisSize.min, children: [ Icon(icon, size: 14, color: AppColors.textHint), const SizedBox(width: 4), Text( value, style: const TextStyle( fontSize: 13, color: AppColors.textSecondary, ), ), ], ); } }