feat: implement core platform features including business directory, admin dashboard, authentication, and API infrastructure
Some checks failed
Build and Push App / build (push) Failing after 16m2s

This commit is contained in:
2026-04-18 22:10:19 +02:00
parent 6ec1a3ae84
commit 3e2063e4fa
89 changed files with 4405 additions and 967 deletions

View File

@@ -61,3 +61,21 @@ export async function removeFeaturedBusiness(id: string) {
return { success: false, error: "Erreur lors de la suppression" };
}
}
export async function getPendingVerificationCount() {
try {
return await prisma.business.count({
where: {
isActive: true,
verified: false,
isSuspended: false,
plan: {
in: ['BOOSTER', 'EMPIRE']
}
}
});
} catch (error) {
console.error("Failed to get pending count:", error);
return 0;
}
}

View File

@@ -0,0 +1,60 @@
"use server";
import { prisma } from '@/lib/prisma';
import { revalidatePath } from 'next/cache';
export async function getCountries() {
try {
return await prisma.country.findMany({
orderBy: { name: 'asc' }
});
} catch (error) {
console.error('Error fetching countries:', error);
return [];
}
}
export async function addCountry(data: { name: string, code: string, flag?: string }) {
try {
const country = await prisma.country.create({
data: {
name: data.name,
code: data.code.toUpperCase(),
flag: data.flag || null,
isActive: true
}
});
revalidatePath('/countries');
return { success: true, country };
} catch (error) {
console.error('Error adding country:', error);
return { success: false, error: 'Ce pays ou code existe déjà.' };
}
}
export async function deleteCountry(id: string) {
try {
await prisma.country.delete({
where: { id }
});
revalidatePath('/countries');
return { success: true };
} catch (error) {
console.error('Error deleting country:', error);
return { success: false, error: 'Erreur lors de la suppression.' };
}
}
export async function toggleCountryStatus(id: string, isActive: boolean) {
try {
await prisma.country.update({
where: { id },
data: { isActive }
});
revalidatePath('/countries');
return { success: true };
} catch (error) {
console.error('Error toggling country status:', error);
return { success: false };
}
}

View File

@@ -0,0 +1,31 @@
"use server";
import { prisma } from '@/lib/prisma';
import { revalidatePath } from 'next/cache';
export async function getLegalDocument(type: 'CGU' | 'CGV') {
try {
return await prisma.legalDocument.findUnique({
where: { type }
});
} catch (error) {
console.error(`Error fetching ${type}:`, error);
return null;
}
}
export async function updateLegalDocument(type: 'CGU' | 'CGV', title: string, content: string) {
try {
const doc = await prisma.legalDocument.upsert({
where: { type },
update: { title, content },
create: { type, title, content }
});
revalidatePath('/legal');
return { success: true, doc };
} catch (error) {
console.error(`Error updating ${type}:`, error);
return { success: false, error: "Erreur lors de la mise à jour" };
}
}

View File

@@ -50,3 +50,31 @@ export async function updateReportStatus(id: string, status: 'RESOLVED' | 'DISMI
return { success: false, error: "Erreur lors de la mise à jour" };
}
}
export async function getPendingRatings() {
return await prisma.rating.findMany({
where: { status: 'PENDING' },
include: {
user: {
select: { id: true, name: true, email: true }
},
business: {
select: { id: true, name: true }
}
},
orderBy: { createdAt: 'desc' }
});
}
export async function updateRatingStatus(id: string, status: 'APPROVED' | 'REJECTED') {
try {
await prisma.rating.update({
where: { id },
data: { status }
});
revalidatePath('/moderation');
return { success: true };
} catch (error) {
return { success: false, error: "Erreur lors de la mise à jour de l'avis" };
}
}

View File

@@ -0,0 +1,54 @@
"use server";
import { prisma } from '@/lib/prisma';
import { revalidatePath } from 'next/cache';
export async function getPricingPlans() {
try {
return await prisma.pricingPlan.findMany({
orderBy: { offerLimit: 'asc' }
});
} catch (error) {
console.error('Error fetching pricing plans:', error);
return [];
}
}
export async function updatePricingPlanDetail(id: string, data: any) {
try {
await prisma.pricingPlan.update({
where: { id },
data: {
name: data.name,
priceXOF: data.priceXOF,
priceEUR: data.priceEUR,
description: data.description,
features: data.features, // Expected to be string[]
offerLimit: parseInt(data.offerLimit),
recommended: !!data.recommended,
color: data.color
}
});
revalidatePath('/plans');
return { success: true };
} catch (error) {
console.error('Error updating pricing plan detail:', error);
return { success: false, error: 'Erreur lors de la mise à jour des détails du forfait.' };
}
}
export async function updateBusinessPlan(id: string, plan: 'STARTER' | 'BOOSTER' | 'EMPIRE') {
try {
await prisma.business.update({
where: { id },
data: { plan }
});
revalidatePath('/entrepreneurs');
return { success: true };
} catch (error) {
console.error('Error updating business plan:', error);
return { success: false, error: 'Erreur lors de la mise à jour du forfait.' };
}
}

View File

@@ -11,16 +11,16 @@ export async function getSiteSettings() {
// Default fallback values if not initialized
const defaultSettings = {
siteName: "Afropreunariat",
siteName: "Afrohub",
siteSlogan: "La plateforme de référence pour l'entrepreneuriat africain.",
contactEmail: "support@afropreunariat.com",
contactEmail: "support@afrohub.com",
contactPhone: "+225 00 00 00 00 00",
address: "Abidjan, Côte d'Ivoire",
facebookUrl: "",
twitterUrl: "",
instagramUrl: "",
linkedinUrl: "",
footerText: "© 2025 Afropreunariat. Tous droits réservés."
footerText: "© 2025 Afrohub. Tous droits réservés."
};
if (!settings) return defaultSettings;