import { useCallback, useState } from 'react'; import { useSeoMeta } from '@unhead/react'; import { Activity, AlertTriangle, CheckCircle2, Loader2, RefreshCw, Server, ShieldAlert } from 'lucide-react'; import { Button } from '@/components/ui/button'; import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; import { useCurrentUser } from '@/hooks/useCurrentUser'; import { isAdminPubkey } from '@/lib/admins'; import { useTranslation } from '@/contexts/language'; const OPS_URL = 'https://relay.skate-spots.org/ops'; interface OpsStatus { updatedAt: string; relay: { local: string; public: string }; version: string; cordn: { announces20m: number; rejects15m: number }; storage: { diskPct: number; memAvailMiB: number; mediaBytes: number }; tls: { days: number }; services: Record; issues: string[]; } function Metric({ label, value, good = true }: { label: string; value: string; good?: boolean }) { return (

{label}

{value}

); } /** * Admin-only, read-only relay operator snapshot. The endpoint requires a * NIP-98 signature from one of the two relay admin pubkeys; this page never * exposes a restart/config action. * * Labels are intentionally English-only: this is an internal operator tool, * not a public product surface. */ export default function OpsPage() { const { user } = useCurrentUser(); const { t } = useTranslation(); const [status, setStatus] = useState(null); const [error, setError] = useState(null); const [loading, setLoading] = useState(false); useSeoMeta({ title: 'Operator status — SkateSpots', description: 'Private relay health snapshot.', }); const load = useCallback(async () => { if (!user) return; setLoading(true); setError(null); try { const event = await user.signer.signEvent({ kind: 27235, content: '', created_at: Math.floor(Date.now() / 1000), tags: [ ['u', OPS_URL], ['method', 'GET'], ['expiration', String(Math.floor(Date.now() / 1000) + 120)], ], }); const response = await fetch(OPS_URL, { headers: { authorization: `Nostr ${btoa(JSON.stringify(event))}` }, }); const body = await response.json().catch(() => ({})); if (!response.ok) throw new Error(body.error || `HTTP ${response.status}`); setStatus(body as OpsStatus); } catch (err) { setError(err instanceof Error ? err.message : String(err)); } finally { setLoading(false); } }, [user]); if (!isAdminPubkey(user?.pubkey)) { return (

Admins only

This page is restricted to the two relay admin npubs.

); } return (
Private operator surface

Relay status

Read-only snapshot, signed by your admin npub.

{error && (
{error}
)} {!status ? (

Load the signed snapshot to inspect the relay.

With Amber this requires one approval.

) : ( <>
{status.issues.length === 0 ? ( <> All checks passing ) : ( <> {status.issues.length} issue(s) )} Updated {new Date(status.updatedAt).toLocaleString()}
300} /> 14} /> 0} />
Services {Object.entries(status.services).map(([name, up]) => (
{name}
))}
{status.issues.length > 0 && ( Issues {status.issues.map((issue) =>

• {issue}

)}
)} )}

{t('settingsUi.settingsPage.advanced')} · read-only

); }