111 lines
3.5 KiB
TypeScript
111 lines
3.5 KiB
TypeScript
'use client';
|
|
import { useState, useEffect } from 'react';
|
|
import { PROJECT_CONFIG } from '@/lib/project.config';
|
|
import { settingsService } from '@/lib/services';
|
|
import { parseFooterMessage } from '@/lib/utils';
|
|
|
|
interface FooterProps {
|
|
className?: string;
|
|
variant?: 'home' | 'public';
|
|
}
|
|
|
|
export default function Footer({ className = '', variant = 'public' }: FooterProps) {
|
|
const [footerMessage, setFooterMessage] = useState('');
|
|
const [loading, setLoading] = useState(true);
|
|
|
|
useEffect(() => {
|
|
const loadFooterMessage = async () => {
|
|
try {
|
|
// Vérifier si Supabase est configuré avant d'essayer d'accéder aux paramètres
|
|
const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL;
|
|
const supabaseAnonKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY;
|
|
|
|
if (!supabaseUrl || !supabaseAnonKey || supabaseUrl === 'https://placeholder.supabase.co') {
|
|
// Supabase n'est pas configuré, utiliser le message par défaut
|
|
setFooterMessage('Développé avec ❤️ pour faciliter la démocratie participative - [Logiciel libre et open source](GITURL) et transparent pour tous');
|
|
setLoading(false);
|
|
return;
|
|
}
|
|
|
|
const message = await settingsService.getStringValue(
|
|
'footer_message',
|
|
'Développé avec ❤️ pour faciliter la démocratie participative - [Logiciel libre et open source](GITURL) et transparent pour tous'
|
|
);
|
|
setFooterMessage(message);
|
|
} catch (error) {
|
|
// Ignorer silencieusement les erreurs et utiliser le message par défaut
|
|
setFooterMessage('Développé avec ❤️ pour faciliter la démocratie participative - [Logiciel libre et open source](GITURL) et transparent pour tous');
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
loadFooterMessage();
|
|
}, []);
|
|
|
|
if (loading) {
|
|
return null; // Ne pas afficher le bas de page pendant le chargement
|
|
}
|
|
|
|
const { text: processedText, links } = parseFooterMessage(footerMessage, PROJECT_CONFIG.repository.url);
|
|
|
|
// Pour la page d'accueil, utiliser un style plus simple
|
|
if (variant === 'home') {
|
|
return (
|
|
<div className={`text-center mt-16 pb-8 ${className}`}>
|
|
<p className="text-slate-600 dark:text-slate-400 text-lg">
|
|
{processedText}
|
|
</p>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
// Pour les pages publiques, utiliser un style plus discret avec liens
|
|
const renderFooterText = () => {
|
|
if (links.length === 0) {
|
|
return processedText;
|
|
}
|
|
|
|
// Créer un tableau d'éléments avec les liens
|
|
const elements: React.ReactNode[] = [];
|
|
let lastIndex = 0;
|
|
|
|
links.forEach((link, index) => {
|
|
// Ajouter le texte avant le lien
|
|
if (link.start > lastIndex) {
|
|
elements.push(processedText.slice(lastIndex, link.start));
|
|
}
|
|
|
|
// Ajouter le lien
|
|
elements.push(
|
|
<a
|
|
key={`link-${index}`}
|
|
href={link.url}
|
|
target="_blank"
|
|
rel="noopener noreferrer"
|
|
className="text-gray-500 hover:text-gray-700 underline"
|
|
>
|
|
{link.text}
|
|
</a>
|
|
);
|
|
|
|
lastIndex = link.end;
|
|
});
|
|
|
|
// Ajouter le texte restant
|
|
if (lastIndex < processedText.length) {
|
|
elements.push(processedText.slice(lastIndex));
|
|
}
|
|
|
|
return elements;
|
|
};
|
|
|
|
return (
|
|
<div className={`text-center mt-16 pb-20 ${className}`}>
|
|
<p className="text-gray-400 text-sm">
|
|
{renderFooterText()}
|
|
</p>
|
|
</div>
|
|
);
|
|
}
|