import 'package:flutter/material.dart'; import 'package:flutter_slidable/flutter_slidable.dart'; import 'package:inventory_system/services/supplier_service.dart'; import 'package:inventory_system/screens/admin/supplier/supplier_form.dart'; import 'package:inventory_system/screens/bottom_nav_bar.dart'; import 'package:inventory_system/screens/nav_bar.dart'; import 'package:inventory_system/screens/title_bar.dart'; class SupplierScreen extends StatefulWidget { const SupplierScreen({super.key}); @override State createState() => _SupplierScreenState(); } class _SupplierScreenState extends State { int _selectedIndex = 0; final SupplierService _supplierService = SupplierService(); late Future> _suppliersFuture; List _allSuppliers = []; List _filteredSuppliers = []; final TextEditingController _searchController = TextEditingController(); @override void initState() { super.initState(); _suppliersFuture = _fetchSuppliers(); _searchController.addListener(_onSearchChanged); } Future> _fetchSuppliers() async { try { final suppliers = await _supplierService.fetchSuppliers(); // Sort suppliers alphabetically by company name suppliers.sort((a, b) { final nameA = a['supplierCompName'] as String? ?? ''; final nameB = b['supplierCompName'] as String? ?? ''; return nameA.toLowerCase().compareTo(nameB.toLowerCase()); }); if (mounted) { setState(() { _allSuppliers = suppliers; _filteredSuppliers = suppliers; }); } return suppliers; } catch (e) { if (mounted) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('Failed to load suppliers: $e')), ); } rethrow; } } @override void dispose() { _searchController.removeListener(_onSearchChanged); _searchController.dispose(); super.dispose(); } void _onSearchChanged() { final query = _searchController.text.toLowerCase(); setState(() { _filteredSuppliers = _allSuppliers.where((supplier) { final name = supplier['supplierCompName'].toString().toLowerCase(); final address = supplier['supplierAddress'].toString().toLowerCase(); return name.contains(query) || address.contains(query); }).toList(); }); } void _handleDelete(int supplierId) async { try { await _supplierService.deleteSupplier(supplierId); ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('Supplier deleted successfully')), ); _fetchSuppliers(); // Refresh the list } catch (e) { if (mounted) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('Failed to delete supplier: $e')), ); } } } void _confirmDelete(int supplierId, String supplierName) { showDialog( context: context, builder: (context) => AlertDialog( title: const Text('Delete Supplier'), content: Text('Are you sure you want to delete $supplierName?'), actions: [ TextButton( onPressed: () => Navigator.pop(context), child: const Text('Cancel'), ), TextButton( onPressed: () { Navigator.pop(context); _handleDelete(supplierId); }, child: const Text('Delete', style: TextStyle(color: Colors.red)), ), ], ), ); } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: const Color(0xFFF5F5F7), appBar: const TitleBar(title: 'Supplier'), drawer: const NavBar(isAdmin: true, selectedScreen: AppScreen.supplier), body: Padding( padding: const EdgeInsets.all(16.0), child: Column( children: [ Row( children: [ ElevatedButton.icon( onPressed: () { Navigator.push( context, MaterialPageRoute( builder: (context) => const SupplierFormScreen(), ), ).then((_) => _fetchSuppliers()); }, icon: const Icon(Icons.add, size: 18), label: const Text('Add Supplier'), style: ElevatedButton.styleFrom( backgroundColor: Colors.purple.shade100, foregroundColor: Colors.black87, elevation: 0, padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), ), ), ), const SizedBox(width: 12), Expanded( child: TextField( controller: _searchController, decoration: InputDecoration( hintText: 'Search', hintStyle: TextStyle(color: Colors.grey.shade400), prefixIcon: const Icon(Icons.search), suffixIcon: _searchController.text.isNotEmpty ? IconButton( icon: const Icon(Icons.clear), onPressed: () => _searchController.clear(), ) : null, filled: true, fillColor: Colors.white, border: OutlineInputBorder( borderRadius: BorderRadius.circular(12), borderSide: BorderSide.none, ), contentPadding: const EdgeInsets.symmetric(horizontal: 16), ), ), ), ], ), const SizedBox(height: 16), Expanded( child: RefreshIndicator( onRefresh: _fetchSuppliers, child: FutureBuilder>( future: _suppliersFuture, builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return const Center(child: CircularProgressIndicator()); } if (snapshot.hasError) { return Center( child: Text( 'Error: ${snapshot.error}', textAlign: TextAlign.center, style: const TextStyle(color: Colors.red), ), ); } if (_filteredSuppliers.isEmpty) { return Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon(Icons.search_off, size: 64, color: Colors.grey.shade400), const SizedBox(height: 16), Text( 'No suppliers found', style: TextStyle(fontSize: 16, color: Colors.grey.shade600), ), ], ), ); } return ListView.builder( itemCount: _filteredSuppliers.length, itemBuilder: (context, index) { final supplier = _filteredSuppliers[index]; return Padding( padding: const EdgeInsets.only(bottom: 12), child: Slidable( key: Key(supplier['supplierId'].toString()), endActionPane: ActionPane( motion: const ScrollMotion(), children: [ SlidableAction( onPressed: (context) { Navigator.push( context, MaterialPageRoute( builder: (context) => SupplierFormScreen(supplier: supplier), ), ).then((_) => _fetchSuppliers()); }, backgroundColor: Colors.blue, foregroundColor: Colors.white, icon: Icons.edit, label: 'Edit', ), SlidableAction( onPressed: (context) => _confirmDelete( supplier['supplierId'], supplier['supplierCompName'], ), backgroundColor: Colors.red, foregroundColor: Colors.white, icon: Icons.delete, label: 'Delete', borderRadius: const BorderRadius.horizontal( right: Radius.circular(16)), ), ], ), child: Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(16), border: Border.all( color: Colors.grey.shade300, width: 1), boxShadow: [ BoxShadow( color: Colors.grey.withOpacity(0.05), blurRadius: 4, offset: const Offset(0, 2), ), ], ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Flexible( child: Text( supplier['supplierCompName'] ?? 'N/A', style: const TextStyle( fontSize: 16, fontWeight: FontWeight.w600, color: Colors.black87, ), ), ), Text( supplier['supplierPhoneNo'] ?? 'N/A', style: TextStyle( fontSize: 13, fontWeight: FontWeight.w500, color: Colors.grey.shade600, ), ), ], ), const SizedBox(height: 8), Text( supplier['supplierAddress'] ?? 'No address provided', style: TextStyle( fontSize: 12, color: Colors.grey.shade600, height: 1.4, ), ), const SizedBox(height: 8), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Flexible( child: Text( supplier['supplierPIC'] ?? 'N/A', style: TextStyle( fontSize: 12, color: Colors.grey.shade600, ), ), ), Text( supplier['supplierEmail'] ?? 'No email provided', style: const TextStyle( fontSize: 12, color: Colors.blue, fontStyle: FontStyle.italic), ), ], ), ], ), ), ), ); }, ); }, ), ), ), ], ), ), bottomNavigationBar: BottomNavBar( selectedIndex: _selectedIndex, onItemTapped: (index) { if (index == 0) { Navigator.pop(context); } else { setState(() { _selectedIndex = index; }); } }, ), ); } }