fix: Preserve anchor links after login redirect

- Fix onLogin callback to properly set user state
- Use preserveFullUrl() to maintain hash fragments in redirects
- Switch to window.location.assign() for better browser support
- Faster redirect timing (500ms) for improved
This commit is contained in:
Johannes
2025-09-14 16:48:05 +02:00
parent d36b9de4a6
commit c9160136cb
3 changed files with 75 additions and 5 deletions

View File

@@ -80,7 +80,16 @@ function App() {
) : (
<>
{error && <Alert type="error" message={error} showIcon style={{ margin: 16 }} />}
<LoginPage onLogin={() => setUser(null)} />
<LoginPage onLogin={(userData) => {
// Re-fetch user data nach erfolgreichem Login
getCurrentUser().then(res => {
if (res.success) {
setUser(res.data);
}
}).catch(() => {
setUser(null);
});
}} />
</>
)}
</AntApp>
@@ -148,7 +157,16 @@ function App() {
) : (
<>
<Route path="/" element={<ClientProjects user={user} darkMode={darkMode} onLogout={handleLogout} onToggleDarkMode={handleToggleDarkMode} />} />
<Route path="/login" element={<LoginPage onLogin={() => setUser(null)} />} />
<Route path="/login" element={<LoginPage onLogin={(userData) => {
// Re-fetch user data nach erfolgreichem Login
getCurrentUser().then(res => {
if (res.success) {
setUser(res.data);
}
}).catch(() => {
setUser(null);
});
}} />} />
<Route path=":project/:tab?" element={<ProjectDetail user={user} darkMode={darkMode} onLogout={handleLogout} onToggleDarkMode={handleToggleDarkMode} />} />
{/* Catch-All-Route für nicht gefundene Pfade */}
<Route path="*" element={<Navigate to="/" replace />} />

View File

@@ -1,6 +1,7 @@
import React, { useState } from 'react';
import { Form, Input, Button, Typography, Alert, message } from 'antd';
import { LockOutlined, UserOutlined } from '@ant-design/icons';
import { preserveFullUrl } from '../utils/urlUtils';
const { Title } = Typography;
@@ -23,10 +24,15 @@ export default function LoginPage({ onLogin }) {
if (data.success) {
localStorage.setItem('jwt', data.token);
message.success('Login erfolgreich!');
setTimeout(() => {
window.location.href = window.location.pathname + window.location.search || '/';
}, 600);
// Callback für App.js um Re-Auth zu triggern
onLogin && onLogin(data);
// Forciere einen harten Reload mit der vollständigen URL inklusive Hash
setTimeout(() => {
// Verwende assign() statt replace() für bessere Browser-Kompatibilität
window.location.assign(preserveFullUrl());
}, 500);
} else {
setError(data.error?.message || 'Login fehlgeschlagen');
}

View File

@@ -0,0 +1,46 @@
// URL-Hash-Preservation Utilities für Login-Flow
// Vollständige URL mit Hash speichern (für Login-Redirects)
export const preserveFullUrl = () => {
const fullUrl = window.location.pathname + window.location.search + window.location.hash;
return fullUrl || '/';
};
// Hash aus URL extrahieren (ohne #)
export const extractHash = () => {
return window.location.hash.substring(1);
};
// Hash in localStorage speichern (für komplexe Login-Flows)
export const saveHashForRedirect = () => {
const hash = extractHash();
if (hash) {
localStorage.setItem('pendingHash', hash);
}
};
// Gespeichtes Hash wiederherstellen und löschen
export const restoreAndClearHash = () => {
const hash = localStorage.getItem('pendingHash');
if (hash) {
localStorage.removeItem('pendingHash');
return hash;
}
return null;
};
// Nach Login zum gespeicherten Hash navigieren
export const redirectToSavedHash = (navigate) => {
const hash = restoreAndClearHash();
if (hash) {
// Hash in URL setzen und scrollen
window.location.hash = hash;
// Scroll-Event für den Fall dass scrollToAnchor nicht automatisch ausgelöst wird
setTimeout(() => {
const element = document.getElementById(hash);
if (element) {
element.scrollIntoView({ behavior: 'smooth', block: 'center' });
}
}, 100);
}
};