// web/screens/upload.jsx — Веб-загрузка фото пользователем (И4, §3.4). // multipart POST /v1/upload → создаёт серию (владелец = текущий юзер). function UploadScreen({ setRoute, me }) { const [files, setFiles] = React.useState([]); const [contentType, setContentType] = React.useState("photo"); const [editorial, setEditorial] = React.useState(false); const [busy, setBusy] = React.useState(false); const [result, setResult] = React.useState(null); const [, toast] = useToasts(); const inputRef = React.useRef(null); const quota = me && me.quota; const remaining = quota && quota.fileLimit >= 0 ? Math.max(0, quota.fileLimit - quota.filesUsed) : null; const addFiles = (list) => { const arr = Array.from(list).filter((f) => /\.(jpe?g|png)$/i.test(f.name)); setFiles((prev) => [...prev, ...arr]); }; const onDrop = (e) => { e.preventDefault(); addFiles(e.dataTransfer.files); }; const removeAt = (i) => setFiles((p) => p.filter((_, j) => j !== i)); const submit = async () => { if (!files.length) return; setBusy(true); setResult(null); try { const r = await api.upload(files, { contentType, isEditorial: editorial }); setResult(r); if (r.shootId) { toast("Создана серия · " + r.accepted + " фото", "ok"); setTimeout(() => setRoute("series", r.shootId), 800); } else { toast("Ничего не загружено", "error"); } } catch (e) { toast("Ошибка: " + e.message, "error"); } finally { setBusy(false); } }; return (