spb/groupe-ka Public
Groupe KA — site du holding + KA ID (compte unique & SSO des 7 plateformes). Next.js 16, SQLite, Google & Apple login.
TypeScript 93.9%
CSS 6%
1// Auteur : Simon-Pierre Boucher — contact@spboucher.ai2"use client";34import { useEffect, useState } from "react";56type Me = {7 name: string;8 avatarUrl: string | null;9} | null;1011export default function UserButton({12 variant = "full",13}: {14 /** « icon » : pastille ronde seule (header mobile) ; « full » : avatar + prénom. */15 variant?: "full" | "icon";16}) {17 const [me, setMe] = useState<Me>(null);18 const [loaded, setLoaded] = useState(false);1920 useEffect(() => {21 fetch("/api/auth/me")22 .then((r) => r.json())23 .then((d) => setMe(d.user))24 .catch(() => setMe(null))25 .finally(() => setLoaded(true));26 }, []);2728 if (variant === "icon") {29 const connected = loaded && me;30 return (31 <a32 href={connected ? "/compte" : "/connexion"}33 aria-label={connected ? "Mon compte KA ID" : "Se connecter"}34 className="flex h-11 w-11 items-center justify-center rounded-md border-[1.5px] border-ink bg-surface shadow-[3px_3px_0_rgba(20,24,20,0.25)] transition-colors hover:bg-lime"35 >36 {connected && me!.avatarUrl ? (37 // eslint-disable-next-line @next/next/no-img-element38 <img39 src={me!.avatarUrl}40 alt=""41 width={26}42 height={26}43 className="h-[26px] w-[26px] rounded-full border border-ink object-cover"44 />45 ) : connected ? (46 <span className="gk-display flex h-[26px] w-[26px] items-center justify-center rounded-full bg-ink text-[12px] font-bold text-lime">47 {me!.name.slice(0, 1).toUpperCase()}48 </span>49 ) : (50 <svg width="19" height="19" viewBox="0 0 24 24" aria-hidden="true">51 <path52 fill="none"53 stroke="currentColor"54 strokeWidth="2"55 strokeLinecap="round"56 d="M12 12a4.2 4.2 0 1 0 0-8.4 4.2 4.2 0 0 0 0 8.4Zm-7.4 8.4c.9-3.6 3.9-5.7 7.4-5.7s6.5 2.1 7.4 5.7"57 />58 </svg>59 )}60 </a>61 );62 }6364 if (loaded && me) {65 return (66 <a67 href="/compte"68 className="gk-display inline-flex items-center gap-2 rounded-full border-[1.5px] border-ink px-3 py-[5px] text-[13.5px] font-bold text-ink transition-colors hover:bg-lime"69 aria-label="Mon compte KA ID"70 >71 {me.avatarUrl ? (72 // eslint-disable-next-line @next/next/no-img-element73 <img74 src={me.avatarUrl}75 alt=""76 width={22}77 height={22}78 className="h-[22px] w-[22px] rounded-full border border-ink object-cover"79 />80 ) : (81 <span className="flex h-[22px] w-[22px] items-center justify-center rounded-full bg-ink text-[11px] text-lime">82 {me.name.slice(0, 1).toUpperCase()}83 </span>84 )}85 {me.name.split(" ")[0]}86 </a>87 );88 }8990 return (91 <a92 href="/connexion"93 className="gk-display inline-block rounded-full border-[1.5px] border-ink px-4 py-[7px] text-[13.5px] font-bold text-ink transition-colors hover:bg-lime"94 >95 KA ID96 </a>97 );98}99