/* global React, Card, Button, Input, Ic, VS */ // Zakładka "Użytkownicy" — admin-only. // Zarządzanie użytkownikami logującymi się do aplikacji (tabela {S}.users). // Pola: login (username), Imię i nazwisko (display_name), email, rola, hasło. function UsersScreen() { const role = VS.getRole(); const isAdmin = role === 'admin'; if (!isAdmin) { return (
Użytkownicy
Dostęp tylko dla administratora.
); } const [list, setList] = React.useState(null); const [err, setErr] = React.useState(''); const [msg, setMsg] = React.useState(''); const [showAdd, setShowAdd] = React.useState(false); const [nLogin, setNLogin] = React.useState(''); const [nName, setNName] = React.useState(''); const [nEmail, setNEmail] = React.useState(''); const [nPass, setNPass] = React.useState(''); const [nRole, setNRole] = React.useState('pracownik'); const [adding, setAdding] = React.useState(false); const load = React.useCallback(() => { VS.adminUsers() .then(r => setList(r || [])) .catch(e => setErr(e.message)); }, []); React.useEffect(() => { load(); }, [load]); function flash(text) { setMsg(text); setTimeout(() => setMsg(''), 2200); } async function addUser() { if (!nLogin.trim() || !nPass.trim()) { flash('Login i hasło wymagane'); return; } setAdding(true); try { await VS.adminAddUser({ username: nLogin.trim(), password: nPass, display_name: nName.trim(), email: nEmail.trim(), role: nRole, }); setNLogin(''); setNName(''); setNEmail(''); setNPass(''); setNRole('pracownik'); setShowAdd(false); load(); flash('Dodano użytkownika.'); } catch (e) { flash('Błąd: ' + e.message); } finally { setAdding(false); } } async function removeUser(u) { if (!confirm(`Usunąć użytkownika "${u.username}"?`)) return; try { await VS.adminDeleteUser(u.id); load(); flash('Usunięto.'); } catch (e) { flash('Błąd: ' + e.message); } } return (
Administracja

Użytkownicy

Lista osób logujących się do aplikacji. Imię i nazwisko pojawia się w dropdownach Operator / Zatwierdził.
{list ? `${list.length} użytkowników` : ''}
{showAdd && (
Dodaj użytkownika
Login
setNLogin(e.target.value)} placeholder="login" />
Imię i nazwisko
setNName(e.target.value)} placeholder="Jan Kowalski" />
E-mail
setNEmail(e.target.value)} placeholder="user@firma.pl" />
Hasło
setNPass(e.target.value)} style={inputStyle} />
Rola
{msg && {msg}}
)} {err && (
{err}
)} {!err && !list &&
Ładowanie…
} {!err && list && list.length === 0 && (
Brak użytkowników.
)} {!err && list && list.length > 0 && (
Login
Imię i nazwisko
E-mail
Rola
Akcje
{list.map((u, i) => ( removeUser(u)} /> ))}
)} {!showAdd && msg && ( {msg} )}
); } function UserRow({ user, last, onChange, onRemove }) { const [editing, setEditing] = React.useState(false); const [name, setName] = React.useState(user.display_name || ''); const [email, setEmail] = React.useState(user.email || ''); const [role, setRole] = React.useState(user.role || 'pracownik'); const [pass, setPass] = React.useState(''); const [busy, setBusy] = React.useState(false); const [msg, setMsg] = React.useState(''); React.useEffect(() => { setName(user.display_name || ''); setEmail(user.email || ''); setRole(user.role || 'pracownik'); setPass(''); }, [user.id, user.display_name, user.email, user.role]); async function save() { setBusy(true); setMsg(''); try { const data = { display_name: name, email, role }; if (pass.trim()) data.password = pass; await VS.adminUpdateUser(user.id, data); setEditing(false); setPass(''); onChange && onChange(); } catch (e) { setMsg('Błąd: ' + e.message); } finally { setBusy(false); } } if (!editing) { return (
{user.username}
{user.display_name || }
{user.email || }
{user.role}
); } return (
{user.username}
setName(e.target.value)} placeholder="Imię i nazwisko" /> setEmail(e.target.value)} placeholder="email" />
setPass(e.target.value)} placeholder="nowe hasło" style={{ ...inputStyle, width: 110 }} /> {msg && {msg}}
); } const inputStyle = { width: '100%', height: 28, padding: '0 8px', background: 'var(--surface)', border: '1px solid var(--border-strong)', borderRadius: 'var(--r-sm)', fontSize: 12, color: 'var(--fg)', fontFamily: 'inherit', outline: 'none', }; Object.assign(window, { UsersScreen });