import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; import '../cart/cart_state.dart'; typedef DiscoverFilters = ({String? q, double? minRating, String sort}); final discoverFiltersProvider = StateProvider( (_) => (q: null, minRating: null, sort: 'rating'), ); final discoverProvider = FutureProvider.autoDispose>>((ref) { final filters = ref.watch(discoverFiltersProvider); return ref.watch(publicApiProvider).discover( city: 'تهران', q: filters.q, minRating: filters.minRating, sort: filters.sort, ); }); class DiscoverScreen extends ConsumerStatefulWidget { const DiscoverScreen({super.key}); @override ConsumerState createState() => _DiscoverScreenState(); } class _DiscoverScreenState extends ConsumerState { final _searchController = TextEditingController(); @override void dispose() { _searchController.dispose(); super.dispose(); } void _applySearch() { final q = _searchController.text.trim(); ref.read(discoverFiltersProvider.notifier).update( (s) => (q: q.isEmpty ? null : q, minRating: s.minRating, sort: s.sort), ); } @override Widget build(BuildContext context) { final cafesAsync = ref.watch(discoverProvider); final filters = ref.watch(discoverFiltersProvider); return Directionality( textDirection: TextDirection.rtl, child: Scaffold( appBar: AppBar( title: const Text('کافه‌یاب میزی'), actions: [ IconButton( icon: const Icon(Icons.qr_code_scanner), onPressed: () => context.push('/qr'), ), ], ), body: Column( children: [ Padding( padding: const EdgeInsets.fromLTRB(16, 16, 16, 8), child: Row( children: [ Expanded( child: TextField( controller: _searchController, decoration: InputDecoration( hintText: 'جستجوی نام کافه...', border: const OutlineInputBorder(), isDense: true, suffixIcon: IconButton( icon: const Icon(Icons.search), onPressed: _applySearch, ), ), onSubmitted: (_) => _applySearch(), ), ), ], ), ), SingleChildScrollView( scrollDirection: Axis.horizontal, padding: const EdgeInsets.symmetric(horizontal: 16), child: Row( children: [ FilterChip( label: const Text('همه'), selected: filters.minRating == null, onSelected: (_) { ref.read(discoverFiltersProvider.notifier).update( (s) => (q: s.q, minRating: null, sort: s.sort), ); }, ), const SizedBox(width: 8), for (final min in [3.0, 4.0, 4.5]) Padding( padding: const EdgeInsets.only(left: 8), child: FilterChip( label: Text('★ $min+'), selected: filters.minRating == min, onSelected: (_) { ref.read(discoverFiltersProvider.notifier).update( (s) => (q: s.q, minRating: min, sort: s.sort), ); }, ), ), ], ), ), Padding( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), child: DropdownButtonFormField( value: filters.sort, decoration: const InputDecoration( labelText: 'مرتب‌سازی', border: OutlineInputBorder(), isDense: true, ), items: const [ DropdownMenuItem(value: 'rating', child: Text('بیشترین امتیاز')), DropdownMenuItem(value: 'reviews', child: Text('بیشترین نظر')), DropdownMenuItem(value: 'name', child: Text('نام')), ], onChanged: (sort) { if (sort == null) return; ref.read(discoverFiltersProvider.notifier).update( (s) => (q: s.q, minRating: s.minRating, sort: sort), ); }, ), ), Expanded( child: cafesAsync.when( data: (cafes) { if (cafes.isEmpty) { return const Center(child: Text('کافه‌ای یافت نشد')); } return ListView.separated( padding: const EdgeInsets.all(16), itemCount: cafes.length, separatorBuilder: (_, __) => const SizedBox(height: 8), itemBuilder: (context, index) { final cafe = cafes[index]; final slug = cafe['slug'] as String; final name = cafe['name'] as String? ?? slug; final avg = (cafe['averageRating'] as num?)?.toDouble() ?? 0; final count = cafe['reviewCount'] as int? ?? 0; final address = cafe['address'] as String?; return Card( child: ListTile( title: Text(name), subtitle: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(cafe['city'] as String? ?? ''), if (address != null && address.isNotEmpty) Text(address), Text('★ ${avg.toStringAsFixed(1)} · $count نظر'), ], ), trailing: const Icon(Icons.chevron_left), onTap: () => context.push('/cafe/$slug'), ), ); }, ); }, loading: () => const Center(child: CircularProgressIndicator()), error: (e, _) => Center(child: Text('خطا: $e')), ), ), ], ), ), ); } }