From f0eb11010d67cc95722d579b296273cb3c2d245c Mon Sep 17 00:00:00 2001 From: Maulana Sodiqin Date: Fri, 28 Nov 2025 18:23:54 +0700 Subject: [PATCH] feat(hackathon): add leave team feature for team members MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add Leave Team button in Quick Actions section for non-leader members - Add confirmation modal before leaving with warning message - Use existing useLeaveTeam hook from service library 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .../hackathon/src/app/teams/[teamId]/page.tsx | 76 ++++++++++++++++++- 1 file changed, 73 insertions(+), 3 deletions(-) diff --git a/apps/hackathon/src/app/teams/[teamId]/page.tsx b/apps/hackathon/src/app/teams/[teamId]/page.tsx index a8d6ba8..4ba40ee 100644 --- a/apps/hackathon/src/app/teams/[teamId]/page.tsx +++ b/apps/hackathon/src/app/teams/[teamId]/page.tsx @@ -7,6 +7,7 @@ import { useInviteMember, useTeamJoinRequests, useRespondToJoinRequest, + useLeaveTeam, ETeamMemberRole, useAuthStore, } from '@imphnen-frontend-service/service'; @@ -52,6 +53,7 @@ const TeamDashboardPage: FC = (): ReactElement => { const { session } = useAuthStore(); const [showInviteModal, setShowInviteModal] = useState(false); const [showJoinRequestsModal, setShowJoinRequestsModal] = useState(false); + const [showLeaveModal, setShowLeaveModal] = useState(false); const [inviteEmail, setInviteEmail] = useState(''); const [imagesLoaded, setImagesLoaded] = useState(false); const [imageLoadCount, setImageLoadCount] = useState(0); @@ -94,6 +96,7 @@ const TeamDashboardPage: FC = (): ReactElement => { ); const { mutateAsync: respondToJoinRequest, isPending: isResponding } = useRespondToJoinRequest(teamId || ''); + const { mutateAsync: leaveTeam, isPending: isLeaving } = useLeaveTeam(); const team = teamData?.data; const members = membersData?.data || []; @@ -139,6 +142,19 @@ const TeamDashboardPage: FC = (): ReactElement => { } }; + const handleLeaveTeam = async () => { + if (!teamId) return; + + try { + await leaveTeam(teamId); + toast.success('You have left the team'); + navigate('/dashboard'); + } catch (error) { + console.error('Failed to leave team:', error); + toast.error('Failed to leave team'); + } + }; + if (isLoadingTeam || isLoadingMembers) { return (
@@ -395,23 +411,33 @@ const TeamDashboardPage: FC = (): ReactElement => { {/* Quick Actions for Members (non-leaders) */} {!isLeader && isMember && ( -
+

Quick Actions

{team.has_submission && ( )} +
)} @@ -696,6 +722,50 @@ const TeamDashboardPage: FC = (): ReactElement => {
)} + + {/* Leave Team Confirmation Modal */} + {showLeaveModal && ( +
+
+
+
+ +
+

+ Leave Team? +

+

+ Are you sure you want to leave {team?.name}? +

+
+
+

+ Warning: If you leave, you will need to request to join again or be re-invited by the team leader. +

+
+
+ + +
+
+
+ )} ); };