"Refactor database schema for user profiles and profile templates updated to remove obsolete db table 'systades (feat): systades.db) system data)"
This commit is contained in:
@@ -985,52 +985,173 @@
|
||||
});
|
||||
}
|
||||
|
||||
// Einstellungen-Formular-Handling
|
||||
const settingsForm = document.querySelector('.settings-card form');
|
||||
const saveSettingsBtn = document.querySelector('.settings-card .profile-action-btn.primary');
|
||||
|
||||
if (saveSettingsBtn && !settingsForm) {
|
||||
saveSettingsBtn.addEventListener('click', function() {
|
||||
// Sammle Daten aus den Eingabefeldern
|
||||
const formData = new FormData();
|
||||
formData.append('action', 'update_profile');
|
||||
formData.append('bio', document.getElementById('bio').value);
|
||||
formData.append('location', document.getElementById('location').value);
|
||||
formData.append('website', document.getElementById('website').value || '');
|
||||
// Avatar-Bearbeitung
|
||||
const avatarEditBtn = document.querySelector('.avatar-edit');
|
||||
if (avatarEditBtn) {
|
||||
avatarEditBtn.addEventListener('click', function() {
|
||||
// Dateiauwahl öffnen
|
||||
const fileInput = document.createElement('input');
|
||||
fileInput.type = 'file';
|
||||
fileInput.accept = 'image/*';
|
||||
fileInput.style.display = 'none';
|
||||
document.body.appendChild(fileInput);
|
||||
|
||||
// AJAX-Anfrage senden
|
||||
fetch('{{ url_for("settings") }}', {
|
||||
method: 'POST',
|
||||
body: formData,
|
||||
credentials: 'same-origin'
|
||||
})
|
||||
.then(response => response.json())
|
||||
.catch(error => {
|
||||
console.error('Fehler beim Speichern der Profileinstellungen:', error);
|
||||
})
|
||||
.then(data => {
|
||||
// Erfolgsanimation
|
||||
const originalText = this.innerHTML;
|
||||
this.innerHTML = '<i class="fas fa-check mr-1"></i> Gespeichert';
|
||||
fileInput.click();
|
||||
|
||||
fileInput.addEventListener('change', function() {
|
||||
if (this.files && this.files[0]) {
|
||||
// Anzeigen des gewählten Bildes
|
||||
const avatarImg = document.querySelector('.avatar');
|
||||
|
||||
// FileReader zum Einlesen des Bildes
|
||||
const reader = new FileReader();
|
||||
reader.onload = function(e) {
|
||||
// Vorschau anzeigen
|
||||
avatarImg.src = e.target.result;
|
||||
|
||||
// Avatar-URL im Einstellungsbereich speichern
|
||||
const avatarUrlInput = document.createElement('input');
|
||||
avatarUrlInput.type = 'hidden';
|
||||
avatarUrlInput.name = 'avatar_url';
|
||||
avatarUrlInput.id = 'avatar_url';
|
||||
avatarUrlInput.value = e.target.result;
|
||||
|
||||
// Entferne vorhandenes Input, falls vorhanden
|
||||
const existingInput = document.getElementById('avatar_url');
|
||||
if (existingInput) {
|
||||
existingInput.remove();
|
||||
}
|
||||
|
||||
// Zum Formular hinzufügen
|
||||
const settingsForm = document.querySelector('.settings-card');
|
||||
if (settingsForm) {
|
||||
settingsForm.appendChild(avatarUrlInput);
|
||||
}
|
||||
|
||||
// Erfolgsmeldung anzeigen
|
||||
showNotification('Avatar wurde aktualisiert! Bitte speichere deine Änderungen.', 'success');
|
||||
};
|
||||
|
||||
reader.readAsDataURL(this.files[0]);
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
this.innerHTML = originalText;
|
||||
}, 2000);
|
||||
// Input entfernen
|
||||
document.body.removeChild(fileInput);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Mindmap-Karten mit Hover-Effekten
|
||||
const mindmapItems = document.querySelectorAll('.mindmap-item');
|
||||
mindmapItems.forEach(item => {
|
||||
item.addEventListener('mouseenter', () => {
|
||||
item.style.transform = 'translateY(-5px)';
|
||||
item.style.boxShadow = '0 12px 30px rgba(0, 0, 0, 0.15)';
|
||||
});
|
||||
|
||||
item.addEventListener('mouseleave', () => {
|
||||
item.style.transform = 'translateY(0)';
|
||||
item.style.boxShadow = 'none';
|
||||
// Einstellungen-Formular-Handling
|
||||
const saveSettingsBtn = document.querySelectorAll('.settings-card .profile-action-btn.primary');
|
||||
|
||||
saveSettingsBtn.forEach(btn => {
|
||||
btn.addEventListener('click', function() {
|
||||
const isPasswordUpdate = this.textContent.includes('Passwort');
|
||||
|
||||
// Passwort-Update
|
||||
if (isPasswordUpdate) {
|
||||
const currentPassword = document.getElementById('password').value;
|
||||
const newPassword = document.getElementById('password_confirm').value;
|
||||
|
||||
if (!currentPassword || !newPassword) {
|
||||
showNotification('Bitte fülle alle Passwortfelder aus', 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
// AJAX-Anfrage senden
|
||||
const formData = new FormData();
|
||||
formData.append('action', 'update_password');
|
||||
formData.append('current_password', currentPassword);
|
||||
formData.append('new_password', newPassword);
|
||||
formData.append('confirm_password', newPassword);
|
||||
|
||||
// Visuelle Rückmeldung
|
||||
const originalText = this.innerHTML;
|
||||
this.innerHTML = '<i class="fas fa-circle-notch fa-spin mr-1"></i> Speichern...';
|
||||
this.disabled = true;
|
||||
|
||||
fetch('{{ url_for("settings") }}', {
|
||||
method: 'POST',
|
||||
body: formData
|
||||
})
|
||||
.then(response => response.json())
|
||||
.catch(error => {
|
||||
console.error('Fehler beim Aktualisieren des Passworts:', error);
|
||||
return { success: false, message: 'Netzwerkfehler. Bitte versuche es erneut.' };
|
||||
})
|
||||
.then(data => {
|
||||
this.innerHTML = originalText;
|
||||
this.disabled = false;
|
||||
|
||||
if (data && data.success) {
|
||||
showNotification('Passwort erfolgreich aktualisiert!', 'success');
|
||||
document.getElementById('password').value = '';
|
||||
document.getElementById('password_confirm').value = '';
|
||||
} else {
|
||||
showNotification(data?.message || 'Fehler beim Aktualisieren des Passworts', 'error');
|
||||
}
|
||||
});
|
||||
}
|
||||
// Profil-Update
|
||||
else {
|
||||
// Sammle Daten aus den Eingabefeldern
|
||||
const formData = new FormData();
|
||||
formData.append('action', 'update_profile');
|
||||
formData.append('bio', document.getElementById('bio').value || '');
|
||||
formData.append('location', document.getElementById('location').value || '');
|
||||
formData.append('website', document.getElementById('website').value || '');
|
||||
|
||||
// Avatar hinzufügen, falls vorhanden
|
||||
const avatarUrlInput = document.getElementById('avatar_url');
|
||||
if (avatarUrlInput) {
|
||||
formData.append('avatar_url', avatarUrlInput.value);
|
||||
}
|
||||
|
||||
// Visuelle Rückmeldung
|
||||
const originalText = this.innerHTML;
|
||||
this.innerHTML = '<i class="fas fa-circle-notch fa-spin mr-1"></i> Speichern...';
|
||||
this.disabled = true;
|
||||
|
||||
// AJAX-Anfrage senden
|
||||
fetch('{{ url_for("settings") }}', {
|
||||
method: 'POST',
|
||||
body: formData
|
||||
})
|
||||
.then(response => {
|
||||
if (!response.ok) {
|
||||
throw new Error('Fehler beim Speichern');
|
||||
}
|
||||
return response.json();
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Fehler beim Speichern der Profileinstellungen:', error);
|
||||
return { success: false, message: 'Netzwerkfehler. Bitte versuche es erneut.' };
|
||||
})
|
||||
.then(data => {
|
||||
this.innerHTML = originalText;
|
||||
this.disabled = false;
|
||||
|
||||
if (data && data.success) {
|
||||
// Erfolgsanimation
|
||||
showNotification('Profil erfolgreich aktualisiert!', 'success');
|
||||
|
||||
// UI aktualisieren ohne Neuladen
|
||||
const bioElement = document.querySelector('.user-bio');
|
||||
const locationElement = document.querySelector('.user-meta span:first-child');
|
||||
|
||||
if (bioElement) {
|
||||
bioElement.textContent = document.getElementById('bio').value || 'Keine Bio vorhanden. Klicke auf bearbeiten, um eine hinzuzufügen.';
|
||||
}
|
||||
|
||||
if (locationElement) {
|
||||
const location = document.getElementById('location').value;
|
||||
locationElement.innerHTML = `<i class="fas fa-map-marker-alt"></i> ${location || 'Kein Standort angegeben'}`;
|
||||
}
|
||||
} else {
|
||||
showNotification(data?.message || 'Fehler beim Aktualisieren des Profils', 'error');
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1054,6 +1175,76 @@
|
||||
borderElem.style.borderLeftColor = borderElem.dataset.color;
|
||||
}
|
||||
});
|
||||
|
||||
// Mindmap-Karten mit Hover-Effekten
|
||||
const mindmapItems = document.querySelectorAll('.mindmap-item');
|
||||
mindmapItems.forEach(item => {
|
||||
item.addEventListener('mouseenter', () => {
|
||||
item.style.transform = 'translateY(-5px)';
|
||||
item.style.boxShadow = '0 12px 30px rgba(0, 0, 0, 0.15)';
|
||||
});
|
||||
|
||||
item.addEventListener('mouseleave', () => {
|
||||
item.style.transform = 'translateY(0)';
|
||||
item.style.boxShadow = 'none';
|
||||
});
|
||||
});
|
||||
|
||||
// Benachrichtigungsfunktion
|
||||
function showNotification(message, type = 'info') {
|
||||
// Bestehende Benachrichtigung entfernen
|
||||
const existingNotification = document.getElementById('notification');
|
||||
if (existingNotification) {
|
||||
existingNotification.remove();
|
||||
}
|
||||
|
||||
// Neue Benachrichtigung erstellen
|
||||
const notification = document.createElement('div');
|
||||
notification.id = 'notification';
|
||||
notification.className = `fixed top-4 right-4 p-4 rounded-lg shadow-lg z-50 flex items-center transform transition-all duration-300 translate-y-0 opacity-0`;
|
||||
|
||||
// Typ-basierte Stile
|
||||
if (type === 'success') {
|
||||
notification.classList.add('bg-green-500', 'text-white');
|
||||
notification.innerHTML = `<i class="fas fa-check-circle mr-2"></i> ${message}`;
|
||||
} else if (type === 'error') {
|
||||
notification.classList.add('bg-red-500', 'text-white');
|
||||
notification.innerHTML = `<i class="fas fa-exclamation-circle mr-2"></i> ${message}`;
|
||||
} else {
|
||||
notification.classList.add('bg-blue-500', 'text-white');
|
||||
notification.innerHTML = `<i class="fas fa-info-circle mr-2"></i> ${message}`;
|
||||
}
|
||||
|
||||
// Close-Button
|
||||
const closeBtn = document.createElement('button');
|
||||
closeBtn.className = 'ml-4 text-white opacity-75 hover:opacity-100';
|
||||
closeBtn.innerHTML = '<i class="fas fa-times"></i>';
|
||||
closeBtn.addEventListener('click', () => {
|
||||
notification.classList.add('opacity-0', 'translate-y-[-10px]');
|
||||
setTimeout(() => notification.remove(), 300);
|
||||
});
|
||||
|
||||
notification.appendChild(closeBtn);
|
||||
document.body.appendChild(notification);
|
||||
|
||||
// Animation starten
|
||||
setTimeout(() => {
|
||||
notification.classList.remove('opacity-0');
|
||||
notification.classList.add('opacity-100');
|
||||
}, 10);
|
||||
|
||||
// Automatisch ausblenden nach 5 Sekunden
|
||||
setTimeout(() => {
|
||||
if (document.body.contains(notification)) {
|
||||
notification.classList.add('opacity-0', 'translate-y-[-10px]');
|
||||
setTimeout(() => {
|
||||
if (document.body.contains(notification)) {
|
||||
notification.remove();
|
||||
}
|
||||
}, 300);
|
||||
}
|
||||
}, 5000);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user