Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

improved perfomance for tournaments page #76

Merged
merged 3 commits into from
Jul 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions app/api/tournaments/[id]/route.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@ export async function GET(request, { params }) {
Organizer;

const tournament = await Tournament.findById(id)
.populate('gameId')
.populate('organizerId')
.select('tournamentName tournamentDates gameType prize slots registeredNumber gameId organizerId')
.populate('gameId', 'name gameBannerPhoto')
.populate('organizerId', 'orgName bannerPhoto')
.lean();

if (tournament) {
Expand Down
92 changes: 77 additions & 15 deletions app/api/tournaments/route.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,38 +3,47 @@ import dbConnect from '../../../lib/dbConnect';
import Tournament from '../../../model/Tournament';
import Games from '../../../model/Games';
import Organizer from '../../../model/Organizer';
import { prefetchTournaments } from '../../../lib/prefetchTournaments';

export async function GET(request) {
await dbConnect();

const { searchParams } = new URL(request.url);
const page = parseInt(searchParams.get('page') || '1');
const limit = parseInt(searchParams.get('limit') || '10');
const gameType = searchParams.get('gameType');
const organizerId = searchParams.get('organizerId');

const skip = (page - 1) * limit;
try {
const { tournaments: allTournaments } = await prefetchTournaments();

const query = {};
if (gameType) query.gameType = gameType;
if (organizerId) query.organizerId = organizerId;
// Apply filters
let filteredTournaments = allTournaments;
if (gameType) {
filteredTournaments = filteredTournaments.filter(t => t.gameType === gameType);
}
if (organizerId) {
filteredTournaments = filteredTournaments.filter(t => t.organizerId._id.toString() === organizerId);
}

try {
const tournaments = await Tournament.find(query)
.populate('gameId', 'name category gameBannerPhoto')
.populate('organizerId', 'orgName bannerPhoto')
.skip(skip)
.limit(limit)
.lean();
// Sort tournaments (adjust the sorting field as needed)
filteredTournaments.sort((a, b) => new Date(b.tournamentDates.started) - new Date(a.tournamentDates.started));

const total = await Tournament.countDocuments(query);
// Apply pagination
const total = filteredTournaments.length;
const start = (page - 1) * limit;
const end = start + limit;
const paginatedTournaments = filteredTournaments.slice(start, end);

return NextResponse.json({
tournaments,
tournaments: paginatedTournaments,
totalPages: Math.ceil(total / limit),
currentPage: page,
}, {
headers: {
'Cache-Control': 'public, s-maxage=60, stale-while-revalidate=600',
},
});
} catch (error) {
console.error('Error in GET /tournaments:', error);
return NextResponse.json({
error: 'Internal Server Error',
details: error.message
Expand Down Expand Up @@ -124,3 +133,56 @@ export async function POST(request) {
}, { status: 500 });
}
}









// import { NextResponse } from 'next/server';
// import dbConnect from '../../../lib/dbConnect';
// import Tournament from '../../../model/Tournament';
// import Games from '../../../model/Games';
// import Organizer from '../../../model/Organizer';

// export async function GET(request) {
// await dbConnect();

// const { searchParams } = new URL(request.url);
// const page = parseInt(searchParams.get('page') || '1');
// const limit = parseInt(searchParams.get('limit') || '10');
// const gameType = searchParams.get('gameType');
// const organizerId = searchParams.get('organizerId');

// const skip = (page - 1) * limit;

// const query = {};
// if (gameType) query.gameType = gameType;
// if (organizerId) query.organizerId = organizerId;

// try {
// const tournaments = await Tournament.find(query)
// .populate('gameId', 'name category gameBannerPhoto')
// .populate('organizerId', 'orgName bannerPhoto')
// .skip(skip)
// .limit(limit)
// .lean();

// const total = await Tournament.countDocuments(query);

// return NextResponse.json({
// tournaments,
// totalPages: Math.ceil(total / limit),
// currentPage: page,
// });
// } catch (error) {
// return NextResponse.json({
// error: 'Internal Server Error',
// details: error.message
// }, { status: 500 });
// }
// }

6 changes: 5 additions & 1 deletion app/page.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import HeroSection from "../components/HeroSection";
// import FeatureSection from "../components/FeatureSection/FeatureSection";
import FaqSection from "../components/FaqSection";
import { prefetchTournaments } from '../lib/prefetchTournaments';

export default async function Home() {
// Prefetch tournaments data
await prefetchTournaments();

export default function Home() {
return (
<main className="">
<HeroSection />
Expand Down
5 changes: 4 additions & 1 deletion app/tournaments/[id]/page.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Image from 'next/image';
import Link from 'next/link';
import { CalendarIcon, ClockIcon, PersonIcon, CrossCircledIcon, LockClosedIcon } from '@radix-ui/react-icons';
import { CalendarIcon, ClockIcon } from '@radix-ui/react-icons';
import { Trophy, DollarSign, Users, Shield } from 'lucide-react';
import dbConnect from '../../../lib/dbConnect';
import Tournament from '../../../model/Tournament';
Expand Down Expand Up @@ -142,6 +142,9 @@ export default async function TournamentPage({ params }) {
);
}

// Add caching and revalidation
export const revalidate = 60; // Revalidate this page every 60 seconds

// Static tournament data for UI demonstration
// const tournament = {
// id: "1",
Expand Down
141 changes: 3 additions & 138 deletions components/TournamentSection.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,17 @@ export default function TournamentSection({ filters }) {

useEffect(() => {
async function fetchTournaments() {
setIsLoading(true);
try {
const response = await fetch("/api/tournaments");
if (!response.ok) {
const errorData = await response.json();
console.error("Error in fetchTournaments:", errorData);
throw new Error(
`Failed to fetch tournaments: ${response.status}. ${errorData.error} - ${errorData.details}`
);
throw new Error("Failed to fetch tournaments");
}
const data = await response.json();
console.log("Fetched tournaments:", data);
setTournaments(data.tournaments);
setIsLoading(false);
} catch (err) {
console.error("Error in fetchTournaments:", err);
setError(err.message);
} finally {
setIsLoading(false);
}
}
Expand Down Expand Up @@ -76,6 +70,7 @@ export default function TournamentSection({ filters }) {
key={tournament._id}
href={`/tournaments/${tournament._id}`}
className="hover:scale-105 transition-all"
prefetch={true} // prefetch the tournament page
>
<TournamentCard {...tournament} />
</Link>
Expand Down Expand Up @@ -176,133 +171,3 @@ function TournamentCard({
</div>
);
}

// Example data for tournaments
// const tournamentsData = [
// {
// image:
// "https://media.battlexo.com/tournament/668292838ab430dcee21f257/banner/icon/29fd717a-2be9-4c19-8394-865ff112a15a.webp",
// title: "KINGS ESPORTS PRO SCRIMS (12PM)",
// date: "JUL 1, 2024",
// time: "11:00 PM",
// entryFee: 500,
// mode: "Squad",
// participants: "16/21",
// host: {
// image:
// "https://media.battlexo.com/space/262/icon/43ed1dc5-1493-4932-ab9c-c7bedbdfe584.webp",
// name: "KINGS ESPORTS",
// },
// },
// {
// image:
// "https://media.battlexo.com/tournament/668292838ab430dcee21f257/banner/icon/29fd717a-2be9-4c19-8394-865ff112a15a.webp",
// title: "KINGS ESPORTS PRO SCRIMS (12PM)",
// date: "JUL 1, 2024",
// time: "11:00 PM",
// entryFee: 500,
// mode: "Duo",
// participants: "16/21",
// host: {
// image:
// "https://media.battlexo.com/space/262/icon/43ed1dc5-1493-4932-ab9c-c7bedbdfe584.webp",
// name: "KINGS ESPORTS",
// },
// },
// {
// image:
// "https://media.battlexo.com/tournament/668292838ab430dcee21f257/banner/icon/29fd717a-2be9-4c19-8394-865ff112a15a.webp",
// title: "KINGS ESPORTS PRO SCRIMS (12PM)",
// date: "JUL 1, 2024",
// time: "11:00 PM",
// entryFee: 500,
// mode: "Squad",
// participants: "16/21",
// host: {
// image:
// "https://media.battlexo.com/space/262/icon/43ed1dc5-1493-4932-ab9c-c7bedbdfe584.webp",
// name: "KINGS ESPORTS",
// },
// },
// {
// image:
// "https://media.battlexo.com/tournament/668292838ab430dcee21f257/banner/icon/29fd717a-2be9-4c19-8394-865ff112a15a.webp",
// title: "KINGS ESPORTS PRO SCRIMS (12PM)",
// date: "JUL 1, 2024",
// time: "11:00 PM",
// entryFee: 500,
// mode: "Squad",
// participants: "16/21",
// host: {
// image:
// "https://media.battlexo.com/space/262/icon/43ed1dc5-1493-4932-ab9c-c7bedbdfe584.webp",
// name: "KINGS ESPORTS",
// },
// },
// {
// image:
// "https://media.battlexo.com/tournament/668292838ab430dcee21f257/banner/icon/29fd717a-2be9-4c19-8394-865ff112a15a.webp",
// title: "KINGS ESPORTS PRO SCRIMS (12PM)",
// date: "JUL 1, 2024",
// time: "11:00 PM",
// entryFee: 500,
// mode: "Squad",
// participants: "16/21",
// status: "Completed",
// host: {
// image:
// "https://media.battlexo.com/space/262/icon/43ed1dc5-1493-4932-ab9c-c7bedbdfe584.webp",
// name: "KINGS ESPORTS",
// },
// },
// {
// image:
// "https://media.battlexo.com/tournament/668292838ab430dcee21f257/banner/icon/29fd717a-2be9-4c19-8394-865ff112a15a.webp",
// title: "KINGS ESPORTS PRO SCRIMS (12PM)",
// date: "JUL 1, 2024",
// time: "11:00 PM",
// entryFee: 500,
// mode: "Squad",
// participants: "16/21",
// host: {
// image:
// "https://media.battlexo.com/space/262/icon/43ed1dc5-1493-4932-ab9c-c7bedbdfe584.webp",
// name: "KINGS ESPORTS",
// },
// },
// {
// image:
// "https://media.battlexo.com/tournament/668292838ab430dcee21f257/banner/icon/29fd717a-2be9-4c19-8394-865ff112a15a.webp",
// title: "KINGS ESPORTS PRO SCRIMS (12PM)",
// date: "JUL 1, 2024",
// time: "11:00 PM",
// entryFee: 500,
// mode: "Squad",
// participants: "16/21",
// status: "Live",
// host: {
// image:
// "https://media.battlexo.com/space/262/icon/43ed1dc5-1493-4932-ab9c-c7bedbdfe584.webp",
// name: "KINGS ESPORTS",
// },
// },
// {
// image:
// "https://media.battlexo.com/tournament/668292838ab430dcee21f257/banner/icon/29fd717a-2be9-4c19-8394-865ff112a15a.webp",
// title: "KINGS ESPORTS PRO SCRIMS (12PM)",
// date: "JUL 1, 2024",
// time: "11:00 PM",
// entryFee: 500,
// mode: "Solo",
// participants: "16/21",
// host: {
// image:
// "https://media.battlexo.com/space/262/icon/43ed1dc5-1493-4932-ab9c-c7bedbdfe584.webp",
// name: "KINGS ESPORTS",
// },
// },
// ].map((tournament, index) => ({
// ...tournament,
// id: index + 1,
// status: tournament.status || "Open",
// }));
18 changes: 18 additions & 0 deletions lib/prefetchTournaments.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { cache } from 'react';
import dbConnect from './dbConnect';
import Tournament from '../model/Tournament';

export const prefetchTournaments = cache(async () => {
await dbConnect();
try {
const tournaments = await Tournament.find()
.select('tournamentName tournamentDates gameType prize slots registeredNumber gameId organizerId')
.populate('gameId', 'gameBannerPhoto')
.populate('organizerId', 'orgName bannerPhoto')
.lean();
return { tournaments };
} catch (error) {
console.error('Error prefetching tournaments:', error);
return { tournaments: [] };
}
});
13 changes: 13 additions & 0 deletions model/Tournament.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,19 @@ const TournamentSchema = new Schema({
size: String
});

// 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 });

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

module.exports = Tournament;
Loading
Loading