feat: Synology WebDAV Integration - Admin-Einstellungen + Datei-Spiegelung
This commit is contained in:
@@ -2696,6 +2696,104 @@ function UploadShareAdminPanel({ toast }) {
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ── WebDAV / Synology NAS Einstellungen ───────────────────────────────────
|
||||
function WebDavSettings({ toast }) {
|
||||
const [cfg, setCfg] = useState({ url:'', user:'', password:'', basePath:'/dickendock', enabled:false });
|
||||
const [testing, setTesting] = useState(false);
|
||||
const [saving, setSaving] = useState(false);
|
||||
const [showPw, setShowPw] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
api('/admin/webdav').then(d => setCfg(d)).catch(() => {});
|
||||
}, []);
|
||||
|
||||
async function save() {
|
||||
setSaving(true);
|
||||
try {
|
||||
await api('/admin/webdav', { method:'PUT', body: cfg });
|
||||
toast('WebDAV Einstellungen gespeichert ✓');
|
||||
} catch(e) { toast('Fehler: ' + e.message); }
|
||||
finally { setSaving(false); }
|
||||
}
|
||||
|
||||
async function test() {
|
||||
setTesting(true);
|
||||
try {
|
||||
await api('/admin/webdav/test', { body: cfg });
|
||||
toast('✓ Verbindung erfolgreich!');
|
||||
} catch(e) { toast('✗ ' + e.message); }
|
||||
finally { setTesting(false); }
|
||||
}
|
||||
|
||||
const field = (label, key, type='text', placeholder='') => (
|
||||
<div style={{marginBottom:10}}>
|
||||
<div style={{color:'rgba(255,255,255,0.4)',fontFamily:'monospace',fontSize:10,marginBottom:4}}>{label}</div>
|
||||
<div style={{position:'relative'}}>
|
||||
<input
|
||||
type={type === 'password' ? (showPw ? 'text' : 'password') : type}
|
||||
value={cfg[key] || ''}
|
||||
onChange={e => setCfg(p => ({...p, [key]: e.target.value}))}
|
||||
placeholder={placeholder}
|
||||
style={{...S.inp, width:'100%', boxSizing:'border-box', paddingRight: type==='password' ? 36 : 12}}
|
||||
/>
|
||||
{type === 'password' && (
|
||||
<button onClick={()=>setShowPw(v=>!v)}
|
||||
style={{position:'absolute',right:8,top:'50%',transform:'translateY(-50%)',background:'none',border:'none',color:'rgba(255,255,255,0.4)',cursor:'pointer',fontSize:13}}>
|
||||
{showPw ? '🙈' : '👁'}
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
return (
|
||||
<div>
|
||||
{/* Enable Toggle */}
|
||||
<div style={{display:'flex',alignItems:'center',gap:10,marginBottom:16,cursor:'pointer'}}
|
||||
onClick={() => setCfg(p => ({...p, enabled: !p.enabled}))}>
|
||||
<div style={{
|
||||
width:36, height:20, borderRadius:10, position:'relative',
|
||||
background: cfg.enabled ? '#4ade80' : 'rgba(255,255,255,0.1)',
|
||||
border: `1px solid ${cfg.enabled ? '#4ade80' : 'rgba(255,255,255,0.2)'}`,
|
||||
transition: 'all 0.2s',
|
||||
}}>
|
||||
<div style={{
|
||||
position:'absolute', top:2, left: cfg.enabled ? 18 : 2,
|
||||
width:14, height:14, borderRadius:'50%', background:'#fff',
|
||||
transition: 'left 0.2s',
|
||||
}}/>
|
||||
</div>
|
||||
<span style={{color:cfg.enabled?'#4ade80':'rgba(255,255,255,0.5)',fontFamily:'monospace',fontSize:12}}>
|
||||
{cfg.enabled ? 'WebDAV aktiv – Dateien werden auf NAS gespiegelt' : 'WebDAV deaktiviert'}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{field('WEBDAV URL', 'url', 'text', 'http://192.168.1.100:5005 oder https://nas.local:5006')}
|
||||
{field('BENUTZERNAME', 'user', 'text', 'admin')}
|
||||
{field('PASSWORT', 'password', 'password', '')}
|
||||
{field('BASISPFAD AUF DER SYNOLOGY', 'basePath', 'text', '/dickendock')}
|
||||
|
||||
<div style={{color:'rgba(255,255,255,0.3)',fontFamily:'monospace',fontSize:10,marginBottom:16,lineHeight:1.6}}>
|
||||
Dateien werden unter <span style={{color:'rgba(255,255,255,0.5)'}}>Basispfad/Username/Dateiname</span> gespeichert.<br/>
|
||||
Beispiel: /dickendock/flo/dokumente/rechnung.pdf<br/>
|
||||
Synology WebDAV aktivieren: Systemsteuerung → Dateidienste → WebDAV
|
||||
</div>
|
||||
|
||||
<div style={{display:'flex',gap:8}}>
|
||||
<button onClick={test} disabled={testing || !cfg.url}
|
||||
style={{...S.btn('#60a5fa'), opacity:(testing||!cfg.url)?0.5:1}}>
|
||||
{testing ? '⏳ Teste...' : '🔌 Verbindung testen'}
|
||||
</button>
|
||||
<button onClick={save} disabled={saving}
|
||||
style={{...S.btn('#4ade80'), opacity:saving?0.5:1}}>
|
||||
{saving ? '⏳...' : '💾 Speichern'}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function AdminPanel({ toast, mobile, user, nav }) {
|
||||
const [section, setSection] = useState('profil');
|
||||
useEffect(() => { if (nav?.section) setSection(nav.section); }, [nav?.ts]);
|
||||
@@ -2848,6 +2946,9 @@ function AdminPanel({ toast, mobile, user, nav }) {
|
||||
<Sec title="TMDB API (KINO-FEATURE)">
|
||||
<TmdbSettings toast={toast}/>
|
||||
</Sec>
|
||||
<Sec title="SYNOLOGY NAS / WEBDAV">
|
||||
<WebDavSettings toast={toast}/>
|
||||
</Sec>
|
||||
</div>
|
||||
)}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user