Add database and Prisma configurations, enhance event and leaderboard components with API integration, and update navigation for session management
This commit is contained in:
@@ -1,80 +1,25 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
interface Event {
|
||||
id: number;
|
||||
id: string;
|
||||
date: string;
|
||||
name: string;
|
||||
description: string;
|
||||
type: "summit" | "launch" | "festival" | "competition";
|
||||
status: "upcoming" | "live" | "past";
|
||||
type: "SUMMIT" | "LAUNCH" | "FESTIVAL" | "COMPETITION";
|
||||
status: "UPCOMING" | "LIVE" | "PAST";
|
||||
}
|
||||
|
||||
const events: Event[] = [
|
||||
{
|
||||
id: 1,
|
||||
date: "18 NOVEMBRE 2023",
|
||||
name: "Sommet de l'Innovation Tech",
|
||||
description:
|
||||
"Rejoignez les leaders de l'industrie et les innovateurs pour une journée de discussions sur les technologies de pointe, les percées de l'IA et des opportunités de networking.",
|
||||
type: "summit",
|
||||
status: "past",
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
date: "3 DÉCEMBRE 2023",
|
||||
name: "Lancement de la Révolution IA",
|
||||
description:
|
||||
"Assistez au lancement de systèmes d'IA révolutionnaires qui vont remodeler le paysage du gaming. Aperçus exclusifs et opportunités d'accès anticipé.",
|
||||
type: "launch",
|
||||
status: "past",
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
date: "22 DÉCEMBRE 2023",
|
||||
name: "Festival du Code d'Hiver",
|
||||
description:
|
||||
"Une célébration de l'excellence en programmation avec des hackathons, des défis de codage et des prix. Montrez vos compétences et rivalisez avec les meilleurs développeurs.",
|
||||
type: "festival",
|
||||
status: "past",
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
date: "15 JANVIER 2024",
|
||||
name: "Expo Informatique Quantique",
|
||||
description:
|
||||
"Explorez l'avenir de l'informatique quantique dans le gaming. Démonstrations interactives, conférences d'experts et ateliers pratiques pour tous les niveaux.",
|
||||
type: "summit",
|
||||
status: "upcoming",
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
date: "8 FÉVRIER 2024",
|
||||
name: "Championnat Cyber Arena",
|
||||
description:
|
||||
"L'événement de gaming compétitif ultime. Compétissez pour la gloire, des récompenses exclusives et le titre de Champion Cyber Arena. Inscriptions ouvertes.",
|
||||
type: "competition",
|
||||
status: "upcoming",
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
date: "12 MARS 2024",
|
||||
name: "Gala Tech du Printemps",
|
||||
description:
|
||||
"Une soirée élégante célébrant les réalisations technologiques. Cérémonie de remise de prix, networking et annonces exclusives des plus grandes entreprises tech.",
|
||||
type: "festival",
|
||||
status: "upcoming",
|
||||
},
|
||||
];
|
||||
|
||||
const getEventTypeColor = (type: Event["type"]) => {
|
||||
switch (type) {
|
||||
case "summit":
|
||||
case "SUMMIT":
|
||||
return "from-blue-600 to-cyan-500";
|
||||
case "launch":
|
||||
case "LAUNCH":
|
||||
return "from-purple-600 to-pink-500";
|
||||
case "festival":
|
||||
case "FESTIVAL":
|
||||
return "from-pixel-gold to-orange-500";
|
||||
case "competition":
|
||||
case "COMPETITION":
|
||||
return "from-red-600 to-orange-500";
|
||||
default:
|
||||
return "from-gray-600 to-gray-500";
|
||||
@@ -83,13 +28,13 @@ const getEventTypeColor = (type: Event["type"]) => {
|
||||
|
||||
const getEventTypeLabel = (type: Event["type"]) => {
|
||||
switch (type) {
|
||||
case "summit":
|
||||
case "SUMMIT":
|
||||
return "Sommet";
|
||||
case "launch":
|
||||
case "LAUNCH":
|
||||
return "Lancement";
|
||||
case "festival":
|
||||
case "FESTIVAL":
|
||||
return "Festival";
|
||||
case "competition":
|
||||
case "COMPETITION":
|
||||
return "Compétition";
|
||||
default:
|
||||
return type;
|
||||
@@ -98,19 +43,19 @@ const getEventTypeLabel = (type: Event["type"]) => {
|
||||
|
||||
const getStatusBadge = (status: Event["status"]) => {
|
||||
switch (status) {
|
||||
case "upcoming":
|
||||
case "UPCOMING":
|
||||
return (
|
||||
<span className="px-3 py-1 bg-green-900/50 border border-green-500/50 text-green-400 text-xs uppercase tracking-widest rounded">
|
||||
À venir
|
||||
</span>
|
||||
);
|
||||
case "live":
|
||||
case "LIVE":
|
||||
return (
|
||||
<span className="px-3 py-1 bg-red-900/50 border border-red-500/50 text-red-400 text-xs uppercase tracking-widest rounded animate-pulse">
|
||||
En direct
|
||||
</span>
|
||||
);
|
||||
case "past":
|
||||
case "PAST":
|
||||
return (
|
||||
<span className="px-3 py-1 bg-gray-800/50 border border-gray-600/50 text-gray-400 text-xs uppercase tracking-widest rounded">
|
||||
Passé
|
||||
@@ -120,6 +65,29 @@ const getStatusBadge = (status: Event["status"]) => {
|
||||
};
|
||||
|
||||
export default function EventsPageSection() {
|
||||
const [events, setEvents] = useState<Event[]>([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
useEffect(() => {
|
||||
fetch("/api/events")
|
||||
.then((res) => res.json())
|
||||
.then((data) => {
|
||||
setEvents(data);
|
||||
setLoading(false);
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error("Error fetching events:", err);
|
||||
setLoading(false);
|
||||
});
|
||||
}, []);
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<section className="relative w-full min-h-screen flex flex-col items-center justify-center overflow-hidden pt-24 pb-16">
|
||||
<div className="text-pixel-gold text-xl">Chargement...</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<section className="relative w-full min-h-screen flex flex-col items-center justify-center overflow-hidden pt-24 pb-16">
|
||||
{/* Background Image */}
|
||||
@@ -198,17 +166,17 @@ export default function EventsPageSection() {
|
||||
</p>
|
||||
|
||||
{/* Action Button */}
|
||||
{event.status === "upcoming" && (
|
||||
{event.status === "UPCOMING" && (
|
||||
<button className="w-full px-4 py-2 border border-pixel-gold/50 bg-black/40 text-white uppercase text-xs tracking-widest rounded hover:bg-pixel-gold/10 hover:border-pixel-gold transition">
|
||||
S'inscrire maintenant
|
||||
</button>
|
||||
)}
|
||||
{event.status === "live" && (
|
||||
{event.status === "LIVE" && (
|
||||
<button className="w-full px-4 py-2 border border-red-500/50 bg-red-900/20 text-red-400 uppercase text-xs tracking-widest rounded hover:bg-red-900/30 transition animate-pulse">
|
||||
Rejoindre en direct
|
||||
</button>
|
||||
)}
|
||||
{event.status === "past" && (
|
||||
{event.status === "PAST" && (
|
||||
<button className="w-full px-4 py-2 border border-gray-600/50 bg-gray-900/20 text-gray-500 uppercase text-xs tracking-widest rounded cursor-not-allowed">
|
||||
Événement terminé
|
||||
</button>
|
||||
|
||||
@@ -1,26 +1,44 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
interface Event {
|
||||
id: string;
|
||||
date: string;
|
||||
name: string;
|
||||
}
|
||||
|
||||
const events: Event[] = [
|
||||
{
|
||||
date: "18 NOVEMBRE 2023",
|
||||
name: "Sommet de l'Innovation Tech",
|
||||
},
|
||||
{
|
||||
date: "3 DÉCEMBRE 2023",
|
||||
name: "Lancement de la Révolution IA",
|
||||
},
|
||||
{
|
||||
date: "22 DÉCEMBRE 2023",
|
||||
name: "Festival du Code d'Hiver",
|
||||
},
|
||||
];
|
||||
|
||||
export default function EventsSection() {
|
||||
const [events, setEvents] = useState<Event[]>([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
useEffect(() => {
|
||||
fetch("/api/events")
|
||||
.then((res) => res.json())
|
||||
.then((data) => {
|
||||
// Prendre seulement les 3 premiers événements pour la section d'accueil
|
||||
setEvents(data.slice(0, 3));
|
||||
setLoading(false);
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error("Error fetching events:", err);
|
||||
setLoading(false);
|
||||
});
|
||||
}, []);
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<section className="w-full bg-gray-950 border-t border-pixel-gold/30 py-16">
|
||||
<div className="max-w-7xl mx-auto px-8 text-center text-pixel-gold">
|
||||
Chargement...
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
if (events.length === 0) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<section className="w-full bg-gray-950 border-t border-pixel-gold/30 py-16">
|
||||
<div className="max-w-7xl mx-auto px-8">
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
interface LeaderboardEntry {
|
||||
rank: number;
|
||||
username: string;
|
||||
score: number;
|
||||
level: number;
|
||||
avatar?: string | null;
|
||||
}
|
||||
|
||||
// Format number with consistent locale to avoid hydration mismatch
|
||||
@@ -12,20 +15,32 @@ const formatScore = (score: number): string => {
|
||||
return score.toLocaleString("en-US");
|
||||
};
|
||||
|
||||
const mockLeaderboard: LeaderboardEntry[] = [
|
||||
{ rank: 1, username: "DragonSlayer99", score: 125000, level: 85 },
|
||||
{ rank: 2, username: "MineMaster", score: 118500, level: 82 },
|
||||
{ rank: 3, username: "CraftKing", score: 112000, level: 80 },
|
||||
{ rank: 4, username: "PixelWarrior", score: 105500, level: 78 },
|
||||
{ rank: 5, username: "FarminePro", score: 99000, level: 75 },
|
||||
{ rank: 6, username: "GoldDigger", score: 92500, level: 73 },
|
||||
{ rank: 7, username: "EpicGamer", score: 87000, level: 71 },
|
||||
{ rank: 8, username: "Legendary", score: 81500, level: 69 },
|
||||
{ rank: 9, username: "MysticMiner", score: 76000, level: 67 },
|
||||
{ rank: 10, username: "TopPlayer", score: 70500, level: 65 },
|
||||
];
|
||||
|
||||
export default function Leaderboard() {
|
||||
const [leaderboard, setLeaderboard] = useState<LeaderboardEntry[]>([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
useEffect(() => {
|
||||
fetch("/api/leaderboard")
|
||||
.then((res) => res.json())
|
||||
.then((data) => {
|
||||
setLeaderboard(data);
|
||||
setLoading(false);
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error("Error fetching leaderboard:", err);
|
||||
setLoading(false);
|
||||
});
|
||||
}, []);
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<section className="w-full bg-black py-16 px-6 border-t-2 border-pixel-dark-purple">
|
||||
<div className="max-w-4xl mx-auto text-center text-pixel-gold">
|
||||
Chargement...
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<section className="w-full bg-black py-16 px-6 border-t-2 border-pixel-dark-purple">
|
||||
<div className="max-w-4xl mx-auto">
|
||||
@@ -44,7 +59,7 @@ export default function Leaderboard() {
|
||||
|
||||
{/* Entries */}
|
||||
<div className="divide-y divide-pixel-gold/10">
|
||||
{mockLeaderboard.map((entry) => (
|
||||
{leaderboard.map((entry) => (
|
||||
<div
|
||||
key={entry.rank}
|
||||
className={`grid grid-cols-12 gap-4 p-4 hover:bg-gray-900/50 transition ${
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
interface LeaderboardEntry {
|
||||
rank: number;
|
||||
username: string;
|
||||
score: number;
|
||||
level: number;
|
||||
avatar?: string;
|
||||
avatar?: string | null;
|
||||
}
|
||||
|
||||
// Format number with consistent locale to avoid hydration mismatch
|
||||
@@ -13,25 +15,30 @@ const formatScore = (score: number): string => {
|
||||
return score.toLocaleString("en-US");
|
||||
};
|
||||
|
||||
const mockLeaderboard: LeaderboardEntry[] = [
|
||||
{ rank: 1, username: "TechMaster2024", score: 125000, level: 85 },
|
||||
{ rank: 2, username: "CodeWarrior", score: 118500, level: 82 },
|
||||
{ rank: 3, username: "AIGenius", score: 112000, level: 80 },
|
||||
{ rank: 4, username: "DevLegend", score: 105500, level: 78 },
|
||||
{ rank: 5, username: "InnovationPro", score: 99000, level: 75 },
|
||||
{ rank: 6, username: "TechNinja", score: 92500, level: 73 },
|
||||
{ rank: 7, username: "DigitalHero", score: 87000, level: 71 },
|
||||
{ rank: 8, username: "CodeCrusher", score: 81500, level: 69 },
|
||||
{ rank: 9, username: "TechWizard", score: 76000, level: 67 },
|
||||
{ rank: 10, username: "InnovationKing", score: 70500, level: 65 },
|
||||
{ rank: 11, username: "DevMaster", score: 68000, level: 64 },
|
||||
{ rank: 12, username: "TechElite", score: 65500, level: 63 },
|
||||
{ rank: 13, username: "CodeChampion", score: 63000, level: 62 },
|
||||
{ rank: 14, username: "AIVisionary", score: 60500, level: 61 },
|
||||
{ rank: 15, username: "TechPioneer", score: 58000, level: 60 },
|
||||
];
|
||||
|
||||
export default function LeaderboardSection() {
|
||||
const [leaderboard, setLeaderboard] = useState<LeaderboardEntry[]>([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
useEffect(() => {
|
||||
fetch("/api/leaderboard")
|
||||
.then((res) => res.json())
|
||||
.then((data) => {
|
||||
setLeaderboard(data);
|
||||
setLoading(false);
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error("Error fetching leaderboard:", err);
|
||||
setLoading(false);
|
||||
});
|
||||
}, []);
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<section className="relative w-full min-h-screen flex flex-col items-center justify-center overflow-hidden pt-24 pb-16">
|
||||
<div className="text-pixel-gold text-xl">Chargement...</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<section className="relative w-full min-h-screen flex flex-col items-center justify-center overflow-hidden pt-24 pb-16">
|
||||
{/* Background Image */}
|
||||
@@ -78,7 +85,7 @@ export default function LeaderboardSection() {
|
||||
|
||||
{/* Entries */}
|
||||
<div className="divide-y divide-pixel-gold/10">
|
||||
{mockLeaderboard.map((entry) => (
|
||||
{leaderboard.map((entry) => (
|
||||
<div
|
||||
key={entry.rank}
|
||||
className={`grid grid-cols-12 gap-4 p-4 hover:bg-gray-900/50 transition ${
|
||||
@@ -106,11 +113,21 @@ export default function LeaderboardSection() {
|
||||
|
||||
{/* Player */}
|
||||
<div className="col-span-6 flex items-center gap-3">
|
||||
<div className="w-10 h-10 rounded-full bg-gradient-to-br from-gray-800 to-gray-900 border border-pixel-gold/30 flex items-center justify-center">
|
||||
<span className="text-pixel-gold text-xs font-bold">
|
||||
{entry.username.charAt(0).toUpperCase()}
|
||||
</span>
|
||||
</div>
|
||||
{entry.avatar ? (
|
||||
<div className="w-10 h-10 rounded-full border border-pixel-gold/30 overflow-hidden">
|
||||
<img
|
||||
src={entry.avatar}
|
||||
alt={entry.username}
|
||||
className="w-full h-full object-cover"
|
||||
/>
|
||||
</div>
|
||||
) : (
|
||||
<div className="w-10 h-10 rounded-full bg-gradient-to-br from-gray-800 to-gray-900 border border-pixel-gold/30 flex items-center justify-center">
|
||||
<span className="text-pixel-gold text-xs font-bold">
|
||||
{entry.username.charAt(0).toUpperCase()}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
<span
|
||||
className={`font-bold ${
|
||||
entry.rank <= 3 ? "text-pixel-gold" : "text-white"
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
"use client";
|
||||
|
||||
import Link from "next/link";
|
||||
import { useSession, signOut } from "next-auth/react";
|
||||
import PlayerStats from "./PlayerStats";
|
||||
|
||||
export default function Navigation() {
|
||||
const { data: session } = useSession();
|
||||
|
||||
return (
|
||||
<nav className="w-full fixed top-0 left-0 z-50 px-8 py-3 bg-black/80 backdrop-blur-sm border-b border-gray-800/30">
|
||||
<div className="max-w-7xl mx-auto flex items-center justify-between">
|
||||
@@ -39,11 +42,44 @@ export default function Navigation() {
|
||||
>
|
||||
LEADERBOARD
|
||||
</Link>
|
||||
{session?.user?.role === "ADMIN" && (
|
||||
<Link
|
||||
href="/admin"
|
||||
className="text-pixel-gold hover:text-orange-400 transition text-xs font-normal uppercase tracking-widest"
|
||||
>
|
||||
ADMIN
|
||||
</Link>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Player Stats - Right */}
|
||||
<div>
|
||||
<PlayerStats />
|
||||
{/* Right Side */}
|
||||
<div className="flex items-center gap-4">
|
||||
{session ? (
|
||||
<>
|
||||
<PlayerStats />
|
||||
<button
|
||||
onClick={() => signOut()}
|
||||
className="text-gray-400 hover:text-pixel-gold transition text-xs font-normal uppercase tracking-widest"
|
||||
>
|
||||
Déconnexion
|
||||
</button>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<Link
|
||||
href="/login"
|
||||
className="text-white hover:text-pixel-gold transition text-xs font-normal uppercase tracking-widest"
|
||||
>
|
||||
Connexion
|
||||
</Link>
|
||||
<Link
|
||||
href="/register"
|
||||
className="px-4 py-2 border border-pixel-gold/50 bg-black/60 text-white uppercase text-xs tracking-widest rounded hover:bg-pixel-gold/10 hover:border-pixel-gold transition"
|
||||
>
|
||||
Inscription
|
||||
</Link>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
@@ -1,31 +1,68 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
interface PlayerStatsProps {
|
||||
username?: string;
|
||||
avatar?: string;
|
||||
hp?: number;
|
||||
maxHp?: number;
|
||||
xp?: number;
|
||||
maxXp?: number;
|
||||
level?: number;
|
||||
}
|
||||
import { useSession } from "next-auth/react";
|
||||
|
||||
// Format number with consistent locale to avoid hydration mismatch
|
||||
const formatNumber = (num: number): string => {
|
||||
return num.toLocaleString("en-US");
|
||||
};
|
||||
|
||||
export default function PlayerStats({
|
||||
username = "DragonSlayer99",
|
||||
avatar = "/got-2.jpg",
|
||||
hp = 750,
|
||||
maxHp = 1000,
|
||||
xp = 3250,
|
||||
maxXp = 5000,
|
||||
level = 42,
|
||||
}: PlayerStatsProps) {
|
||||
export default function PlayerStats() {
|
||||
const { data: session } = useSession();
|
||||
const [userData, setUserData] = useState({
|
||||
username: "Guest",
|
||||
avatar: null as string | null,
|
||||
hp: 1000,
|
||||
maxHp: 1000,
|
||||
xp: 0,
|
||||
maxXp: 5000,
|
||||
level: 1,
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (session?.user?.id) {
|
||||
fetch(`/api/users/${session.user.id}`)
|
||||
.then((res) => res.json())
|
||||
.then((data) => {
|
||||
if (data) {
|
||||
setUserData({
|
||||
username: data.username || "Guest",
|
||||
avatar: data.avatar,
|
||||
hp: data.hp || 1000,
|
||||
maxHp: data.maxHp || 1000,
|
||||
xp: data.xp || 0,
|
||||
maxXp: data.maxXp || 5000,
|
||||
level: data.level || 1,
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
// Utiliser les données de session si l'API échoue
|
||||
setUserData({
|
||||
username: session.user.username || "Guest",
|
||||
avatar: null,
|
||||
hp: 1000,
|
||||
maxHp: 1000,
|
||||
xp: 0,
|
||||
maxXp: 5000,
|
||||
level: 1,
|
||||
});
|
||||
});
|
||||
} else {
|
||||
setUserData({
|
||||
username: "Guest",
|
||||
avatar: null,
|
||||
hp: 1000,
|
||||
maxHp: 1000,
|
||||
xp: 0,
|
||||
maxXp: 5000,
|
||||
level: 1,
|
||||
});
|
||||
}
|
||||
}, [session]);
|
||||
|
||||
const { username, avatar, hp, maxHp, xp, maxXp, level } = userData;
|
||||
const [hpPercentage, setHpPercentage] = useState(0);
|
||||
const [xpPercentage, setXpPercentage] = useState(0);
|
||||
|
||||
@@ -56,12 +93,18 @@ export default function PlayerStats({
|
||||
return (
|
||||
<div className="flex items-center gap-3">
|
||||
{/* Avatar */}
|
||||
<div className="w-10 h-10 rounded-full border border-pixel-gold/20 overflow-hidden bg-gray-900">
|
||||
<img
|
||||
src={avatar}
|
||||
alt={username}
|
||||
className="w-full h-full object-cover"
|
||||
/>
|
||||
<div className="w-10 h-10 rounded-full border border-pixel-gold/20 overflow-hidden bg-gray-900 flex items-center justify-center">
|
||||
{avatar ? (
|
||||
<img
|
||||
src={avatar}
|
||||
alt={username}
|
||||
className="w-full h-full object-cover"
|
||||
/>
|
||||
) : (
|
||||
<span className="text-pixel-gold text-xs font-bold">
|
||||
{username.charAt(0).toUpperCase()}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Stats */}
|
||||
|
||||
16
components/SessionProvider.tsx
Normal file
16
components/SessionProvider.tsx
Normal file
@@ -0,0 +1,16 @@
|
||||
"use client";
|
||||
|
||||
import { SessionProvider as NextAuthSessionProvider } from "next-auth/react";
|
||||
|
||||
export default function SessionProvider({
|
||||
children,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
return (
|
||||
<NextAuthSessionProvider basePath="/api/auth">
|
||||
{children}
|
||||
</NextAuthSessionProvider>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user