/** * Convert a title into a URL-safe slug. * Lowercases, strips accents, replaces non-alphanumerics with hyphens, * collapses repeated hyphens, and trims leading/trailing hyphens. */ export function slugify(title: string): string { return title .toLowerCase() .normalize('NFKD') .replace(/[\u0300-\u036f]/g, '') .replace(/[^a-z0-9]+/g, '-') .replace(/-+/g, '-') .replace(/^-|-$/g, ''); } /** * Generate a slug from a title that does not collide with any of the * provided existing slugs. Appends -2, -3, ... when needed. */ export function uniqueSlug(title: string, existingSlugs: string[]): string { const base = slugify(title) || 'event'; const taken = new Set(existingSlugs); if (!taken.has(base)) return base; let n = 2; while (taken.has(`${base}-${n}`)) n++; return `${base}-${n}`; }