synchronisation du contenu avec la DB et amélioration du CMS

- Migration du blog et des interviews des données mockées vers PostgreSQL (Prisma).
- Refonte des pages publiques en Server Components pour de meilleures performances/SEO.
- Intégration d'un éditeur de texte riche (React Quill) avec titres H1-H6 et séparateurs.
- Correction des erreurs de validation Prisma liées aux paramètres asynchrones (Next.js 15+).
- Correction des problèmes d'affichage des modales de suspension via React Portals.
- Installation de @tailwindcss/typography et correction du débordement de texte (break-words).
- Implémentation des actions de modération (suspension/révocation) pour les utilisateurs et boutiques.
This commit is contained in:
2026-04-12 18:59:20 +02:00
parent b73939d381
commit 887030ee47
84 changed files with 5577 additions and 15128 deletions

View File

@@ -1,11 +1,12 @@
"use client";
import { useTransition } from 'react';
import { useTransition, useState } from 'react';
import { useRouter } from 'next/navigation';
import { createBlogPost, updateBlogPost } from '@/app/actions/blog';
import { Loader2, ArrowLeft, Save } from 'lucide-react';
import Link from 'next/link';
import { toast } from 'react-hot-toast';
import RichTextEditor from './RichTextEditor';
interface Props {
initialData?: {
@@ -21,6 +22,7 @@ interface Props {
export default function BlogForm({ initialData }: Props) {
const router = useRouter();
const [isPending, startTransition] = useTransition();
const [content, setContent] = useState(initialData?.content || '');
const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
@@ -28,7 +30,7 @@ export default function BlogForm({ initialData }: Props) {
const data = {
title: formData.get('title') as string,
excerpt: formData.get('excerpt') as string,
content: formData.get('content') as string,
content: content,
author: formData.get('author') as string,
imageUrl: formData.get('imageUrl') as string,
};
@@ -110,12 +112,9 @@ export default function BlogForm({ initialData }: Props) {
<div className="space-y-2">
<label className="text-sm font-medium text-slate-400">Contenu de l'article</label>
<textarea
name="content"
defaultValue={initialData?.content}
required
rows={12}
className="w-full bg-slate-900 border border-slate-700 rounded-lg p-3 text-white focus:outline-none focus:border-indigo-500 font-serif leading-relaxed"
<RichTextEditor
value={content}
onChange={setContent}
placeholder="Rédigez votre article ici..."
/>
</div>