Skip to content

Comments

feat: Simplify team registration with referral codes#10

Merged
ManasMalla merged 7 commits intomainfrom
feature/referral-code-team-registration
Dec 29, 2025
Merged

feat: Simplify team registration with referral codes#10
ManasMalla merged 7 commits intomainfrom
feature/referral-code-team-registration

Conversation

@CherukuriPavanKumar
Copy link
Collaborator

@CherukuriPavanKumar CherukuriPavanKumar commented Dec 29, 2025

🎯 Summary

This PR completely overhauls the team registration system to use simple referral codes instead of the complex autocomplete search flow.

✨ What's New

1. New /create-team Page

  • Team leads can create teams with unique names
  • Automatically generates 6-character referral codes (e.g., ABC123)
  • Share functionality with copy-to-clipboard
  • Full dark mode support

2. Enhanced /register Page

  • Added "Team Registration" section with radio buttons
  • Team leads: Select "Yes, I'll create a team" → redirects to team creation
  • Team members: Select "No, I'll join a team" → optionally enter referral code
  • Referral code validation with auto-join functionality
  • Team size limits enforced (max 4 members)

3. Simplified Flow

  • Removed: Tshirt size, LinkedIn profile, and other extra fields
  • Removed: Confirmation page requirement
  • New: Direct registration → dashboard flow
  • All paths end at /dashboard with immediate access to QR code

🔄 User Flows

Team Lead:

  1. Register → Select "Yes, I'll create a team"
  2. Enter team name → Get referral code
  3. Share code with team members
  4. Redirected to dashboard

Team Member (with code):

  1. Register → Select "No, I'll join a team"
  2. Enter referral code → Auto-join team
  3. Redirected to dashboard

Team Member (no code):

  1. Register → Select "No" → Skip code
  2. Redirected to dashboard (can join later)

📝 Changes Made

  • ✅ Created src/app/create-team/page.tsx
  • ✅ Updated src/app/register/page.tsx with team selection UI
  • ✅ Updated src/utils/getUserProgress.ts to remove profile checks
  • ✅ Modified redirect logic to bypass confirmation page

🎨 Features

  • Referral code generation (6 chars, uppercase alphanumeric)
  • Code validation and error handling
  • Team size limit enforcement (4 members max)
  • Duplicate team name prevention
  • Copy-to-clipboard functionality
  • Mobile share API integration
  • Full dark mode support throughout

🧪 Testing Checklist

  • Test team lead registration flow
  • Test member registration with valid code
  • Test member registration without code
  • Verify team size limits
  • Check duplicate team name handling
  • Verify invalid code error handling
  • Test dark mode on all new pages
  • Verify mobile responsiveness

📦 Related

This simplifies the registration process based on user feedback that the previous autocomplete flow was "too complex and too many steps".

- Created /create-team page for team leads with 6-char referral code generation
- Added team registration section to /register with lead/member selection
- Implemented referral code validation and auto-join functionality
- Removed tshirt size and LinkedIn profile requirements
- All registration paths now redirect to /dashboard
- Team size limits enforced (max 4 members)
- Bypassed confirmation page for streamlined flow
Copilot AI review requested due to automatic review settings December 29, 2025 15:36
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR simplifies the team registration flow by introducing a referral code system, replacing the previous complex autocomplete search mechanism. Team leads can now create teams and receive unique codes, while team members can join using these codes during registration.

Key Changes:

  • New team creation page with referral code generation and sharing functionality
  • Enhanced registration page with team lead/member selection and referral code input
  • Removed profile completion requirements (t-shirt size, LinkedIn) to streamline the flow

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 12 comments.

File Description
src/app/create-team/page.tsx New page for team leads to create teams and generate referral codes with dark mode support
src/app/register/page.tsx Added team registration section with radio buttons for lead/member selection and referral code validation
src/utils/getUserProgress.ts Removed profile completion checks (t-shirt size, LinkedIn) to simplify registration requirements
src/app/confirmation/page.tsx Fixed React key prop warning in autocomplete rendering and updated navigation method

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

}, [user, router]);

const generateReferralCode = () => {
return Math.random().toString(36).substring(2, 8).toUpperCase();
Copy link

Copilot AI Dec 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The referral code generation using Math.random().toString(36).substring(2, 8) may not always produce 6 characters. When converting to base-36, the result can be shorter than 6 characters after removing the "0." prefix, leading to codes shorter than expected. Consider generating a code with a guaranteed length of 6 characters.

Suggested change
return Math.random().toString(36).substring(2, 8).toUpperCase();
let code = "";
// Ensure we always generate at least 6 characters before slicing
while (code.length < 6) {
code += Math.random().toString(36).substring(2);
}
return code.substring(0, 6).toUpperCase();

Copilot uses AI. Check for mistakes.
Comment on lines 49 to 51
// Generate referral code
const code = generateReferralCode();
setReferralCode(code);
Copy link

Copilot AI Dec 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's no check to ensure referral code uniqueness when creating a team. Multiple teams could theoretically end up with the same referral code since Math.random() can produce collisions. Consider adding validation to check if the generated code already exists in the database, or use a more robust unique identifier generation approach.

Copilot uses AI. Check for mistakes.
Comment on lines 53 to 54
// Get team number
const teamNumber = (await getCountFromServer(query(teamsRef))).data().count + 1;
Copy link

Copilot AI Dec 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Race condition: The team number calculation using getCountFromServer followed by count + 1 is not atomic. If two teams are created simultaneously, they could end up with the same team number. Consider using Firestore's serverTimestamp or a counter transaction to ensure uniqueness.

Copilot uses AI. Check for mistakes.

useEffect(() => {
if (!user) {
alert("Please login to create a team");
Copy link

Copilot AI Dec 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The alert message says "Please login to create a team" but the user is not logged in yet. The terminology is inconsistent with typical authentication flows. Consider changing to "You must be logged in to create a team" or "Please sign in to create a team".

Suggested change
alert("Please login to create a team");
alert("You must be logged in to create a team");

Copilot uses AI. Check for mistakes.
Comment on lines +131 to +147
if (teamData.participants && teamData.participants.length >= 4) {
alert("This team is full (maximum 4 members). Please use a different referral code.");
setLoadingState(false);
return;
}

// Check if user is already in this team
if (teamData.participants && teamData.participants.includes(user.uid)) {
alert("You are already in this team!");
setLoadingState(false);
return;
}

// Add user to team
await updateDoc(doc(db, "teams", teamDoc.id), {
participants: arrayUnion(user.uid),
});
Copy link

Copilot AI Dec 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Race condition: There's a time-of-check to time-of-use (TOCTOU) issue between checking team size at line 131 and adding the user at line 145. Multiple users could join simultaneously and exceed the 4-member limit. Consider using a Firestore transaction to atomically check and update the participants array.

Copilot uses AI. Check for mistakes.
Comment on lines 174 to 181
if (isTeamLead) {
window.location.href = "/create-team";
} else if (teamInfo) {
// Successfully joined team, go to dashboard
window.location.href = "/dashboard";
} else {
// No team yet, but registration complete - go to dashboard
window.location.href = "/dashboard";
Copy link

Copilot AI Dec 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using window.location.href for navigation instead of Next.js router.push() causes a full page reload, which is less efficient and loses client-side state. Consider using router.push() consistently for better performance and user experience.

Copilot uses AI. Check for mistakes.
Comment on lines 66 to 71
// Update user's registration
await updateDoc(doc(db, "registrations", user.uid), {
isTeamLead: 1,
isTeamMember: 1,
teamName: teamName,
});
Copy link

Copilot AI Dec 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing error handling for updateDoc. If the user document doesn't exist in the registrations collection, this will fail silently or throw an error. Consider adding try-catch around this specific operation or verifying the document exists before updating.

Copilot uses AI. Check for mistakes.
Comment on lines 145 to 171
await updateDoc(doc(db, "teams", teamDoc.id), {
participants: arrayUnion(user.uid),
});

teamInfo = {
teamName: teamData.teamName,
isTeamMember: 1,
};
} catch (error) {
console.error("Error validating referral code:", error);
alert("Failed to join team. Please try again.");
setLoadingState(false);
return;
}
}

// Save registration data
await addData("registrations", user.uid, {
...formState,
["displayPicture"]: user?.photoURL ?? "",
["isTeamMember"]: -1,
["isTeamLead"]: 0,
["isTeamMember"]: teamInfo ? 1 : 0,
["isTeamLead"]: isTeamLead ? 1 : 0,
["coc"]: 1,
["terms"]: 1,
["payment_status"]: "captured", // Skip payment for now
["payment_status"]: "captured",
["teamName"]: teamInfo?.teamName || "",
});
Copy link

Copilot AI Dec 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The user is added to the team's participants array but if the subsequent addData call at line 162 fails, the user will be in the team but won't have a registration document, leading to data inconsistency. Consider wrapping both operations in a transaction or implementing rollback logic.

Copilot uses AI. Check for mistakes.
Comment on lines 436 to 462
<div className="flex items-center space-x-4 mb-4">
<label className="flex items-center space-x-2 cursor-pointer">
<input
type="radio"
name="isLead"
checked={isTeamLead === true}
onChange={() => {
setIsTeamLead(true);
setReferralCode("");
}}
required
className="w-4 h-4"
/>
<span className="text-gray-900 dark:text-gray-300">Yes, I'll create a team</span>
</label>
<label className="flex items-center space-x-2 cursor-pointer">
<input
type="radio"
name="isLead"
checked={isTeamLead === false}
onChange={() => setIsTeamLead(false)}
required
className="w-4 h-4"
/>
<span className="text-gray-900 dark:text-gray-300">No, I'll join a team</span>
</label>
</div>
Copy link

Copilot AI Dec 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The isTeamLead radio button group has the required attribute, but there's no validation preventing form submission if neither option is selected. The HTML5 required attribute on radio buttons requires at least one in the group to be checked, but the initial state is undefined which could allow submission. Consider adding explicit validation in handleSubmit.

Copilot uses AI. Check for mistakes.
["terms"]: 1,
["payment_status"]: "captured", // Skip payment for now
["payment_status"]: "captured",
["teamName"]: teamInfo?.teamName || "",
Copy link

Copilot AI Dec 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The teamInfo.teamName could be undefined since teamInfo is typed as null or an object with optional teamName. When isTeamMember is 0 (no team), passing an empty string is correct, but when teamInfo exists, accessing teamInfo.teamName without null-checking could cause issues if teamName is missing from the Firestore document. Consider adding proper null-checking: teamInfo?.teamName ?? "".

Suggested change
["teamName"]: teamInfo?.teamName || "",
["teamName"]: teamInfo?.teamName ?? "",

Copilot uses AI. Check for mistakes.
@ManasMalla
Copy link
Contributor

@copilot Can we have the expereince that we are now giving in the /create-team page within the registration page, and instead of only coying the referal code, can we generate the link like /register?referral=code so that people can click that link and automatically the referral link is autofilled and disabled for editing making him a team member?

Copy link
Contributor

Copilot AI commented Dec 29, 2025

@ManasMalla I've opened a new pull request, #11, to work on those changes. Once the pull request is ready, I'll request review from you.

Copilot AI and others added 4 commits December 29, 2025 15:48
Co-authored-by: ManasMalla <38750492+ManasMalla@users.noreply.github.com>
Co-authored-by: ManasMalla <38750492+ManasMalla@users.noreply.github.com>
…R safety

Co-authored-by: ManasMalla <38750492+ManasMalla@users.noreply.github.com>
Integrate team creation into registration flow with URL-based referral links
@ManasMalla ManasMalla merged commit c345836 into main Dec 29, 2025
1 check failed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants