feat: implement dynamic home page with configurable blog and category settings
This commit is contained in:
@@ -40,6 +40,9 @@ model Business {
|
||||
city String?
|
||||
description String
|
||||
logoUrl String
|
||||
coverUrl String?
|
||||
coverPosition String? @default("50% 50%")
|
||||
coverZoom Float? @default(1.0)
|
||||
videoUrl String?
|
||||
contactEmail String
|
||||
contactPhone String?
|
||||
@@ -85,12 +88,6 @@ model Country {
|
||||
updatedAt DateTime @updatedAt
|
||||
}
|
||||
|
||||
enum Plan {
|
||||
STARTER
|
||||
BOOSTER
|
||||
EMPIRE
|
||||
}
|
||||
|
||||
model PricingPlan {
|
||||
id String @id @default(uuid())
|
||||
tier Plan @unique
|
||||
@@ -265,6 +262,12 @@ enum UserRole {
|
||||
ADMIN
|
||||
}
|
||||
|
||||
enum Plan {
|
||||
STARTER
|
||||
BOOSTER
|
||||
EMPIRE
|
||||
}
|
||||
|
||||
enum OfferType {
|
||||
PRODUCT
|
||||
SERVICE
|
||||
@@ -287,8 +290,17 @@ model SiteSetting {
|
||||
instagramUrl String?
|
||||
linkedinUrl String?
|
||||
footerText String? @default("© 2025 Afrohub. Tous droits réservés.")
|
||||
homeBlogShow Boolean @default(true)
|
||||
homeBlogTitle String @default("Derniers Articles")
|
||||
homeBlogSubtitle String @default("Toutes les actualités de l'entrepreneuriat africain.")
|
||||
homeBlogCount Int @default(3)
|
||||
homeBlogSelection String @default("latest")
|
||||
homeBlogIds String[] @default([])
|
||||
homeBlogCategories String[] @default([])
|
||||
homeCategories String[] @default(["Technologie & IT", "Agriculture & Agrobusiness", "Mode & Textile", "Cosmétique & Beauté"])
|
||||
updatedAt DateTime @updatedAt
|
||||
}
|
||||
|
||||
model LegalDocument {
|
||||
id String @id @default(uuid())
|
||||
type String @unique // 'CGU' or 'CGV'
|
||||
|
||||
@@ -75,3 +75,14 @@ export async function deleteBlogPost(id: string) {
|
||||
return { success: false, error: "Erreur lors de la suppression" };
|
||||
}
|
||||
}
|
||||
|
||||
export async function getBlogPosts() {
|
||||
try {
|
||||
return await prisma.blogPost.findMany({
|
||||
orderBy: { date: 'desc' }
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("Failed to fetch blog posts:", error);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,15 @@ export async function getSiteSettings() {
|
||||
twitterUrl: "",
|
||||
instagramUrl: "",
|
||||
linkedinUrl: "",
|
||||
footerText: "© 2025 Afrohub. Tous droits réservés."
|
||||
footerText: "© 2025 Afrohub. Tous droits réservés.",
|
||||
homeBlogShow: true,
|
||||
homeBlogTitle: "Derniers Articles",
|
||||
homeBlogSubtitle: "Toutes les actualités de l'entrepreneuriat africain.",
|
||||
homeBlogCount: 3,
|
||||
homeBlogSelection: "latest",
|
||||
homeBlogIds: [],
|
||||
homeBlogCategories: [],
|
||||
homeCategories: ["Technologie & IT", "Agriculture & Agrobusiness", "Mode & Textile", "Cosmétique & Beauté"]
|
||||
};
|
||||
|
||||
if (!settings) return defaultSettings;
|
||||
@@ -43,7 +51,7 @@ export async function updateSiteSettings(data: any) {
|
||||
});
|
||||
|
||||
revalidatePath('/settings');
|
||||
revalidatePath('/', 'layout'); // Revalidate all public pages because footer/header might use it
|
||||
revalidatePath('/', 'layout');
|
||||
|
||||
return { success: true, settings };
|
||||
} catch (error) {
|
||||
|
||||
@@ -1,19 +1,58 @@
|
||||
"use client";
|
||||
|
||||
import React, { useState, useEffect, useTransition } from 'react';
|
||||
import { Save, Globe, Mail, Phone, MapPin, Share2, Link as LinkIcon, Loader2 } from 'lucide-react';
|
||||
import { Save, Globe, Mail, Phone, MapPin, Share2, Link as LinkIcon, Loader2, Newspaper, Briefcase } from 'lucide-react';
|
||||
import { getSiteSettings, updateSiteSettings } from '@/app/actions/settings';
|
||||
import { toast } from 'react-hot-toast';
|
||||
import { getBlogPosts } from '@/app/actions/blog';
|
||||
|
||||
const BUSINESS_CATEGORIES = [
|
||||
"Technologie & IT",
|
||||
"Agriculture & Agrobusiness",
|
||||
"Mode & Textile",
|
||||
"Cosmétique & Beauté",
|
||||
"Services aux entreprises",
|
||||
"Restauration & Alimentation",
|
||||
"Construction & BTP",
|
||||
"Éducation & Formation",
|
||||
"Santé & Bien-être",
|
||||
"Artisanat & Déco",
|
||||
"Tourisme & Loisirs",
|
||||
"Finance & Assurance",
|
||||
"Immobilier",
|
||||
"Transport & Logistique",
|
||||
"Média & Communication",
|
||||
"Autre"
|
||||
];
|
||||
|
||||
const BLOG_CATEGORIES = [
|
||||
"Actualité",
|
||||
"Conseils",
|
||||
"Success Story",
|
||||
"Événement",
|
||||
"Formation"
|
||||
];
|
||||
|
||||
export default function SettingsPage() {
|
||||
const [isPending, startTransition] = useTransition();
|
||||
const [settings, setSettings] = useState<any>(null);
|
||||
const [allPosts, setAllPosts] = useState<any[]>([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [selectedPostIds, setSelectedPostIds] = useState<string[]>([]);
|
||||
const [selectedHomeCategories, setSelectedHomeCategories] = useState<string[]>([]);
|
||||
const [selectedBlogCategories, setSelectedBlogCategories] = useState<string[]>([]);
|
||||
|
||||
useEffect(() => {
|
||||
async function loadData() {
|
||||
const data = await getSiteSettings();
|
||||
setSettings(data);
|
||||
const [settingsData, postsData] = await Promise.all([
|
||||
getSiteSettings(),
|
||||
getBlogPosts()
|
||||
]);
|
||||
setSettings(settingsData);
|
||||
setAllPosts(postsData);
|
||||
setSelectedPostIds(settingsData?.homeBlogIds || []);
|
||||
setSelectedHomeCategories(settingsData?.homeCategories || []);
|
||||
setSelectedBlogCategories(settingsData?.homeBlogCategories || []);
|
||||
setLoading(false);
|
||||
}
|
||||
loadData();
|
||||
@@ -33,6 +72,14 @@ export default function SettingsPage() {
|
||||
instagramUrl: formData.get('instagramUrl'),
|
||||
linkedinUrl: formData.get('linkedinUrl'),
|
||||
footerText: formData.get('footerText'),
|
||||
homeBlogShow: formData.get('homeBlogShow') === 'on',
|
||||
homeBlogTitle: formData.get('homeBlogTitle'),
|
||||
homeBlogSubtitle: formData.get('homeBlogSubtitle'),
|
||||
homeBlogCount: parseInt(formData.get('homeBlogCount') as string || '3'),
|
||||
homeBlogSelection: formData.get('homeBlogSelection'),
|
||||
homeBlogIds: selectedPostIds,
|
||||
homeBlogCategories: selectedBlogCategories,
|
||||
homeCategories: selectedHomeCategories,
|
||||
};
|
||||
|
||||
startTransition(async () => {
|
||||
@@ -45,6 +92,24 @@ export default function SettingsPage() {
|
||||
});
|
||||
};
|
||||
|
||||
const togglePostId = (id: string) => {
|
||||
setSelectedPostIds(prev =>
|
||||
prev.includes(id) ? prev.filter(i => i !== id) : [...prev, id]
|
||||
);
|
||||
};
|
||||
|
||||
const toggleHomeCategory = (cat: string) => {
|
||||
setSelectedHomeCategories(prev =>
|
||||
prev.includes(cat) ? prev.filter(c => c !== cat) : [...prev, cat]
|
||||
);
|
||||
};
|
||||
|
||||
const toggleBlogCategory = (cat: string) => {
|
||||
setSelectedBlogCategories(prev =>
|
||||
prev.includes(cat) ? prev.filter(c => c !== cat) : [...prev, cat]
|
||||
);
|
||||
};
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<div className="flex items-center justify-center p-20">
|
||||
@@ -97,6 +162,149 @@ export default function SettingsPage() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Section Page d'Accueil - Secteurs */}
|
||||
<div className="bg-slate-900/50 border border-slate-700 rounded-2xl overflow-hidden">
|
||||
<div className="p-4 bg-slate-800/50 border-b border-slate-700 flex items-center gap-2">
|
||||
<Briefcase className="w-5 h-5 text-yellow-400" />
|
||||
<h2 className="font-semibold text-white">Secteurs en Vedette (Home)</h2>
|
||||
</div>
|
||||
<div className="p-6">
|
||||
<p className="text-sm text-slate-400 mb-4">Sélectionnez les secteurs d'activité à afficher sur la page d'accueil.</p>
|
||||
<div className="grid grid-cols-2 md:grid-cols-4 gap-2">
|
||||
{BUSINESS_CATEGORIES.map(cat => (
|
||||
<button
|
||||
key={cat}
|
||||
type="button"
|
||||
onClick={() => toggleHomeCategory(cat)}
|
||||
className={`text-left p-2 rounded-lg border text-xs transition-all ${
|
||||
selectedHomeCategories.includes(cat)
|
||||
? 'bg-indigo-600/20 border-indigo-500 text-indigo-300'
|
||||
: 'bg-slate-950 border-slate-700 text-slate-400 hover:border-slate-500'
|
||||
}`}
|
||||
>
|
||||
{cat}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Section Page d'Accueil - Blog */}
|
||||
<div className="bg-slate-900/50 border border-slate-700 rounded-2xl overflow-hidden">
|
||||
<div className="p-4 bg-slate-800/50 border-b border-slate-700 flex items-center gap-2">
|
||||
<Newspaper className="w-5 h-5 text-purple-400" />
|
||||
<h2 className="font-semibold text-white">Section Blog sur l'Accueil</h2>
|
||||
</div>
|
||||
<div className="p-6 space-y-6">
|
||||
<div className="flex items-center gap-3 p-3 bg-indigo-600/10 border border-indigo-500/20 rounded-xl">
|
||||
<input
|
||||
type="checkbox"
|
||||
name="homeBlogShow"
|
||||
id="homeBlogShow"
|
||||
defaultChecked={settings?.homeBlogShow}
|
||||
className="w-5 h-5 rounded border-slate-700 bg-slate-950 text-indigo-600 focus:ring-indigo-500"
|
||||
/>
|
||||
<label htmlFor="homeBlogShow" className="text-sm font-medium text-slate-300 font-bold uppercase tracking-wider">Activer cette section</label>
|
||||
</div>
|
||||
|
||||
<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 de la section</label>
|
||||
<input
|
||||
name="homeBlogTitle"
|
||||
defaultValue={settings?.homeBlogTitle}
|
||||
className="w-full bg-slate-950 border border-slate-700 rounded-xl p-3 text-white focus:outline-none focus:border-indigo-500"
|
||||
/>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<label className="text-sm font-medium text-slate-400">Sous-titre</label>
|
||||
<input
|
||||
name="homeBlogSubtitle"
|
||||
defaultValue={settings?.homeBlogSubtitle}
|
||||
className="w-full bg-slate-950 border border-slate-700 rounded-xl p-3 text-white focus:outline-none focus:border-indigo-500"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="border-t border-slate-700 pt-6">
|
||||
<label className="text-sm font-medium text-slate-400 block mb-3">Mode de sélection des articles</label>
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
|
||||
<label className={`flex flex-col p-4 rounded-xl border cursor-pointer transition-all ${settings?.homeBlogSelection === 'latest' ? 'bg-indigo-600/10 border-indigo-500' : 'bg-slate-950 border-slate-700 hover:border-slate-500'}`}>
|
||||
<input type="radio" name="homeBlogSelection" value="latest" defaultChecked={settings?.homeBlogSelection === 'latest'} className="sr-only" />
|
||||
<span className="text-white font-bold text-sm">Les plus récents</span>
|
||||
<span className="text-xs text-slate-500 mt-1">Affiche automatiquement les X derniers articles.</span>
|
||||
</label>
|
||||
<label className={`flex flex-col p-4 rounded-xl border cursor-pointer transition-all ${settings?.homeBlogSelection === 'manual' ? 'bg-indigo-600/10 border-indigo-500' : 'bg-slate-950 border-slate-700 hover:border-slate-500'}`}>
|
||||
<input type="radio" name="homeBlogSelection" value="manual" defaultChecked={settings?.homeBlogSelection === 'manual'} className="sr-only" />
|
||||
<span className="text-white font-bold text-sm">Sélection manuelle</span>
|
||||
<span className="text-xs text-slate-500 mt-1">Choisissez précisément les articles à mettre en avant.</span>
|
||||
</label>
|
||||
<label className={`flex flex-col p-4 rounded-xl border cursor-pointer transition-all ${settings?.homeBlogSelection === 'category' ? 'bg-indigo-600/10 border-indigo-500' : 'bg-slate-950 border-slate-700 hover:border-slate-500'}`}>
|
||||
<input type="radio" name="homeBlogSelection" value="category" defaultChecked={settings?.homeBlogSelection === 'category'} className="sr-only" />
|
||||
<span className="text-white font-bold text-sm">Par catégorie</span>
|
||||
<span className="text-xs text-slate-500 mt-1">Affiche les articles appartenant à certaines catégories.</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 gap-6">
|
||||
<div className="space-y-2">
|
||||
<label className="text-sm font-medium text-slate-400">Nombre maximum d'articles</label>
|
||||
<input
|
||||
type="number"
|
||||
name="homeBlogCount"
|
||||
defaultValue={settings?.homeBlogCount}
|
||||
min="1" max="12"
|
||||
className="w-full bg-slate-950 border border-slate-700 rounded-xl p-3 text-white focus:outline-none focus:border-indigo-500"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Manual Selection UI */}
|
||||
<div className="space-y-3">
|
||||
<label className="text-sm font-medium text-slate-400">Articles sélectionnés (si mode manuel)</label>
|
||||
<div className="grid grid-cols-1 gap-2 max-h-60 overflow-y-auto p-2 bg-slate-950 rounded-xl border border-slate-700">
|
||||
{allPosts.map(post => (
|
||||
<button
|
||||
key={post.id}
|
||||
type="button"
|
||||
onClick={() => togglePostId(post.id)}
|
||||
className={`flex items-center justify-between p-3 rounded-lg text-sm transition-all ${
|
||||
selectedPostIds.includes(post.id)
|
||||
? 'bg-indigo-600/20 border-indigo-500/50 text-white'
|
||||
: 'text-slate-400 hover:bg-slate-900'
|
||||
}`}
|
||||
>
|
||||
<span>{post.title}</span>
|
||||
{selectedPostIds.includes(post.id) && <span className="text-indigo-400 font-bold text-xs">SÉLECTIONNÉ</span>}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Category Selection UI */}
|
||||
<div className="space-y-3">
|
||||
<label className="text-sm font-medium text-slate-400">Catégories d'articles (si mode catégorie)</label>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{BLOG_CATEGORIES.map(cat => (
|
||||
<button
|
||||
key={cat}
|
||||
type="button"
|
||||
onClick={() => toggleBlogCategory(cat)}
|
||||
className={`px-4 py-2 rounded-full border text-xs transition-all ${
|
||||
selectedBlogCategories.includes(cat)
|
||||
? 'bg-purple-600 border-purple-500 text-white'
|
||||
: 'bg-slate-950 border-slate-700 text-slate-400 hover:border-slate-500'
|
||||
}`}
|
||||
>
|
||||
{cat}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Section Contact */}
|
||||
<div className="bg-slate-900/50 border border-slate-700 rounded-2xl overflow-hidden">
|
||||
<div className="p-4 bg-slate-800/50 border-b border-slate-700 flex items-center gap-2">
|
||||
|
||||
77
app/page.tsx
77
app/page.tsx
@@ -3,15 +3,19 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import Link from 'next/link';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { Search, MapPin, Briefcase, TrendingUp, Loader2 } from 'lucide-react';
|
||||
import { CATEGORIES, Business } from '../types';
|
||||
import { Search, MapPin, Briefcase, TrendingUp, Loader2, ArrowRight } from 'lucide-react';
|
||||
import { CATEGORIES, Business, BlogPost } from '../types';
|
||||
import BusinessCard from '../components/BusinessCard';
|
||||
import { useUser } from '../components/UserProvider';
|
||||
|
||||
const HomePage = () => {
|
||||
const router = useRouter();
|
||||
const { settings } = useUser();
|
||||
const [searchTerm, setSearchTerm] = useState('');
|
||||
const [featuredBusinesses, setFeaturedBusinesses] = useState<Business[]>([]);
|
||||
const [posts, setPosts] = useState<BlogPost[]>([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [loadingPosts, setLoadingPosts] = useState(true);
|
||||
|
||||
useEffect(() => {
|
||||
const fetchFeatured = async () => {
|
||||
@@ -28,6 +32,21 @@ const HomePage = () => {
|
||||
}
|
||||
};
|
||||
fetchFeatured();
|
||||
|
||||
const fetchPosts = async () => {
|
||||
try {
|
||||
const res = await fetch('/api/blog');
|
||||
const data = await res.json();
|
||||
if (Array.isArray(data)) {
|
||||
setPosts(data);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error fetching blog posts:', error);
|
||||
} finally {
|
||||
setLoadingPosts(false);
|
||||
}
|
||||
};
|
||||
fetchPosts();
|
||||
}, []);
|
||||
|
||||
const handleSearch = (e: React.FormEvent) => {
|
||||
@@ -77,7 +96,7 @@ const HomePage = () => {
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-16">
|
||||
<h2 className="text-3xl font-bold text-gray-900 mb-8 font-serif">Secteurs en vedette</h2>
|
||||
<div className="grid grid-cols-2 md:grid-cols-4 gap-4">
|
||||
{CATEGORIES.slice(0, 4).map((cat, idx) => (
|
||||
{(settings?.homeCategories || CATEGORIES.slice(0, 4)).map((cat: string, idx: number) => (
|
||||
<Link
|
||||
key={idx}
|
||||
href={`/annuaire?category=${encodeURIComponent(cat)}`}
|
||||
@@ -118,6 +137,58 @@ const HomePage = () => {
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Blog Section */}
|
||||
{settings?.homeBlogShow !== false && (
|
||||
<div className="py-16">
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div className="flex justify-between items-end mb-8">
|
||||
<div>
|
||||
<h2 className="text-3xl font-bold text-gray-900 font-serif">{settings?.homeBlogTitle || "Derniers Articles"}</h2>
|
||||
<p className="text-gray-500 mt-2">{settings?.homeBlogSubtitle || "Toutes les actualités de l'entrepreneuriat africain."}</p>
|
||||
</div>
|
||||
<Link href="/blog" className="text-brand-600 font-medium hover:text-brand-700 flex items-center">
|
||||
Voir tout le blog <ArrowRight className="w-4 h-4 ml-1" />
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
{loadingPosts ? (
|
||||
<div className="flex justify-center py-12">
|
||||
<Loader2 className="w-10 h-10 text-brand-600 animate-spin" />
|
||||
</div>
|
||||
) : (
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
|
||||
{posts
|
||||
.filter(post => {
|
||||
if (settings?.homeBlogSelection === 'manual') {
|
||||
return settings.homeBlogIds?.includes(post.id);
|
||||
}
|
||||
if (settings?.homeBlogSelection === 'category') {
|
||||
return post.tags?.some((tag: string) => settings.homeBlogCategories?.includes(tag));
|
||||
}
|
||||
return true;
|
||||
})
|
||||
.slice(0, settings?.homeBlogCount || 3)
|
||||
.map(post => (
|
||||
<Link key={post.id} href={`/blog/${post.slug || post.id}`} className="group bg-white rounded-xl shadow-sm border border-gray-100 overflow-hidden hover:shadow-md transition-all">
|
||||
<div className="h-48 overflow-hidden">
|
||||
<img src={post.imageUrl} alt={post.title} className="w-full h-full object-cover group-hover:scale-105 transition-transform duration-500" />
|
||||
</div>
|
||||
<div className="p-6">
|
||||
<h3 className="text-xl font-bold text-gray-900 mb-2 line-clamp-2 group-hover:text-brand-600 transition-colors">{post.title}</h3>
|
||||
<p className="text-gray-500 text-sm line-clamp-3 mb-4">{post.excerpt}</p>
|
||||
<div className="flex items-center justify-between mt-auto pt-4 border-t border-gray-50">
|
||||
<span className="text-xs font-medium text-gray-400">{new Date(post.date).toLocaleDateString('fr-FR')}</span>
|
||||
<span className="text-brand-600 font-bold text-xs">Lire la suite →</span>
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -11,7 +11,15 @@ export async function getSiteSettings() {
|
||||
twitterUrl: "#",
|
||||
instagramUrl: "#",
|
||||
linkedinUrl: "#",
|
||||
footerText: "© 2025 Afrohub. Tous droits réservés."
|
||||
footerText: "© 2025 Afrohub. Tous droits réservés.",
|
||||
homeBlogShow: true,
|
||||
homeBlogTitle: "Derniers Articles",
|
||||
homeBlogSubtitle: "Toutes les actualités de l'entrepreneuriat africain.",
|
||||
homeBlogCount: 3,
|
||||
homeBlogSelection: "latest",
|
||||
homeBlogIds: [],
|
||||
homeBlogCategories: [],
|
||||
homeCategories: ["Technologie & IT", "Agriculture & Agrobusiness", "Mode & Textile", "Cosmétique & Beauté"]
|
||||
};
|
||||
|
||||
try {
|
||||
|
||||
@@ -256,6 +256,14 @@ model SiteSetting {
|
||||
instagramUrl String?
|
||||
linkedinUrl String?
|
||||
footerText String? @default("© 2025 Afrohub. Tous droits réservés.")
|
||||
homeBlogShow Boolean @default(true)
|
||||
homeBlogTitle String @default("Derniers Articles")
|
||||
homeBlogSubtitle String @default("Toutes les actualités de l'entrepreneuriat africain.")
|
||||
homeBlogCount Int @default(3)
|
||||
homeBlogSelection String @default("latest")
|
||||
homeBlogIds String[] @default([])
|
||||
homeBlogCategories String[] @default([])
|
||||
homeCategories String[] @default(["Technologie & IT", "Agriculture & Agrobusiness", "Mode & Textile", "Cosmétique & Beauté"])
|
||||
updatedAt DateTime @updatedAt
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user