feat: Anzeigename im Web (Profil bearbeiten + Anzeige)
- Profil: Anzeigename + Login-Name editierbar (vorher Benutzername read-only). Login-Namenwechsel speichert den frisch zurueckgegebenen Token. - Menue/Dropdown und "Erstellt von"/Picker zeigen den Anzeigenamen. - localStorage-User um display_name ergaenzt. Version v32. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -858,16 +858,21 @@
|
||||
|
||||
<!-- Account Info -->
|
||||
<div class="settings-section">
|
||||
<h4>Konto</h4>
|
||||
<h4 data-i18n="profile_account">Konto</h4>
|
||||
<div class="form-group">
|
||||
<label>Benutzername</label>
|
||||
<input type="text" id="profile-username" disabled class="input-disabled" />
|
||||
<label data-i18n="profile_display_name">Anzeigename</label>
|
||||
<input type="text" id="profile-display-name-input" data-i18n-placeholder="profile_display_name_ph" placeholder="Anzeigename" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label data-i18n="profile_login_name">Login-Name</label>
|
||||
<input type="text" id="profile-username" spellcheck="false" autocapitalize="none" />
|
||||
<p class="panel-desc" data-i18n="profile_login_name_desc">Klein geschrieben, fürs Anmelden. Groß-/Kleinschreibung egal.</p>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>E-Mail</label>
|
||||
<input type="email" id="profile-email" placeholder="Keine E-Mail hinterlegt" />
|
||||
</div>
|
||||
<button class="btn btn-primary btn-sm" id="profile-save-info">Speichern</button>
|
||||
<button class="btn btn-primary btn-sm" id="profile-save-info" data-i18n="save">Speichern</button>
|
||||
</div>
|
||||
|
||||
<!-- Password -->
|
||||
|
||||
@@ -60,7 +60,7 @@ async function launchApp() {
|
||||
|
||||
// User dropdown menu
|
||||
const dropdown = document.getElementById('user-dropdown');
|
||||
document.getElementById('dropdown-username').textContent = user.username || 'Benutzer';
|
||||
document.getElementById('dropdown-username').textContent = user.display_name || user.username || 'Benutzer';
|
||||
|
||||
avatar.addEventListener('click', e => {
|
||||
e.stopPropagation();
|
||||
|
||||
@@ -2951,9 +2951,10 @@ function bindSettingsModal() {
|
||||
export function openProfileModal() {
|
||||
const user = JSON.parse(localStorage.getItem('user') || '{}');
|
||||
|
||||
// Username & email
|
||||
// Names & email
|
||||
document.getElementById('profile-username').value = user.username || '';
|
||||
document.getElementById('profile-display-name').textContent = user.username || '';
|
||||
document.getElementById('profile-display-name-input').value = user.display_name || user.username || '';
|
||||
document.getElementById('profile-display-name').textContent = user.display_name || user.username || '';
|
||||
|
||||
// Load fresh profile data
|
||||
api.get('/profile/').then(profile => {
|
||||
@@ -3021,11 +3022,26 @@ function renderProfileCalendars() {
|
||||
}
|
||||
|
||||
function bindProfileModal() {
|
||||
// Save profile info (email)
|
||||
// Save profile info (display name, login name, email)
|
||||
document.getElementById('profile-save-info').onclick = async () => {
|
||||
const email = document.getElementById('profile-email').value.trim();
|
||||
const displayName = document.getElementById('profile-display-name-input').value.trim();
|
||||
const loginName = document.getElementById('profile-username').value.trim();
|
||||
const user = JSON.parse(localStorage.getItem('user') || '{}');
|
||||
const body = { email: email || null };
|
||||
if (displayName) body.display_name = displayName;
|
||||
if (loginName && loginName.toLowerCase() !== (user.username || '')) body.username = loginName;
|
||||
try {
|
||||
await api.put('/profile/', { email: email || null });
|
||||
const res = await api.put('/profile/', body);
|
||||
// A login-name change returns a fresh token (the old one is now invalid).
|
||||
if (res && res.access_token) localStorage.setItem('token', res.access_token);
|
||||
// Keep the cached user (menu, "created by", etc.) in sync.
|
||||
const updated = { ...user };
|
||||
if (displayName) updated.display_name = displayName;
|
||||
if (body.username) updated.username = body.username.toLowerCase();
|
||||
localStorage.setItem('user', JSON.stringify(updated));
|
||||
const dd = document.getElementById('dropdown-username');
|
||||
if (dd) dd.textContent = updated.display_name || updated.username || 'Benutzer';
|
||||
showToast(t('profile_saved'));
|
||||
} catch (e) { showToast(e.message, true); }
|
||||
};
|
||||
|
||||
@@ -128,6 +128,11 @@ const translations = {
|
||||
settings_group_visible_desc: 'Wähle, welcher deiner Kalender für deine Gruppenmitglieder sichtbar ist',
|
||||
group_visible_none: 'Keiner',
|
||||
drag_reorder: 'Zum Sortieren ziehen',
|
||||
profile_account: 'Konto',
|
||||
profile_display_name: 'Anzeigename',
|
||||
profile_display_name_ph: 'Anzeigename',
|
||||
profile_login_name: 'Login-Name',
|
||||
profile_login_name_desc: 'Klein geschrieben, fürs Anmelden. Groß-/Kleinschreibung egal.',
|
||||
settings_hour_height: 'Stundenhöhe (Wochen- & Tagesansicht)',
|
||||
settings_hour_height_desc: 'Wie viel Platz eine Stunde in der Zeitrasteransicht einnimmt',
|
||||
hour_compact: 'Kompakt', hour_normal: 'Normal',
|
||||
@@ -387,6 +392,11 @@ const translations = {
|
||||
settings_group_visible_desc: 'Choose which of your calendars your group members can see',
|
||||
group_visible_none: 'None',
|
||||
drag_reorder: 'Drag to reorder',
|
||||
profile_account: 'Account',
|
||||
profile_display_name: 'Display name',
|
||||
profile_display_name_ph: 'Display name',
|
||||
profile_login_name: 'Login name',
|
||||
profile_login_name_desc: 'Lowercase, used to sign in. Case-insensitive.',
|
||||
settings_hour_height: 'Hour height (week & day view)',
|
||||
settings_hour_height_desc: 'How much space one hour takes in the time grid',
|
||||
hour_compact: 'Compact', hour_normal: 'Normal',
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
// Increment APP_VERSION with every code change
|
||||
export const APP_VERSION = 'v31';
|
||||
export const APP_VERSION = 'v32';
|
||||
|
||||
Reference in New Issue
Block a user