"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:
2025-05-02 19:21:19 +02:00
parent d0821db983
commit 7003c89447
3 changed files with 313 additions and 63 deletions

View File

@@ -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 %}