import { useEffect, useState } from "react"; import { useParams } from "react-router-dom"; import { apiClient } from "@shared/api/client"; type Farm = { id: string; name: string; hub_site_id: string; status: string; last_seen: string | null; }; type Member = { user_id: string; role: string; email: string | null; farm_ids: string[]; }; type SyncStatus = { outbox_pending: number; conflicts_pending: number; hubs: Array; }; export default function EnterpriseCabinetPage(): JSX.Element { const { slug } = useParams(); const [farms, setFarms] = useState([]); const [members, setMembers] = useState([]); const [enterpriseId, setEnterpriseId] = useState(""); const [syncStatus, setSyncStatus] = useState(null); const [pairCode, setPairCode] = useState(""); const [pairingBusy, setPairingBusy] = useState(false); const [inviteEmail, setInviteEmail] = useState(""); const [inviteRole, setInviteRole] = useState("viewer"); useEffect(() => { void (async () => { const ents = await apiClient.get>("/api/v1/enterprise/enterprises"); const ent = ents.find((e) => e.slug === slug); if (!ent) return; setEnterpriseId(ent.id); const [list, status, mems] = await Promise.all([ apiClient.get(`/api/v1/enterprise/enterprises/${ent.id}/farms`), apiClient.get(`/api/v1/enterprise/enterprises/${ent.id}/sync-status`), apiClient.get(`/api/v1/enterprise/enterprises/${ent.id}/members`), ]); setFarms(list); setSyncStatus(status); setMembers(mems); })(); }, [slug]); async function startPairing(): Promise { if (!enterpriseId) return; setPairingBusy(true); try { const resp = await apiClient.post<{ code: string }>( `/api/v1/enterprise/pair/start`, { enterprise_id: enterpriseId, farm_name: "New hub" }, ); setPairCode(resp.code); } finally { setPairingBusy(false); } } async function inviteMember(): Promise { if (!enterpriseId || !inviteEmail.trim()) return; await apiClient.post(`/api/v1/enterprise/enterprises/${enterpriseId}/members`, { email: inviteEmail.trim(), role: inviteRole, }); const mems = await apiClient.get(`/api/v1/enterprise/enterprises/${enterpriseId}/members`); setMembers(mems); setInviteEmail(""); } return (

Enterprise: {slug}

Pairing, members, farms, sync status. Conflicts — в K-hub «Мультисервер».

Pair hub

{pairCode ? (

Pairing code: {pairCode} (enter on hub admin within 15 min)

) : null}

Members

    {members.map((m) => (
  • {m.email ?? m.user_id} — {m.role} {m.farm_ids.length ? ` · farms: ${m.farm_ids.length}` : ""}
  • ))}
setInviteEmail(e.target.value)} />

Sync status

{syncStatus ? (
  • Outbox pending: {syncStatus.outbox_pending}
  • Conflicts pending: {syncStatus.conflicts_pending}
  • {syncStatus.hubs.map((h) => (
  • {h.name}: lag {h.sync_lag ?? 0} {h.last_seen ? ` · ${h.last_seen}` : " · offline"}
  • ))}
) : (

Loading…

)}

Farms

    {farms.map((f) => (
  • {f.name} ({f.hub_site_id}) — {f.status} {f.last_seen ? ` · last seen ${f.last_seen}` : " · offline"}
  • ))}
{enterpriseId ? (

Zootech UI (WESP copy)

) : null}
); }