-
-
- setEditName(e.target.value)} />
-
-
-
-
setEditPassword(e.target.value)} placeholder="Laisser vide pour ne pas changer" />
+
+ ⚙️ Configuration — {isAdmin ? "compte admin" : "compte membre"}
+
+
+
+
+ setEditName(e.target.value)} />
+
+
+
+
+
+
+
+
+
+
+ setEditPassword(e.target.value)}
+ placeholder="Nouveau mot de passe (laisser vide pour ne pas changer)"
+ />
+
+
+ {error &&
{error}
}
+
-
+ {canDelete && (
+
+ )}
)}
diff --git a/app/api/admin/classes/route.ts b/app/api/admin/classes/route.ts
new file mode 100644
index 0000000..6722fbb
--- /dev/null
+++ b/app/api/admin/classes/route.ts
@@ -0,0 +1,26 @@
+import { NextRequest, NextResponse } from "next/server";
+import { prisma } from "@/lib/prisma";
+import { requireAdmin } from "@/lib/session";
+
+export async function PATCH(req: NextRequest) {
+ const admin = await requireAdmin();
+ if (!admin) return NextResponse.json({ error: "Admin requis" }, { status: 403 });
+
+ const { id, capacity, booked, isFull } = await req.json();
+ if (!id) return NextResponse.json({ error: "id requis" }, { status: 400 });
+
+ try {
+ const slot = await prisma.classSlot.update({
+ where: { id },
+ data: {
+ ...(capacity !== undefined ? { capacity: Math.max(0, Number(capacity)) } : {}),
+ ...(booked !== undefined ? { booked: Math.max(0, Number(booked)) } : {}),
+ ...(isFull !== undefined ? { isFull: !!isFull } : {}),
+ },
+ });
+ return NextResponse.json(slot);
+ } catch (error) {
+ console.error(error);
+ return NextResponse.json({ error: "Erreur" }, { status: 500 });
+ }
+}
\ No newline at end of file
diff --git a/app/api/admin/users/[id]/route.ts b/app/api/admin/users/[id]/route.ts
index d049361..63ba38a 100644
--- a/app/api/admin/users/[id]/route.ts
+++ b/app/api/admin/users/[id]/route.ts
@@ -1,6 +1,7 @@
import { NextRequest, NextResponse } from "next/server";
import { prisma } from "@/lib/prisma";
import { requireAdmin } from "@/lib/session";
+import bcrypt from "bcryptjs";
export async function PATCH(req: NextRequest) {
const admin = await requireAdmin();
@@ -10,7 +11,7 @@ export async function PATCH(req: NextRequest) {
if (!id) return NextResponse.json({ error: "id requis" }, { status: 400 });
const allowed = [
- "name", "email", "isMuayThai", "isYoga", "role", "phone", "avatar"
+ "name", "email", "isMuayThai", "isYoga", "role", "phone", "avatar", "password"
];
const updateData: any = {};
@@ -20,6 +21,16 @@ export async function PATCH(req: NextRequest) {
if (updateData.email) updateData.email = updateData.email.toLowerCase();
+ if (updateData.password) {
+ if (updateData.password.length < 6) {
+ return NextResponse.json(
+ { error: "Le mot de passe doit contenir au moins 6 caractères" },
+ { status: 400 }
+ );
+ }
+ updateData.password = await bcrypt.hash(updateData.password, 10);
+ }
+
try {
if (updateData.isMuayThai === true) {
await prisma.muayThaiProfile.upsert({
diff --git a/app/api/classes/route.ts b/app/api/classes/route.ts
new file mode 100644
index 0000000..b08e3fe
--- /dev/null
+++ b/app/api/classes/route.ts
@@ -0,0 +1,13 @@
+import { NextResponse } from "next/server";
+import { prisma } from "@/lib/prisma";
+
+export async function GET() {
+ try {
+ const slots = await prisma.classSlot.findMany({
+ orderBy: { label: "asc" },
+ });
+ return NextResponse.json(slots);
+ } catch {
+ return NextResponse.json({ error: "Erreur" }, { status: 500 });
+ }
+}
\ No newline at end of file
diff --git a/app/layout.tsx b/app/layout.tsx
index d05bdbb..9b3a295 100644
--- a/app/layout.tsx
+++ b/app/layout.tsx
@@ -10,6 +10,11 @@ export const metadata: Metadata = {
description:
"JuanitoSport - Muay Thai & Yog4Fight à Bazainville. Cours d'essai gratuit, ambiance familiale.",
manifest: "/manifest.json",
+ icons: {
+ icon: "/favicon.svg",
+ shortcut: "/favicon.svg",
+ apple: "/icons/apple-touch-icon.png",
+ },
appleWebApp: {
capable: true,
statusBarStyle: "black-translucent",
diff --git a/app/muay-thai/page.tsx b/app/muay-thai/page.tsx
index d1332c1..1028641 100644
--- a/app/muay-thai/page.tsx
+++ b/app/muay-thai/page.tsx
@@ -2,6 +2,7 @@
import Header from "@/components/Header";
import Link from "next/link";
+import Availability from "@/components/Availability";
const EQUIPMENT = [
{ icon: "🪢", name: "Corde à sauter" },
@@ -42,27 +43,14 @@ export default function MuayThaiPage() {
📅 Horaires
-
+
Cours de Muay Thai à{" "}
BAZAINVILLE (salle
"l'atelier")
-
-
- Mardi
-
- 19h00 – 21h00
-
-
-
- Vendredi
-
- 20h00 – 22h00
-
-
-
-
- À partir du 12 septembre
+
+
+ 🏁 Reprise des cours ce mardi 8 septembre
diff --git a/app/page.tsx b/app/page.tsx
index ff54aa4..8e661e7 100644
--- a/app/page.tsx
+++ b/app/page.tsx
@@ -29,41 +29,41 @@ export default function LandingPage() {