fixed draw issues

This commit is contained in:
Deep Koluguri 2025-11-06 12:40:19 -05:00
parent d01cc13edc
commit 1b1ead0c11
2 changed files with 76 additions and 15 deletions

View File

@ -146,6 +146,16 @@ const createMonthlyDraw = async (req, res) => {
message: 'Selected winner is not a member of this group' message: 'Selected winner is not a member of this group'
}); });
} }
// Check if this member has already won
if (wonMemberIds.includes(winner_id)) {
return res.status(400).json({
success: false,
message: `${selectedWinner.User.full_name} has already won in a previous draw. Each member can only win once.`,
alreadyWon: true,
winnerName: selectedWinner.User.full_name
});
}
} else { } else {
// Regular draw - provably fair random selection // Regular draw - provably fair random selection
serverSeed = crypto.randomBytes(32).toString('hex'); serverSeed = crypto.randomBytes(32).toString('hex');

View File

@ -83,12 +83,24 @@ class _AddPastDrawDialogState extends State<AddPastDrawDialog> {
title: 'Success', title: 'Success',
); );
Get.back(result: true); Get.back(result: true);
} else {
// Check if it's a duplicate winner error
final isAlreadyWon = response['alreadyWon'] ?? false;
final winnerName = response['winnerName'] ?? '';
if (isAlreadyWon && winnerName.isNotEmpty) {
SnackbarUtil.showError(
'$winnerName has already won in a previous draw.\nEach member can only win once.',
title: 'Duplicate Winner',
duration: const Duration(seconds: 4),
);
} else { } else {
SnackbarUtil.showError( SnackbarUtil.showError(
response['message'] ?? 'Failed to add draw', response['message'] ?? 'Failed to add draw',
title: 'Error', title: 'Error',
); );
} }
}
} catch (e) { } catch (e) {
SnackbarUtil.showError('Error: ${e.toString()}'); SnackbarUtil.showError('Error: ${e.toString()}');
} finally { } finally {
@ -223,6 +235,10 @@ class _AddPastDrawDialogState extends State<AddPastDrawDialog> {
); );
} }
// Get list of members who have already won
final monthlyDraws = Get.find<ChitGroupService>().monthlyDraws;
final winnerIds = monthlyDraws.map((draw) => draw.winnerId).where((id) => id != null).toSet();
return Container( return Container(
constraints: BoxConstraints( constraints: BoxConstraints(
maxHeight: 300.h, // Limit height for scrolling maxHeight: 300.h, // Limit height for scrolling
@ -237,10 +253,11 @@ class _AddPastDrawDialogState extends State<AddPastDrawDialog> {
itemBuilder: (context, index) { itemBuilder: (context, index) {
final member = members[index]; final member = members[index];
final isSelected = member.userId == _selectedMemberId; final isSelected = member.userId == _selectedMemberId;
final hasAlreadyWon = winnerIds.contains(member.userId);
final isLast = index == members.length - 1; final isLast = index == members.length - 1;
return InkWell( return InkWell(
onTap: () { onTap: hasAlreadyWon ? null : () {
setState(() { setState(() {
_selectedMemberId = member.userId; _selectedMemberId = member.userId;
}); });
@ -255,7 +272,9 @@ class _AddPastDrawDialogState extends State<AddPastDrawDialog> {
vertical: 14.h, vertical: 14.h,
), ),
decoration: BoxDecoration( decoration: BoxDecoration(
color: isSelected ? Colors.green.shade50 : null, color: hasAlreadyWon
? Colors.grey.shade100
: (isSelected ? Colors.green.shade50 : null),
border: !isLast ? Border( border: !isLast ? Border(
bottom: BorderSide(color: Colors.grey.shade200), bottom: BorderSide(color: Colors.grey.shade200),
) : null, ) : null,
@ -263,8 +282,12 @@ class _AddPastDrawDialogState extends State<AddPastDrawDialog> {
child: Row( child: Row(
children: [ children: [
Icon( Icon(
isSelected ? Icons.radio_button_checked : Icons.radio_button_unchecked, hasAlreadyWon
color: isSelected ? Colors.green.shade600 : Colors.grey.shade400, ? Icons.block
: (isSelected ? Icons.radio_button_checked : Icons.radio_button_unchecked),
color: hasAlreadyWon
? Colors.grey.shade400
: (isSelected ? Colors.green.shade600 : Colors.grey.shade400),
size: 24.w, size: 24.w,
), ),
SizedBox(width: 12.w), SizedBox(width: 12.w),
@ -272,20 +295,48 @@ class _AddPastDrawDialogState extends State<AddPastDrawDialog> {
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Text( Row(
children: [
Expanded(
child: Text(
member.user?.fullName ?? 'Unknown', member.user?.fullName ?? 'Unknown',
style: TextStyle( style: TextStyle(
fontSize: 16.sp, fontSize: 16.sp,
fontWeight: isSelected ? FontWeight.w600 : FontWeight.normal, fontWeight: isSelected ? FontWeight.w600 : FontWeight.normal,
color: hasAlreadyWon ? Colors.grey.shade500 : null,
decoration: hasAlreadyWon ? TextDecoration.lineThrough : null,
), ),
), ),
),
if (hasAlreadyWon) ...[
Container(
padding: EdgeInsets.symmetric(
horizontal: 6.w,
vertical: 2.h,
),
decoration: BoxDecoration(
color: Colors.orange.shade100,
borderRadius: BorderRadius.circular(4.r),
),
child: Text(
'Already Won',
style: TextStyle(
fontSize: 10.sp,
color: Colors.orange.shade800,
fontWeight: FontWeight.w600,
),
),
),
],
],
),
if (member.user?.mobileNumber != null) ...[ if (member.user?.mobileNumber != null) ...[
SizedBox(height: 2.h), SizedBox(height: 2.h),
Text( Text(
member.user!.mobileNumber, member.user!.mobileNumber,
style: TextStyle( style: TextStyle(
fontSize: 13.sp, fontSize: 13.sp,
color: Colors.grey.shade600, color: hasAlreadyWon ? Colors.grey.shade400 : Colors.grey.shade600,
), ),
), ),
], ],