import { clsx, type ClassValue } from "clsx" import { twMerge } from "tailwind-merge" export function cn(...inputs: ClassValue[]) { return twMerge(clsx(inputs)) } /** * Traite le message du footer en remplaçant [LINK] par le lien vers le repository */ export function processFooterMessage(message: string, repositoryUrl: string): string { return message.replace(/\[LINK\]/g, repositoryUrl); } /** * Traite le message du footer et retourne le texte avec les liens Markdown remplacés */ export function parseFooterMessage(message: string, repositoryUrl: string): { text: string; links: Array<{ text: string; url: string; start: number; end: number }> } { const links: Array<{ text: string; url: string; start: number; end: number }> = []; let processedText = message; // Remplacer [texte](GITURL) par le texte du lien const linkRegex = /\[([^\]]+)\]\(GITURL\)/g; let match; let offset = 0; while ((match = linkRegex.exec(message)) !== null) { const linkText = match[1]; // Le texte entre crochets const fullMatch = match[0]; // Le match complet [texte](GITURL) const start = match.index + offset; const end = start + linkText.length; links.push({ text: linkText, url: repositoryUrl, start, end }); processedText = processedText.replace(fullMatch, linkText); offset += linkText.length - fullMatch.length; } return { text: processedText, links }; } /** * Génère un slug à partir d'un titre */ export function generateSlug(title: string): string { return title .toLowerCase() .normalize('NFD') .replace(/[\u0300-\u036f]/g, '') // Supprime les accents .replace(/[^a-z0-9\s-]/g, '') // Garde seulement lettres, chiffres, espaces et tirets .replace(/\s+/g, '-') // Remplace les espaces par des tirets .replace(/-+/g, '-') // Remplace les tirets multiples par un seul .trim(); } /** * Génère un ID court aléatoire */ export function generateShortId(): string { const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; let result = ''; for (let i = 0; i < 8; i++) { result += chars.charAt(Math.floor(Math.random() * chars.length)); } return result; } /** * Formate un montant en euros */ export function formatCurrency(amount: number): string { return new Intl.NumberFormat('fr-FR', { style: 'currency', currency: 'EUR', }).format(amount); } /** * Formate une date */ export function formatDate(date: Date | string): string { const dateObj = typeof date === 'string' ? new Date(date) : date; return dateObj.toLocaleDateString('fr-FR'); } /** * Valide une adresse email */ export function validateEmail(email: string): boolean { const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; return emailRegex.test(email); } /** * Nettoie le HTML pour éviter les attaques XSS */ export function sanitizeHtml(html: string): string { // Supprime les balises dangereuses return html.replace(/)<[^<]*)*<\/script>/gi, ''); }