refactoring

This commit is contained in:
2025-11-10 13:39:12 +01:00
parent 5341a2e4ba
commit ea95188dd7
2 changed files with 216 additions and 120 deletions

View File

@@ -0,0 +1,158 @@
import { useCallback, useEffect, useRef, useState } from 'react';
const TOKEN_STORAGE_KEY = 'pickupConfigToken';
const useSessionManager = ({
normalizeConfigEntries,
normalizeAdminSettings,
onUnauthorized,
setError,
setLoading
}) => {
const [session, setSession] = useState(null);
const unauthorizedRef = useRef(onUnauthorized || (() => {}));
useEffect(() => {
unauthorizedRef.current = onUnauthorized || (() => {});
}, [onUnauthorized]);
const handleUnauthorized = useCallback(() => {
setSession(null);
try {
localStorage.removeItem(TOKEN_STORAGE_KEY);
} catch (storageError) {
console.warn('Konnte Token nicht aus dem Speicher entfernen:', storageError);
}
unauthorizedRef.current();
}, []);
const handleUnauthorizedRef = useRef(() => {});
useEffect(() => {
handleUnauthorizedRef.current = handleUnauthorized;
}, [handleUnauthorized]);
const authorizedFetch = useCallback(
async (url, options = {}, tokenOverride) => {
const activeToken = tokenOverride || session?.token;
if (!activeToken) {
throw new Error('Keine aktive Session');
}
const headers = {
Authorization: `Bearer ${activeToken}`,
...(options.headers || {})
};
const response = await fetch(url, { ...options, headers });
if (response.status === 401) {
handleUnauthorizedRef.current();
throw new Error('Nicht autorisiert');
}
return response;
},
[session?.token]
);
const storeToken = useCallback((token) => {
if (!token) {
return;
}
try {
localStorage.setItem(TOKEN_STORAGE_KEY, token);
} catch (storageError) {
console.warn('Konnte Token nicht speichern:', storageError);
}
}, []);
const getStoredToken = useCallback(() => {
try {
return localStorage.getItem(TOKEN_STORAGE_KEY);
} catch (storageError) {
console.warn('Konnte gespeicherten Token nicht lesen:', storageError);
return null;
}
}, []);
const bootstrapSession = useCallback(
async (token, { progress } = {}) => {
if (!token) {
return {};
}
setLoading(true);
setError('');
progress?.update?.('Session wird aufgebaut...', 20);
try {
const response = await fetch('/api/auth/session', {
headers: { Authorization: `Bearer ${token}` }
});
if (response.status === 401) {
handleUnauthorized();
return {};
}
if (!response.ok) {
throw new Error(`HTTP ${response.status}`);
}
const data = await response.json();
const sessionData = { token, profile: data.profile, isAdmin: data.isAdmin };
setSession(sessionData);
progress?.update?.('Betriebe werden geprüft...', 45);
const stores = Array.isArray(data.stores) ? data.stores : [];
const adminSettings = data.isAdmin ? normalizeAdminSettings(data.adminSettings) : null;
const configResponse = await fetch('/api/config', {
headers: { Authorization: `Bearer ${token}` }
});
if (configResponse.status === 401) {
handleUnauthorized();
return {};
}
if (!configResponse.ok) {
throw new Error(`HTTP ${configResponse.status}`);
}
const configData = await configResponse.json();
progress?.update?.('Konfiguration wird geladen...', 75);
const config = normalizeConfigEntries(Array.isArray(configData) ? configData : []);
progress?.update?.('Synchronisierung abgeschlossen', 95);
return {
session: sessionData,
stores,
adminSettings,
config,
storeRefreshJob: data.storeRefreshJob,
storesFresh: data.storesFresh
};
} catch (error) {
setError(`Session konnte nicht wiederhergestellt werden: ${error.message}`);
return {};
} finally {
setLoading(false);
}
},
[normalizeAdminSettings, normalizeConfigEntries, handleUnauthorized, setError, setLoading]
);
const performLogout = useCallback(async () => {
if (!session?.token) {
handleUnauthorized();
return;
}
try {
await authorizedFetch('/api/auth/logout', { method: 'POST' });
} catch (err) {
console.warn('Logout fehlgeschlagen:', err);
} finally {
handleUnauthorized();
}
}, [session?.token, authorizedFetch, handleUnauthorized]);
return {
session,
authorizedFetch,
bootstrapSession,
performLogout,
handleUnauthorized,
storeToken,
getStoredToken
};
};
export default useSessionManager;