import { useEffect, useState } from "react"; import { useOutletContext } from "react-router-dom"; import { UserPlus, RefreshCw } from "lucide-react"; import { createModerator, createPartner, createSupport, fetchStaffUsers, setNodePermission, type StaffRole, type StaffUser, } from "./api"; export default function StaffPage() { const role = useOutletContext(); const [staff, setStaff] = useState([]); const [loading, setLoading] = useState(true); const [modUsername, setModUsername] = useState(""); const [modPassword, setModPassword] = useState(""); const [modCanManageNodes, setModCanManageNodes] = useState(false); const [partnerUsername, setPartnerUsername] = useState(""); const [partnerPassword, setPartnerPassword] = useState(""); const [partnerPercent, setPartnerPercent] = useState("10"); const [supportUsername, setSupportUsername] = useState(""); const [supportPassword, setSupportPassword] = useState(""); const [error, setError] = useState(""); const load = async () => { setLoading(true); try { setStaff(await fetchStaffUsers()); } catch (e) { console.error(e); } finally { setLoading(false); } }; useEffect(() => { load(); }, []); const handleCreateModerator = async (e: React.FormEvent) => { e.preventDefault(); setError(""); try { await createModerator(modUsername, modPassword, modCanManageNodes); setModUsername(""); setModPassword(""); setModCanManageNodes(false); await load(); } catch { setError("Не удалось создать модератора (логин уже занят?)."); } }; const handleCreatePartner = async (e: React.FormEvent) => { e.preventDefault(); setError(""); try { await createPartner(partnerUsername, partnerPassword, Number(partnerPercent)); setPartnerUsername(""); setPartnerPassword(""); setPartnerPercent("10"); await load(); } catch { setError("Не удалось создать партнёра (логин уже занят?)."); } }; const handleCreateSupport = async (e: React.FormEvent) => { e.preventDefault(); setError(""); try { await createSupport(supportUsername, supportPassword); setSupportUsername(""); setSupportPassword(""); await load(); } catch { setError("Не удалось создать аккаунт саппорта (логин уже занят?)."); } }; const handleTogglePermission = async (userId: string, current: boolean) => { try { await setNodePermission(userId, !current); await load(); } catch (e) { console.error(e); } }; return (

Staff

{error &&

{error}

}
{role.role === "owner" && (

Новый модератор

setModUsername(e.target.value)} className="w-full bg-white/5 border border-white/10 rounded-lg p-2.5 text-sm outline-none focus:border-secondary" /> setModPassword(e.target.value)} className="w-full bg-white/5 border border-white/10 rounded-lg p-2.5 text-sm outline-none focus:border-secondary" />
)} {role.role === "owner" && (

Новый саппорт

setSupportUsername(e.target.value)} className="w-full bg-white/5 border border-white/10 rounded-lg p-2.5 text-sm outline-none focus:border-secondary" /> setSupportPassword(e.target.value)} className="w-full bg-white/5 border border-white/10 rounded-lg p-2.5 text-sm outline-none focus:border-secondary" />

Видит только раздел "Тикеты" — доступа к нодам/staff/выводам нет.

)}

Новый партнёр

setPartnerUsername(e.target.value)} className="w-full bg-white/5 border border-white/10 rounded-lg p-2.5 text-sm outline-none focus:border-primary" /> setPartnerPassword(e.target.value)} className="w-full bg-white/5 border border-white/10 rounded-lg p-2.5 text-sm outline-none focus:border-primary" />
setPartnerPercent(e.target.value)} className="w-24 bg-white/5 border border-white/10 rounded-lg p-2.5 text-sm outline-none focus:border-primary" /> % с продаж

Список staff

{staff.map((u) => (
{u.username} {u.role}
{u.role === "partner" && (

{u.commission_percent}% · код: {u.partner_code}

)}
{role.role === "owner" && u.role === "moderator" && ( )}
))} {staff.length === 0 && !loading && (

Пока никого нет

)}
); }