Add house leaderboard feature: Integrate house leaderboard functionality in LeaderboardPage and LeaderboardSection components. Update userStatsService to fetch house leaderboard data, and enhance UI to display house rankings, scores, and member details. Update Prisma schema to include house-related models and relationships, and seed database with initial house data.
Some checks failed
Deploy with Docker Compose / deploy (push) Has been cancelled

This commit is contained in:
Julien Froidefond
2025-12-17 13:35:18 +01:00
parent cb02b494f4
commit 85ee812ab1
36 changed files with 5422 additions and 13 deletions

View File

@@ -0,0 +1,51 @@
import { NextResponse } from "next/server";
import { auth } from "@/lib/auth";
import { houseService } from "@/services/houses/house.service";
export async function GET(
request: Request,
{ params }: { params: Promise<{ houseId: string }> }
) {
try {
const session = await auth();
if (!session?.user?.id) {
return NextResponse.json(
{ error: "Vous devez être connecté" },
{ status: 401 }
);
}
const { houseId } = await params;
// Vérifier que l'utilisateur est membre de la maison
const isMember = await houseService.isUserMemberOfHouse(
session.user.id,
houseId
);
if (!isMember) {
return NextResponse.json(
{ error: "Vous devez être membre de cette maison" },
{ status: 403 }
);
}
const { searchParams } = new URL(request.url);
const status = searchParams.get("status") as "PENDING" | "ACCEPTED" | "REJECTED" | "CANCELLED" | null;
const invitations = await houseService.getHouseInvitations(
houseId,
status || undefined
);
return NextResponse.json(invitations);
} catch (error) {
console.error("Error fetching house invitations:", error);
return NextResponse.json(
{ error: "Erreur lors de la récupération des invitations" },
{ status: 500 }
);
}
}

View File

@@ -0,0 +1,48 @@
import { NextResponse } from "next/server";
import { auth } from "@/lib/auth";
import { houseService } from "@/services/houses/house.service";
export async function GET(
request: Request,
{ params }: { params: Promise<{ houseId: string }> }
) {
try {
const session = await auth();
if (!session?.user?.id) {
return NextResponse.json(
{ error: "Vous devez être connecté" },
{ status: 401 }
);
}
const { houseId } = await params;
// Vérifier que l'utilisateur est propriétaire ou admin
const isAuthorized = await houseService.isUserOwnerOrAdmin(
session.user.id,
houseId
);
if (!isAuthorized) {
return NextResponse.json(
{ error: "Vous n'avez pas les permissions pour voir les demandes" },
{ status: 403 }
);
}
const { searchParams } = new URL(request.url);
const status = searchParams.get("status") as "PENDING" | "ACCEPTED" | "REJECTED" | "CANCELLED" | null;
const requests = await houseService.getHouseRequests(houseId, status || undefined);
return NextResponse.json(requests);
} catch (error) {
console.error("Error fetching house requests:", error);
return NextResponse.json(
{ error: "Erreur lors de la récupération des demandes" },
{ status: 500 }
);
}
}

View File

@@ -0,0 +1,59 @@
import { NextResponse } from "next/server";
import { auth } from "@/lib/auth";
import { houseService } from "@/services/houses/house.service";
export async function GET(
request: Request,
{ params }: { params: Promise<{ houseId: string }> }
) {
try {
const session = await auth();
if (!session?.user?.id) {
return NextResponse.json(
{ error: "Vous devez être connecté" },
{ status: 401 }
);
}
const { houseId } = await params;
const house = await houseService.getHouseById(houseId, {
memberships: {
include: {
user: {
select: {
id: true,
username: true,
avatar: true,
score: true,
level: true,
},
},
},
},
creator: {
select: {
id: true,
username: true,
avatar: true,
},
},
});
if (!house) {
return NextResponse.json(
{ error: "Maison non trouvée" },
{ status: 404 }
);
}
return NextResponse.json(house);
} catch (error) {
console.error("Error fetching house:", error);
return NextResponse.json(
{ error: "Erreur lors de la récupération de la maison" },
{ status: 500 }
);
}
}

View File

@@ -0,0 +1,48 @@
import { NextResponse } from "next/server";
import { auth } from "@/lib/auth";
import { houseService } from "@/services/houses/house.service";
export async function GET() {
try {
const session = await auth();
if (!session?.user?.id) {
return NextResponse.json(
{ error: "Vous devez être connecté" },
{ status: 401 }
);
}
const house = await houseService.getUserHouse(session.user.id, {
memberships: {
include: {
user: {
select: {
id: true,
username: true,
avatar: true,
score: true,
level: true,
},
},
},
},
creator: {
select: {
id: true,
username: true,
avatar: true,
},
},
});
return NextResponse.json(house);
} catch (error) {
console.error("Error fetching user house:", error);
return NextResponse.json(
{ error: "Erreur lors de la récupération de votre maison" },
{ status: 500 }
);
}
}

87
app/api/houses/route.ts Normal file
View File

@@ -0,0 +1,87 @@
import { NextResponse } from "next/server";
import { auth } from "@/lib/auth";
import { houseService } from "@/services/houses/house.service";
export async function GET(request: Request) {
try {
const session = await auth();
if (!session?.user?.id) {
return NextResponse.json(
{ error: "Vous devez être connecté" },
{ status: 401 }
);
}
const { searchParams } = new URL(request.url);
const search = searchParams.get("search");
const include = searchParams.get("include")?.split(",") || [];
const includeOptions: {
memberships?: {
include: {
user: {
select: {
id: boolean;
username: boolean;
avatar: boolean;
score?: boolean;
level?: boolean;
};
};
};
};
creator?: {
select: {
id: boolean;
username: boolean;
avatar: boolean;
};
};
} = {};
if (include.includes("members")) {
includeOptions.memberships = {
include: {
user: {
select: {
id: true,
username: true,
avatar: true,
score: true,
level: true,
},
},
},
};
}
if (include.includes("creator")) {
includeOptions.creator = {
select: {
id: true,
username: true,
avatar: true,
},
};
}
let houses;
if (search) {
houses = await houseService.searchHouses(search, {
include: includeOptions,
});
} else {
houses = await houseService.getAllHouses({
include: includeOptions,
});
}
return NextResponse.json(houses);
} catch (error) {
console.error("Error fetching houses:", error);
return NextResponse.json(
{ error: "Erreur lors de la récupération des maisons" },
{ status: 500 }
);
}
}