From 7ab0ec6061fd4e23fd97d6319b994580aeee17a0 Mon Sep 17 00:00:00 2001 From: elpatron Date: Sat, 30 May 2026 19:15:49 +0200 Subject: [PATCH] =?UTF-8?q?fix(logs):=20Ereignis-Bearbeitung=20sichern=20u?= =?UTF-8?q?nd=20Warnung=20bei=20ungespeicherten=20=C3=84nderungen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Normalisiert partielle Logbuch-Events beim Speichern (z. B. Besegelung) und warnt beim Verlassen von Editor, Tabs und Browser. Co-authored-by: Cursor --- client/src/App.tsx | 38 +++-- client/src/components/LogEntryEditor.tsx | 159 ++++++++++++------- client/src/context/UnsavedChangesContext.tsx | 77 +++++++++ client/src/i18n/locales/de.json | 6 + client/src/i18n/locales/en.json | 6 + client/src/utils/logEntryPayload.ts | 43 ++++- 6 files changed, 259 insertions(+), 70 deletions(-) create mode 100644 client/src/context/UnsavedChangesContext.tsx diff --git a/client/src/App.tsx b/client/src/App.tsx index a984777..098c544 100644 --- a/client/src/App.tsx +++ b/client/src/App.tsx @@ -13,6 +13,7 @@ import SettingsForm from './components/SettingsForm.tsx' import InvitationAcceptance from './components/InvitationAcceptance.tsx' import AppTourOverlay from './components/AppTourOverlay.tsx' import { AppTourProvider, useAppTour, type AppTab } from './context/AppTourContext.tsx' +import { UnsavedChangesProvider, useUnsavedChangesContext } from './context/UnsavedChangesContext.tsx' import { getActiveMasterKey, logoutUser, checkServerSession } from './services/auth.js' import { PlausibleEvents, trackPlausibleEvent } from './services/analytics.js' import { @@ -48,6 +49,7 @@ const PENDING_PUSH_LOGBOOK_KEY = 'pending_push_logbook_id' function App() { const { t, i18n } = useTranslation() + const { confirmLeave } = useUnsavedChangesContext() const { registerNavigation, requestStartAfterLogin, isActive, currentStepId } = useAppTour() const [isAuthenticated, setIsAuthenticated] = useState(false) const [activeLogbookId, setActiveLogbookId] = useState(null) @@ -347,7 +349,14 @@ function App() { consumePendingPushLogbook() } - const handleLogout = () => { + const handleTabChange = async (tab: AppTab) => { + if (tab === activeTab) return + if (!(await confirmLeave())) return + setActiveTab(tab) + } + + const handleLogout = async () => { + if (!(await confirmLeave())) return void logoutUser() setIsAuthenticated(false) setActiveLogbookId(null) @@ -358,7 +367,8 @@ function App() { localStorage.removeItem('active_logbook_title') } - const handleBackToDashboard = () => { + const handleBackToDashboard = async () => { + if (!(await confirmLeave())) return setActiveLogbookId(null) setActiveLogbookTitle(null) setTourSelectedEntryId(null) @@ -505,7 +515,7 @@ function App() {