refactor: use permission system instead of direct session checks in admin pages
This commit is contained in:
@@ -2,7 +2,7 @@ import { prisma } from "@/lib/prisma"
|
|||||||
import Navigation from "@/components/Navigation"
|
import Navigation from "@/components/Navigation"
|
||||||
import Link from "next/link"
|
import Link from "next/link"
|
||||||
import { notFound, redirect } from "next/navigation"
|
import { notFound, redirect } from "next/navigation"
|
||||||
import { getSession } from "@/lib/auth-simple"
|
import { canManageTournament, hasRole } from "@/lib/permissions"
|
||||||
import { getTournamentStatus } from "@/lib/tournamentUtils"
|
import { getTournamentStatus } from "@/lib/tournamentUtils"
|
||||||
|
|
||||||
interface PageProps {
|
interface PageProps {
|
||||||
@@ -12,21 +12,16 @@ interface PageProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default async function TournamentDetailPage({ params }: PageProps) {
|
export default async function TournamentDetailPage({ params }: PageProps) {
|
||||||
const session = await getSession()
|
const tournamentId = parseInt(params.id)
|
||||||
|
|
||||||
if (!session) {
|
// Check if user can manage this tournament
|
||||||
|
const permission = await canManageTournament(tournamentId)
|
||||||
|
if (!permission.allowed) {
|
||||||
redirect("/auth/login")
|
redirect("/auth/login")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fetch user role from database
|
// Check if user can create tournaments (tournament_admin or club_admin)
|
||||||
const user = await prisma.user.findUnique({
|
const canCreate = await hasRole('tournament_admin')
|
||||||
where: { id: session.user.id },
|
|
||||||
select: { role: true },
|
|
||||||
});
|
|
||||||
|
|
||||||
const isAdmin = user?.role === "club_admin"
|
|
||||||
|
|
||||||
const tournamentId = parseInt(params.id)
|
|
||||||
|
|
||||||
let tournament = await prisma.event.findUnique({
|
let tournament = await prisma.event.findUnique({
|
||||||
where: { id: tournamentId },
|
where: { id: tournamentId },
|
||||||
@@ -158,7 +153,7 @@ export default async function TournamentDetailPage({ params }: PageProps) {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="flex space-x-2">
|
<div className="flex space-x-2">
|
||||||
{isAdmin && (
|
{permission.allowed && (
|
||||||
<>
|
<>
|
||||||
<Link
|
<Link
|
||||||
href={`/admin/tournaments/${tournament.id}/edit`}
|
href={`/admin/tournaments/${tournament.id}/edit`}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import Link from "next/link"
|
|||||||
import { getSession } from "@/lib/auth-simple"
|
import { getSession } from "@/lib/auth-simple"
|
||||||
import { redirect } from "next/navigation"
|
import { redirect } from "next/navigation"
|
||||||
import { getTournamentStatus } from "@/lib/tournamentUtils"
|
import { getTournamentStatus } from "@/lib/tournamentUtils"
|
||||||
|
import { hasRole, getManageableTournaments } from "@/lib/permissions"
|
||||||
|
|
||||||
export default async function AdminTournamentsPage() {
|
export default async function AdminTournamentsPage() {
|
||||||
const session = await getSession()
|
const session = await getSession()
|
||||||
@@ -12,26 +13,12 @@ export default async function AdminTournamentsPage() {
|
|||||||
redirect("/auth/login")
|
redirect("/auth/login")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fetch user role from database
|
// Check if user can create tournaments (tournament_admin or club_admin)
|
||||||
const user = await prisma.user.findUnique({
|
const canCreateResult = await hasRole('tournament_admin')
|
||||||
where: { id: session.user.id },
|
const canCreate = canCreateResult.allowed
|
||||||
select: { role: true },
|
|
||||||
});
|
|
||||||
|
|
||||||
const isAdmin = user?.role === "club_admin"
|
// Get tournaments manageable by the current user
|
||||||
|
const tournaments = await getManageableTournaments()
|
||||||
const tournaments = await prisma.event.findMany({
|
|
||||||
orderBy: { createdAt: "desc" },
|
|
||||||
include: {
|
|
||||||
participants: true,
|
|
||||||
teams: {
|
|
||||||
include: {
|
|
||||||
player1: true,
|
|
||||||
player2: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
// Update tournament statuses based on event date
|
// Update tournament statuses based on event date
|
||||||
const updatedTournaments = await Promise.all(
|
const updatedTournaments = await Promise.all(
|
||||||
@@ -59,9 +46,9 @@ export default async function AdminTournamentsPage() {
|
|||||||
<div className="px-4 py-6 sm:px-0">
|
<div className="px-4 py-6 sm:px-0">
|
||||||
<div className="flex justify-between items-center mb-6">
|
<div className="flex justify-between items-center mb-6">
|
||||||
<h1 className="text-3xl font-bold text-gray-900">
|
<h1 className="text-3xl font-bold text-gray-900">
|
||||||
{isAdmin ? 'Tournament Management' : 'Tournaments'}
|
{canCreate ? 'Tournament Management' : 'Tournaments'}
|
||||||
</h1>
|
</h1>
|
||||||
{isAdmin && (
|
{canCreate && (
|
||||||
<Link
|
<Link
|
||||||
href="/admin/tournaments/new"
|
href="/admin/tournaments/new"
|
||||||
className="inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-green-600 hover:bg-green-700"
|
className="inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-green-600 hover:bg-green-700"
|
||||||
@@ -132,14 +119,12 @@ export default async function AdminTournamentsPage() {
|
|||||||
>
|
>
|
||||||
View
|
View
|
||||||
</Link>
|
</Link>
|
||||||
{isAdmin && (
|
|
||||||
<Link
|
<Link
|
||||||
href={`/admin/tournaments/${tournament.id}/edit`}
|
href={`/admin/tournaments/${tournament.id}/edit`}
|
||||||
className="text-blue-600 hover:text-blue-900"
|
className="text-blue-600 hover:text-blue-900"
|
||||||
>
|
>
|
||||||
Edit
|
Edit
|
||||||
</Link>
|
</Link>
|
||||||
)}
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
))}
|
))}
|
||||||
@@ -149,7 +134,7 @@ export default async function AdminTournamentsPage() {
|
|||||||
{updatedTournaments.length === 0 && (
|
{updatedTournaments.length === 0 && (
|
||||||
<div className="text-center py-12">
|
<div className="text-center py-12">
|
||||||
<p className="text-gray-500">No tournaments found.</p>
|
<p className="text-gray-500">No tournaments found.</p>
|
||||||
{isAdmin && (
|
{canCreate && (
|
||||||
<Link
|
<Link
|
||||||
href="/admin/tournaments/new"
|
href="/admin/tournaments/new"
|
||||||
className="text-green-600 hover:text-green-900 mt-2 inline-block"
|
className="text-green-600 hover:text-green-900 mt-2 inline-block"
|
||||||
|
|||||||
Reference in New Issue
Block a user