import 'package:auto_route/auto_route.dart'; import 'package:flutter/material.dart'; import '../../../common/theme/theme.dart'; import '../../components/field/field.dart'; import '../../router/app_router.gr.dart'; import 'widgets/empty_merchant_card.dart'; import 'widgets/merchant_card.dart'; @RoutePage() class MerchantPage extends StatefulWidget { const MerchantPage({super.key}); @override State createState() => _MerchantPageState(); } class _MerchantPageState extends State { final TextEditingController _searchController = TextEditingController(); final List _allMerchants = _generateMockMerchants(); List _filteredMerchants = []; @override void initState() { super.initState(); _filteredMerchants = _allMerchants; } @override void dispose() { _searchController.dispose(); super.dispose(); } void _filterMerchants(String query) { setState(() { if (query.isEmpty) { _filteredMerchants = _allMerchants; } else { _filteredMerchants = _allMerchants .where( (merchant) => merchant.name.toLowerCase().contains(query.toLowerCase()) || merchant.category.toLowerCase().contains(query.toLowerCase()), ) .toList(); } }); } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: AppColor.background, appBar: AppBar( title: Text('Merchants'), bottom: PreferredSize( preferredSize: const Size.fromHeight(70), child: SearchTextField( hintText: 'Search merchants...', prefixIcon: Icons.search, controller: _searchController, onClear: () { _searchController.clear(); _filterMerchants(''); }, ), ), ), body: _filteredMerchants.isEmpty ? _buildEmptyState() : Padding( padding: const EdgeInsets.all(16), child: GridView.builder( gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 2, crossAxisSpacing: 16, mainAxisSpacing: 16, childAspectRatio: 0.85, ), itemCount: _filteredMerchants.length, itemBuilder: (context, index) { return _buildMerchantCard(_filteredMerchants[index]); }, ), ), ); } Widget _buildMerchantCard(MerchantModel merchant) { return MerchantCard( merchant: merchant, onTap: () { context.router.push(MerchantDetailRoute(merchant: merchant)); }, ); } Widget _buildEmptyState() { return const EmptyMerchantCard(); } static List _generateMockMerchants() { return [ MerchantModel( id: '1', name: 'Warung Makan Sederhana', category: 'Food & Beverage', rating: 4.5, isOpen: true, imageUrl: 'https://via.placeholder.com/150', ), MerchantModel( id: '2', name: 'Toko Elektronik', category: 'Electronics', rating: 4.2, isOpen: true, imageUrl: 'https://via.placeholder.com/150', ), MerchantModel( id: '3', name: 'Apotek Sehat', category: 'Healthcare', rating: 4.8, isOpen: false, imageUrl: 'https://via.placeholder.com/150', ), MerchantModel( id: '4', name: 'Fashion Store', category: 'Clothing', rating: 4.1, isOpen: true, imageUrl: 'https://via.placeholder.com/150', ), MerchantModel( id: '5', name: 'Bengkel Motor', category: 'Automotive', rating: 4.3, isOpen: true, imageUrl: 'https://via.placeholder.com/150', ), MerchantModel( id: '6', name: 'Minimarket 24', category: 'Retail', rating: 4.0, isOpen: true, imageUrl: 'https://via.placeholder.com/150', ), MerchantModel( id: '7', name: 'Salon Kecantikan', category: 'Beauty', rating: 4.6, isOpen: false, imageUrl: 'https://via.placeholder.com/150', ), MerchantModel( id: '8', name: 'Laundry Express', category: 'Service', rating: 4.4, isOpen: true, imageUrl: 'https://via.placeholder.com/150', ), ]; } } class MerchantModel { final String id; final String name; final String category; final double rating; final bool isOpen; final String imageUrl; MerchantModel({ required this.id, required this.name, required this.category, required this.rating, required this.isOpen, required this.imageUrl, }); }