diff --git a/services/web-ui/public/screens-admin.jsx b/services/web-ui/public/screens-admin.jsx index dbef83f..b7a8c7b 100644 --- a/services/web-ui/public/screens-admin.jsx +++ b/services/web-ui/public/screens-admin.jsx @@ -614,6 +614,37 @@ function DetailRow({ k, v, mono }) { } function Settings() { + const [s3, setS3] = React.useState({ s3_endpoint: '', s3_bucket: '', s3_access_key: '', s3_secret_key: '', s3_region: 'us-east-1' }); + const [s3Loading, setS3Loading] = React.useState(true); + const [s3Saving, setS3Saving] = React.useState(false); + const [s3Testing, setS3Testing] = React.useState(false); + const [s3Msg, setS3Msg] = React.useState(null); + const [secretExists, setSecretExists] = React.useState(false); + + React.useEffect(() => { + window.ZAMPP_API.fetch('/settings/s3') + .then(data => { + setS3({ s3_endpoint: data.s3_endpoint || '', s3_bucket: data.s3_bucket || '', s3_access_key: data.s3_access_key || '', s3_secret_key: '', s3_region: data.s3_region || 'us-east-1' }); + setSecretExists(!!data.s3_secret_key_exists); + setS3Loading(false); + }) + .catch(() => setS3Loading(false)); + }, []); + + const saveS3 = () => { + setS3Saving(true); setS3Msg(null); + window.ZAMPP_API.fetch('/settings/s3', { method: 'PUT', body: JSON.stringify(s3) }) + .then(() => { setS3Saving(false); setS3Msg({ ok: true, text: 'Saved and applied.' }); if (s3.s3_secret_key) setSecretExists(true); }) + .catch(e => { setS3Saving(false); setS3Msg({ ok: false, text: e.message }); }); + }; + + const testS3 = () => { + setS3Testing(true); setS3Msg(null); + window.ZAMPP_API.fetch('/settings/s3/test', { method: 'POST', body: JSON.stringify(s3) }) + .then(r => { setS3Testing(false); setS3Msg({ ok: r.ok !== false, text: r.message || 'Connection OK' }); }) + .catch(e => { setS3Testing(false); setS3Msg({ ok: false, text: e.message }); }); + }; + return (