diff --git a/components/hackathons/submissions/SubmissionForm.tsx b/components/hackathons/submissions/SubmissionForm.tsx index fdbcdcd0e..abb2e0e4f 100644 --- a/components/hackathons/submissions/SubmissionForm.tsx +++ b/components/hackathons/submissions/SubmissionForm.tsx @@ -468,7 +468,33 @@ const SubmissionFormContent: React.FC = ({ form.setValue('links', updatedLinks, { shouldValidate: true }); }; + // Team size configuration and computed state (only when hackathon defines limits) + const teamMin = currentHackathon?.teamMin; + const teamMax = currentHackathon?.teamMax; + const hasTeamLimits = teamMin !== undefined && teamMax !== undefined; + const watchedTeamMembers = form.watch('teamMembers'); + const currentTeamSize = (watchedTeamMembers?.length ?? 0) + 1; + const isTeamAtCapacity = hasTeamLimits && currentTeamSize >= teamMax; + const isTeamBelowMinimum = hasTeamLimits && currentTeamSize < teamMin; + const membersNeededForMinimum = hasTeamLimits ? teamMin - currentTeamSize : 0; + + function getTeamSizeBadgeStyle(): string { + if (isTeamAtCapacity) { + return 'border-yellow-500 bg-yellow-500/10 text-yellow-500'; + } + if (isTeamBelowMinimum) { + return 'border-orange-500 bg-orange-500/10 text-orange-500'; + } + return 'border-gray-600 text-gray-400'; + } + const handleAddInvitee = () => { + // Guard: prevent adding members when team is at capacity + if (isTeamAtCapacity) { + toast.error(`Team is at maximum capacity (${teamMax} members)`); + return; + } + if (!currentInviteeName || !currentInviteeRole || !currentInviteeEmail) { toast.error('Please fill in name, email and role'); return; @@ -517,6 +543,14 @@ const SubmissionFormContent: React.FC = ({ form.setError('teamName', { message: 'Team Name is required' }); return; } + + if (isTeamBelowMinimum) { + toast.error( + `Your team needs at least ${teamMin} members. Please invite ${membersNeededForMinimum} more member${membersNeededForMinimum > 1 ? 's' : ''} to continue.` + ); + return; + } + isValid = true; } } else { @@ -931,9 +965,35 @@ const SubmissionFormContent: React.FC = ({ />
- - Invite Members (Optional) - +
+ + Invite Members + {hasTeamLimits && teamMin > 1 && ( + + (min {teamMin} members) + + )} + + {hasTeamLimits && ( + + + {currentTeamSize} / {teamMax} members + + )} +
+ {isTeamBelowMinimum && ( +

+ You need at least {membersNeededForMinimum} more + member{membersNeededForMinimum > 1 ? 's' : ''} to + proceed. +

+ )}
= ({ setCurrentInviteeName(e.target.value) } className='border-gray-700 bg-gray-800/50 text-white' + disabled={isTeamAtCapacity} /> = ({ setCurrentInviteeEmail(e.target.value) } className='border-gray-700 bg-gray-800/50 text-white' + disabled={isTeamAtCapacity} /> = ({ setCurrentInviteeRole(e.target.value) } className='border-gray-700 bg-gray-800/50 text-white' + disabled={isTeamAtCapacity} />