import 'package:flutter/material.dart'; import '../services/dio_client.dart'; import '../services/invoice_service.dart'; class InvoiceInstallmentScreen extends StatefulWidget { final int invoiceId; const InvoiceInstallmentScreen({ super.key, required this.invoiceId, }); @override State createState() => _InvoiceInstallmentScreenState(); } class _InvoiceInstallmentScreenState extends State { bool loading = true; List installments = []; @override void initState() { super.initState(); load(); } Future load() async { final service = InvoiceService(DioClient.getInstance(context)); final res = await service.getInstallments(widget.invoiceId); if (res['success'] == true) { installments = res['installments'] ?? []; } loading = false; setState(() {}); } @override Widget build(BuildContext context) { final width = MediaQuery.of(context).size.width; return Scaffold( backgroundColor: Colors.grey.shade100, appBar: AppBar( title: const Text("Installments"), elevation: 1, ), body: loading ? const Center(child: CircularProgressIndicator()) : installments.isEmpty ? _buildEmptyState() : ListView.builder( padding: EdgeInsets.symmetric( horizontal: width * 0.04, vertical: 16, ), itemCount: installments.length, itemBuilder: (_, i) { return InstallmentCard(inst: installments[i]); }, ), ); } Widget _buildEmptyState() { return Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon(Icons.receipt_long, size: 70, color: Colors.grey.shade400), const SizedBox(height: 12), Text( "No Installments Created", style: TextStyle( fontSize: 18, color: Colors.grey.shade600, ), ), ], ), ); } } class InstallmentCard extends StatelessWidget { final Map inst; const InstallmentCard({super.key, required this.inst}); String getString(key) => inst[key]?.toString() ?? "N/A"; @override Widget build(BuildContext context) { final width = MediaQuery.of(context).size.width; final isTablet = width > 600; final padding = isTablet ? 28.0 : 20.0; final amountSize = isTablet ? 30.0 : 26.0; return LayoutBuilder( builder: (context, constraints) { return Container( margin: const EdgeInsets.only(bottom: 18), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(18), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.05), blurRadius: 12, offset: const Offset(0, 4), ), ], ), child: Padding( padding: EdgeInsets.all(padding), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // Amount + Payment Method Row Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( "₹${getString('amount')}", style: TextStyle( fontSize: amountSize, fontWeight: FontWeight.bold, letterSpacing: 0.2, ), ), // Payment Chip Container( padding: EdgeInsets.symmetric( vertical: isTablet ? 8 : 6, horizontal: isTablet ? 16 : 12, ), decoration: BoxDecoration( color: Colors.blue.shade50, borderRadius: BorderRadius.circular(50), ), child: Text( getString('payment_method'), style: TextStyle( fontWeight: FontWeight.w600, color: Colors.blue.shade700, fontSize: isTablet ? 15 : 13.5, ), ), ), ], ), SizedBox(height: isTablet ? 24 : 18), // Responsive Info Rows buildInfoRow( Icons.calendar_month, "Date", getString("installment_date"), isTablet ), SizedBox(height: isTablet ? 14 : 10), buildInfoRow( Icons.confirmation_number, "Reference", getString("reference_no"), isTablet ), SizedBox(height: isTablet ? 24 : 18), Divider(color: Colors.grey.shade300, thickness: 1), SizedBox(height: isTablet ? 10 : 6), Align( alignment: Alignment.centerRight, child: Text( "Installment #${inst['id'] ?? ''}", style: TextStyle( fontSize: isTablet ? 15 : 13, color: Colors.grey.shade600, fontWeight: FontWeight.w500, ), ), ), ], ), ), ); }, ); } /// Responsive info row builder Widget buildInfoRow(IconData icon, String label, String value, bool isTablet) { return Row( children: [ Icon(icon, size: isTablet ? 24 : 20, color: Colors.grey.shade600), const SizedBox(width: 10), Text( "$label:", style: TextStyle( fontSize: isTablet ? 17 : 15, fontWeight: FontWeight.w600, color: Colors.grey.shade700, ), ), const SizedBox(width: 6), Expanded( child: Text( value, style: TextStyle( fontSize: isTablet ? 16 : 15, color: Colors.grey.shade800, fontWeight: FontWeight.w500, ), ), ), ], ); } }