Profil-Seite: Anzeigename, Passwort ändern, Persona (ersetzt USER.md)
- Neuer Menüpunkt 'Mein Profil' statt 'Logout' - Profil-Page: Anzeigename, Persona (Freitext), Passwort ändern, Logout - ProfileEndpoint: GET/PUT /api/profile, PUT /api/profile/password - User-Persona im System-Prompt statt USER.md (Fallback: Anzeigename/Username) - SystemPromptBuilder: dataDir-Parameter entfernt, userPersona-Parameter hinzugefügt - DB-Migration: persona-Spalte in users-Tabelle
This commit is contained in:
1 parent
f49c526384
commit
7149904ae4
12 files changed
+341
-26
No files matched your search
@@ -221,6 +221,40 @@ async function apiRemoveAgentSkill(agentId, slug) {
|
||||
return fetch(`/api/agents/${agentId}/skills/${slug}`, { method: 'DELETE' });
|
||||
}
|
||||
|
||||
// ── Profile API ──
|
||||
|
||||
async function apiGetProfile() {
|
||||
const resp = await fetch('/api/profile');
|
||||
if (!resp.ok) return null;
|
||||
return resp.json();
|
||||
}
|
||||
|
||||
async function apiUpdateProfile(data) {
|
||||
const resp = await fetch('/api/profile', {
|
||||
method: 'PUT',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(data)
|
||||
});
|
||||
if (!resp.ok) {
|
||||
const err = await resp.json();
|
||||
throw new Error(err.error || 'Fehler beim Speichern');
|
||||
}
|
||||
return resp.json();
|
||||
}
|
||||
|
||||
async function apiChangePassword(currentPassword, newPassword) {
|
||||
const resp = await fetch('/api/profile/password', {
|
||||
method: 'PUT',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ currentPassword, newPassword })
|
||||
});
|
||||
if (!resp.ok) {
|
||||
const err = await resp.json();
|
||||
throw new Error(err.error || 'Fehler beim Ändern');
|
||||
}
|
||||
return resp.json();
|
||||
}
|
||||
|
||||
async function apiBackupDb() {
|
||||
const resp = await fetch('/api/backup', { method: 'POST' });
|
||||
if (!resp.ok) throw new Error('Backup fehlgeschlagen');
|
||||
|
||||
@@ -8,11 +8,10 @@ registerPage('dashboard', {
|
||||
navigateTo('settings');
|
||||
});
|
||||
|
||||
// Logout-Link
|
||||
document.getElementById('dashboardLogoutLink').addEventListener('click', async (e) => {
|
||||
// Profil-Link
|
||||
document.getElementById('dashboardProfileLink').addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
await apiLogout();
|
||||
navigateTo('login');
|
||||
navigateTo('profile');
|
||||
});
|
||||
|
||||
// Globaler Click-Handler zum Schließen aller Card-Menüs
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
// ── Profile Page ──
|
||||
|
||||
registerPage('profile', {
|
||||
async init() {
|
||||
var profile = await apiGetProfile();
|
||||
if (!profile) return;
|
||||
|
||||
var usernameInput = document.getElementById('profileUsername');
|
||||
var displayNameInput = document.getElementById('profileDisplayName');
|
||||
var personaInput = document.getElementById('profilePersona');
|
||||
var saveBtn = document.getElementById('profileSaveBtn');
|
||||
var messageDiv = document.getElementById('profileMessage');
|
||||
|
||||
var currentPwInput = document.getElementById('profileCurrentPassword');
|
||||
var newPwInput = document.getElementById('profileNewPassword');
|
||||
var confirmPwInput = document.getElementById('profileConfirmPassword');
|
||||
var passwordBtn = document.getElementById('profilePasswordBtn');
|
||||
var passwordMessageDiv = document.getElementById('profilePasswordMessage');
|
||||
|
||||
var logoutBtn = document.getElementById('profileLogoutBtn');
|
||||
|
||||
// Felder befüllen
|
||||
usernameInput.value = profile.username || '';
|
||||
displayNameInput.value = profile.displayName || '';
|
||||
personaInput.value = profile.persona || '';
|
||||
|
||||
// Profil speichern
|
||||
saveBtn.addEventListener('click', async function() {
|
||||
saveBtn.disabled = true;
|
||||
saveBtn.textContent = 'Speichern...';
|
||||
messageDiv.hidden = true;
|
||||
|
||||
try {
|
||||
var updated = await apiUpdateProfile({
|
||||
displayName: displayNameInput.value.trim(),
|
||||
persona: personaInput.value.trim()
|
||||
});
|
||||
|
||||
// currentUser aktualisieren
|
||||
if (currentUser) {
|
||||
currentUser.displayName = updated.displayName;
|
||||
}
|
||||
|
||||
messageDiv.textContent = 'Profil gespeichert';
|
||||
messageDiv.className = 'profile-message profile-message-success';
|
||||
messageDiv.hidden = false;
|
||||
setTimeout(function() { messageDiv.hidden = true; }, 3000);
|
||||
} catch (err) {
|
||||
messageDiv.textContent = err.message;
|
||||
messageDiv.className = 'profile-message profile-message-error';
|
||||
messageDiv.hidden = false;
|
||||
} finally {
|
||||
saveBtn.disabled = false;
|
||||
saveBtn.textContent = 'Speichern';
|
||||
}
|
||||
});
|
||||
|
||||
// Passwort ändern
|
||||
passwordBtn.addEventListener('click', async function() {
|
||||
passwordMessageDiv.hidden = true;
|
||||
|
||||
var currentPw = currentPwInput.value;
|
||||
var newPw = newPwInput.value;
|
||||
var confirmPw = confirmPwInput.value;
|
||||
|
||||
if (!currentPw || !newPw) {
|
||||
passwordMessageDiv.textContent = 'Alle Felder ausfüllen';
|
||||
passwordMessageDiv.className = 'profile-message profile-message-error';
|
||||
passwordMessageDiv.hidden = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (newPw !== confirmPw) {
|
||||
passwordMessageDiv.textContent = 'Neue Passwörter stimmen nicht überein';
|
||||
passwordMessageDiv.className = 'profile-message profile-message-error';
|
||||
passwordMessageDiv.hidden = false;
|
||||
return;
|
||||
}
|
||||
|
||||
passwordBtn.disabled = true;
|
||||
passwordBtn.textContent = 'Ändern...';
|
||||
|
||||
try {
|
||||
await apiChangePassword(currentPw, newPw);
|
||||
|
||||
currentPwInput.value = '';
|
||||
newPwInput.value = '';
|
||||
confirmPwInput.value = '';
|
||||
|
||||
passwordMessageDiv.textContent = 'Passwort geändert';
|
||||
passwordMessageDiv.className = 'profile-message profile-message-success';
|
||||
passwordMessageDiv.hidden = false;
|
||||
setTimeout(function() { passwordMessageDiv.hidden = true; }, 3000);
|
||||
} catch (err) {
|
||||
passwordMessageDiv.textContent = err.message;
|
||||
passwordMessageDiv.className = 'profile-message profile-message-error';
|
||||
passwordMessageDiv.hidden = false;
|
||||
} finally {
|
||||
passwordBtn.disabled = false;
|
||||
passwordBtn.textContent = 'Passwort ändern';
|
||||
}
|
||||
});
|
||||
|
||||
// Logout
|
||||
logoutBtn.addEventListener('click', async function() {
|
||||
await apiLogout();
|
||||
currentUser = null;
|
||||
navigateTo('login');
|
||||
});
|
||||
},
|
||||
destroy() {}
|
||||
});
|
||||
Reference in new issue
Block a user