Vrai-Prix — l'évaluation du vrai prix des propriétés résidentielles au Québec.
TypeScript 90.2%
JavaScript 3.5%
Python 3.4%
CSS 1.9%
HTML 0.6%
1// Auteur : Simon-Pierre Boucher — contact@spboucher.ai2/**3 * Bouton compte de l'en-tête (KA ID — SSO du Groupe KA).4 * · Déconnecté : pilule « KA ID » → /api/auth/ka/login?next=<page courante>5 * · Connecté : avatar (ou initiale) + prénom → /compte6 * Composant client : interroge /api/auth/me au montage (session cookie httpOnly).7 */8"use client";9import { useEffect, useState } from "react";10import Link from "next/link";11import { usePathname } from "next/navigation";12import { useLang } from "./LangContext";1314type MeUser = {15 ka_id: string;16 email: string;17 name: string;18 picture: string;19 provider: string;20};2122export default function AccountButton() {23 const { lang } = useLang();24 const fr = lang === "fr";25 const path = usePathname();26 // undefined = chargement (on ne montre rien pour éviter le clignotement)27 const [user, setUser] = useState<MeUser | null | undefined>(undefined);2829 useEffect(() => {30 let alive = true;31 fetch("/api/auth/me")32 .then((r) => r.json())33 .then((d) => alive && setUser(d?.user ?? null))34 .catch(() => alive && setUser(null));35 return () => {36 alive = false;37 };38 }, [path]);3940 if (user === undefined) {41 return <span className="min-h-[36px] w-[52px]" aria-hidden="true" />;42 }4344 if (user === null) {45 return (46 <a47 href={`/api/auth/ka/login?next=${encodeURIComponent(path || "/")}`}48 className="vp-mono inline-flex min-h-[36px] items-center rounded-[2px] bg-ink px-3.5 py-1.5 text-[11px] font-medium uppercase tracking-[0.1em] text-paper transition-colors hover:bg-accent"49 title={fr ? "Se connecter avec KA ID" : "Sign in with KA ID"}50 >51 KA ID52 </a>53 );54 }5556 const prenom = (user.name || user.email).split(" ")[0];57 return (58 <Link59 href="/compte"60 className="group inline-flex min-h-[36px] items-center gap-2 py-1"61 title={fr ? "Mon compte — carte de membre Groupe KA" : "My account — Groupe KA member card"}62 >63 {user.picture ? (64 // eslint-disable-next-line @next/next/no-img-element65 <img66 src={user.picture}67 alt=""68 referrerPolicy="no-referrer"69 className="h-7 w-7 rounded-full object-cover grayscale transition-[filter] group-hover:grayscale-0"70 />71 ) : (72 <span className="vp-display flex h-7 w-7 items-center justify-center rounded-full bg-ink text-[13px] font-bold text-paper">73 {prenom.charAt(0).toUpperCase()}74 </span>75 )}76 <span className="vp-display max-w-[92px] truncate border-b-2 border-transparent text-[13px] font-bold text-ink group-hover:border-accent">77 {prenom}78 </span>79 </Link>80 );81}82