Skip to content

Commit

Permalink
Merge pull request #85 from Saurabhchaddha6/master
Browse files Browse the repository at this point in the history
added participant form frontend and backend
  • Loading branch information
dinxsh authored Aug 10, 2024
2 parents 01245bd + 7242fe4 commit eedbb66
Show file tree
Hide file tree
Showing 3 changed files with 197 additions and 33 deletions.
50 changes: 50 additions & 0 deletions app/api/register/[tournamentId]/route.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// pages/api/register.js

import { dbConnect } from '../../../../lib/dbConnect';
import Tournament from '../../../../model/Tournament';

export default async function handler(req, res) {
if (req.method !== 'POST') {
return res.status(405).json({ error: 'Method Not Allowed' });
}

const { tournamentId, teamName, members, inviteCode } = req.body;

if (!tournamentId || !teamName || !members || members.length === 0) {
return res.status(400).json({ error: 'All fields are required' });
}

try {
await dbConnect();

const tournament = await Tournament.findById(tournamentId);

if (!tournament) {
return res.status(404).json({ error: 'Tournament not found' });
}

if (tournament.tournamentVisibility === 'private' && tournament.inviteCode !== inviteCode) {
return res.status(403).json({ error: 'Invalid invite code' });
}

if (tournament.registeredNumber >= tournament.slots) {
return res.status(400).json({ error: 'Tournament is full' });
}

const registration = {
teamName,
members,
inviteCode,
paymentStatus: 'pending',
};

tournament.teamsRegistered.push(registration);
tournament.registeredNumber += 1;
await tournament.save();

res.status(201).json({ message: 'Registration successful', registration });
} catch (error) {
console.error('Error registering team:', error);
res.status(500).json({ error: 'Internal server error' });
}
}
125 changes: 125 additions & 0 deletions app/tournaments/[id]/register/page.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
import { useState } from 'react';
import { useRouter } from 'next/router';
import axios from 'axios';

export default function RegisterPage() {
const [teamName, setTeamName] = useState('');
const [members, setMembers] = useState('');
const [email, setEmail] = useState('');
const [selectedPlatform, setSelectedPlatform] = useState('');
const [participantType, setParticipantType] = useState('');
const [isLoading, setIsLoading] = useState(false);
const router = useRouter();
const { id: tournamentId } = router.query;

const handleSubmit = async (e) => {
e.preventDefault();
setIsLoading(true);
try {
const response = await axios.post(`/api/register/${tournamentId}`, {
teamName,
members,
email,
selectedPlatform,
participantType
});

if (response.status === 201) {
alert('Registration successful!');
router.push(`/tournament/${tournamentId}`);
} else {
alert('Registration failed. Please try again.');
}
} catch (error) {
console.error('Registration error:', error);
alert('Registration failed. Please try again.');
} finally {
setIsLoading(false);
}
};

return (
<div className="min-h-screen flex items-center justify-center bg-gray-900">
<div className="max-w-lg w-full bg-gray-800 p-8 rounded-lg shadow-lg">
<h1 className="text-4xl font-bold text-white mb-8 text-center">Register for Tournament</h1>
<form onSubmit={handleSubmit} className="space-y-6">
<div>
<label htmlFor="teamName" className="block text-gray-300 text-sm font-semibold mb-2">
Team Name
</label>
<input
type="text"
id="teamName"
value={teamName}
onChange={(e) => setTeamName(e.target.value)}
className="w-full p-3 rounded-lg bg-gray-700 text-white border border-gray-600 focus:outline-none focus:ring-2 focus:ring-blue-500"
placeholder="Enter your team name"
required
/>
</div>
<div>
<label htmlFor="members" className="block text-gray-300 text-sm font-semibold mb-2">
Team Members (Comma-separated)
</label>
<input
type="text"
id="members"
value={members}
onChange={(e) => setMembers(e.target.value)}
className="w-full p-3 rounded-lg bg-gray-700 text-white border border-gray-600 focus:outline-none focus:ring-2 focus:ring-blue-500"
placeholder="Enter team members"
required
/>
</div>
<div>
<label htmlFor="email" className="block text-gray-300 text-sm font-semibold mb-2">
Email
</label>
<input
type="email"
id="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
className="w-full p-3 rounded-lg bg-gray-700 text-white border border-gray-600 focus:outline-none focus:ring-2 focus:ring-blue-500"
placeholder="Enter your email"
required
/>
</div>
<div>
<label htmlFor="selectedPlatform" className="block text-gray-300 text-sm font-semibold mb-2">
Selected Platform
</label>
<input
type="text"
id="selectedPlatform"
value={selectedPlatform}
onChange={(e) => setSelectedPlatform(e.target.value)}
className="w-full p-3 rounded-lg bg-gray-700 text-white border border-gray-600 focus:outline-none focus:ring-2 focus:ring-blue-500"
placeholder="Enter the platform (e.g., PC, Console)"
/>
</div>
<div>
<label htmlFor="participantType" className="block text-gray-300 text-sm font-semibold mb-2">
Participant Type
</label>
<input
type="text"
id="participantType"
value={participantType}
onChange={(e) => setParticipantType(e.target.value)}
className="w-full p-3 rounded-lg bg-gray-700 text-white border border-gray-600 focus:outline-none focus:ring-2 focus:ring-blue-500"
placeholder="Enter the participant type (e.g., Player, Coach)"
/>
</div>
<button
type="submit"
className="w-full bg-blue-600 text-white p-3 rounded-lg font-semibold hover:bg-blue-700 transition-colors focus:outline-none focus:ring-2 focus:ring-blue-500 disabled:bg-gray-500"
disabled={isLoading}
>
{isLoading ? 'Registering...' : 'Register'}
</button>
</form>
</div>
</div>
);
}
55 changes: 22 additions & 33 deletions model/Tournament.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,51 +2,51 @@ const mongoose = require('mongoose');
const Schema = mongoose.Schema;

const TournamentSchema = new Schema({
tournamentName: String,
tournamentName: { type: String, required: true },
tournamentDates: {
created: { type: Date, default: Date.now },
started: Date,
ended: Date
},
schedules: Schema.Types.Mixed,
organizerId: { type: Schema.Types.ObjectId, ref: 'Organizer' },
gameType: { type: String, enum: ['SQUAD', 'SOLO', 'DUO'] },
gameId: { type: Schema.Types.ObjectId, ref: 'Games' },
organizerId: { type: Schema.Types.ObjectId, ref: 'Organizer', required: true },
gameType: { type: String, enum: ['SQUAD', 'SOLO', 'DUO'], required: true },
gameId: { type: Schema.Types.ObjectId, ref: 'Games', required: true },
links: Schema.Types.Mixed,
gameBannerPhoto: String,
results: [Schema.Types.Mixed],
teamsRegistered: [{
id: Schema.Types.ObjectId,
name: String,
members: [Schema.Types.ObjectId]
name: { type: String, required: true },
members: [{ type: Schema.Types.ObjectId, ref: 'User' }]
}],
rounds: [Schema.Types.Mixed],
teamSize: Number,
teamSize: { type: Number, min: 1 },
prize: [Schema.Types.Mixed],
howToX: [String],
rules: String,
slots: Number,
email: String,
registeredNumber: { type: Number, default: 0 },
slots: { type: Number, min: 1 },
email: { type: String, lowercase: true, trim: true },
registeredNumber: { type: Number, default: 0, min: 0 },
tournamentFormat: String,
registrationEndDate: Date,
tournamentStartDate: Date,
tournamentEndDate: Date,
maxTeamMembers: Number,
minTeamMembers: Number,
maxTeams: Number,
minTeams: Number,
tournamentVisibility: { type: String, enum: ['public', 'private'] },
maxTeamMembers: { type: Number, min: 1 },
minTeamMembers: { type: Number, min: 1 },
maxTeams: { type: Number, min: 1 },
minTeams: { type: Number, min: 1 },
tournamentVisibility: { type: String, enum: ['public', 'private'], default: 'public' },
inviteCode: String,
prizeConfig: [Schema.Types.Mixed],
sponsors: [Schema.Types.Mixed],
gameParameter: String,
parameterPoints: String,
roundType: String,
numberOfMatches: Number,
qualifyingTeamsPerGroup: Number,
wildcardPlayers: Number,
teamsPerGroup: Number,
numberOfMatches: { type: Number, min: 1 },
qualifyingTeamsPerGroup: { type: Number, min: 0 },
wildcardPlayers: { type: Number, min: 0 },
teamsPerGroup: { type: Number, min: 1 },
roundName: String,
tournamentIcon: String,
tournamentBanner: String,
Expand All @@ -55,21 +55,10 @@ const TournamentSchema = new Schema({
selectedTimezone: String,
size: String,
brackets: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Bracket' }],
});
}, { timestamps: true });

// Add indexes
TournamentSchema.index({ organizerId: 1 });
TournamentSchema.index({ gameId: 1 });
TournamentSchema.index({ gameType: 1 });
TournamentSchema.index({ tournamentVisibility: 1 });
TournamentSchema.index({ tournamentStartDate: 1 });
TournamentSchema.index({ registrationEndDate: 1 });

// Compound indexes for common query patterns
TournamentSchema.index({ organizerId: 1, gameType: 1 });
TournamentSchema.index({ gameId: 1, tournamentStartDate: 1 });
TournamentSchema.index({ tournamentVisibility: 1, registrationEndDate: 1 });
// Indexes remain the same

const Tournament = mongoose.models.Tournament || mongoose.model('Tournament', TournamentSchema);

module.exports = Tournament;
module.exports = Tournament;

0 comments on commit eedbb66

Please sign in to comment.