Files
vocero-client/frontend-s2s/src/components/Account.tsx
T

90 lines
2.8 KiB
TypeScript

import { LogIn } from "lucide-react";
import { useEffect, useRef, useState } from "react";
import type { AccountInfo } from "../lib/contracts";
export function Account({ account }: { account: AccountInfo | null }) {
const [open, setOpen] = useState(false);
const ref = useRef<HTMLDivElement>(null);
useEffect(() => {
if (!open) {
return;
}
const close = (event: PointerEvent) => {
if (event.target instanceof Node && !ref.current?.contains(event.target)) {
setOpen(false);
}
};
const escape = (event: KeyboardEvent) => {
if (event.key === "Escape") {
setOpen(false);
}
};
document.addEventListener("pointerdown", close);
document.addEventListener("keydown", escape);
return () => {
document.removeEventListener("pointerdown", close);
document.removeEventListener("keydown", escape);
};
}, [open]);
if (!account?.enabled) {
return null;
}
if (!account.loggedIn) {
return account.auth && account.loginUrl ? (
<a className="signin-pill" href={account.loginUrl}>
<LogIn size={16} />
<span>Iniciar sesión</span>
</a>
) : null;
}
const unlimited = account.tier === "pro" || account.tier === "org";
const remaining =
account.remainingSec == null || unlimited
? "Sin límite"
: `${String(Math.floor(account.remainingSec / 60))}:${String(Math.round(account.remainingSec) % 60).padStart(2, "0")} restantes hoy`;
return (
<div className="account" ref={ref}>
<button
className="account-chip"
type="button"
aria-expanded={open}
onClick={() => {
setOpen(!open);
}}
>
{account.avatar ? (
<img className="account-avatar" src={account.avatar} alt="" />
) : (
<span className="account-avatar account-avatar-fallback">{account.username?.[0]?.toUpperCase() ?? "?"}</span>
)}
<span className="account-handle">{account.username}</span>
{unlimited && <span className="account-pro">{account.tier === "pro" ? "PRO" : "EQUIPO"}</span>}
</button>
{open && (
<div className="account-pop">
<div className="account-pop-row account-pop-name">{account.username}</div>
<div className="account-pop-row account-pop-meta">
<span>{remaining}</span>
</div>
{!unlimited && (
<a
className="account-pop-link"
href="https://huggingface.co/subscribe/pro"
target="_blank"
rel="noopener noreferrer"
>
Pasar a PRO
</a>
)}
{account.logoutUrl && (
<a className="account-pop-link account-signout" href={account.logoutUrl}>
Cerrar sesión
</a>
)}
</div>
)}
</div>
);
}