feat: button-driven Telegram menu (reply keyboard + commands), reachability diagnostic, How-To update

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XNQ8ghPfzAfsyVYd6HgFb6
This commit is contained in:
2026-07-23 20:12:27 +00:00
parent 5105c7d529
commit 7608bc62da
4 changed files with 148 additions and 29 deletions
+11 -1
View File
@@ -64,6 +64,15 @@ export default function AdminApp() {
const r = await fetch('/api/admin/test-nas', { method: 'POST' }).then((x) => x.json());
notify(r.message || (r.ok ? 'OK' : 'Fehler'));
};
const netcheck = async () => {
if (!s.nas_host) { notify('Erst Host eintragen und speichern.'); return; }
notify('Prüfe Erreichbarkeit …');
const r = await fetch('/api/admin/netcheck', { method: 'POST', headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ host: s.nas_host, port: s.nas_port || 22 }) }).then((x) => x.json());
const dnsMsg = r.resolve ? (r.resolve.ok ? `DNS ✓ (${r.resolve.address})` : `DNS ✕ (${r.resolve.error})`) : '';
const tcpMsg = r.tcp ? (r.tcp.ok ? `Port erreichbar in ${r.tcp.ms}ms ✓` : `nicht erreichbar: ${r.tcp.error}`) : (r.error || 'Fehler');
notify(`${dnsMsg}${dnsMsg ? ' · ' : ''}${tcpMsg}`);
};
const storageAction = async (action: string, confirmMsg?: string) => {
if (confirmMsg && !confirm(confirmMsg)) return;
notify('Räume auf …');
@@ -174,7 +183,8 @@ export default function AdminApp() {
<section className="karte">
<div className="kopfzeile"><span className="mono-label">Synology-NAS (zweite Sicherung)</span>
<button className="mini" onClick={testNas}>Verbindung testen</button></div>
<div className="reihe"><button className="mini" onClick={netcheck}>Erreichbarkeit</button>
<button className="mini" onClick={testNas}>Verbindung testen</button></div></div>
<div className="steuer">
<label className="schalt"><input type="checkbox" checked={!!s.nas_enabled} onChange={(e) => field('nas_enabled', e.target.checked)} />
<span><b>Ergebnisse zusätzlich aufs NAS spiegeln</b><em>Jedes fertige Bild wird nach <code>klarbild/JJJJ-MM/</code> gesichert.</em></span></label>