chitfund/luckychit/lib/interfaces/manager/create_group_dialog.dart

860 lines
38 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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/utils/chit_calculator.dart';
import '../../core/utils/snackbar_util.dart';
import '../../shared/widgets/monthly_schedule_table.dart';
class CreateGroupDialog extends StatefulWidget {
const CreateGroupDialog({super.key});
@override
State<CreateGroupDialog> createState() => _CreateGroupDialogState();
}
class _CreateGroupDialogState extends State<CreateGroupDialog> {
final _formKey = GlobalKey<FormState>();
final _nameController = TextEditingController();
final _totalValueController = TextEditingController();
final _monthlyInstallmentController = TextEditingController();
final _durationMonthsController = TextEditingController();
final _maxMembersController = TextEditingController();
final _foremanCommissionController = TextEditingController();
final _foremanCommissionTypeController = TextEditingController();
final _maxDividendController = TextEditingController();
final _drawDateController = TextEditingController();
bool _isLoading = false;
String? _selectedDrawDate;
@override
void initState() {
super.initState();
_drawDateController.text = '15'; // Default draw date
_foremanCommissionController.text = '250'; // Default commission
_foremanCommissionTypeController.text = 'fixed'; // Default commission type
_maxDividendController.text = '500'; // Default max dividend
}
@override
void dispose() {
_nameController.dispose();
_totalValueController.dispose();
_monthlyInstallmentController.dispose();
_durationMonthsController.dispose();
_maxMembersController.dispose();
_foremanCommissionController.dispose();
_foremanCommissionTypeController.dispose();
_maxDividendController.dispose();
_drawDateController.dispose();
super.dispose();
}
void _calculateMonthlyInstallment() {
final totalValue = double.tryParse(_totalValueController.text);
final durationMonths = int.tryParse(_durationMonthsController.text);
final commissionType = _foremanCommissionTypeController.text;
if (totalValue != null && durationMonths != null) {
double commission;
if (commissionType == 'percentage') {
final rate = double.tryParse(_foremanCommissionController.text) ?? 5.0;
commission = (totalValue / durationMonths) * (rate / 100);
} else {
commission = double.tryParse(_foremanCommissionController.text) ?? 250.0;
}
// Generic formula: Monthly Installment = (Total Value ÷ Duration Months) + Commission
final subscriptionPerMonth = totalValue / durationMonths;
final monthlyInstallment = subscriptionPerMonth + commission;
_monthlyInstallmentController.text = monthlyInstallment.toStringAsFixed(0);
}
setState(() {}); // Rebuild to update schedule
}
void _calculateTotalValue() {
final monthlyInstallment = double.tryParse(_monthlyInstallmentController.text);
final durationMonths = int.tryParse(_durationMonthsController.text);
final commissionType = _foremanCommissionTypeController.text;
if (monthlyInstallment != null && durationMonths != null) {
double totalValue;
if (commissionType == 'percentage') {
// For percentage commission: total_value = monthly_installment * duration_months / (1 + rate/100)
final rate = double.tryParse(_foremanCommissionController.text) ?? 5.0;
totalValue = (monthlyInstallment * durationMonths) / (1 + rate/100);
} else {
// For fixed commission: total_value = (monthly_installment - commission) × duration_months
final commission = double.tryParse(_foremanCommissionController.text) ?? 250.0;
totalValue = (monthlyInstallment - commission) * durationMonths;
}
_totalValueController.text = totalValue.toStringAsFixed(0);
}
setState(() {}); // Rebuild to update schedule
}
// Calculate advantage structure using the generic formula
Map<String, dynamic> _calculateAdvantageStructure() {
final totalValue = double.tryParse(_totalValueController.text) ?? 0;
final durationMonths = int.tryParse(_durationMonthsController.text) ?? 0;
final commissionType = _foremanCommissionTypeController.text;
final commission = double.tryParse(_foremanCommissionController.text) ?? 250;
final maxDividend = double.tryParse(_maxDividendController.text) ?? (commission * 2);
if (totalValue <= 0 || durationMonths <= 0) {
return {};
}
// Use the generic calculator
final advantageStructure = ChitCalculator.calculateAdvantageStructure(
chitValue: totalValue,
months: durationMonths,
commissionPerMonth: commission,
maxDividend: maxDividend,
);
return {
'first_month': {
'payment': advantageStructure['first_month_winner']['installment_paid'],
'receipt': advantageStructure['first_month_winner']['bid_amount'],
'net_gain': advantageStructure['first_month_winner']['net_gain'],
'dividend_per_member': advantageStructure['first_month_winner']['dividend_others_get'],
},
'last_month': {
'payment': advantageStructure['last_month_winner']['total_paid'],
'receipt': advantageStructure['last_month_winner']['total_received'],
'net_gain': advantageStructure['last_month_winner']['net_gain_total'],
'dividend_per_member': advantageStructure['last_month_winner']['dividend_others_pay'] * -1,
},
'monthly_commission': advantageStructure['commission_per_month'],
'winner_payout': advantageStructure['first_month_winner']['bid_amount'],
'dividend_per_member_early': advantageStructure['first_month_winner']['dividend_others_get'],
'subscription_per_month': advantageStructure['subscription_per_month'],
'installment_per_month': advantageStructure['installment_per_month'],
};
}
Future<void> _createGroup() async {
if (!_formKey.currentState!.validate()) return;
setState(() => _isLoading = true);
try {
final groupData = {
'name': _nameController.text.trim(),
'total_value': double.parse(_totalValueController.text),
'monthly_installment': double.parse(_monthlyInstallmentController.text),
'duration_months': int.parse(_durationMonthsController.text),
'max_members': int.parse(_maxMembersController.text),
'foreman_commission_amount': double.parse(_foremanCommissionController.text),
'foreman_commission_type': _foremanCommissionTypeController.text,
if (_foremanCommissionTypeController.text == 'percentage')
'foreman_commission_rate': double.parse(_foremanCommissionController.text),
'draw_date': int.parse(_drawDateController.text),
};
final success = await ChitGroupService.to.createChitGroup(groupData);
if (success) {
Navigator.of(context).pop(); // Close dialog
SnackbarUtil.showSuccess(
'Chit group created successfully!',
title: 'Success',
);
}
} catch (e) {
SnackbarUtil.showError(
'Failed to create chit group. Please try again.',
title: 'Error',
);
} finally {
setState(() => _isLoading = false);
}
}
@override
Widget build(BuildContext context) {
return Dialog(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16.r)),
child: Container(
width: MediaQuery.of(context).size.width > 600 ? 600.w : double.infinity,
constraints: BoxConstraints(
maxHeight: 0.85.sh,
maxWidth: MediaQuery.of(context).size.width * 0.95,
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
// Header
Container(
padding: EdgeInsets.all(20.w),
decoration: BoxDecoration(
color: Colors.green.shade600,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(16.r),
topRight: Radius.circular(16.r),
),
),
child: Row(
children: [
Icon(
Icons.group_add,
color: Colors.white,
size: 24.w,
),
SizedBox(width: 12.w),
Text(
'Create New Chitfund',
style: TextStyle(
color: Colors.white,
fontSize: 18.sp,
fontWeight: FontWeight.w600,
),
),
const Spacer(),
IconButton(
onPressed: () => Navigator.of(context).pop(),
icon: const Icon(Icons.close, color: Colors.white),
padding: EdgeInsets.zero,
constraints: const BoxConstraints(),
),
],
),
),
// Form Content
Flexible(
child: SingleChildScrollView(
padding: EdgeInsets.all(20.w),
child: Form(
key: _formKey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Basic Information Section
_buildSectionTitle('Basic Information'),
SizedBox(height: 16.h),
TextFormField(
controller: _nameController,
decoration: InputDecoration(
labelText: 'Chitfund Name',
hintText: 'Enter chitfund name',
prefixIcon: const Icon(Icons.group),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8.r),
),
),
validator: (value) {
if (value == null || value.trim().isEmpty) {
return 'Chitfund name is required';
}
if (value.trim().length < 3) {
return 'Chitfund name must be at least 3 characters';
}
return null;
},
),
SizedBox(height: 16.h),
// Financial Details Section
_buildSectionTitle('Chitfund Details'),
SizedBox(height: 16.h),
Row(
children: [
Expanded(
child: TextFormField(
controller: _totalValueController,
decoration: InputDecoration(
labelText: 'Total Value (₹)',
hintText: 'e.g., 100000',
prefixIcon: const Icon(Icons.currency_rupee),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8.r),
),
),
keyboardType: TextInputType.number,
onChanged: (_) => _calculateMonthlyInstallment(),
validator: (value) {
if (value == null || value.isEmpty) {
return 'Total value is required';
}
final amount = double.tryParse(value);
if (amount == null || amount <= 0) {
return 'Please enter a valid amount';
}
if (amount < 1000) {
return 'Minimum amount is ₹1,000';
}
return null;
},
),
),
SizedBox(width: 16.w),
Expanded(
child: TextFormField(
controller: _monthlyInstallmentController,
decoration: InputDecoration(
labelText: 'Monthly Installment (₹)',
hintText: 'e.g., 5000',
prefixIcon: const Icon(Icons.payment),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8.r),
),
),
keyboardType: TextInputType.number,
onChanged: (_) => _calculateTotalValue(),
validator: (value) {
if (value == null || value.isEmpty) {
return 'Monthly installment is required';
}
final amount = double.tryParse(value);
if (amount == null || amount <= 0) {
return 'Please enter a valid amount';
}
if (amount < 100) {
return 'Minimum installment is ₹100';
}
return null;
},
),
),
],
),
SizedBox(height: 16.h),
Row(
children: [
Expanded(
child: TextFormField(
controller: _durationMonthsController,
decoration: InputDecoration(
labelText: 'Duration (Months)',
hintText: 'e.g., 20',
prefixIcon: const Icon(Icons.calendar_today),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8.r),
),
),
keyboardType: TextInputType.number,
onChanged: (_) => _calculateMonthlyInstallment(),
validator: (value) {
if (value == null || value.isEmpty) {
return 'Duration is required';
}
final months = int.tryParse(value);
if (months == null || months < 6) {
return 'Minimum duration is 6 months';
}
if (months > 60) {
return 'Maximum duration is 60 months';
}
return null;
},
),
),
SizedBox(width: 16.w),
Expanded(
child: TextFormField(
controller: _maxMembersController,
decoration: InputDecoration(
labelText: 'Maximum Members',
hintText: 'e.g., 20',
prefixIcon: const Icon(Icons.people),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8.r),
),
),
keyboardType: TextInputType.number,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Maximum members is required';
}
final members = int.tryParse(value);
if (members == null || members < 2) {
return 'Minimum 2 members required';
}
if (members > 100) {
return 'Maximum 100 members allowed';
}
return null;
},
),
),
],
),
SizedBox(height: 16.h),
Row(
children: [
Expanded(
child: TextFormField(
controller: _foremanCommissionController,
decoration: InputDecoration(
labelText: _foremanCommissionTypeController.text == 'percentage'
? 'Foreman Commission Rate (%)'
: 'Foreman Commission (₹)',
hintText: _foremanCommissionTypeController.text == 'percentage'
? 'e.g., 5'
: 'e.g., 250',
prefixIcon: Icon(
_foremanCommissionTypeController.text == 'percentage'
? Icons.percent
: Icons.currency_rupee,
),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8.r),
),
),
keyboardType: TextInputType.number,
onChanged: (_) => _calculateMonthlyInstallment(),
validator: (value) {
if (value == null || value.isEmpty) {
return _foremanCommissionTypeController.text == 'percentage'
? 'Commission rate is required'
: 'Commission is required';
}
final commission = double.tryParse(value);
if (commission == null || commission < 0) {
return 'Please enter a valid value';
}
if (_foremanCommissionTypeController.text == 'percentage' && commission > 100) {
return 'Commission rate cannot exceed 100%';
}
return null;
},
),
),
SizedBox(width: 16.w),
Expanded(
child: DropdownButtonFormField<String>(
value: _foremanCommissionTypeController.text,
decoration: InputDecoration(
labelText: 'Commission Type',
prefixIcon: const Icon(Icons.settings),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8.r),
),
),
items: const [
DropdownMenuItem(value: 'fixed', child: Text('Fixed Amount')),
DropdownMenuItem(value: 'percentage', child: Text('Percentage')),
],
onChanged: (value) {
if (value != null) {
_foremanCommissionTypeController.text = value;
// Update the commission field value based on type
if (value == 'percentage') {
_foremanCommissionController.text = '5'; // Default 5%
} else {
_foremanCommissionController.text = '250'; // Default ₹250
}
_calculateMonthlyInstallment();
setState(() {}); // Trigger rebuild to update UI
}
},
),
),
],
),
SizedBox(height: 16.h),
Row(
children: [
Expanded(
child: TextFormField(
controller: _maxDividendController,
decoration: InputDecoration(
labelText: 'Max Dividend (₹)',
hintText: 'e.g., 500',
prefixIcon: const Icon(Icons.trending_up),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8.r),
),
),
keyboardType: TextInputType.number,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Max dividend is required';
}
final maxDividend = double.tryParse(value);
if (maxDividend == null || maxDividend < 0) {
return 'Please enter a valid amount';
}
return null;
},
),
),
SizedBox(width: 16.w),
Expanded(child: Container()), // Empty space for alignment
],
),
SizedBox(height: 16.h),
Row(
children: [
Expanded(
child: TextFormField(
controller: _drawDateController,
decoration: InputDecoration(
labelText: 'Draw Date (Day of Month)',
hintText: 'e.g., 15',
prefixIcon: const Icon(Icons.casino),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8.r),
),
),
keyboardType: TextInputType.number,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Draw date is required';
}
final day = int.tryParse(value);
if (day == null || day < 1 || day > 31) {
return 'Please enter a valid day (1-31)';
}
return null;
},
),
),
SizedBox(width: 16.w),
Expanded(child: Container()), // Empty space for alignment
],
),
SizedBox(height: 24.h),
// Summary Section
_buildSectionTitle('Summary'),
SizedBox(height: 16.h),
Container(
padding: EdgeInsets.all(16.w),
decoration: BoxDecoration(
color: Colors.grey.shade50,
borderRadius: BorderRadius.circular(8.r),
border: Border.all(color: Colors.grey.shade300),
),
child: Column(
children: [
_buildSummaryRow('Chitfund Name', _nameController.text.isEmpty ? 'Not set' : _nameController.text),
_buildSummaryRow('Total Value', _totalValueController.text.isEmpty ? 'Not set' : '${_totalValueController.text}'),
_buildSummaryRow('Monthly Installment', _monthlyInstallmentController.text.isEmpty ? 'Not set' : '${_monthlyInstallmentController.text}'),
_buildSummaryRow('Duration', _durationMonthsController.text.isEmpty ? 'Not set' : '${_durationMonthsController.text} months'),
_buildSummaryRow('Max Members', _maxMembersController.text.isEmpty ? 'Not set' : _maxMembersController.text),
_buildSummaryRow('Commission', _foremanCommissionController.text.isEmpty ? 'Not set' : '${_foremanCommissionController.text}'),
_buildSummaryRow('Max Dividend', _maxDividendController.text.isEmpty ? 'Not set' : '${_maxDividendController.text}'),
_buildSummaryRow('Draw Date', _drawDateController.text.isEmpty ? 'Not set' : '${_drawDateController.text}th of each month'),
],
),
),
SizedBox(height: 24.h),
// Advantage Structure Section
_buildSectionTitle('Advantage Structure'),
SizedBox(height: 16.h),
_buildAdvantageStructureCard(),
SizedBox(height: 24.h),
// Monthly Schedule Section
_buildSectionTitle('Month-wise Payment Schedule'),
SizedBox(height: 16.h),
ExpandableMonthlySchedule(
totalValue: double.tryParse(_totalValueController.text) ?? 0,
durationMonths: int.tryParse(_durationMonthsController.text) ?? 0,
monthlyInstallment: double.tryParse(_monthlyInstallmentController.text) ?? 0,
commission: double.tryParse(_foremanCommissionController.text) ?? 0,
maxDividend: double.tryParse(_maxDividendController.text) ?? 0,
),
SizedBox(height: 24.h),
// Action Buttons
Row(
children: [
Expanded(
child: OutlinedButton(
onPressed: () => Navigator.of(context).pop(),
style: OutlinedButton.styleFrom(
padding: EdgeInsets.symmetric(vertical: 16.h),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8.r),
),
),
child: Text(
'Cancel',
style: TextStyle(fontSize: 16.sp),
),
),
),
SizedBox(width: 16.w),
Expanded(
child: ElevatedButton(
onPressed: _isLoading ? null : _createGroup,
style: ElevatedButton.styleFrom(
backgroundColor: Colors.green.shade600,
foregroundColor: Colors.white,
padding: EdgeInsets.symmetric(vertical: 16.h),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8.r),
),
),
child: _isLoading
? SizedBox(
height: 20.h,
width: 20.w,
child: const CircularProgressIndicator(
strokeWidth: 2,
valueColor: AlwaysStoppedAnimation<Color>(Colors.white),
),
)
: Text(
'Create Chitfund',
style: TextStyle(fontSize: 16.sp),
),
),
),
],
),
],
),
),
),
),
],
),
),
);
}
Widget _buildSectionTitle(String title) {
return Text(
title,
style: TextStyle(
fontSize: 16.sp,
fontWeight: FontWeight.w600,
color: Colors.grey.shade800,
),
);
}
Widget _buildSummaryRow(String label, String value) {
return Padding(
padding: EdgeInsets.symmetric(vertical: 4.h),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
label,
style: TextStyle(
fontSize: 14.sp,
color: Colors.grey.shade600,
),
),
Text(
value,
style: TextStyle(
fontSize: 14.sp,
fontWeight: FontWeight.w500,
color: Colors.grey.shade800,
),
),
],
),
);
}
Widget _buildAdvantageStructureCard() {
final advantageData = _calculateAdvantageStructure();
if (advantageData.isEmpty) {
return Container(
padding: EdgeInsets.all(16.w),
decoration: BoxDecoration(
color: Colors.orange.shade50,
borderRadius: BorderRadius.circular(8.r),
border: Border.all(color: Colors.orange.shade200),
),
child: Row(
children: [
Icon(Icons.info_outline, color: Colors.orange.shade600, size: 20.w),
SizedBox(width: 8.w),
Expanded(
child: Text(
'Fill in the group details above to see the advantage structure',
style: TextStyle(
fontSize: 14.sp,
color: Colors.orange.shade700,
),
),
),
],
),
);
}
return Container(
padding: EdgeInsets.all(16.w),
decoration: BoxDecoration(
color: Colors.blue.shade50,
borderRadius: BorderRadius.circular(8.r),
border: Border.all(color: Colors.blue.shade200),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Icon(Icons.trending_up, color: Colors.blue.shade600, size: 20.w),
SizedBox(width: 8.w),
Text(
'Chit Fund Advantage Structure',
style: TextStyle(
fontSize: 16.sp,
fontWeight: FontWeight.w600,
color: Colors.blue.shade800,
),
),
],
),
SizedBox(height: 16.h),
// First Month Winner
Container(
padding: EdgeInsets.all(12.w),
decoration: BoxDecoration(
color: Colors.green.shade50,
borderRadius: BorderRadius.circular(8.r),
border: Border.all(color: Colors.green.shade200),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Icon(Icons.rocket_launch, color: Colors.green.shade600, size: 16.w),
SizedBox(width: 8.w),
Text(
'First Month Winner (Early Advantage)',
style: TextStyle(
fontSize: 14.sp,
fontWeight: FontWeight.w600,
color: Colors.green.shade700,
),
),
],
),
SizedBox(height: 8.h),
_buildAdvantageRow('Monthly Payment', '${advantageData['first_month']['payment'].toStringAsFixed(0)}'),
_buildAdvantageRow('Bid Amount', '${advantageData['first_month']['receipt'].toStringAsFixed(0)}'),
_buildAdvantageRow('Net Gain', '${advantageData['first_month']['net_gain'].toStringAsFixed(0)}', isHighlight: true),
_buildAdvantageRow('Others Get Dividend', '${advantageData['first_month']['dividend_per_member'].toStringAsFixed(0)}', isHighlight: false),
],
),
),
SizedBox(height: 12.h),
// Last Month Winner
Container(
padding: EdgeInsets.all(12.w),
decoration: BoxDecoration(
color: Colors.purple.shade50,
borderRadius: BorderRadius.circular(8.r),
border: Border.all(color: Colors.purple.shade200),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Icon(Icons.schedule, color: Colors.purple.shade600, size: 16.w),
SizedBox(width: 8.w),
Text(
'Last Month Winner (Late Advantage)',
style: TextStyle(
fontSize: 14.sp,
fontWeight: FontWeight.w600,
color: Colors.purple.shade700,
),
),
],
),
SizedBox(height: 8.h),
_buildAdvantageRow('Total Paid', '${advantageData['last_month']['payment'].toStringAsFixed(0)}'),
_buildAdvantageRow('Total Received', '${advantageData['last_month']['receipt'].toStringAsFixed(0)}'),
_buildAdvantageRow('Net Gain', '${advantageData['last_month']['net_gain'].toStringAsFixed(0)}', isHighlight: true),
_buildAdvantageRow('Others Pay Extra', '${(advantageData['last_month']['dividend_per_member'] * -1).toStringAsFixed(0)}', isHighlight: false),
],
),
),
SizedBox(height: 12.h),
// Commission Info
Container(
padding: EdgeInsets.all(12.w),
decoration: BoxDecoration(
color: Colors.orange.shade50,
borderRadius: BorderRadius.circular(8.r),
border: Border.all(color: Colors.orange.shade200),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Icon(Icons.percent, color: Colors.orange.shade600, size: 16.w),
SizedBox(width: 8.w),
Text(
'Fixed Monthly Commission: ₹${advantageData['monthly_commission'].toStringAsFixed(0)}',
style: TextStyle(
fontSize: 14.sp,
fontWeight: FontWeight.w600,
color: Colors.orange.shade700,
),
),
],
),
SizedBox(height: 8.h),
_buildAdvantageRow('Subscription/Month', '${advantageData['subscription_per_month'].toStringAsFixed(0)}'),
_buildAdvantageRow('Installment/Month', '${advantageData['installment_per_month'].toStringAsFixed(0)}'),
_buildAdvantageRow('Winner Payout', '${advantageData['winner_payout'].toStringAsFixed(0)}'),
_buildAdvantageRow('Early Month Dividend', '${advantageData['dividend_per_member_early'].toStringAsFixed(0)} per member'),
],
),
),
],
),
);
}
Widget _buildAdvantageRow(String label, String value, {bool isHighlight = false}) {
return Padding(
padding: EdgeInsets.symmetric(vertical: 2.h),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
label,
style: TextStyle(
fontSize: 13.sp,
color: Colors.grey.shade600,
),
),
Text(
value,
style: TextStyle(
fontSize: 13.sp,
fontWeight: isHighlight ? FontWeight.w600 : FontWeight.w500,
color: isHighlight ? Colors.green.shade700 : Colors.grey.shade800,
),
),
],
),
);
}
}