Comptes adherents, boite de reception admin, edition profil

Comptes de connexion adherent
- addMember cree desormais un compte users (role member, lie a la fiche)
  avec un mot de passe temporaire genere
- Le mdp temporaire s'affiche sur la fiche admin (/backend/adherents/[id])
  jusqu'a la 1ere connexion ; bouton "Reinitialiser le mot de passe"
- 1ere connexion : changement de mot de passe force (must_change_password)
  via /backend/changer-mot-de-passe, redirection geree dans authorized()
- users += must_change_password, temp_password (migration 0003)

Boite de reception admin (consultation)
- Page /backend/demandes : demandes d'adhesion + messages de contact
  avec statuts (approuvee/rejetee, lu/archive)
- Lien sidebar + badge (nouveaux), carte tableau de bord cliquable

Espace adherent
- L'adherent peut editer sa propre fiche (updateOwnProfile) : infos,
  description, horaires, tags, image d'entete + logo
- Statut/categorie/mise a l'honneur restent reserves au staff

Promotions : moderation deja en place, inchangee.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
MichaelandClaude Opus 4.8 committed 2026-06-27 09:47:05 +02:00
1 parent b4d94f2115
commit 119ad4665a
16 files changed
+1146 -25

No files matched your search

+15 -6
View File
@@ -2,7 +2,8 @@ import { redirect } from "next/navigation";
import { eq } from "drizzle-orm";
import { auth } from "@/auth";
import { db } from "@/db";
import { promotions } from "@/db/schema";
import { contactMessages, membershipRequests, promotions } from "@/db/schema";
import { isStaff } from "@/lib/rbac";
import { BackendShell } from "./BackendShell";
export const dynamic = "force-dynamic";
@@ -17,15 +18,23 @@ export default async function BackendLayout({
redirect("/login");
}
const pendingRows = await db
.select({ id: promotions.id })
.from(promotions)
.where(eq(promotions.status, "pending"));
let pendingCount = 0;
let inboxCount = 0;
if (isStaff(session.user.role)) {
const [pendingRows, newReqs, newMsgs] = await Promise.all([
db.select({ id: promotions.id }).from(promotions).where(eq(promotions.status, "pending")),
db.select({ id: membershipRequests.id }).from(membershipRequests).where(eq(membershipRequests.status, "new")),
db.select({ id: contactMessages.id }).from(contactMessages).where(eq(contactMessages.status, "new")),
]);
pendingCount = pendingRows.length;
inboxCount = newReqs.length + newMsgs.length;
}
return (
<BackendShell
user={{ name: session.user.name ?? "Adhérent", role: session.user.role }}
pendingCount={pendingRows.length}
pendingCount={pendingCount}
inboxCount={inboxCount}
>
{children}
</BackendShell>