"use client"; import { ExternalLink, QrCode } from "lucide-react"; import { useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; import QRCodeSvg from "react-qr-code"; import { CopyField, SettingsCard, SettingsSection, whiteButton, } from "@/components/settings/settings-parts"; import { Button } from "@/components/ui/button"; import { Dialog, DialogDescription, DialogHeader, DialogPanel, DialogPopup, DialogTitle, } from "@/components/ui/dialog"; import { authClient } from "@/lib/auth-client"; import { getPortalLink, portalPairingUri } from "@/lib/portal"; import { cn } from "@/lib/utils"; // Patient Portal section (Settings → Signing): surfaces the clinic's public // portal link so patients can open it, copy it, or scan a QR. The portal lives // at /portal/. The QR encodes a `temetro-portal:` pairing URI (relay // URL + clinic signing key) — the wallet app scans it and talks to this clinic // over the Temetro Network relay, so it works from a real phone (no localhost). export function PatientPortalSection() { const { t } = useTranslation(); const { data: activeOrg } = authClient.useActiveOrganization(); const [qrOpen, setQrOpen] = useState(false); const [qrUri, setQrUri] = useState(""); const slug = activeOrg?.slug; const origin = typeof window !== "undefined" ? window.location.origin : ""; const portalUrl = slug ? `${origin}/portal/${slug}` : ""; // Fetch the relay-based pairing descriptor for the QR (non-secret). useEffect(() => { if (!slug) { setQrUri(""); return; } let active = true; getPortalLink(slug) .then((link) => { if (active) setQrUri(portalPairingUri(link)); }) .catch(() => { if (active) setQrUri(""); }); return () => { active = false; }; }, [slug]); return (
{t("settings.portal.qrTitle")} {t("settings.portal.qrDescription")} {qrUri ? (
) : null}

{portalUrl}

); }