feat: add user accounts, authentication, and game history with Prisma 7

- Implement user registration and login with NextAuth v5 (email/password, JWT)
- Add authentication modal in UI with login/register tabs
- Create user profile screen showing game statistics and history
- Integrate Prisma 7 ORM with SQLite database for data persistence
- Store game results (mode, path, clicks, time) in database
- Auto-save completed games only when user is authenticated
- Separate business logic into reusable hooks (useSoloGame, useMultiGame)
- Organize UI into composable screen components (HomeScreen, SoloScreen, ProfileScreen, etc)
- Add session persistence across F5 refresh for solo and multiplayer
- Style auth modal, account button, and profile stats dashboard
This commit is contained in:
jessy-david-dev
2026-04-10 15:43:07 +02:00
parent 6a75e80e6c
commit dc09658fdb
44 changed files with 12371 additions and 91 deletions
+58
View File
@@ -0,0 +1,58 @@
import { NextRequest, NextResponse } from "next/server";
import { auth } from "../../../auth";
import { prisma } from "../../../lib/prisma";
// POST /api/games — sauvegarder une partie
export async function POST(req: NextRequest) {
const session = await auth();
if (!session?.user?.id) {
return NextResponse.json({ error: "Non connecté" }, { status: 401 });
}
const { mode, startArticle, targetArticle, path, clicks, timeSeconds, won } =
await req.json() as {
mode: string;
startArticle: string;
targetArticle: string;
path: string[];
clicks: number;
timeSeconds: number;
won: boolean;
};
const game = await prisma.game.create({
data: {
userId: session.user.id,
mode,
startArticle,
targetArticle,
path: JSON.stringify(path),
clicks,
timeSeconds,
won,
},
});
return NextResponse.json({ id: game.id });
}
// GET /api/games — historique de l'utilisateur connecté
export async function GET() {
const session = await auth();
if (!session?.user?.id) {
return NextResponse.json({ error: "Non connecté" }, { status: 401 });
}
const games = await prisma.game.findMany({
where: { userId: session.user.id },
orderBy: { playedAt: "desc" },
take: 50,
});
return NextResponse.json(
games.map((g) => ({
...g,
path: JSON.parse(g.path) as string[],
}))
);
}