import { ArrowLeft, BadgeCheck, CircleAlert, Sparkles, Star } from "lucide-react"; import { useEffect, useState } from "react"; import { api, errorMessage } from "../api"; import { ActionButton } from "../components/ActionButton"; import { AuthorizationTable } from "../components/AuthorizationTable"; import { Alert, AuditTable, Badge, LoadingSurface, PageFrame, SectionHead, SplitLayout, Summary } from "../components/ui"; import { useI18n } from "../i18n"; import { displayName, displayPhone, displayUsername, formatDate, formatUnix, toInt } from "../lib/format"; import type { Navigate } from "../routing"; import type { AccountDetail } from "../types"; export function AccountDetailPage({ id, navigate }: { id: number; navigate: Navigate }) { const { t } = useI18n(); const [detail, setDetail] = useState(null); const [error, setError] = useState(""); const [busy, setBusy] = useState(false); const [months, setMonths] = useState("1"); const [starsAmount, setStarsAmount] = useState("1000"); const [freezeUntil, setFreezeUntil] = useState(() => toDateTimeLocal(new Date(Date.now() + 7 * 86400_000))); const [freezeAppealURL, setFreezeAppealURL] = useState(""); async function load() { setBusy(true); setError(""); try { const next = await api.account(id); setDetail(next); if (next.Restriction.Frozen) { if (next.Restriction.Until) { setFreezeUntil(toDateTimeLocal(new Date(next.Restriction.Until))); } setFreezeAppealURL(next.Restriction.AppealURL || ""); } } catch (err) { setError(errorMessage(err)); } finally { setBusy(false); } } useEffect(() => { void load(); }, [id]); if (error) { return {error}; } if (!detail) { return ; } const account = detail.Account; return ( navigate("/accounts")}> {t("common.backToList")}} >
{displayName(account)}
{displayUsername(account.Username) || t("account.noUsername")} ยท {displayPhone(account.Phone) || t("account.noPhone")}
{account.PremiumUntil > 0 ? {t("account.premium")} : {t("account.notPremium")}} {detail.Verified ? {t("common.verified")} : {t("account.notVerified")}} {account.Frozen ? {t("account.accountFrozen")} : {t("account.accountActive")}}
0 ? formatUnix(account.PremiumUntil) : t("common.none")} />
{detail.About &&

{detail.About}

}
} side={
{t("account.actionDock")}
} path="/api/actions/set-frozen" payload={() => ({ user_id: account.ID, frozen: true, freeze_until: new Date(freezeUntil).toISOString(), freeze_appeal_url: freezeAppealURL.trim() })} onDone={load} /> {account.Frozen && ( } path="/api/actions/set-frozen" payload={() => ({ user_id: account.ID, frozen: false })} onDone={load} /> )}
} tone="warn" path="/api/actions/grant-premium" payload={() => ({ user_id: account.ID, months: toInt(months) })} onDone={load} /> } tone="warn" path="/api/actions/grant-premium" payload={() => ({ user_id: account.ID, months: 0 })} onDone={load} /> } tone="warn" path="/api/actions/grant-stars" payload={() => ({ user_id: account.ID, amount: toInt(starsAmount) })} onDone={load} /> } tone="warn" path="/api/actions/set-verified" payload={() => ({ user_id: account.ID, verified: !detail.Verified })} onDone={load} />
} />
); } function toDateTimeLocal(date: Date): string { const local = new Date(date.getTime() - date.getTimezoneOffset() * 60_000); return local.toISOString().slice(0, 16); }