import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import '../../core/services/chit_group_service.dart'; import '../../core/models/chit_group.dart'; import '../../core/utils/snackbar_util.dart'; class EditGroupDialog extends StatefulWidget { final ChitGroup group; const EditGroupDialog({ super.key, required this.group, }); @override State createState() => _EditGroupDialogState(); } class _EditGroupDialogState extends State { final _formKey = GlobalKey(); final _nameController = TextEditingController(); final _totalValueController = TextEditingController(); final _monthlyInstallmentController = TextEditingController(); final _durationController = TextEditingController(); final _maxMembersController = TextEditingController(); final _commissionController = TextEditingController(); final _drawDateController = TextEditingController(); final _service = ChitGroupService.to; bool _isLoading = false; @override void initState() { super.initState(); _nameController.text = widget.group.name; _totalValueController.text = widget.group.totalValue.toStringAsFixed(0); _monthlyInstallmentController.text = widget.group.monthlyInstallment.toStringAsFixed(0); _durationController.text = widget.group.durationMonths.toString(); _maxMembersController.text = widget.group.maxMembers.toString(); _commissionController.text = widget.group.foremanCommissionAmount.toStringAsFixed(0); _drawDateController.text = widget.group.drawDate.toString(); } @override void dispose() { _nameController.dispose(); _totalValueController.dispose(); _monthlyInstallmentController.dispose(); _durationController.dispose(); _maxMembersController.dispose(); _commissionController.dispose(); _drawDateController.dispose(); super.dispose(); } Future _handleSubmit() async { if (_formKey.currentState!.validate()) { setState(() => _isLoading = true); try { final updates = {}; // Only include changed fields if (_nameController.text != widget.group.name) { updates['name'] = _nameController.text; } final newTotalValue = double.parse(_totalValueController.text); if (newTotalValue != widget.group.totalValue) { updates['total_value'] = newTotalValue; } final newInstallment = double.parse(_monthlyInstallmentController.text); if (newInstallment != widget.group.monthlyInstallment) { updates['monthly_installment'] = newInstallment; } final newDuration = int.parse(_durationController.text); if (newDuration != widget.group.durationMonths) { updates['duration_months'] = newDuration; } final newMaxMembers = int.parse(_maxMembersController.text); if (newMaxMembers != widget.group.maxMembers) { updates['max_members'] = newMaxMembers; } final newCommission = double.parse(_commissionController.text); if (newCommission != widget.group.foremanCommissionAmount) { updates['foreman_commission_amount'] = newCommission; } final newDrawDate = int.parse(_drawDateController.text); if (newDrawDate != widget.group.drawDate) { updates['draw_date'] = newDrawDate; } if (updates.isEmpty) { SnackbarUtil.showWarning('No changes made'); Get.back(); return; } final response = await _service.updateChitGroup(widget.group.id, updates); if (response) { SnackbarUtil.showSuccess( 'Group details updated successfully', title: 'Success', ); Get.back(result: true); } } catch (e) { SnackbarUtil.showError('Error: ${e.toString()}'); } finally { setState(() => _isLoading = false); } } } @override Widget build(BuildContext context) { return Dialog( shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20.r)), child: Container( width: 500.w, constraints: BoxConstraints( maxHeight: MediaQuery.of(context).size.height * 0.85, ), child: Column( mainAxisSize: MainAxisSize.min, children: [ // Fixed Header Container( padding: EdgeInsets.all(24.w), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.only( topLeft: Radius.circular(20.r), topRight: Radius.circular(20.r), ), border: Border( bottom: BorderSide(color: Colors.grey.shade200), ), ), child: Row( children: [ Icon(Icons.edit, color: Colors.green.shade600, size: 28.w), SizedBox(width: 12.w), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Edit Group Details', style: TextStyle( fontSize: 20.sp, fontWeight: FontWeight.bold, ), ), Text( 'Only works for forming groups', style: TextStyle( fontSize: 12.sp, color: Colors.grey.shade600, ), ), ], ), ), IconButton( icon: const Icon(Icons.close), onPressed: () => Get.back(), ), ], ), ), // Scrollable Content Flexible( child: SingleChildScrollView( padding: EdgeInsets.all(24.w), child: Form( key: _formKey, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // Group Name Text( 'Group Name *', style: TextStyle( fontSize: 16.sp, fontWeight: FontWeight.w600, ), ), SizedBox(height: 8.h), TextFormField( controller: _nameController, decoration: InputDecoration( hintText: 'Group name', prefixIcon: const Icon(Icons.group), border: OutlineInputBorder( borderRadius: BorderRadius.circular(12.r), ), filled: true, fillColor: Colors.grey.shade50, ), validator: (value) { if (value?.isEmpty ?? true) return 'Name is required'; if (value!.length < 3) return 'Name too short'; return null; }, ), SizedBox(height: 20.h), // Financial Details Row 1 Row( children: [ Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Total Value *', style: TextStyle( fontSize: 16.sp, fontWeight: FontWeight.w600, ), ), SizedBox(height: 8.h), TextFormField( controller: _totalValueController, keyboardType: TextInputType.number, decoration: InputDecoration( hintText: 'Total value', prefixText: '₹ ', border: OutlineInputBorder( borderRadius: BorderRadius.circular(12.r), ), filled: true, fillColor: Colors.grey.shade50, ), validator: (value) { if (value?.isEmpty ?? true) return 'Required'; if (double.tryParse(value!) == null) return 'Invalid'; return null; }, ), ], ), ), SizedBox(width: 16.w), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Monthly Installment *', style: TextStyle( fontSize: 16.sp, fontWeight: FontWeight.w600, ), ), SizedBox(height: 8.h), TextFormField( controller: _monthlyInstallmentController, keyboardType: TextInputType.number, decoration: InputDecoration( hintText: 'Installment', prefixText: '₹ ', border: OutlineInputBorder( borderRadius: BorderRadius.circular(12.r), ), filled: true, fillColor: Colors.grey.shade50, ), validator: (value) { if (value?.isEmpty ?? true) return 'Required'; if (double.tryParse(value!) == null) return 'Invalid'; return null; }, ), ], ), ), ], ), SizedBox(height: 20.h), // Financial Details Row 2 Row( children: [ Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Duration (Months) *', style: TextStyle( fontSize: 16.sp, fontWeight: FontWeight.w600, ), ), SizedBox(height: 8.h), TextFormField( controller: _durationController, keyboardType: TextInputType.number, decoration: InputDecoration( hintText: 'Months', border: OutlineInputBorder( borderRadius: BorderRadius.circular(12.r), ), filled: true, fillColor: Colors.grey.shade50, ), validator: (value) { if (value?.isEmpty ?? true) return 'Required'; final num = int.tryParse(value!); if (num == null || num < 1) return 'Invalid'; return null; }, ), ], ), ), SizedBox(width: 16.w), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Max Members *', style: TextStyle( fontSize: 16.sp, fontWeight: FontWeight.w600, ), ), SizedBox(height: 8.h), TextFormField( controller: _maxMembersController, keyboardType: TextInputType.number, decoration: InputDecoration( hintText: 'Members', border: OutlineInputBorder( borderRadius: BorderRadius.circular(12.r), ), filled: true, fillColor: Colors.grey.shade50, ), validator: (value) { if (value?.isEmpty ?? true) return 'Required'; final num = int.tryParse(value!); if (num == null || num < 1) return 'Invalid'; return null; }, ), ], ), ), ], ), SizedBox(height: 20.h), // Commission and Draw Date Row Row( children: [ Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Commission Amount *', style: TextStyle( fontSize: 16.sp, fontWeight: FontWeight.w600, ), ), SizedBox(height: 8.h), TextFormField( controller: _commissionController, keyboardType: TextInputType.number, decoration: InputDecoration( hintText: 'Commission', prefixText: '₹ ', border: OutlineInputBorder( borderRadius: BorderRadius.circular(12.r), ), filled: true, fillColor: Colors.grey.shade50, ), validator: (value) { if (value?.isEmpty ?? true) return 'Required'; if (double.tryParse(value!) == null) return 'Invalid'; return null; }, ), ], ), ), SizedBox(width: 16.w), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Draw Date *', style: TextStyle( fontSize: 16.sp, fontWeight: FontWeight.w600, ), ), SizedBox(height: 8.h), TextFormField( controller: _drawDateController, keyboardType: TextInputType.number, decoration: InputDecoration( hintText: 'Day (1-31)', border: OutlineInputBorder( borderRadius: BorderRadius.circular(12.r), ), filled: true, fillColor: Colors.grey.shade50, ), validator: (value) { if (value?.isEmpty ?? true) return 'Required'; final num = int.tryParse(value!); if (num == null || num < 1 || num > 31) { return '1-31 only'; } return null; }, ), ], ), ), ], ), SizedBox(height: 20.h), // Info Note Container( padding: EdgeInsets.all(12.w), decoration: BoxDecoration( color: Colors.blue.shade50, borderRadius: BorderRadius.circular(12.r), border: Border.all(color: Colors.blue.shade200), ), child: Row( children: [ Icon(Icons.info_outline, color: Colors.blue.shade700, size: 20.w), SizedBox(width: 8.w), Expanded( child: Text( 'Group can only be edited while in "Forming" status. Once started, it cannot be changed.', style: TextStyle( fontSize: 12.sp, color: Colors.blue.shade900, ), ), ), ], ), ), ], ), ), ), ), // Fixed Footer with Actions Container( padding: EdgeInsets.all(24.w), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.only( bottomLeft: Radius.circular(20.r), bottomRight: Radius.circular(20.r), ), border: Border( top: BorderSide(color: Colors.grey.shade200), ), ), child: Row( children: [ Expanded( child: OutlinedButton( onPressed: _isLoading ? null : () => Get.back(), style: OutlinedButton.styleFrom( padding: EdgeInsets.symmetric(vertical: 14.h), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12.r), ), ), child: Text( 'Cancel', style: TextStyle(fontSize: 16.sp), ), ), ), SizedBox(width: 16.w), Expanded( child: ElevatedButton( onPressed: _isLoading ? null : _handleSubmit, style: ElevatedButton.styleFrom( backgroundColor: Colors.green.shade600, foregroundColor: Colors.white, padding: EdgeInsets.symmetric(vertical: 14.h), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12.r), ), elevation: 2, ), child: _isLoading ? SizedBox( height: 20.h, width: 20.w, child: const CircularProgressIndicator( strokeWidth: 2, valueColor: AlwaysStoppedAnimation(Colors.white), ), ) : Text( 'Update Group', style: TextStyle(fontSize: 16.sp, fontWeight: FontWeight.w600), ), ), ), ], ), ), ], ), ), ); } }