feat(admin): Sprint 4 — Organisations CE + Prestataires pirogue (CRUD)

This commit is contained in:
Claude Integration 2026-05-31 21:36:22 +00:00
parent 19b4ff8293
commit 99f3bbdc71
14 changed files with 1141 additions and 0 deletions

View file

@ -0,0 +1,60 @@
import "server-only";
import { Prisma } from "@/generated/prisma/client";
import { prisma } from "@/lib/prisma";
export type AdminOrgFilters = { q?: string };
export type AdminOrgListItem = {
id: string;
name: string;
slug: string;
description: string | null;
createdAt: Date;
membersCount: number;
};
export async function listOrganizationsAdmin(filters: AdminOrgFilters = {}): Promise<AdminOrgListItem[]> {
const where: Prisma.OrganizationWhereInput = {};
if (filters.q) {
where.OR = [
{ name: { contains: filters.q, mode: "insensitive" } },
{ slug: { contains: filters.q, mode: "insensitive" } },
{ description: { contains: filters.q, mode: "insensitive" } },
];
}
const rows = await prisma.organization.findMany({
where,
orderBy: [{ name: "asc" }],
take: 200,
select: {
id: true,
name: true,
slug: true,
description: true,
createdAt: true,
_count: { select: { members: true } },
},
});
return rows.map((o) => ({
id: o.id,
name: o.name,
slug: o.slug,
description: o.description,
createdAt: o.createdAt,
membersCount: o._count.members,
}));
}
export async function getOrganizationForAdmin(id: string) {
return prisma.organization.findUnique({
where: { id },
include: {
members: {
orderBy: [{ role: "asc" }, { lastName: "asc" }],
select: { id: true, firstName: true, lastName: true, email: true, role: true, isActive: true },
},
},
});
}

View file

@ -0,0 +1,84 @@
import "server-only";
import { Prisma } from "@/generated/prisma/client";
import { prisma } from "@/lib/prisma";
export type AdminPirogueFilters = {
q?: string;
river?: string;
active?: "yes" | "no";
};
export type AdminPirogueListItem = {
id: string;
name: string;
contactEmail: string | null;
contactPhone: string | null;
rivers: string[];
active: boolean;
carbetsCount: number;
updatedAt: Date;
};
export async function listPirogueProvidersAdmin(filters: AdminPirogueFilters = {}): Promise<AdminPirogueListItem[]> {
const where: Prisma.PirogueProviderWhereInput = {};
if (filters.q) {
where.OR = [
{ name: { contains: filters.q, mode: "insensitive" } },
{ contactEmail: { contains: filters.q, mode: "insensitive" } },
{ description: { contains: filters.q, mode: "insensitive" } },
];
}
if (filters.river) where.rivers = { has: filters.river };
if (filters.active === "yes") where.active = true;
if (filters.active === "no") where.active = false;
const rows = await prisma.pirogueProvider.findMany({
where,
orderBy: [{ active: "desc" }, { name: "asc" }],
take: 200,
select: {
id: true,
name: true,
contactEmail: true,
contactPhone: true,
rivers: true,
active: true,
updatedAt: true,
_count: { select: { carbets: true } },
},
});
return rows.map((p) => ({
id: p.id,
name: p.name,
contactEmail: p.contactEmail,
contactPhone: p.contactPhone,
rivers: p.rivers,
active: p.active,
carbetsCount: p._count.carbets,
updatedAt: p.updatedAt,
}));
}
export async function getPirogueProviderForAdmin(id: string) {
return prisma.pirogueProvider.findUnique({
where: { id },
include: {
carbets: {
orderBy: [{ updatedAt: "desc" }],
take: 20,
select: { id: true, title: true, slug: true, river: true, status: true, updatedAt: true },
},
},
});
}
export async function listPirogueRivers(): Promise<string[]> {
const rows = await prisma.pirogueProvider.findMany({
where: { active: true },
select: { rivers: true },
});
const set = new Set<string>();
for (const r of rows) for (const x of r.rivers) set.add(x);
return Array.from(set).sort();
}