feat: v0.8.3 — PWA-Support, Desktop-Verhalten, Testmodus-Kennzeichnung

- PWA: manifest.webmanifest + Icons (192/512/180px) + Apple-Touch-Meta-Tags
  → Web-App lässt sich auf Homebildschirm hinzufügen (iOS/Android)
- Desktop: user-select:none global + contextmenu blockiert
- BackendChoice: lokaler Modus als Testmodus mit TEST-Badge und Warnung

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-06 12:40:12 +02:00
parent f88825ebe0
commit e0cf5f1381
13 changed files with 65 additions and 15 deletions
+15 -8
View File
@@ -303,8 +303,8 @@ export default function App() {
const [modal, setModal] = useState(null);
const [printContent, setPrintContent] = useState(null);
const [darkMode, setDarkMode] = useState(() => localStorage.getItem("rapport_dark") === "1");
const [showChangelog, setShowChangelog] = useState(() => localStorage.getItem("rapport_changelog_seen") !== "0.8.2");
const [changelogVersion, setChangelogVersion] = useState("0.8.2");
const [showChangelog, setShowChangelog] = useState(() => localStorage.getItem("rapport_changelog_seen") !== "0.8.3");
const [changelogVersion, setChangelogVersion] = useState("0.8.3");
const [showAbout, setShowAbout] = useState(false);
const [navOpen, setNavOpen] = useState(false);
const [expandedNav, setExpandedNav] = useState(new Set(["buchhaltung"]));
@@ -518,7 +518,7 @@ export default function App() {
</>;
}
return <>
<Login verifyLogin={verifyLogin} settings={data.settings} version="0.8.2" cloudUnreachable={cloudUnreachable} />
<Login verifyLogin={verifyLogin} settings={data.settings} version="0.8.3" cloudUnreachable={cloudUnreachable} />
<UpdateNotifier />
</>;
}
@@ -793,8 +793,8 @@ export default function App() {
<div style={{ display: "flex", justifyContent: "space-between", alignItems: "center" }}>
<button onClick={() => setShowAbout(true)} style={{ background: "none", border: "none", padding: 0, color: "#555", fontSize: 10, letterSpacing: "0.08em", cursor: "pointer", fontFamily: "inherit", textAlign: "left" }}
onMouseEnter={e => e.currentTarget.style.color = "#aaa"} onMouseLeave={e => e.currentTarget.style.color = "#555"}>ÜBER RAPPORT</button>
<button onClick={() => { setChangelogVersion("0.8.2"); setShowChangelog(true); }} style={{ background: "none", border: "none", padding: 0, color: "#aaa", fontSize: 10, letterSpacing: "0.08em", cursor: "pointer", fontFamily: "inherit" }}
onMouseEnter={e => e.currentTarget.style.color = "#f0ede8"} onMouseLeave={e => e.currentTarget.style.color = "#aaa"}>0.8.2</button>
<button onClick={() => { setChangelogVersion("0.8.3"); setShowChangelog(true); }} style={{ background: "none", border: "none", padding: 0, color: "#aaa", fontSize: 10, letterSpacing: "0.08em", cursor: "pointer", fontFamily: "inherit" }}
onMouseEnter={e => e.currentTarget.style.color = "#f0ede8"} onMouseLeave={e => e.currentTarget.style.color = "#aaa"}>0.8.3</button>
</div>
</div>}
@@ -859,6 +859,13 @@ export default function App() {
{showChangelog && (() => {
const CHANGELOGS = {
"0.8.3": {
items: [
["Desktop-App-Verhalten", "Kein Text mehr markierbar, kein Rechtsklick-Menü — die App verhält sich jetzt wie eine native Desktop-Applikation. Eingabefelder sind weiterhin voll benutzbar."],
["PWA-Support", "Die Web-Version lässt sich auf dem Homebildschirm von iPhone/iPad und Android hinzufügen. Nach dem Hinzufügen öffnet sie sich vollbild ohne Browser-Chrome — mit eigenem App-Icon und Name."],
["Testmodus klar gekennzeichnet", "Wer Rapport ohne Server ausprobiert, sieht jetzt explizit, dass es sich um einen Testmodus mit Einschränkungen handelt (5 MB Limit, kein Backup, kein Mehrbenutzer)."],
],
},
"0.8.2": {
items: [
["Selbstheilung für hängende 0.8.0-Installationen", "Wer von 0.7 auf 0.8 geupdated hat und in den Cloud-Setup-Wizard geschoben wurde, kommt mit 0.8.2 automatisch zurück in seinen Lokal-Modus. Der Auto-Recovery-Code erkennt: Cloud-Modus gesetzt + lokale Daten vorhanden + keine Cloud-Anmeldung → Cloud-Konfiguration wird zurückgenommen, alle Daten bleiben erhalten."],
@@ -948,7 +955,7 @@ export default function App() {
},
};
const versions = Object.keys(CHANGELOGS);
const current = CHANGELOGS[changelogVersion] || CHANGELOGS["0.8.2"];
const current = CHANGELOGS[changelogVersion] || CHANGELOGS["0.8.3"];
return (
<div style={{ position: "fixed", inset: 0, background: "rgba(0,0,0,0.55)", zIndex: 200, display: "flex", alignItems: "center", justifyContent: "center", padding: 24 }}>
<div style={{ background: "#fff", borderRadius: 10, width: "100%", maxWidth: 480, boxShadow: "0 8px 40px rgba(0,0,0,0.18)", overflow: "hidden" }}>
@@ -977,7 +984,7 @@ export default function App() {
))}
</div>
<div style={{ padding: "12px 32px 24px" }}>
<button className="btn btn-primary" style={{ width: "100%", fontSize: 13 }} onClick={() => { setShowChangelog(false); localStorage.setItem("rapport_changelog_seen", "0.8.2"); }}>
<button className="btn btn-primary" style={{ width: "100%", fontSize: 13 }} onClick={() => { setShowChangelog(false); localStorage.setItem("rapport_changelog_seen", "0.8.3"); }}>
Schliessen
</button>
</div>
@@ -992,7 +999,7 @@ export default function App() {
<div style={{ background: "#1a1a18", padding: "28px 32px 24px" }}>
<div style={{ fontSize: 10, letterSpacing: "0.18em", color: "#b07848", marginBottom: 8, fontWeight: 600 }}>ÜBER RAPPORT</div>
<div style={{ fontFamily: "'Playfair Display', serif", fontSize: 28, color: "#f0ede8", fontWeight: 400, lineHeight: 1.1 }}>Rapport</div>
<div style={{ fontSize: 11, color: "#888", marginTop: 6, letterSpacing: "0.04em" }}>Alpha 0.8.2 · Studio-Management für Architekturbüros</div>
<div style={{ fontSize: 11, color: "#888", marginTop: 6, letterSpacing: "0.04em" }}>Alpha 0.8.3 · Studio-Management für Architekturbüros</div>
</div>
<div style={{ padding: "20px 32px 8px" }}>
<div style={{ fontSize: 11, fontWeight: 600, color: "#888", letterSpacing: "0.1em", marginBottom: 12 }}>LIZENZ</div>