Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 9s
CI - Lint, Typecheck & Test / quality-assurance (pull_request) Failing after 1m57s
Build & Deploy / 🧪 QA (push) Failing after 2m3s
Build & Deploy / 🏗️ Build (push) Has been skipped
Build & Deploy / 🚀 Deploy (push) Has been skipped
Build & Deploy / 🧪 Post-Deploy Verification (push) Has been skipped
Build & Deploy / 🔔 Notify (push) Successful in 2s
43 lines
1.1 KiB
TypeScript
43 lines
1.1 KiB
TypeScript
'use client';
|
|
|
|
import React, { useState, useEffect } from 'react';
|
|
|
|
interface ObfuscatedPhoneProps {
|
|
phone: string;
|
|
className?: string;
|
|
children?: React.ReactNode;
|
|
}
|
|
|
|
/**
|
|
* A component that helps protect phone numbers from simple spambots.
|
|
* It stays obscured during SSR and hydrates into a functional tel: link on the client.
|
|
*/
|
|
export default function ObfuscatedPhone({ phone, className = '', children }: ObfuscatedPhoneProps) {
|
|
const [mounted, setMounted] = useState(false);
|
|
|
|
useEffect(() => {
|
|
// eslint-disable-next-line react-hooks/set-state-in-effect
|
|
setMounted(true);
|
|
}, []);
|
|
|
|
// Format phone number for tel: link (remove spaces, etc.)
|
|
const telLink = `tel:${phone.replace(/\s+/g, '')}`;
|
|
|
|
if (!mounted) {
|
|
// Show a placeholder or obscured version during SSR
|
|
// e.g. +49 881 925 [at] 37298
|
|
const obscured = phone.replace(/(\d{3})(\d{3})$/, ' $1...$2');
|
|
return (
|
|
<span className={className} aria-hidden="true">
|
|
{children || obscured}
|
|
</span>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<a href={telLink} className={className}>
|
|
{children || phone}
|
|
</a>
|
|
);
|
|
}
|