fix: Render ProfileModal in App.jsx and support guest display name editing from Navbar

This commit is contained in:
Richard
2026-08-01 12:20:24 +02:00
parent 5f1607f0d3
commit 4b13e57fcb
4 changed files with 42 additions and 15 deletions
+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-BUskNRc4.js"></script>
<script type="module" crossorigin src="/assets/index-AKhcitQN.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-DHeBvKbG.css">
</head>
<body class="bg-paper text-main font-sans antialiased min-h-screen">
+14
View File
@@ -651,6 +651,20 @@ export default function App() {
onSubmit={handleGuestSubmit}
/>
)}
{showProfileModal && (
<ProfileModal
user={user}
skills={skills}
onClose={() => setShowProfileModal(false)}
onUserUpdated={(updatedUser) => {
setUser(updatedUser);
setShowProfileModal(false);
refreshEvents();
}}
onRefreshSkills={refreshSkills}
/>
)}
</div>
);
}
+8 -4
View File
@@ -62,13 +62,17 @@ export default function Navbar({
</h1>
<div className="text-[10px] font-mono text-muted mt-1 uppercase tracking-wider flex items-center gap-1.5">
{user ? (
<span className="text-emerald-500 font-semibold">[ {user.display_name || user.username} ]</span>
<span onClick={(e) => { e.stopPropagation(); onOpenProfile(); }} className="text-emerald-500 font-semibold hover:underline cursor-pointer">
[ {user.display_name || user.username} ]
</span>
) : savedGuestName ? (
<span className="text-amber-400 font-semibold flex items-center gap-1">
[ 👤 GAST: {savedGuestName} ]
<span onClick={(e) => { e.stopPropagation(); onOpenProfile(); }} className="text-amber-400 font-semibold flex items-center gap-1 hover:underline cursor-pointer" title="Klicken um Gast-Name zu ändern">
[ 👤 GAST: {savedGuestName} ]
</span>
) : (
<span className="text-amber-500 font-semibold">[ GAST-MODUS ]</span>
<span onClick={(e) => { e.stopPropagation(); onOpenProfile(); }} className="text-amber-500 font-semibold hover:underline cursor-pointer" title="Klicken um Gast-Name einzutragen">
[ GAST-MODUS ]
</span>
)}
</div>
</div>
+19 -10
View File
@@ -4,7 +4,9 @@ import { apiFetch } from '../api/client';
import { getRandomSkillColor } from '../utils/colors';
export default function ProfileModal({ user, skills, onClose, onUserUpdated, onRefreshSkills }) {
const [displayName, setDisplayName] = useState(user?.display_name || '');
const [displayName, setDisplayName] = useState(
user?.display_name || localStorage.getItem('guest_display_name') || ''
);
const [selectedSkillIds, setSelectedSkillIds] = useState(
user?.skills ? user.skills.map(s => s.id) : []
);
@@ -26,15 +28,22 @@ export default function ProfileModal({ user, skills, onClose, onUserUpdated, onR
setSavingProfile(true);
try {
const updatedUser = await apiFetch('/users/me/', {
method: 'PATCH',
body: JSON.stringify({
display_name: displayName.trim(),
skill_ids: selectedSkillIds
})
});
setSuccess('Profil und Anzeigename erfolgreich aktualisiert!');
onUserUpdated(updatedUser);
if (user) {
const updatedUser = await apiFetch('/users/me/', {
method: 'PATCH',
body: JSON.stringify({
display_name: displayName.trim(),
skill_ids: selectedSkillIds
})
});
setSuccess('Profil und Anzeigename erfolgreich aktualisiert!');
if (onUserUpdated) onUserUpdated(updatedUser);
} else {
localStorage.setItem('guest_display_name', displayName.trim());
window.dispatchEvent(new Event('guest_name_updated'));
setSuccess('Gast-Name erfolgreich gespeichert!');
setTimeout(() => onClose(), 600);
}
} catch (err) {
setError(err.message || 'Speichern des Profils fehlgeschlagen.');
} finally {