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 89.7%
CSS 5.8%
HTML 4.4%
1// Auteur : Simon-Pierre Boucher — contact@spboucher.ai2// Carte de membre IMPRIMABLE au format carte bancaire (CR80 : 85,6 × 54 mm),3// recto (identité) / verso (QR + zone NFC). À imprimer à l'échelle 100 %,4// avec les arrière-plans activés, puis coller un autocollant NFC (NTAG215)5// au dos, programmé avec l'URL d'identification du membre.6import type { Metadata } from "next";7import { redirect } from "next/navigation";8import QRCode from "qrcode";9import { getSessionUser } from "@/lib/auth";10import { ensureKaId } from "@/lib/db";11import { roleCard } from "@/lib/roles";12import PrintButton from "./PrintButton";1314export const metadata: Metadata = {15 title: "Carte imprimable | Groupe KA",16 robots: { index: false },17};1819export const dynamic = "force-dynamic";2021function fmtDate(iso: string | null): string {22 if (!iso) return "";23 const d = new Date(iso.includes("T") ? iso : iso.replace(" ", "T") + "Z");24 if (Number.isNaN(d.getTime())) return "";25 return d.toLocaleDateString("fr-CA", { month: "2-digit", year: "numeric" });26}2728export default async function CarteImprimable() {29 const user = await getSessionUser();30 if (!user) redirect("/connexion?next=%2Fcompte%2Fcarte");31 const kaId = user.kaId ?? ensureKaId(user.id);32 const url = `https://www.groupe-ka.com/m/${kaId}`;33 const qr = await QRCode.toDataURL(url, {34 margin: 0,35 width: 400,36 color: { dark: "#141814", light: "#ffffff" },37 });3839 return (40 <main className="print-page mx-auto max-w-2xl px-4 pb-16 sm:px-6">41 <section className="no-print pt-10">42 <p className="kicker">Carte physique · à imprimer</p>43 <h1 className="gk-display mt-3 text-[clamp(24px,4.5vw,36px)] leading-[1.02] font-bold tracking-[-0.03em] uppercase">44 Votre carte, <span className="hl">en vrai</span>45 </h1>46 <p className="mt-3 max-w-lg text-[13.5px] text-ink-2">47 Format carte bancaire (85,6 × 54 mm). Imprimez à l'échelle48 100 % avec les arrière-plans activés, découpez le long des repères,49 et collez un autocollant NFC au dos (zone indiquée).50 </p>51 <div className="mt-5 flex flex-wrap gap-3">52 <PrintButton />53 <a href="/compte" className="btn btn-ghost">54 ← Mon compte55 </a>56 </div>57 </section>5859 <div className="print-cards mt-8 flex flex-col items-center gap-8">60 {/* ---------- RECTO ---------- */}61 <div className="pcard pcard-front">62 <div className="pcard-watermark" aria-hidden="true">63 KA64 </div>65 <div className="pcard-head">66 <span className="pcard-brand">67 Groupe <span className="pcard-ka">KA</span>68 </span>69 <span className="pcard-label">CARTE DE MEMBRE</span>70 </div>71 <div className="pcard-id">72 <span className="pcard-id-label">KA-ID</span>73 <span className="pcard-id-value">{kaId}</span>74 </div>75 <div className="pcard-foot">76 <div className="pcard-holder">77 <span className="pcard-name">{user.name || user.email}</span>78 {roleCard(user.role) && (79 <span className="pcard-role">{roleCard(user.role)}</span>80 )}81 <span className="pcard-since">82 MEMBRE DEPUIS {fmtDate(user.createdAt)}83 </span>84 </div>85 {user.avatarUrl ? (86 // eslint-disable-next-line @next/next/no-img-element87 <img className="pcard-avatar" src={user.avatarUrl} alt="" />88 ) : (89 <span className="pcard-avatar pcard-avatar-empty">90 {(user.name || user.email).charAt(0).toUpperCase()}91 </span>92 )}93 </div>94 </div>9596 {/* ---------- VERSO ---------- */}97 <div className="pcard pcard-back">98 <div className="pcard-back-left">99 {/* eslint-disable-next-line @next/next/no-img-element */}100 <img className="pcard-qr" src={qr} alt={`Code QR — ${url}`} />101 </div>102 <div className="pcard-back-right">103 <p className="pcard-back-title">104 Tapez la carte (NFC)105 <br />106 ou scannez le code107 </p>108 <p className="pcard-back-url">groupe-ka.com/m/{kaId.slice(3)}</p>109 <div className="pcard-nfc" aria-hidden="true">110 <span className="pcard-nfc-ico">)))</span> zone NFC — coller la111 puce ici112 </div>113 <p className="pcard-back-foot">114 Identité vérifiable en ligne · Lou·Ka — Immo·Ka — Vrai-Prix —115 ValoPlex — Auto·Ka — Fabri·Ka — Food·Ka116 </p>117 </div>118 </div>119 </div>120121 <p className="no-print gk-mono mt-8 text-[11px] text-ink-3">122 Astuce : imprimez sur du papier cartonné (200 g+) ou plastifiez.123 L'autocollant NFC se colle au dos, dans la zone « NFC ».124 </p>125 </main>126 );127}128