mirror of
https://github.com/R0m1k3/PleinR.git
synced 2026-10-23 23:28:04 +02:00
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:
1 parent
b4d94f2115
commit
119ad4665a
16 files changed
+1146
-25
No files matched your search
@@ -3,7 +3,7 @@ import { redirect } from "next/navigation";
|
||||
import { desc, eq } from "drizzle-orm";
|
||||
import { auth } from "@/auth";
|
||||
import { db } from "@/db";
|
||||
import { activityLog, members, membershipRequests, promotions } from "@/db/schema";
|
||||
import { activityLog, contactMessages, members, membershipRequests, promotions } from "@/db/schema";
|
||||
import { isStaff } from "@/lib/rbac";
|
||||
|
||||
export const dynamic = "force-dynamic";
|
||||
@@ -38,11 +38,12 @@ export default async function DashboardPage() {
|
||||
redirect("/backend/espace");
|
||||
}
|
||||
|
||||
const [activeMembers, livePromos, pendingPromos, requests, activity] = await Promise.all([
|
||||
const [activeMembers, livePromos, pendingPromos, requests, newMessages, activity] = await Promise.all([
|
||||
db.select({ id: members.id }).from(members).where(eq(members.status, "active")),
|
||||
db.select({ id: promotions.id }).from(promotions).where(eq(promotions.status, "live")),
|
||||
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")),
|
||||
db.select().from(activityLog).orderBy(desc(activityLog.createdAt)).limit(6),
|
||||
]);
|
||||
|
||||
@@ -63,7 +64,15 @@ export default async function DashboardPage() {
|
||||
<StatCard label="Adhérents actifs" value={activeMembers.length} hint="sur le réseau" valueColor="#13324F" hintColor="#1f8a5b" />
|
||||
<StatCard label="Promotions en ligne" value={livePromos.length} hint="visibles sur le site" />
|
||||
<StatCard label="À modérer" value={pendingCount} hint="en attente de validation" valueColor="#9a6638" hintColor="#9a6638" />
|
||||
<StatCard label="Demandes d'adhésion" value={requests.length} hint="à traiter" valueColor="#13324F" hintColor="#9a6638" />
|
||||
<Link href="/backend/demandes" style={{ textDecoration: "none" }}>
|
||||
<StatCard
|
||||
label="Demandes & messages"
|
||||
value={requests.length + newMessages.length}
|
||||
hint={`${requests.length} adhésion · ${newMessages.length} contact`}
|
||||
valueColor="#13324F"
|
||||
hintColor="#9a6638"
|
||||
/>
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
<div className="grid dash-split">
|
||||
|
||||
Reference in new issue
Block a user