feat: add JSON import functionality for content creation in the admin dashboard

This commit is contained in:
2026-05-17 13:23:11 +02:00
parent 8f0dc7f38c
commit 0054f731c7
10 changed files with 907 additions and 35 deletions

View File

@@ -0,0 +1,13 @@
import ImportJsonForm from '@/components/ImportJsonForm';
export const metadata = {
title: 'Import JSON - CMS Afrohub',
};
export default function ImportJsonPage() {
return (
<div className="py-8">
<ImportJsonForm />
</div>
);
}

View File

@@ -5,6 +5,7 @@ import DeleteActualitesButton from '@/components/DeleteActualitesButton';
import DeleteInterviewButton from '@/components/DeleteInterviewButton';
import DeleteEventButton from '@/components/DeleteEventButton';
import ApproveContentButton from '@/components/ApproveContentButton';
import { FileJson } from 'lucide-react';
async function getData() {
const posts = await prisma.blogPost.findMany({ orderBy: { createdAt: 'desc' } });
@@ -50,6 +51,7 @@ export default async function ActualitesCMSPage() {
<Plus className="w-4 h-4" />
Nouvel Événement
</Link>
</div>
</div>

View File

@@ -0,0 +1,64 @@
import { NextRequest, NextResponse } from 'next/server'
import prisma from '@/lib/prisma'
import { generateSlug } from '@/lib/utils'
import { revalidatePath } from 'next/cache'
export async function POST(request: NextRequest) {
try {
// Simple API Key authentication
const apiKey = request.headers.get('x-api-key')
const expectedApiKey = process.env.EXTERNAL_API_KEY
if (!expectedApiKey) {
console.error('EXTERNAL_API_KEY is not defined in environment variables.')
return NextResponse.json({ error: 'Server configuration error' }, { status: 500 })
}
if (apiKey !== expectedApiKey) {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
}
const body = await request.json()
// Validation
const { title, excerpt, content, author, imageUrl, type, tags, status, publishedAt } = body
if (!title || !excerpt || !content || !author || !imageUrl) {
return NextResponse.json({
error: 'Missing required fields: title, excerpt, content, author, imageUrl'
}, { status: 400 })
}
const rawSlug = generateSlug(title)
const slug = `${rawSlug}-${Math.random().toString(36).substring(2, 7)}`
// Si un "type" est fourni, on l'ajoute automatiquement aux tags pour le catégoriser
const finalTags = tags || []
if (type && typeof type === 'string' && !finalTags.includes(type)) {
finalTags.push(type)
}
const post = await prisma.blogPost.create({
data: {
title,
excerpt,
content,
author,
imageUrl,
slug,
tags: finalTags,
status: status || 'PUBLISHED',
publishedAt: publishedAt ? new Date(publishedAt) : new Date(Date.now() - 60000), // -1 min to ensure visibility
date: new Date()
}
})
revalidatePath('/actualites')
revalidatePath('/')
return NextResponse.json({ success: true, post }, { status: 201 })
} catch (error) {
console.error('POST /api/external/articles error:', error)
return NextResponse.json({ error: 'Internal server error' }, { status: 500 })
}
}

View File

@@ -0,0 +1,58 @@
import { NextRequest, NextResponse } from 'next/server'
import prisma from '@/lib/prisma'
import { generateSlug } from '@/lib/utils'
import { revalidatePath } from 'next/cache'
export async function POST(request: NextRequest) {
try {
// Simple API Key authentication
const apiKey = request.headers.get('x-api-key')
const expectedApiKey = process.env.EXTERNAL_API_KEY
if (!expectedApiKey) {
console.error('EXTERNAL_API_KEY is not defined in environment variables.')
return NextResponse.json({ error: 'Server configuration error' }, { status: 500 })
}
if (apiKey !== expectedApiKey) {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
}
const body = await request.json()
// Validation
const { title, description, date, location, thumbnailUrl, link, tags, status, publishedAt } = body
if (!title || !description || !date || !location || !thumbnailUrl) {
return NextResponse.json({
error: 'Missing required fields: title, description, date, location, thumbnailUrl'
}, { status: 400 })
}
const rawSlug = generateSlug(title)
const slug = `${rawSlug}-${Math.random().toString(36).substring(2, 7)}`
const event = await prisma.event.create({
data: {
title,
description,
date: new Date(date),
location,
thumbnailUrl,
link,
slug,
tags: tags || [],
status: status || 'PUBLISHED',
publishedAt: publishedAt ? new Date(publishedAt) : new Date()
}
})
revalidatePath('/evenements')
revalidatePath('/')
return NextResponse.json({ success: true, event }, { status: 201 })
} catch (error) {
console.error('POST /api/external/events error:', error)
return NextResponse.json({ error: 'Internal server error' }, { status: 500 })
}
}