Fix: Team management in profile, register page errors, and Hero link …#16
Conversation
There was a problem hiding this comment.
Pull request overview
This PR enhances team management functionality in the profile page, resolves build issues in the register page, and fixes UI inconsistencies in the Hero and Timeline components.
- Added join/leave team capabilities with referral code support for team members
- Fixed missing state variables and removed duplicate imports causing build failures
- Removed duplicate className attribute and updated registration deadline date
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 7 comments.
| File | Description |
|---|---|
| src/components/Timeline.tsx | Updated registration deadline from Dec 31 to Jan 1 |
| src/components/Hero.tsx | Removed duplicate className attribute on the location link |
| src/app/register/page.tsx | Fixed build issues by removing duplicate imports (setDoc, useSearchParams) and adding missing state variables (copied, generatedReferralCode, teamCreated) |
| src/app/profile/page.tsx | Implemented comprehensive team management: restricted problem statement editing to team leads only, added join team functionality with referral codes, and added leave team option for non-lead members |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| alert("Invalid referral code. Please check and try again."); | ||
| setJoining(false); | ||
| return; | ||
| } | ||
|
|
||
| const teamDoc = teamSnapshot.docs[0]; | ||
| const teamData = teamDoc.data(); | ||
|
|
||
| if (teamData.participants && teamData.participants.length >= 5) { | ||
| alert("This team is full (maximum 5 members)."); | ||
| setJoining(false); | ||
| return; | ||
| } | ||
|
|
||
| if (teamData.participants && teamData.participants.includes(user.uid)) { | ||
| alert("You are already in this team!"); | ||
| setJoining(false); | ||
| return; | ||
| } | ||
|
|
||
| await updateDoc(doc(db, "teams", teamDoc.id), { | ||
| participants: arrayUnion(user.uid), | ||
| }); | ||
|
|
||
| await updateDoc(doc(db, "registrations", user.uid), { | ||
| isTeamMember: 1, | ||
| teamName: teamData.teamName, | ||
| }); | ||
|
|
||
| alert("Successfully joined team!"); | ||
| window.location.reload(); | ||
| } catch (error) { | ||
| console.error("Error joining team:", error); | ||
| alert("Failed to join team. Please try again."); |
There was a problem hiding this comment.
Using alert() for user feedback is not ideal for modern web applications. Consider replacing with a more user-friendly toast notification system or inline error/success messages that provide a better user experience and don't block the UI.
| const handleJoinTeam = async () => { | ||
| if (!user?.uid || !joinTeamCode) return; | ||
|
|
||
| setJoining(true); | ||
| try { | ||
| const teamsRef = collection(db, "teams"); | ||
| const teamQuery = query(teamsRef, where("referralCode", "==", joinTeamCode.toUpperCase())); | ||
| const teamSnapshot = await getDocs(teamQuery); | ||
|
|
||
| if (teamSnapshot.empty) { | ||
| alert("Invalid referral code. Please check and try again."); | ||
| setJoining(false); | ||
| return; | ||
| } |
There was a problem hiding this comment.
The handleJoinTeam function doesn't verify the current team membership status before attempting to join. Although the UI conditionally renders the Join Team section based on isTeamMember, the function itself should validate userData.isTeamMember to prevent a user from joining if they're already in a team (in case the function is called directly or due to stale state). Consider adding a check like: if (userData?.isTeamMember === 1) { alert("You are already in a team!"); return; }
| setJoining(true); | ||
| try { | ||
| await updateDoc(doc(db, "teams", teamData.teamName), { | ||
| participants: arrayRemove(user.uid), | ||
| }); | ||
|
|
||
| await updateDoc(doc(db, "registrations", user.uid), { | ||
| isTeamMember: 0, | ||
| teamName: "", | ||
| }); | ||
|
|
||
| alert("Successfully left the team."); | ||
| window.location.reload(); | ||
| } catch (error) { | ||
| console.error("Error leaving team:", error); | ||
| alert("Failed to leave team. Please try again."); | ||
| } finally { | ||
| setJoining(false); |
There was a problem hiding this comment.
The "joining" state variable is being reused for the "Leave Team" operation. This is semantically incorrect and could lead to confusion. Consider renaming this state to something more generic like "isProcessing" or creating a separate state variable for leave operations to improve code clarity.
| alert("Successfully left the team."); | ||
| window.location.reload(); | ||
| } catch (error) { | ||
| console.error("Error leaving team:", error); | ||
| alert("Failed to leave team. Please try again."); |
There was a problem hiding this comment.
Using alert() for user feedback is not ideal for modern web applications. Consider replacing with a more user-friendly toast notification system or inline error/success messages that provide a better user experience and don't block the UI.
| onChange={(e) => setJoinTeamCode(e.target.value)} | ||
| placeholder="Enter 6-digit code" | ||
| className="w-full px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-[#0a0a0a] text-gray-900 dark:text-white focus:ring-2 focus:ring-blue-500 focus:border-transparent" | ||
| /> | ||
| </div> | ||
| <button | ||
| onClick={handleJoinTeam} | ||
| disabled={joining || !joinTeamCode} |
There was a problem hiding this comment.
The referral code input lacks validation for format and length. According to the placeholder text, it expects a 6-digit code, but the input doesn't enforce this constraint. Consider adding input validation (e.g., maxLength={6}, pattern matching) and client-side validation to ensure the code format is correct before making the database query.
| onChange={(e) => setJoinTeamCode(e.target.value)} | |
| placeholder="Enter 6-digit code" | |
| className="w-full px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-[#0a0a0a] text-gray-900 dark:text-white focus:ring-2 focus:ring-blue-500 focus:border-transparent" | |
| /> | |
| </div> | |
| <button | |
| onClick={handleJoinTeam} | |
| disabled={joining || !joinTeamCode} | |
| onChange={(e) => { | |
| const numericValue = e.target.value.replace(/\D/g, "").slice(0, 6); | |
| setJoinTeamCode(numericValue); | |
| }} | |
| placeholder="Enter 6-digit code" | |
| maxLength={6} | |
| inputMode="numeric" | |
| pattern="\d{6}" | |
| className="w-full px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-[#0a0a0a] text-gray-900 dark:text-white focus:ring-2 focus:ring-blue-500 focus:border-transparent" | |
| /> | |
| </div> | |
| <button | |
| onClick={handleJoinTeam} | |
| disabled={joining || joinTeamCode.length !== 6} |
| const handleLeaveTeam = async () => { | ||
| if (!user?.uid || !teamData?.teamName) return; | ||
|
|
||
| if (!confirm("Are you sure you want to leave this team?")) return; | ||
|
|
||
| setJoining(true); | ||
| try { | ||
| await updateDoc(doc(db, "teams", teamData.teamName), { | ||
| participants: arrayRemove(user.uid), | ||
| }); | ||
|
|
||
| await updateDoc(doc(db, "registrations", user.uid), { | ||
| isTeamMember: 0, | ||
| teamName: "", | ||
| }); | ||
|
|
||
| alert("Successfully left the team."); | ||
| window.location.reload(); | ||
| } catch (error) { | ||
| console.error("Error leaving team:", error); | ||
| alert("Failed to leave team. Please try again."); | ||
| } finally { | ||
| setJoining(false); | ||
| } | ||
| }; |
There was a problem hiding this comment.
The handleLeaveTeam function doesn't check if the user is the team lead before allowing them to leave. If a team lead leaves the team, this could result in an orphaned team with no lead, potentially causing issues with team management. Consider either preventing team leads from leaving without transferring leadership, or implementing logic to handle team lead departure (e.g., promoting another member or disbanding the team).
| @@ -1,5 +1,5 @@ | |||
| "use client"; | |||
| import { getDoc, doc, query, collection, where, getDocs, documentId, updateDoc } from "firebase/firestore"; | |||
| import { getDoc, doc, query, collection, where, getDocs, documentId, updateDoc, arrayUnion, arrayRemove } from "firebase/firestore"; | |||
There was a problem hiding this comment.
Unused import documentId.
| import { getDoc, doc, query, collection, where, getDocs, documentId, updateDoc, arrayUnion, arrayRemove } from "firebase/firestore"; | |
| import { getDoc, doc, query, collection, where, getDocs, updateDoc, arrayUnion, arrayRemove } from "firebase/firestore"; |
🧩 Summary
This PR improves team management flow, fixes build issues, and updates UI components for better stability and clarity across the application.
✨ Changes Included
Profile Page (page.tsx)
Restricted Problem Statement editing access to Team Leads only.
Added Join Team functionality using a referral code.
Added Leave Team option for existing team members.
Register Page (page.tsx)
Fixed duplicate imports.
Resolved missing state variables that were causing build failures.
Hero Component (Hero.tsx)
Removed duplicate className attribute to prevent JSX warnings and improve code cleanliness.
Timeline Component (Timeline.tsx)
Updated the registration deadline date to reflect the latest schedule.