round13: manuelle vs. echte Aenderungen trennen, Scan-Uebersicht ueber Navigation persistieren, ausgeblendete Dienste als Tab, Suche ueber Geraetenamen

This commit is contained in:
2026-07-23 01:21:31 +02:00
parent 1f8218dff1
commit 2772c29036
10 changed files with 322 additions and 126 deletions

View File

@@ -0,0 +1,40 @@
import { useCallback, useState } from "react";
/**
* Wie useState, aber der Wert überlebt zusätzlich das Verlassen und erneute
* Betreten einer Seite (z. B. Scanner -> Geräte -> zurück zu Scanner), ohne
* dass ein laufender Scan erneut ausgeführt werden muss. Nutzt sessionStorage
* (pro Browser-Tab, weg nach Schließen des Tabs - bewusst kein dauerhafter
* Speicher, da es sich um vorübergehende "wartet auf Bestätigung"-Zustände
* handelt, keine echten Nutzdaten).
*/
export function usePersistedState<T>(key: string, initial: T): [T, (value: T | ((prev: T) => T)) => void] {
const storageKey = `launchpad:${key}`;
const [state, setState] = useState<T>(() => {
try {
const raw = sessionStorage.getItem(storageKey);
return raw !== null ? (JSON.parse(raw) as T) : initial;
} catch {
return initial;
}
});
const setPersisted = useCallback(
(value: T | ((prev: T) => T)) => {
setState((prev) => {
const next = typeof value === "function" ? (value as (p: T) => T)(prev) : value;
try {
sessionStorage.setItem(storageKey, JSON.stringify(next));
} catch {
// z. B. Speicher voll oder Privatmodus - dann bleibt der Zustand
// wenigstens für den Rest dieser Sitzung im Memory erhalten.
}
return next;
});
},
[storageKey]
);
return [state, setPersisted];
}