feat(admin): CRUD complet carbets + gestion médias (Sprint 2)
Server actions (src/app/admin/carbets/actions.ts) avec validation Zod : - createCarbetAction → INSERT + audit + redirect /admin/carbets/[id] - updateCarbetAction → UPDATE + revalidate page publique - updateCarbetStatusAction → DRAFT/PUBLISHED/ARCHIVED - deleteCarbetAction → soft archive (bookings/reviews FK Restrict) - addMediaAction(carbetId, fd) → INSERT Media + sortOrder - removeMediaAction, reorderMediaAction (transactionnel up/down) Helpers (src/lib/admin/carbets.ts) : - listCarbetsAdmin avec filtres (q/river/status/accessType) - listDistinctRivers, listOwners, listPirogueProviders - getCarbetForEdit (include owner, provider, media, _count bookings/reviews) - Options enum pour les selects (ACCESS_TYPE, TRANSPORT_MODE, STATUS) Pages : - /admin/carbets : liste tableau dense avec recherche/filtres GET, status badge, liens vers édition, count médias/résas - /admin/carbets/new : page création avec CarbetForm - /admin/carbets/[id] : header titre+badge+actions, MediaManager, CarbetForm d'édition. Lien public si PUBLISHED. Composants admin réutilisables : - StatusBadge (DRAFT/PUBLISHED/ARCHIVED + statuts Booking) - FormField + inputCls/selectCls/textareaCls - CarbetForm (client, 5 sections : identité, localisation, accès, séjour, publication) avec useTransition + erreur + succès inline - MediaManager (client, liste + reorder ↑↓ + suppression + ajout par URL) - StatusActions (client, publier/dépublier/archiver/réactiver avec confirm) API : - GET /api/admin/carbets/[id]/media pour refresh client après mutation Audit léger en log console (JSON structuré) — Sprint 5 ajoutera la table.
This commit is contained in:
parent
3ec7a3ff10
commit
9aa0771001
11 changed files with 1202 additions and 0 deletions
17
src/app/api/admin/carbets/[id]/media/route.ts
Normal file
17
src/app/api/admin/carbets/[id]/media/route.ts
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
import { NextResponse } from "next/server";
|
||||
import { requireRole } from "@/lib/authorization";
|
||||
import { UserRole } from "@/generated/prisma/enums";
|
||||
import { prisma } from "@/lib/prisma";
|
||||
|
||||
export const dynamic = "force-dynamic";
|
||||
|
||||
export async function GET(_req: Request, ctx: { params: Promise<{ id: string }> }) {
|
||||
await requireRole([UserRole.ADMIN]);
|
||||
const { id } = await ctx.params;
|
||||
const media = await prisma.media.findMany({
|
||||
where: { carbetId: id },
|
||||
orderBy: { sortOrder: "asc" },
|
||||
select: { id: true, type: true, s3Key: true, s3Url: true, sortOrder: true },
|
||||
});
|
||||
return NextResponse.json(media);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue