feat: Add email verification, owner shift deletion, Coolify Docker compose setup, and fixes

This commit is contained in:
Richard
2026-07-31 10:16:22 +02:00
parent a69f31649c
commit 6ffcc58a4c
13 changed files with 458 additions and 334 deletions
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -11,7 +11,7 @@
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@500;600;700&family=JetBrains+Mono:wght@400;500;600;700&family=Plus+Jakarta+Sans:wght@400;500;600;700;800&display=swap" rel="stylesheet">
<title>Schichtplaner — Veranstaltungsschichtpläne</title>
<script type="module" crossorigin src="/assets/index-D9iEQytx.js"></script>
<script type="module" crossorigin src="/assets/index-BHd9ZwUB.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-VOnznzhX.css">
</head>
<body class="bg-paper text-main font-sans antialiased min-h-screen">
+26 -2
View File
@@ -106,14 +106,34 @@ export default function App() {
try {
const userData = await apiFetch('/users/me/');
setUser(userData);
if (!userData.is_admin_user && !userData.is_staff && !userData.is_superuser && activeTab === 'admin') {
setActiveTab('home');
}
} catch (e) {
setAuthToken(null);
setUser(null);
setActiveTab('home');
}
}
// 3. Check URL parameters for guest account claim link
// 3. Check URL parameters for email verification and claim link
const urlParams = new URLSearchParams(window.location.search);
const verifyToken = urlParams.get('verify_email');
if (verifyToken) {
try {
const data = await apiFetch('/users/verify-email/', {
method: 'POST',
body: JSON.stringify({ token: verifyToken })
});
setAuthToken(data.token);
setUser(data.user);
showNotification(data.message || '✅ E-Mail-Adresse erfolgreich bestätigt!');
window.history.replaceState({}, document.title, window.location.pathname);
} catch (err) {
showNotification(`⚠️ E-Mail Bestätigung: ${err.message}`);
}
}
const cToken = urlParams.get('claim_token');
const gName = urlParams.get('guest_name');
if (cToken && gName) {
@@ -190,12 +210,16 @@ export default function App() {
const handleLogout = () => {
setAuthToken(null);
setUser(null);
setActiveTab('home');
showNotification('Erfolgreich abgemeldet.');
if (selectedEventId) fetchEventMatrix(selectedEventId);
};
const handleAuthSuccess = (userData, message) => {
setUser(userData);
if (userData && !userData.is_admin_user && !userData.is_staff && !userData.is_superuser && activeTab === 'admin') {
setActiveTab('home');
}
showNotification(message || 'Erfolgreich angemeldet!');
if (selectedEventId) fetchEventMatrix(selectedEventId);
};
@@ -423,7 +447,7 @@ export default function App() {
onSelectEvent={handleSelectEvent}
branding={branding}
/>
) : activeTab === 'admin' ? (
) : activeTab === 'admin' && user && (user.is_admin_user || user.is_staff || user.is_superuser) ? (
<AdminPage
branding={branding}
onRefreshBranding={async () => {
+2 -2
View File
@@ -48,8 +48,8 @@ export default function AuthModal({ onClose, onSuccess, claimToken, prefilledGue
body: JSON.stringify(bodyObj)
});
if (data.requires_approval) {
onSuccess(null, data.message);
if (data.requires_verification || data.requires_approval || !data.token) {
onSuccess(null, data.message || 'Konto erfolgreich registriert! Bitte schau in deine E-Mail zur Bestätigung oder warte auf die Admin-Freischaltung.');
onClose();
return;
}