import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import '../providers/invoice_installment_screen.dart'; import '../providers/invoice_provider.dart'; import 'invoice_detail_screen.dart'; class InvoiceScreen extends StatefulWidget { const InvoiceScreen({super.key}); @override State createState() => _InvoiceScreenState(); } class _InvoiceScreenState extends State { String searchQuery = ""; @override void initState() { super.initState(); WidgetsBinding.instance.addPostFrameCallback((_) { Provider.of(context, listen: false) .loadInvoices(context); }); } @override Widget build(BuildContext context) { final provider = Provider.of(context); final width = MediaQuery.of(context).size.width; final scale = (width / 430).clamp(0.88, 1.08); if (provider.loading) { return const Center(child: CircularProgressIndicator()); } // 🔍 Filter invoices based on search query final filteredInvoices = provider.invoices.where((inv) { final q = searchQuery.toLowerCase(); return inv['invoice_number'].toString().toLowerCase().contains(q) || inv['invoice_date'].toString().toLowerCase().contains(q) || inv['formatted_amount'].toString().toLowerCase().contains(q) || inv['status'].toString().toLowerCase().contains(q); }).toList(); return Column( children: [ // 🔍 SEARCH BAR Container( margin: EdgeInsets.fromLTRB(16 * scale, 16 * scale, 16 * scale, 8 * scale), padding: EdgeInsets.symmetric(horizontal: 14 * scale), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(14 * scale), boxShadow: [ BoxShadow( color: Colors.black12.withOpacity(0.08), blurRadius: 8 * scale, offset: Offset(0, 3 * scale), ), ], ), child: TextField( onChanged: (v) => setState(() => searchQuery = v), style: TextStyle(fontSize: 14 * scale), decoration: InputDecoration( icon: Icon(Icons.search, size: 22 * scale), hintText: "Search Invoice Number, Date, Amount...", border: InputBorder.none, ), ), ), // 📄 LIST OF INVOICES Expanded( child: filteredInvoices.isEmpty ? Center( child: Text( "No invoices found", style: TextStyle( fontSize: 18 * scale, fontWeight: FontWeight.w600, ), ), ) : ListView.builder( padding: EdgeInsets.all(16 * scale), itemCount: filteredInvoices.length, itemBuilder: (_, i) { final inv = filteredInvoices[i]; return Card( color: Colors.white, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(16 * scale), ), elevation: 3, margin: EdgeInsets.only(bottom: 14 * scale), child: Stack( children: [ Padding( padding: EdgeInsets.all(16 * scale), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ /// Invoice Number Text( "Invoice ${inv['invoice_number'] ?? 'N/A'}", style: TextStyle( fontSize: 20 * scale, fontWeight: FontWeight.bold, color: Colors.blue, ), ), SizedBox(height: 8 * scale), /// Date + Amount Text( "Date: ${inv['invoice_date'] ?? 'N/A'}", style: TextStyle(fontSize: 15 * scale), ), Text( "Amount: ₹${inv['formatted_amount'] ?? '0'}", style: TextStyle(fontSize: 15 * scale), ), SizedBox(height: 16 * scale), /// BUTTONS ROW Row( children: [ Expanded( child: GradientButton( text: "Invoice Details", fontSize: 15 * scale, radius: 12 * scale, padding: 14 * scale, gradient: const LinearGradient( colors: [ Color(0xFF1976D2), Color(0xFF42A5F5), ], ), onTap: () { Navigator.push( context, MaterialPageRoute( builder: (_) => InvoiceDetailScreen( invoiceId: inv['invoice_id']), ), ); }, ), ), SizedBox(width: 12 * scale), Expanded( child: GradientButton( text: "Installments", fontSize: 15 * scale, radius: 12 * scale, padding: 14 * scale, gradient: const LinearGradient( colors: [ Color(0xFF43A047), Color(0xFF81C784), ], ), onTap: () { Navigator.push( context, MaterialPageRoute( builder: (_) => InvoiceInstallmentScreen( invoiceId: inv['invoice_id']), ), ); }, ), ), ], ), ], ), ), /// STATUS BADGE Positioned( right: 12 * scale, top: 12 * scale, child: Container( padding: EdgeInsets.symmetric( horizontal: 10 * scale, vertical: 6 * scale, ), decoration: BoxDecoration( color: _getStatusColor(inv['status']), borderRadius: BorderRadius.circular(12 * scale), ), child: Text( inv['status'] ?? 'N/A', style: TextStyle( color: Colors.white, fontSize: 12 * scale, fontWeight: FontWeight.bold, ), ), ), ), ], ), ); }, ), ), ], ); } } /// Status Color Helper Color _getStatusColor(String? status) { switch (status?.toLowerCase()) { case 'pending': return Colors.orange; case 'in transit': return Colors.blue; case 'overdue': return Colors.redAccent; case 'paid': return Colors.green; default: return Colors.grey; } } /// ------------------------------------------------------- /// RESPONSIVE GRADIENT BUTTON /// ------------------------------------------------------- class GradientButton extends StatelessWidget { final String text; final Gradient gradient; final VoidCallback onTap; final double fontSize; final double padding; final double radius; const GradientButton({ super.key, required this.text, required this.gradient, required this.onTap, required this.fontSize, required this.padding, required this.radius, }); @override Widget build(BuildContext context) { return InkWell( borderRadius: BorderRadius.circular(radius), onTap: onTap, child: Ink( decoration: BoxDecoration( gradient: gradient, borderRadius: BorderRadius.circular(radius), ), child: Container( padding: EdgeInsets.symmetric(vertical: padding), alignment: Alignment.center, child: Text( text, style: TextStyle( color: Colors.white, fontSize: fontSize, fontWeight: FontWeight.w600, ), ), ), ), ); } }