// ----------------------------------------------------------------------------- // House-Ka — Homes-for-sale aggregator (Canada outside Québec) // Author: Simon-Pierre Boucher — contact@spboucher.ai // pages/Account.tsx : user profile — Groupe KA membership card (KA-ID), // read-only hub profile (edited at groupe-ka.com), favourites, actions // ----------------------------------------------------------------------------- import { useEffect, useState } from "react"; import { Link, useNavigate } from "react-router-dom"; import { FavItem, fetchFavorites, fetchMe, logout } from "../api"; import type { Socials, User } from "../api"; import { Ico } from "../components/Icons"; const fmtEpoch = (ts: number | null | undefined): string => { if (!ts) return "—"; return new Date(ts * 1000).toLocaleDateString("en-CA", { day: "numeric", month: "long", year: "numeric", }); }; const SOCIAL_BASE: Record = { instagram: "https://www.instagram.com/", facebook: "https://www.facebook.com/", x: "https://x.com/", linkedin: "https://www.linkedin.com/in/", tiktok: "https://www.tiktok.com/@", youtube: "https://www.youtube.com/@", }; /** "@handle" or "handle" -> full platform URL; URLs kept as-is */ function socialUrl(key: string, value: string): string { const v = value.trim(); if (/^https?:\/\//i.test(v)) return v; if (key === "website") return `https://${v}`; return (SOCIAL_BASE[key] ?? "https://") + v.replace(/^@/, ""); } const SOCIAL_FIELDS: { key: keyof Socials; label: string }[] = [ { key: "instagram", label: "Instagram" }, { key: "facebook", label: "Facebook" }, { key: "x", label: "X (Twitter)" }, { key: "linkedin", label: "LinkedIn" }, { key: "tiktok", label: "TikTok" }, { key: "youtube", label: "YouTube" }, ]; /** Profile managed at the Groupe KA HUB — READ-ONLY (edit it once at * groupe-ka.com/compte, visible on every Groupe KA platform). */ function HubProfileSection({ me }: { me: User }) { const socialLinks = SOCIAL_FIELDS.filter((s) => (me.socials?.[s.key] ?? "").trim()); return (

My Groupe KA profile

{me.bio &&

{me.bio}

}
{(me.job_title || me.company) && ( {[me.job_title, me.company].filter(Boolean).join(" · ")} )} {me.city && {me.city}} {me.age != null && {me.age} yrs} {me.website && ( Website ↗ )} {socialLinks.map((s) => ( {s.label} ))}
Edit my profile on groupe-ka.com ↗

Your profile is managed at the group level: enter it once, visible on every Groupe KA platform.

); } /** House-Ka favourites from the "My Ka universe" central store. */ function FavouritesSection() { const [items, setItems] = useState(null); useEffect(() => { fetchFavorites().then((f) => setItems(f.items)).catch(() => setItems([])); }, []); if (items === null || items.length === 0) return null; return (

My favourites ({items.length})

{items.map((f) => ( {f.price_label} {f.title}{f.subtitle ? ` — ${f.subtitle}` : ""} See the listing ))}

Your ♥ favourites follow you across the whole Groupe KA ecosystem — manage them on groupe-ka.com/mon-ka.

); } export default function AccountPage() { const [me, setMe] = useState(undefined); // undefined = loading const [copied, setCopied] = useState(false); const nav = useNavigate(); useEffect(() => { document.title = "My account | House-Ka"; fetchMe().then((r) => setMe(r.user)).catch(() => setMe(null)); }, []); const copyKaId = async () => { if (!me?.ka_id) return; try { await navigator.clipboard.writeText(me.ka_id); setCopied(true); setTimeout(() => setCopied(false), 1800); } catch { /* clipboard unavailable: too bad */ } }; if (me === undefined) { return
Loading…
; } if (me === null) { return (
My account

Sign in for your profile.

Sign in with your KA ID account — you get your member identifier, valid across the whole Groupe KA ecosystem.

Sign in with KA ID
); } return (
My account

{me.name ? <>Hi, {me.name.split(" ")[0]}. : <>Your profile.}

{/* ——— Groupe KA membership card ——— */}
Groupe KA Membership card · Groupe KA
KA-ID {me.ka_id || "—"}
{me.name || me.email} {me.role_label && ( {me.role_label} )} Member since {fmtEpoch(me.created_at)}
{me.picture && ( )}
{/* ——— Details ——— */}
Name {me.name || "—"}
Email {me.email || "—"}
Member ID {me.ka_id || me.sub}
Sign-in {me.provider === "ka-id" ? "KA ID (groupe-ka.com)" : "Google account"}
{me.city && (
City {me.city}
)} {me.role_label && (
Status {me.role_label}
)}
Member since {fmtEpoch(me.created_at)}
Last sign-in {fmtEpoch(me.last_login)}
{me.profile_source === "groupe-ka" && } {me.profile_source === "groupe-ka" && me.public && me.public_url && (

Your public profile:{" "} {me.public_url.replace(/^https?:\/\//, "")} {" "} — visibility is managed on groupe-ka.com/compte.

)}

Your KA-ID is your unique identifier across the{" "} Groupe KA {" "} ecosystem — it follows you on every platform of the group. House-Ka keeps only the information on this profile; nothing else, never sold.

{/* ——— Actions ——— */}
); }