feat: add admin dashboard and core API routes with Docker configuration

This commit is contained in:
2026-10-29 19:46:37 +01:00
parent 2fdabe1dfd
commit 4f4856d9dc
89 changed files with 1984 additions and 1034 deletions

View File

@@ -5,6 +5,7 @@ import React from 'react';
import Link from 'next/link';
import { usePathname } from 'next/navigation';
import { Facebook, Twitter, Instagram, Linkedin } from 'lucide-react';
import { safeUrl } from '@/lib/utils';
interface FooterProps {
settings?: any;
@@ -49,7 +50,7 @@ const Footer = ({ settings }: FooterProps) => {
{socialLinks.map((social, index) => (
<a
key={index}
href={social.url}
href={safeUrl(social.url)}
target="_blank"
rel="noopener noreferrer"
className="p-2 rounded-full border border-gray-800 text-gray-400 hover:text-brand-500 hover:border-brand-500/50 hover:bg-white/5 transition-all"

View File

@@ -3,6 +3,7 @@
import React, { useState, useEffect } from 'react';
import Link from 'next/link';
import { Search, MapPin, ChevronLeft, ChevronRight, ArrowRight } from 'lucide-react';
import { safeUrl } from '@/lib/utils';
interface HomeSlide {
id: string;
@@ -130,7 +131,7 @@ const HomeSlider = ({ slides, onSearch }: Props) => {
<div className="flex flex-wrap gap-4 items-center">
<Link
href={slide.type === 'BUSINESS' ? `/annuaire/${slide.business?.id}` : (slide.linkUrl || '#')}
href={slide.type === 'BUSINESS' ? `/annuaire/${slide.business?.id}` : safeUrl(slide.linkUrl)}
className="inline-flex items-center gap-2 bg-brand-600 text-white px-8 py-4 rounded-lg font-bold hover:bg-brand-700 transition-all shadow-lg shadow-brand-600/20 hover:scale-105"
>
{slide.type === 'BUSINESS' ? 'Voir la fiche' : 'En savoir plus'}

View File

@@ -22,9 +22,27 @@ export function UserProvider({ children }: { children: ReactNode }) {
React.useEffect(() => {
const savedUser = localStorage.getItem('afro_user');
if (savedUser) {
setUser(JSON.parse(savedUser));
try {
setUser(JSON.parse(savedUser));
} catch {
localStorage.removeItem('afro_user');
}
}
// Synchronize user session from signed HttpOnly cookie
fetch('/api/users/me')
.then(async res => {
if (res.ok) {
const freshUser = await res.json();
setUser(freshUser);
localStorage.setItem('afro_user', JSON.stringify(freshUser));
} else if (res.status === 401) {
setUser(null);
localStorage.removeItem('afro_user');
}
})
.catch(err => console.error('Error verifying session:', err));
// Fetch settings
fetch('/api/settings')
.then(res => res.json())
@@ -47,6 +65,9 @@ export function UserProvider({ children }: { children: ReactNode }) {
const logout = () => {
setUser(null);
localStorage.removeItem('afro_user');
fetch('/api/auth/logout', { method: 'POST' }).catch(err =>
console.error('Error logging out:', err)
);
};
return (