portfolio_v2/app/cv/reveal-phone.tsx
franck ec005b1622 Refonte du portfolio : profil GitHub, CV, SEO, export statique
- Accueil façon profil GitHub (bio, homelab, projets épinglés, parcours)
  avec fond dégradé et panneaux liquid glass
- /cv : consultable en ligne (thème sombre), imprimable en PDF propre
  (thème clair, 1 page) ; numéro de téléphone non scrapable
- Pages d'erreur 404 / 500 / global-error animées (GSAP)
- Métadonnées : Open Graph, Twitter, JSON-LD Person, sitemap, robots
  (allowlist Google + bots d'aperçu, reste bloqué)
- Images OG et favicon en PNG statiques
- Contenu du CV : Saint-Paul, langues, expériences détaillées
- Export statique (output: export) + DEPLOY.md
- Retrait de l'indicateur de dev Next.js et des fichiers du starter

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01T3hzMzvei419MwkKFZkvMX
2026-09-08 19:33:47 +04:00

52 lines
1.4 KiB
TypeScript

"use client";
import { useState, useSyncExternalStore } from "react";
// Numéro inversé : jamais présent tel quel dans le HTML rendu côté serveur,
// et pas de correspondance grep directe. Il n'est reconstruit et injecté dans
// le DOM qu'après hydratation (client), pour l'impression du CV et le clic
// « Afficher ». Les harvesters qui n'exécutent pas de JS ne récupèrent rien.
const REV = "78 45 06 396 262+";
const subscribe = () => () => {};
export default function RevealPhone() {
const isClient = useSyncExternalStore(
subscribe,
() => true,
() => false,
);
const [shown, setShown] = useState(false);
if (!isClient) {
return <span className="text-muted">Afficher le numéro</span>;
}
const display = REV.split("").reverse().join("");
const tel = display.replace(/\s/g, "");
const link = (
<a href={`tel:${tel}`} className="text-accent hover:underline">
{display}
</a>
);
return (
<>
{/* Visible uniquement à l'impression / export PDF */}
<span className="hidden print:inline">{link}</span>
<span className="print:hidden">
{shown ? (
link
) : (
<button
type="button"
onClick={() => setShown(true)}
className="text-accent hover:underline"
>
Afficher le numéro
</button>
)}
</span>
</>
);
}