Skip to content

Commit db7cfd4

Browse files
committed
Merge branch 'main' of github.com:boundlessfi/boundless
2 parents 29071f5 + 45b9670 commit db7cfd4

1 file changed

Lines changed: 74 additions & 5 deletions

File tree

components/hackathons/submissions/SubmissionForm.tsx

Lines changed: 74 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -468,7 +468,33 @@ const SubmissionFormContent: React.FC<SubmissionFormContentProps> = ({
468468
form.setValue('links', updatedLinks, { shouldValidate: true });
469469
};
470470

471+
// Team size configuration and computed state (only when hackathon defines limits)
472+
const teamMin = currentHackathon?.teamMin;
473+
const teamMax = currentHackathon?.teamMax;
474+
const hasTeamLimits = teamMin !== undefined && teamMax !== undefined;
475+
const watchedTeamMembers = form.watch('teamMembers');
476+
const currentTeamSize = (watchedTeamMembers?.length ?? 0) + 1;
477+
const isTeamAtCapacity = hasTeamLimits && currentTeamSize >= teamMax;
478+
const isTeamBelowMinimum = hasTeamLimits && currentTeamSize < teamMin;
479+
const membersNeededForMinimum = hasTeamLimits ? teamMin - currentTeamSize : 0;
480+
481+
function getTeamSizeBadgeStyle(): string {
482+
if (isTeamAtCapacity) {
483+
return 'border-yellow-500 bg-yellow-500/10 text-yellow-500';
484+
}
485+
if (isTeamBelowMinimum) {
486+
return 'border-orange-500 bg-orange-500/10 text-orange-500';
487+
}
488+
return 'border-gray-600 text-gray-400';
489+
}
490+
471491
const handleAddInvitee = () => {
492+
// Guard: prevent adding members when team is at capacity
493+
if (isTeamAtCapacity) {
494+
toast.error(`Team is at maximum capacity (${teamMax} members)`);
495+
return;
496+
}
497+
472498
if (!currentInviteeName || !currentInviteeRole || !currentInviteeEmail) {
473499
toast.error('Please fill in name, email and role');
474500
return;
@@ -517,6 +543,14 @@ const SubmissionFormContent: React.FC<SubmissionFormContentProps> = ({
517543
form.setError('teamName', { message: 'Team Name is required' });
518544
return;
519545
}
546+
547+
if (isTeamBelowMinimum) {
548+
toast.error(
549+
`Your team needs at least ${teamMin} members. Please invite ${membersNeededForMinimum} more member${membersNeededForMinimum > 1 ? 's' : ''} to continue.`
550+
);
551+
return;
552+
}
553+
520554
isValid = true;
521555
}
522556
} else {
@@ -931,9 +965,35 @@ const SubmissionFormContent: React.FC<SubmissionFormContentProps> = ({
931965
/>
932966

933967
<div className='space-y-3'>
934-
<FormLabel className='text-white'>
935-
Invite Members (Optional)
936-
</FormLabel>
968+
<div className='flex items-center justify-between'>
969+
<FormLabel className='text-white'>
970+
Invite Members
971+
{hasTeamLimits && teamMin > 1 && (
972+
<span className='ml-1 text-xs text-gray-400'>
973+
(min {teamMin} members)
974+
</span>
975+
)}
976+
</FormLabel>
977+
{hasTeamLimits && (
978+
<Badge
979+
variant='outline'
980+
className={cn(
981+
'transition-colors',
982+
getTeamSizeBadgeStyle()
983+
)}
984+
>
985+
<Users className='mr-1 h-3 w-3' />
986+
{currentTeamSize} / {teamMax} members
987+
</Badge>
988+
)}
989+
</div>
990+
{isTeamBelowMinimum && (
991+
<p className='text-xs text-orange-400'>
992+
You need at least {membersNeededForMinimum} more
993+
member{membersNeededForMinimum > 1 ? 's' : ''} to
994+
proceed.
995+
</p>
996+
)}
937997
<div className='flex flex-col gap-3'>
938998
<div className='grid grid-cols-1 gap-3 md:grid-cols-3'>
939999
<Input
@@ -943,6 +1003,7 @@ const SubmissionFormContent: React.FC<SubmissionFormContentProps> = ({
9431003
setCurrentInviteeName(e.target.value)
9441004
}
9451005
className='border-gray-700 bg-gray-800/50 text-white'
1006+
disabled={isTeamAtCapacity}
9461007
/>
9471008
<Input
9481009
placeholder='Email'
@@ -952,6 +1013,7 @@ const SubmissionFormContent: React.FC<SubmissionFormContentProps> = ({
9521013
setCurrentInviteeEmail(e.target.value)
9531014
}
9541015
className='border-gray-700 bg-gray-800/50 text-white'
1016+
disabled={isTeamAtCapacity}
9551017
/>
9561018
<Input
9571019
placeholder='Role (e.g. Designer)'
@@ -960,15 +1022,22 @@ const SubmissionFormContent: React.FC<SubmissionFormContentProps> = ({
9601022
setCurrentInviteeRole(e.target.value)
9611023
}
9621024
className='border-gray-700 bg-gray-800/50 text-white'
1025+
disabled={isTeamAtCapacity}
9631026
/>
9641027
</div>
9651028
<Button
9661029
type='button'
9671030
onClick={handleAddInvitee}
968-
className='self-start bg-gray-800 text-white hover:bg-gray-700'
1031+
disabled={isTeamAtCapacity}
1032+
className={cn(
1033+
'self-start',
1034+
isTeamAtCapacity
1035+
? 'cursor-not-allowed bg-gray-700 text-gray-500 opacity-50'
1036+
: 'bg-gray-800 text-white hover:bg-gray-700'
1037+
)}
9691038
>
9701039
<Plus className='mr-2 h-4 w-4' />
971-
Add Member
1040+
{isTeamAtCapacity ? 'Team Full' : 'Add Member'}
9721041
</Button>
9731042
</div>
9741043

0 commit comments

Comments
 (0)