diff --git a/luckychit/lib/core/services/chit_group_service.dart b/luckychit/lib/core/services/chit_group_service.dart index e7fe3ed..f273e39 100644 --- a/luckychit/lib/core/services/chit_group_service.dart +++ b/luckychit/lib/core/services/chit_group_service.dart @@ -455,7 +455,7 @@ class ChitGroupService extends GetxController { } // Create monthly draw - Future createMonthlyDraw(String groupId, int month, int year, {String? clientSeed}) async { + Future createMonthlyDraw(String groupId, int month, int year, {String? clientSeed, double? prizeAmount}) async { try { _isLoading.value = true; @@ -464,6 +464,7 @@ class ChitGroupService extends GetxController { 'month': month, 'year': year, if (clientSeed != null) 'client_seed': clientSeed, + if (prizeAmount != null) 'prize_amount': prizeAmount, }; final response = await _apiService.createMonthlyDraw(drawData); @@ -471,15 +472,23 @@ class ChitGroupService extends GetxController { if (response['success']) { // Reload monthly draws await loadGroupMonthlyDraws(groupId); - Get.snackbar('Success', 'Monthly draw completed successfully'); + + // Use post frame callback to avoid setState during build + WidgetsBinding.instance.addPostFrameCallback((_) { + Get.snackbar('Success', 'Monthly draw completed successfully'); + }); return true; } else { - Get.snackbar('Error', response['message']); + WidgetsBinding.instance.addPostFrameCallback((_) { + Get.snackbar('Error', response['message']); + }); return false; } } catch (e) { print('Error creating monthly draw: $e'); - Get.snackbar('Error', 'Failed to create monthly draw'); + WidgetsBinding.instance.addPostFrameCallback((_) { + Get.snackbar('Error', 'Failed to create monthly draw'); + }); return false; } finally { _isLoading.value = false; diff --git a/luckychit/lib/interfaces/manager/draw_animation_page.dart b/luckychit/lib/interfaces/manager/draw_animation_page.dart index 25ad4e6..3726aec 100644 --- a/luckychit/lib/interfaces/manager/draw_animation_page.dart +++ b/luckychit/lib/interfaces/manager/draw_animation_page.dart @@ -67,31 +67,221 @@ class _DrawAnimationPageState extends State }); // Wait a moment to show the winner - await Future.delayed(const Duration(seconds: 3)); + await Future.delayed(const Duration(seconds: 2)); - // Save the draw result + // Find winner details + final winner = widget.eligibleMembers.firstWhere( + (m) => m['id'] == winnerId, + orElse: () => {'name': 'Unknown', 'mobile': ''}, + ); + + // Get the bid amount for this month from financial data + final chitGroupService = Get.find(); + await chitGroupService.loadGroupFinancialData(widget.group.id); + + // Find the financial data for this specific month + final monthNames = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; + final monthKey = '${monthNames[widget.month - 1]}-${widget.year.toString().substring(2)}'; + + final financialEntry = chitGroupService.financialData.firstWhereOrNull( + (entry) => entry.monthYear == monthKey, + ); + + final bidAmount = financialEntry?.bidAmount ?? widget.group.monthlyInstallment; + + // Show confirmation dialog with winner and bid amount + final shouldSave = await _showWinnerConfirmation(winner, bidAmount); + + if (shouldSave == true) { + await _saveDrawResult(winnerId, bidAmount); + } else { + // User cancelled, go back without saving + Get.back(result: false); + } + } + + Future _showWinnerConfirmation(Map winner, double bidAmount) async { + return showDialog( + context: context, + barrierDismissible: false, + builder: (context) => AlertDialog( + backgroundColor: Colors.white, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(16.r), + ), + title: Row( + children: [ + Icon(Icons.emoji_events, color: Colors.amber.shade600, size: 32.w), + SizedBox(width: 12.w), + Expanded( + child: Text( + 'Draw Winner!', + style: TextStyle( + fontSize: 22.sp, + fontWeight: FontWeight.bold, + color: Colors.green.shade700, + ), + ), + ), + ], + ), + content: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Container( + padding: EdgeInsets.all(20.w), + decoration: BoxDecoration( + color: Colors.green.shade50, + borderRadius: BorderRadius.circular(12.r), + border: Border.all(color: Colors.green.shade200, width: 2), + ), + child: Column( + children: [ + Text( + winner['name'] ?? 'Unknown', + style: TextStyle( + fontSize: 24.sp, + fontWeight: FontWeight.bold, + color: Colors.green.shade900, + ), + textAlign: TextAlign.center, + ), + SizedBox(height: 8.h), + Text( + winner['mobile'] ?? '', + style: TextStyle( + fontSize: 16.sp, + color: Colors.grey.shade700, + ), + ), + SizedBox(height: 16.h), + Divider(color: Colors.green.shade200), + SizedBox(height: 16.h), + Text( + 'Prize Amount', + style: TextStyle( + fontSize: 14.sp, + color: Colors.grey.shade600, + ), + ), + SizedBox(height: 8.h), + Text( + _formatIndianCurrency(bidAmount), + style: TextStyle( + fontSize: 32.sp, + fontWeight: FontWeight.bold, + color: Colors.green.shade700, + ), + ), + ], + ), + ), + SizedBox(height: 20.h), + Text( + 'Do you want to save this draw result?', + style: TextStyle( + fontSize: 16.sp, + color: Colors.grey.shade700, + ), + textAlign: TextAlign.center, + ), + ], + ), + actions: [ + OutlinedButton( + onPressed: () => Navigator.pop(context, false), + style: OutlinedButton.styleFrom( + padding: EdgeInsets.symmetric(horizontal: 24.w, vertical: 14.h), + side: BorderSide(color: Colors.grey.shade400), + ), + child: Text( + 'Cancel', + style: TextStyle(fontSize: 16.sp, fontWeight: FontWeight.w600), + ), + ), + ElevatedButton( + onPressed: () => Navigator.pop(context, true), + style: ElevatedButton.styleFrom( + backgroundColor: Colors.green.shade600, + foregroundColor: Colors.white, + padding: EdgeInsets.symmetric(horizontal: 24.w, vertical: 14.h), + ), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Icon(Icons.save, size: 20.w), + SizedBox(width: 8.w), + Text( + 'Save Result', + style: TextStyle(fontSize: 16.sp, fontWeight: FontWeight.w600), + ), + ], + ), + ), + ], + ), + ); + } + + Future _saveDrawResult(String winnerId, double bidAmount) async { final chitGroupService = Get.find(); try { + // Show loading + Get.dialog( + WillPopScope( + onWillPop: () async => false, + child: Center( + child: Container( + padding: EdgeInsets.all(32.w), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(16.r), + ), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + CircularProgressIndicator(), + SizedBox(height: 16.h), + Text( + 'Saving draw result...', + style: TextStyle(fontSize: 16.sp), + ), + ], + ), + ), + ), + ), + barrierDismissible: false, + ); + await chitGroupService.createMonthlyDraw( widget.group.id, widget.month, widget.year, clientSeed: 'DRAW_${DateTime.now().millisecondsSinceEpoch}', + prizeAmount: bidAmount, ); + // Close loading dialog + Get.back(); + // Navigate back with success Get.back(result: true); Get.snackbar( - 'Draw Complete! 🎉', - 'Winner has been selected successfully', + 'Draw Saved! 🎉', + 'Winner has been recorded successfully', backgroundColor: Colors.green, colorText: Colors.white, duration: const Duration(seconds: 3), snackPosition: SnackPosition.TOP, ); } catch (e) { + // Close loading dialog + Get.back(); + + // Close draw page Get.back(result: false); Get.snackbar( @@ -103,6 +293,39 @@ class _DrawAnimationPageState extends State ); } } + + String _formatIndianCurrency(double amount) { + int intAmount = amount.round(); + String amountStr = intAmount.toString(); + String formatted = ''; + + if (amountStr.length <= 3) { + formatted = amountStr; + } else { + int remaining = amountStr.length; + int start = 0; + + if (remaining > 3) { + formatted = amountStr.substring(amountStr.length - 3); + remaining -= 3; + start = amountStr.length - 3; + } else { + formatted = amountStr; + remaining = 0; + } + + while (remaining > 0) { + int groupSize = remaining >= 2 ? 2 : remaining; + int groupStart = start - groupSize; + String group = amountStr.substring(groupStart, start); + formatted = group + ',' + formatted; + start = groupStart; + remaining -= groupSize; + } + } + + return '₹$formatted'; + } @override Widget build(BuildContext context) {