/* global React, Card, Button, Input, Ic, VS, LoadingState, ErrorState */
function MyStampScreen() {
const [stamp, setStamp] = React.useState(null);
const [err, setErr] = React.useState('');
const [msg, setMsg] = React.useState('');
const [busy, setBusy] = React.useState(false);
const [imgBust, setImgBust] = React.useState(0);
const fileInputRef = React.useRef(null);
const role = VS.getRole();
const isAdmin = role === 'admin';
// admin: wszystkie pieczątki
const [allStamps, setAllStamps] = React.useState(null);
const [allStampsErr, setAllStampsErr] = React.useState('');
const [allBust, setAllBust] = React.useState({});
React.useEffect(() => {
VS.myStamp()
.then((s) => setStamp(s))
.catch((e) => setErr(e.message));
}, []);
React.useEffect(() => {
if (!isAdmin) return;
VS.userStamps()
.then((list) => setAllStamps(list))
.catch((e) => setAllStampsErr(e.message));
}, [isAdmin]);
function setField(k, v) {
setStamp((s) => ({ ...s, [k]: v }));
}
async function save() {
if (!stamp) return;
setBusy(true); setMsg('');
try {
await VS.saveMyStamp({ name: stamp.name || '', cert_number: stamp.cert_number || '' });
setMsg('Zapisano.');
setTimeout(() => setMsg(''), 2500);
} catch (e) {
setMsg('Błąd: ' + e.message);
} finally {
setBusy(false);
}
}
async function uploadImage(e) {
const file = e.target.files && e.target.files[0];
if (!file) return;
setBusy(true); setMsg('');
try {
await VS.uploadMyStampImage(file);
setStamp((s) => ({ ...s, has_image: true }));
setImgBust((x) => x + 1);
setMsg('Obrazek wgrany.');
setTimeout(() => setMsg(''), 2500);
} catch (err) {
setMsg('Błąd: ' + err.message);
} finally {
setBusy(false);
e.target.value = '';
}
}
if (err) return ;
if (!stamp) return ;
return (
Pieczątka
Moja pieczątka
Dane pieczątki wykorzystywane w protokołach i raportach.
Moja pieczątka
{msg && (
{msg}
)}
setField('name', v)}
/>
setField('cert_number', v)}
/>
Obrazek pieczątki
{stamp.has_image ? (

) : (
brak
)}
{isAdmin && (
)}
);
}
function StampField({ label, value, onChange }) {
return (
);
}
function AdminStampsSection({ stamps, setStamps, err, allBust, setAllBust }) {
const [open, setOpen] = React.useState(true);
return (
setOpen((o) => !o)}
style={{
display: 'flex', alignItems: 'center', justifyContent: 'space-between',
cursor: 'pointer', userSelect: 'none',
}}
>
Administracja
Pieczątki wszystkich użytkowników
{open && (
{err && (
{err}
)}
{!stamps && !err &&
Ładowanie…
}
{stamps && stamps.length === 0 && (
Brak użytkowników.
)}
{stamps && stamps.length > 0 && (
Użytkownik
Imię i nazwisko
Nr świadectwa
Pieczątka
Akcje
{stamps.map((row) => (
{
setStamps((list) =>
list.map((s) => (s.user_id === row.user_id ? { ...s, ...patch } : s)));
}}
bumpBust={() =>
setAllBust((b) => ({ ...b, [row.user_id]: (b[row.user_id] || 0) + 1 }))
}
/>
))}
)}
)}
);
}
function AdminStampRow({ row, onChange, bust, bumpBust }) {
const [busy, setBusy] = React.useState(false);
const [msg, setMsg] = React.useState('');
const fileRef = React.useRef(null);
async function save() {
setBusy(true); setMsg('');
try {
await VS.saveUserStamp(row.user_id, { name: row.name || '', cert_number: row.cert_number || '' });
setMsg('OK');
setTimeout(() => setMsg(''), 2000);
} catch (e) {
setMsg('Błąd');
} finally {
setBusy(false);
}
}
async function upload(e) {
const file = e.target.files && e.target.files[0];
if (!file) return;
setBusy(true); setMsg('');
try {
await VS.uploadUserStampImage(row.user_id, file);
onChange({ has_image: true });
bumpBust();
setMsg('OK');
setTimeout(() => setMsg(''), 2000);
} catch (err) {
setMsg('Błąd');
} finally {
setBusy(false);
e.target.value = '';
}
}
return (
{row.username}
{row.role || 'user'}
onChange({ name: e.target.value })}
placeholder="Imię i nazwisko"
style={{
width: '100%', height: 28, padding: '0 10px',
background: 'var(--surface)',
border: '1px solid var(--border-strong)',
borderRadius: 'var(--r-sm)',
fontSize: 12, color: 'var(--fg)', outline: 'none',
fontFamily: 'inherit',
}}
/>
onChange({ cert_number: e.target.value })}
placeholder="nr świadectwa"
style={{
width: '100%', height: 28, padding: '0 10px',
background: 'var(--surface)',
border: '1px solid var(--border-strong)',
borderRadius: 'var(--r-sm)',
fontSize: 12, color: 'var(--fg)', outline: 'none',
fontFamily: 'inherit',
}}
/>
{row.has_image ? (

) : (
brak
)}
}
disabled={busy}
onClick={() => fileRef.current && fileRef.current.click()}>
Upload
{msg && (
{msg}
)}
);
}
Object.assign(window, { MyStampScreen });