import 'package:flutter/material.dart'; import '../services/dio_client.dart'; import '../services/invoice_service.dart'; class InvoiceDetailScreen extends StatefulWidget { final int invoiceId; const InvoiceDetailScreen({super.key, required this.invoiceId}); @override State createState() => _InvoiceDetailScreenState(); } class _InvoiceDetailScreenState extends State { bool loading = true; Map invoice = {}; @override void initState() { super.initState(); load(); } Future load() async { final service = InvoiceService(DioClient.getInstance(context)); final res = await service.getInvoiceDetails(widget.invoiceId); if (res['success'] == true) { invoice = res['invoice'] ?? {}; } loading = false; setState(() {}); } /// ---------- REUSABLE ROW ---------- Widget row(String label, dynamic value) { return Padding( padding: const EdgeInsets.symmetric(vertical: 6), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text(label, style: const TextStyle(fontSize: 14, color: Colors.grey)), Expanded( child: Text( value?.toString().isNotEmpty == true ? value.toString() : "N/A", textAlign: TextAlign.end, style: const TextStyle( fontSize: 15, fontWeight: FontWeight.w600, ), ), ), ], ), ); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text("Invoice Details")), body: loading ? const Center(child: CircularProgressIndicator()) /// ================ INVOICE DATA ================ : Padding( padding: const EdgeInsets.all(16), child: ListView( children: [ /// -------- Invoice Summary -------- const Text( "Invoice Summary", style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), ), const SizedBox(height: 10), row("Invoice No", invoice['invoice_number']), row("Invoice Date", invoice['invoice_date']), row("Due Date", invoice['due_date']), row("Status", invoice['status']), const Divider(height: 30), /// -------- Customer Details -------- const Text( "Customer Details", style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), ), const SizedBox(height: 10), row("Name", invoice['customer_name']), row("Company", invoice['company_name']), row("Email", invoice['customer_email']), row("Mobile", invoice['customer_mobile']), row("Address", invoice['customer_address']), row("Pincode", invoice['pincode']), const Divider(height: 30), /// -------- Amounts & Taxes -------- const Text( "Amounts", style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), ), const SizedBox(height: 10), row("Final Amount", invoice['final_amount']), row("Tax Type", invoice['tax_type']), row("GST %", invoice['gst_percent']), row("GST Amount", invoice['gst_amount']), row("Final with GST", invoice['final_amount_with_gst']), const Divider(height: 30), /// -------- Payment Details -------- const Text( "Payment Details", style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), ), const SizedBox(height: 10), row("Payment Method", invoice['payment_method']), row("Reference No", invoice['reference_no']), row("Notes", invoice['notes']), const Divider(height: 30), /// -------- PDF -------- if (invoice['pdf_path'] != null) ElevatedButton.icon( icon: const Icon(Icons.picture_as_pdf), label: const Text("Download PDF"), onPressed: () {}, style: ElevatedButton.styleFrom(backgroundColor: Colors.red), ), const SizedBox(height: 20), /// -------- Invoice Items -------- if (invoice['items'] != null) const Text( "Invoice Items", style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), ), const SizedBox(height: 10), ...List.generate(invoice['items']?.length ?? 0, (i) { final item = invoice['items'][i]; return Card( child: ListTile( title: Text(item['description'] ?? "Item"), subtitle: Text("Qty: ${item['qty'] ?? 0}"), trailing: Text( "₹${item['ttl_amount'] ?? 0}", style: const TextStyle( fontWeight: FontWeight.bold, color: Colors.indigo), ), ), ); }), ], ), ), ); } }