feat: eine Startseite, und die Sicherung geht in die Nextcloud
STARTSEITE. Wer das Dashboard oeffnet, landete bisher in der Galerie -- mit 228 Kacheln und ohne Antwort auf die erste Frage, die man beim Oeffnen hat: laeuft alles? Jetzt zuerst eine Uebersicht: Zahlen, was heute dazukam, ein Bilderstreifen der letzten Uploads, die letzten acht Schritte aus dem Verlauf, die groessten Ordner, die Zugaenge -- und die ADRESSVORLAGE zum Kopieren, weil das die haeufigste Frage ueberhaupt ist. Die Galerie zieht auf /galerie um. Alles in EINER Antwort (/api/dash/uebersicht, gemessen 14 ms). Vier Einzelabfragen waeren vier Runden ueber den Proxy und koennten auseinander- laufen: Dateizahl aus der einen und letzte Ereignisse aus der naechsten Antwort sind zwei verschiedene Zeitpunkte. Der Router zog dabei nach src/router.ts um. Der Grund ist mehr als Geschmack: die Startseite braucht eine Navigationsfunktion, die anderen Seiten nicht -- und sobald EINE Seite eine Eigenschaft mehr hat, passt die gemeinsame Liste in App.tsx nicht mehr. Genau daran ist der erste Versuch gescheitert (TypeScript hat es gefangen). Als Modulfunktion hat wieder jede Seite dieselbe Signatur. SICHERUNG IN DIE NEXTCLOUD. Bisher lagen die Archive auf derselben Platte wie die Daten -- gegen einen Plattenausfall half das gar nicht. Jetzt gehen sie per WebDAV hinauf, mit curl statt rclone: Nextcloud spricht WebDAV, curl spricht WebDAV, und curl ist ohnehin da. Auch dort wird NACHGEZAEHLT: die Kopie wird zurueckgeholt und die Pruefsumme verglichen. Ein PUT, der 201 sagt, hat nichts bewiesen -- abgeschnittene Uebertragungen sehen genauso aus. Und ausgeduennt wird ebenfalls, sonst waechst die Nextcloud still voll. Die Zugangsdaten liegen NEBEN den Sicherungen (C:\backup\d4rk_media\ nextcloud.txt), nicht im Repo: sie gehoeren zur Maschine, nicht zum Code. Fehlt die Datei, sagt das Skript das einmal und sichert lokal weiter -- eine Sicherung, die wegen eines fehlenden Passworts GAR NICHT stattfindet, waere der schlechtere Tausch. Dabei einmal reingefallen: die Pruefung brach mit "sh: set: Illegal option -" ab, nachdem ein Werkzeug die Datei mit CRLF gespeichert hatte -- die Shell im Container liest dann "set -e\r". Sieht aus wie ein Tippfehler und ist keiner. Das Skript entfernt die Wagenruecklaeufe jetzt selbst. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
+16
-28
@@ -1,47 +1,35 @@
|
||||
import { useEffect, useState } from 'react'
|
||||
import { HardDrive, History, Images, KeyRound, LogOut, PieChart, UserCog } from 'lucide-react'
|
||||
import { useEffect } from 'react'
|
||||
import {
|
||||
Gauge,
|
||||
HardDrive,
|
||||
History,
|
||||
Images,
|
||||
KeyRound,
|
||||
LogOut,
|
||||
PieChart,
|
||||
UserCog,
|
||||
} from 'lucide-react'
|
||||
import { run, useStore } from './store'
|
||||
import { Anmelden } from './pages/Anmelden'
|
||||
import { Start } from './pages/Start'
|
||||
import { Galerie } from './pages/Galerie'
|
||||
import { Speicher } from './pages/Speicher'
|
||||
import { Tokens } from './pages/Tokens'
|
||||
import { Konto } from './pages/Konto'
|
||||
import { Verlauf } from './pages/Verlauf'
|
||||
import { Meldungen } from './components/Meldungen'
|
||||
import { gehZu, usePfad } from './router'
|
||||
import { Avatar } from './components/Avatar'
|
||||
|
||||
// Ein winziger Router über die History-API statt einer Bibliothek.
|
||||
//
|
||||
// Echte Pfade und keine Reiter im Zustand, weil der Dienst dafür schon gebaut
|
||||
// ist: index.ts liefert auf alles Unbekannte die index.html aus, damit ein
|
||||
// Neuladen auf /tokens im Router landet und nicht im 404.
|
||||
|
||||
const seiten = [
|
||||
{ pfad: '/', name: 'Galerie', kind: Images, Inhalt: Galerie },
|
||||
{ pfad: '/', name: 'Start', kind: Gauge, Inhalt: Start },
|
||||
{ pfad: '/galerie', name: 'Galerie', kind: Images, Inhalt: Galerie },
|
||||
{ pfad: '/verlauf', name: 'Verlauf', kind: History, Inhalt: Verlauf },
|
||||
{ pfad: '/speicher', name: 'Speicher', kind: PieChart, Inhalt: Speicher },
|
||||
{ pfad: '/tokens', name: 'Token', kind: KeyRound, Inhalt: Tokens },
|
||||
{ pfad: '/konto', name: 'Konto', kind: UserCog, Inhalt: Konto },
|
||||
] as const
|
||||
|
||||
function usePfad(): [string, (p: string) => void] {
|
||||
const [pfad, setPfad] = useState(window.location.pathname)
|
||||
|
||||
useEffect(() => {
|
||||
const zurueck = () => setPfad(window.location.pathname)
|
||||
window.addEventListener('popstate', zurueck)
|
||||
return () => window.removeEventListener('popstate', zurueck)
|
||||
}, [])
|
||||
|
||||
return [
|
||||
pfad,
|
||||
(p: string) => {
|
||||
window.history.pushState(null, '', p)
|
||||
setPfad(p)
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
export function App() {
|
||||
// Einzeln ausgewählt und nicht als ganzer Laden: `useStore()` ohne
|
||||
// Auswahlfunktion abonniert ALLES, und dann zeichnet jede Meldung das
|
||||
@@ -50,7 +38,7 @@ export function App() {
|
||||
const checking = useStore((s) => s.checking)
|
||||
const checkSession = useStore((s) => s.checkSession)
|
||||
const logout = useStore((s) => s.logout)
|
||||
const [pfad, gehZu] = usePfad()
|
||||
const pfad = usePfad()
|
||||
|
||||
useEffect(() => {
|
||||
void checkSession()
|
||||
|
||||
Reference in New Issue
Block a user