import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../../domain/entities/pokemon.dart'; import '../providers/pokedex_provider.dart'; import '../widgets/pokemon_tile.dart'; import '../widgets/scanline_overlay.dart'; import '../widgets/list/pokedex_list_header.dart'; import '../widgets/list/pokedex_count_bar.dart'; /// Liste du Pokédex national avec filtre ALL / CAUGHT. class PokemonListPage extends ConsumerStatefulWidget { const PokemonListPage({Key? key}) : super(key: key); @override ConsumerState createState() => _PokemonListPageState(); } class _PokemonListPageState extends ConsumerState { String _filter = 'ALL'; // ALL, CAUGHT final ScrollController _scrollController = ScrollController(); @override void dispose() { _scrollController.dispose(); super.dispose(); } List _applyFilter(List all) { if (_filter == 'CAUGHT') return all.where((p) => p.isCaught).toList(); return all; } @override Widget build(BuildContext context) { final pokedexAsync = ref.watch(pokedexProvider); final caughtCount = ref.watch(caughtCountProvider); return Container( decoration: const BoxDecoration(color: Color(0xFFC8D1D8)), child: Column( children: [ const PokedexListHeader(), Container( color: const Color(0xFF90A4AE), height: 40, child: Row( children: [ _buildTab('ALL', _filter == 'ALL'), _buildTab('CAUGHT', _filter == 'CAUGHT'), ], ), ), PokedexCountBar(caught: caughtCount, total: pokedexAsync.valueOrNull?.length ?? 0), Expanded( child: Stack( children: [ const ScanlineOverlay(), pokedexAsync.when( loading: () => const Center(child: CircularProgressIndicator()), error: (e, _) => Center( child: Text('Erreur de chargement\n$e', textAlign: TextAlign.center, style: const TextStyle(color: Colors.black54)), ), data: (all) { final filtered = _applyFilter(all); if (filtered.isEmpty) return _emptyState(); return ListView.builder( controller: _scrollController, padding: const EdgeInsets.all(12), itemCount: filtered.length, itemBuilder: (context, index) => PokemonTile(filtered[index]), ); }, ), ], ), ), Container( height: 24, color: const Color(0xFF1B2333), alignment: Alignment.center, child: const Text('NATIONAL POKEDEX V2.0', style: TextStyle(color: Colors.white70, fontSize: 12, letterSpacing: 1)), ), ], ), ); } Widget _emptyState() { return Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ const Icon(Icons.search_off, size: 64, color: Colors.black26), const SizedBox(height: 16), Text('NO POKEMON FOUND IN $_filter', style: const TextStyle(color: Colors.black45, fontSize: 18, fontWeight: FontWeight.bold)), ], ), ); } Widget _buildTab(String title, bool isSelected) { return Expanded( child: GestureDetector( onTap: () { if (_filter != title) { setState(() => _filter = title); if (_scrollController.hasClients) _scrollController.jumpTo(0); } }, child: Container( decoration: BoxDecoration( color: isSelected ? const Color(0xFFB0BEC5) : Colors.transparent, border: isSelected ? const Border(bottom: BorderSide(color: Color(0xFFD32F2F), width: 3)) : null, ), alignment: Alignment.center, child: Text(title, style: TextStyle( fontSize: 18, fontWeight: FontWeight.bold, color: isSelected ? Colors.black : Colors.black54)), ), ), ); } }