feat: initialize Prisma schema and scaffold core application modules including auth, blogs, events, and business directories
Some checks failed
Build and Push App / build (push) Failing after 47s
Some checks failed
Build and Push App / build (push) Failing after 47s
This commit is contained in:
@@ -16,6 +16,10 @@ interface Props {
|
||||
content: string;
|
||||
author: string;
|
||||
imageUrl: string;
|
||||
slug?: string | null;
|
||||
tags?: string[];
|
||||
metaTitle?: string | null;
|
||||
metaDescription?: string | null;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -29,10 +33,14 @@ export default function BlogForm({ initialData }: Props) {
|
||||
const formData = new FormData(event.currentTarget);
|
||||
const data = {
|
||||
title: formData.get('title') as string,
|
||||
slug: formData.get('slug') as string,
|
||||
excerpt: formData.get('excerpt') as string,
|
||||
content: content,
|
||||
author: formData.get('author') as string,
|
||||
imageUrl: formData.get('imageUrl') as string,
|
||||
tags: (formData.get('tags') as string)?.split(',').map(t => t.trim()).filter(t => t !== ''),
|
||||
metaTitle: formData.get('metaTitle') as string,
|
||||
metaDescription: formData.get('metaDescription') as string,
|
||||
};
|
||||
|
||||
startTransition(async () => {
|
||||
@@ -51,7 +59,7 @@ export default function BlogForm({ initialData }: Props) {
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="max-w-4xl mx-auto">
|
||||
<div className="max-w-4xl mx-auto pb-20">
|
||||
<div className="mb-8 flex items-center justify-between">
|
||||
<div className="flex items-center gap-4">
|
||||
<Link href="/blog" className="p-2 bg-slate-800 rounded-lg text-slate-400 hover:text-white transition-colors">
|
||||
@@ -63,60 +71,112 @@ export default function BlogForm({ initialData }: Props) {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<form onSubmit={handleSubmit} className="card space-y-6">
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
<form onSubmit={handleSubmit} className="space-y-8">
|
||||
<div className="card space-y-6">
|
||||
<h2 className="text-xl font-semibold text-white border-b border-slate-800 pb-4">Informations Générales</h2>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
<div className="space-y-2">
|
||||
<label className="text-sm font-medium text-slate-400">Titre</label>
|
||||
<input
|
||||
name="title"
|
||||
defaultValue={initialData?.title}
|
||||
required
|
||||
className="w-full bg-slate-900 border border-slate-700 rounded-lg p-3 text-white focus:outline-none focus:border-indigo-500"
|
||||
placeholder="Ex: L'essor de la Tech en Afrique"
|
||||
/>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<label className="text-sm font-medium text-slate-400">Auteur</label>
|
||||
<input
|
||||
name="author"
|
||||
defaultValue={initialData?.author}
|
||||
required
|
||||
className="w-full bg-slate-900 border border-slate-700 rounded-lg p-3 text-white focus:outline-none focus:border-indigo-500"
|
||||
placeholder="Ex: Jean Dupont"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<label className="text-sm font-medium text-slate-400">Titre</label>
|
||||
<label className="text-sm font-medium text-slate-400">URL de l'image</label>
|
||||
<input
|
||||
name="title"
|
||||
defaultValue={initialData?.title}
|
||||
name="imageUrl"
|
||||
defaultValue={initialData?.imageUrl}
|
||||
required
|
||||
className="w-full bg-slate-900 border border-slate-700 rounded-lg p-3 text-white focus:outline-none focus:border-indigo-500"
|
||||
placeholder="Ex: L'essor de la Tech en Afrique"
|
||||
placeholder="https://images.unsplash.com/..."
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<label className="text-sm font-medium text-slate-400">Auteur</label>
|
||||
<input
|
||||
name="author"
|
||||
defaultValue={initialData?.author}
|
||||
<label className="text-sm font-medium text-slate-400">Extrait (Excerpt)</label>
|
||||
<textarea
|
||||
name="excerpt"
|
||||
defaultValue={initialData?.excerpt}
|
||||
required
|
||||
rows={2}
|
||||
className="w-full bg-slate-900 border border-slate-700 rounded-lg p-3 text-white focus:outline-none focus:border-indigo-500"
|
||||
placeholder="Ex: Jean Dupont"
|
||||
placeholder="Un court résumé de l'article..."
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<label className="text-sm font-medium text-slate-400">Contenu de l'article</label>
|
||||
<RichTextEditor
|
||||
value={content}
|
||||
onChange={setContent}
|
||||
placeholder="Rédigez votre article ici..."
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<label className="text-sm font-medium text-slate-400">URL de l'image</label>
|
||||
<input
|
||||
name="imageUrl"
|
||||
defaultValue={initialData?.imageUrl}
|
||||
required
|
||||
className="w-full bg-slate-900 border border-slate-700 rounded-lg p-3 text-white focus:outline-none focus:border-indigo-500"
|
||||
placeholder="https://images.unsplash.com/..."
|
||||
/>
|
||||
</div>
|
||||
{/* SEO SECTION */}
|
||||
<div className="card space-y-6">
|
||||
<h2 className="text-xl font-semibold text-white border-b border-slate-800 pb-4">Optimisation SEO</h2>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
<div className="space-y-2">
|
||||
<label className="text-sm font-medium text-slate-400">Slug (URL personnalisée)</label>
|
||||
<input
|
||||
name="slug"
|
||||
defaultValue={initialData?.slug || ''}
|
||||
className="w-full bg-slate-900 border border-slate-700 rounded-lg p-3 text-white focus:outline-none focus:border-indigo-500"
|
||||
placeholder="ex: lessor-de-la-tech-afrique"
|
||||
/>
|
||||
<p className="text-xs text-slate-500 italic">Laissez vide pour générer automatiquement à partir du titre.</p>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<label className="text-sm font-medium text-slate-400">Mots-clés (tags, séparés par des virgules)</label>
|
||||
<input
|
||||
name="tags"
|
||||
defaultValue={initialData?.tags?.join(', ') || ''}
|
||||
className="w-full bg-slate-900 border border-slate-700 rounded-lg p-3 text-white focus:outline-none focus:border-indigo-500"
|
||||
placeholder="tech, afrique, innovation"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<label className="text-sm font-medium text-slate-400">Extrait (Excerpt)</label>
|
||||
<textarea
|
||||
name="excerpt"
|
||||
defaultValue={initialData?.excerpt}
|
||||
required
|
||||
rows={2}
|
||||
className="w-full bg-slate-900 border border-slate-700 rounded-lg p-3 text-white focus:outline-none focus:border-indigo-500"
|
||||
placeholder="Un court résumé de l'article..."
|
||||
/>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<label className="text-sm font-medium text-slate-400">Meta Titre (SEO)</label>
|
||||
<input
|
||||
name="metaTitle"
|
||||
defaultValue={initialData?.metaTitle || ''}
|
||||
className="w-full bg-slate-900 border border-slate-700 rounded-lg p-3 text-white focus:outline-none focus:border-indigo-500"
|
||||
placeholder="Titre optimisé pour les moteurs de recherche"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<label className="text-sm font-medium text-slate-400">Contenu de l'article</label>
|
||||
<RichTextEditor
|
||||
value={content}
|
||||
onChange={setContent}
|
||||
placeholder="Rédigez votre article ici..."
|
||||
/>
|
||||
<div className="space-y-2">
|
||||
<label className="text-sm font-medium text-slate-400">Meta Description (SEO)</label>
|
||||
<textarea
|
||||
name="metaDescription"
|
||||
defaultValue={initialData?.metaDescription || ''}
|
||||
rows={3}
|
||||
className="w-full bg-slate-900 border border-slate-700 rounded-lg p-3 text-white focus:outline-none focus:border-indigo-500"
|
||||
placeholder="Description optimisée pour les moteurs de recherche (max 160 caractères)..."
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="pt-4">
|
||||
|
||||
Reference in New Issue
Block a user