feat(teams): hide join/invite options for submitted teams

- Hide "Request to Join" button on browse page for submitted teams
- Hide "Invite Member" and "Join Requests" buttons on team detail for submitted teams
- Change "Submit Project" to "View Submission" for submitted teams
- Rename "Manage Members" to "View Members"
- Hide "Delete Team" for submitted teams

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Maulana Sodiqin
2025-11-29 16:08:05 +07:00
co-authored by Claude
parent 5e65942060
commit a9a1e5450b
3 changed files with 56 additions and 39 deletions
+3 -1
View File
@@ -11,7 +11,9 @@
"Bash(ren:*)", "Bash(ren:*)",
"Bash(npx supabase:*)", "Bash(npx supabase:*)",
"Bash(libs/service/src/types/supabase.ts)", "Bash(libs/service/src/types/supabase.ts)",
"Bash(npx nx build:*)" "Bash(npx nx build:*)",
"Bash(git add:*)",
"Bash(git commit:*)"
], ],
"deny": [], "deny": [],
"ask": [] "ask": []
+47 -33
View File
@@ -369,29 +369,34 @@ const TeamDashboardPage: FC = (): ReactElement => {
Team Management Team Management
</h2> </h2>
<div className="grid gap-3 sm:grid-cols-2"> <div className="grid gap-3 sm:grid-cols-2">
<Button {/* Hide invite/join management after submission */}
className="w-full" {!team.has_submission && (
variant="secondary" <>
onClick={() => setShowInviteModal(true)} <Button
disabled={!canInvite} className="w-full"
> variant="secondary"
<Icon icon="mdi:plus" className="inline-block mr-2" /> onClick={() => setShowInviteModal(true)}
Invite Member{' '} disabled={!canInvite}
{!canInvite && `(${members.length}/${MAX_TEAM_MEMBERS})`} >
</Button> <Icon icon="mdi:plus" className="inline-block mr-2" />
<Button Invite Member{' '}
className="w-full relative" {!canInvite && `(${members.length}/${MAX_TEAM_MEMBERS})`}
variant="secondary" </Button>
onClick={() => setShowJoinRequestsModal(true)} <Button
> className="w-full relative"
<Icon icon="mdi:email" className="inline-block mr-2" /> Join variant="secondary"
Requests onClick={() => setShowJoinRequestsModal(true)}
{pendingJoinRequests.length > 0 && ( >
<span className="absolute -top-2 -right-2 bg-red-500 text-white text-xs font-bold rounded-full w-6 h-6 flex items-center justify-center"> <Icon icon="mdi:email" className="inline-block mr-2" /> Join
{pendingJoinRequests.length} Requests
</span> {pendingJoinRequests.length > 0 && (
)} <span className="absolute -top-2 -right-2 bg-red-500 text-white text-xs font-bold rounded-full w-6 h-6 flex items-center justify-center">
</Button> {pendingJoinRequests.length}
</span>
)}
</Button>
</>
)}
<Link to={`/teams/${teamId}/edit`}> <Link to={`/teams/${teamId}/edit`}>
<Button className="w-full" variant="secondary"> <Button className="w-full" variant="secondary">
<Icon icon="mdi:pencil" className="inline-block mr-2" /> <Icon icon="mdi:pencil" className="inline-block mr-2" />
@@ -404,7 +409,7 @@ const TeamDashboardPage: FC = (): ReactElement => {
icon="mdi:account-group" icon="mdi:account-group"
className="inline-block mr-2" className="inline-block mr-2"
/> />
Manage Members View Members
</Button> </Button>
</Link> </Link>
<Link to={`/teams/${teamId}/chat`}> <Link to={`/teams/${teamId}/chat`}>
@@ -413,20 +418,29 @@ const TeamDashboardPage: FC = (): ReactElement => {
Team Chat Team Chat
</Button> </Button>
</Link> </Link>
<Link to={`/teams/${teamId}/submit`}> {team.has_submission ? (
<Button className="w-full"> <Link to={`/teams/${teamId}/submission`}>
<Icon icon="mdi:rocket" className="inline-block mr-2" /> <Button className="w-full" variant="secondary">
Submit Project <Icon icon="mdi:file-document" className="inline-block mr-2" />
</Button> View Submission
</Link> </Button>
</Link>
) : (
<Link to={`/teams/${teamId}/submit`}>
<Button className="w-full">
<Icon icon="mdi:rocket" className="inline-block mr-2" />
Submit Project
</Button>
</Link>
)}
</div> </div>
{!canInvite && members.length >= MAX_TEAM_MEMBERS && ( {!team.has_submission && !canInvite && members.length >= MAX_TEAM_MEMBERS && (
<p className="text-sm text-gray-600 dark:text-gray-400 mt-3 text-center"> <p className="text-sm text-gray-600 dark:text-gray-400 mt-3 text-center">
Maximum team size reached ({MAX_TEAM_MEMBERS} members) Maximum team size reached ({MAX_TEAM_MEMBERS} members)
</p> </p>
)} )}
{/* Danger Zone - Only show when leader is alone */} {/* Danger Zone - Only show when leader is alone and no submission */}
{members.length === 1 && ( {members.length === 1 && !team.has_submission && (
<div className="mt-6 pt-4 border-t border-gray-200 dark:border-gray-700"> <div className="mt-6 pt-4 border-t border-gray-200 dark:border-gray-700">
<h3 className="text-sm font-medium text-red-600 dark:text-red-400 mb-3"> <h3 className="text-sm font-medium text-red-600 dark:text-red-400 mb-3">
Danger Zone Danger Zone
+6 -5
View File
@@ -199,18 +199,18 @@ const BrowseTeamsPage: FC = (): ReactElement => {
</div> </div>
)} )}
<div className="flex-1 min-w-0"> <div className="flex-1 min-w-0">
<div className="flex items-center gap-2"> <div className="flex items-start gap-2">
<h3 className="text-lg font-bold text-gray-900 dark:text-white line-clamp-2 leading-tight"> <h3 className="text-lg font-bold text-gray-900 dark:text-white line-clamp-1 leading-tight flex-1 min-w-0">
{team.name} {team.name}
</h3> </h3>
{team.has_submission && ( {team.has_submission && (
<span className="inline-flex items-center gap-1 px-2 py-0.5 rounded-full text-xs font-medium bg-green-100 dark:bg-green-900/30 text-green-700 dark:text-green-400 shrink-0"> <span className="inline-flex items-center gap-1 px-2 py-0.5 rounded-full text-xs font-medium bg-green-100 dark:bg-green-900/30 text-green-700 dark:text-green-400 shrink-0 mt-0.5">
<Icon icon="mdi:check-circle" className="text-sm" /> <Icon icon="mdi:check-circle" className="text-sm" />
Submitted Submitted
</span> </span>
)} )}
</div> </div>
<div className="text-sm font-sans text-gray-600 dark:text-gray-400 flex gap-2"> <div className="text-sm font-sans text-gray-600 dark:text-gray-400 flex gap-2 mt-1">
<p className="truncate flex-1 min-w-0 flex items-center gap-x-1"> <p className="truncate flex-1 min-w-0 flex items-center gap-x-1">
<Icon icon="mdi:map-marker" />{' '} <Icon icon="mdi:map-marker" />{' '}
<span>{team.city}</span> <span>{team.city}</span>
@@ -237,7 +237,8 @@ const BrowseTeamsPage: FC = (): ReactElement => {
) : ( ) : (
<> <>
{myTeams.length === 0 && {myTeams.length === 0 &&
(team.member_count || 0) < 5 && ( (team.member_count || 0) < 5 &&
!team.has_submission && (
<Button <Button
className="w-full" className="w-full"
onClick={() => handleJoinRequest(team.id)} onClick={() => handleJoinRequest(team.id)}