Compare commits
2 Commits
3ae5f2527c
...
44c7183e97
| Author | SHA1 | Date | |
|---|---|---|---|
| 44c7183e97 | |||
| d99cae4956 |
2
.env
2
.env
@@ -4,7 +4,7 @@
|
|||||||
# Flask
|
# Flask
|
||||||
FLASK_APP=app.py
|
FLASK_APP=app.py
|
||||||
FLASK_DEBUG=1
|
FLASK_DEBUG=1
|
||||||
SECRET_KEY=your-secret-key-replace-in-production
|
SECRET_KEY=ETMyh4JfBfvpZSscqfuzjCOAvelm5lEju
|
||||||
|
|
||||||
# OpenAI API
|
# OpenAI API
|
||||||
OPENAI_API_KEY=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
|
OPENAI_API_KEY=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
|
||||||
|
|||||||
@@ -250,6 +250,36 @@
|
|||||||
transform: translateY(-2px);
|
transform: translateY(-2px);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.profile-tab.active {
|
||||||
|
color: white;
|
||||||
|
background: rgba(179, 143, 255, 0.2);
|
||||||
|
border-bottom: 3px solid rgba(179, 143, 255, 0.7);
|
||||||
|
transform: translateY(-2px);
|
||||||
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.profile-tab.active::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 3px;
|
||||||
|
background: linear-gradient(90deg, #8B5CF6, #6366F1);
|
||||||
|
border-radius: 3px 3px 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Animation für Tab-Inhalte */
|
||||||
|
.tab-content {
|
||||||
|
transition: all 0.35s cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-content.hidden {
|
||||||
|
display: none;
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(10px);
|
||||||
|
}
|
||||||
|
|
||||||
/* Statistik-Elemente - verkleinert */
|
/* Statistik-Elemente - verkleinert */
|
||||||
.stat-item {
|
.stat-item {
|
||||||
padding: 0.75rem !important;
|
padding: 0.75rem !important;
|
||||||
@@ -322,7 +352,9 @@
|
|||||||
<span><i class="fas fa-map-marker-alt"></i> {{ user.location if user.location else 'Kein Standort angegeben' }}</span>
|
<span><i class="fas fa-map-marker-alt"></i> {{ user.location if user.location else 'Kein Standort angegeben' }}</span>
|
||||||
<span><i class="fas fa-calendar-alt"></i> Mitglied seit {{ user.created_at.strftime('%d.%m.%Y') }}</span>
|
<span><i class="fas fa-calendar-alt"></i> Mitglied seit {{ user.created_at.strftime('%d.%m.%Y') }}</span>
|
||||||
</div>
|
</div>
|
||||||
<button class="edit-profile-btn">Profil bearbeiten</button>
|
<button class="edit-profile-btn mt-4 bg-purple-600 hover:bg-purple-700 text-white font-semibold py-2 px-4 rounded-lg transition-all duration-300 flex items-center">
|
||||||
|
<i class="fas fa-user-edit mr-2"></i> Profil bearbeiten
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -534,16 +566,25 @@
|
|||||||
<div class="tab-content hidden" id="collections-tab">
|
<div class="tab-content hidden" id="collections-tab">
|
||||||
<div id="collections-container">
|
<div id="collections-container">
|
||||||
{% if collections %}
|
{% if collections %}
|
||||||
|
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
||||||
{% for collection in collections %}
|
{% for collection in collections %}
|
||||||
<div class="collection-item">
|
<div class="collection-item bg-opacity-70 rounded-xl overflow-hidden border border-gray-700/60 bg-gray-800/80 transition-all duration-300 hover:transform hover:scale-105 hover:shadow-lg">
|
||||||
<h3>{{ collection.title }}</h3>
|
<div class="p-5">
|
||||||
<p>{{ collection.description }}</p>
|
<h3 class="text-xl font-bold mb-2 text-purple-400">{{ collection.title }}</h3>
|
||||||
<div class="collection-meta">
|
<p class="mb-4 text-sm text-gray-300">{{ collection.description }}</p>
|
||||||
|
<div class="flex justify-between items-center text-xs text-gray-400">
|
||||||
<span>{{ collection.thoughts_count }} Gedanken</span>
|
<span>{{ collection.thoughts_count }} Gedanken</span>
|
||||||
<span>{{ collection.date }}</span>
|
<span>{{ collection.date }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="p-3 border-t border-gray-700/60 bg-gray-900/80 flex justify-center">
|
||||||
|
<a href="#" class="text-purple-400 hover:text-purple-300 transition-colors">
|
||||||
|
<i class="fas fa-eye mr-1"></i> Anzeigen
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
</div>
|
||||||
{% else %}
|
{% else %}
|
||||||
<div class="text-center py-12">
|
<div class="text-center py-12">
|
||||||
<i class="fas fa-folder-open text-5xl text-gray-400 mb-4"></i>
|
<i class="fas fa-folder-open text-5xl text-gray-400 mb-4"></i>
|
||||||
@@ -557,27 +598,29 @@
|
|||||||
<div class="tab-content hidden" id="connections-tab">
|
<div class="tab-content hidden" id="connections-tab">
|
||||||
<div id="connections-container">
|
<div id="connections-container">
|
||||||
{% if connections %}
|
{% if connections %}
|
||||||
|
<div class="grid grid-cols-1 gap-6">
|
||||||
{% for connection in connections %}
|
{% for connection in connections %}
|
||||||
<div class="connection-item">
|
<div class="connection-item bg-opacity-70 rounded-xl p-4 border border-gray-700/60 bg-gray-800/80 transition-all duration-300 hover:bg-gray-800/95">
|
||||||
<div class="connection-nodes">
|
<div class="connection-nodes flex items-stretch">
|
||||||
<div class="connection-node">
|
<div class="connection-node flex-1 p-4 rounded-lg bg-gray-900/80 text-white">
|
||||||
<h4>{{ connection.source.title }}</h4>
|
<h4 class="font-semibold mb-1">{{ connection.source.title }}</h4>
|
||||||
<p>{{ connection.source.excerpt }}</p>
|
<p class="text-sm text-gray-400">{{ connection.source.excerpt }}</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="connection-type">
|
<div class="connection-type flex flex-col items-center justify-center px-4">
|
||||||
<i class="fas fa-arrow-right"></i>
|
<i class="fas fa-arrow-right text-purple-400 mb-1"></i>
|
||||||
<span>{{ connection.relation_type }}</span>
|
<span class="text-xs text-gray-500">{{ connection.relation_type }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="connection-node">
|
<div class="connection-node flex-1 p-4 rounded-lg bg-gray-900/80 text-white">
|
||||||
<h4>{{ connection.target.title }}</h4>
|
<h4 class="font-semibold mb-1">{{ connection.target.title }}</h4>
|
||||||
<p>{{ connection.target.excerpt }}</p>
|
<p class="text-sm text-gray-400">{{ connection.target.excerpt }}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="connection-meta">
|
<div class="connection-meta mt-2 text-right">
|
||||||
<span>{{ connection.date }}</span>
|
<span class="text-xs text-gray-500">{{ connection.date }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
</div>
|
||||||
{% else %}
|
{% else %}
|
||||||
<div class="text-center py-12">
|
<div class="text-center py-12">
|
||||||
<i class="fas fa-project-diagram text-5xl text-gray-400 mb-4"></i>
|
<i class="fas fa-project-diagram text-5xl text-gray-400 mb-4"></i>
|
||||||
@@ -590,54 +633,50 @@
|
|||||||
|
|
||||||
<div class="tab-content hidden" id="settings-tab">
|
<div class="tab-content hidden" id="settings-tab">
|
||||||
<!-- Einstellungs-Tab-Inhalt -->
|
<!-- Einstellungs-Tab-Inhalt -->
|
||||||
<div class="settings-card">
|
<div class="settings-card bg-white/10 backdrop-blur-md rounded-xl p-6 mb-6 border border-white/10">
|
||||||
<div class="settings-card-header">Profilinformationen</div>
|
<div class="settings-card-header text-xl font-bold mb-4 text-purple-300">Profilinformationen</div>
|
||||||
<div class="settings-card-body">
|
<div class="settings-card-body">
|
||||||
<div class="settings-group">
|
<div class="settings-group mb-4">
|
||||||
<label class="settings-label" for="name">Name</label>
|
<label class="settings-label block text-gray-300 mb-2" for="bio">Über mich</label>
|
||||||
<input type="text" id="name" class="settings-input" value="{{ user.name }}" />
|
<textarea id="bio" class="settings-input w-full bg-gray-800/60 border border-gray-700/60 text-white rounded-lg p-3 focus:ring-2 focus:ring-purple-500 focus:border-transparent transition-all" rows="4">{{ user.bio }}</textarea>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="settings-group">
|
<div class="settings-group mb-4">
|
||||||
<label class="settings-label" for="bio">Über mich</label>
|
<label class="settings-label block text-gray-300 mb-2" for="location">Standort</label>
|
||||||
<textarea id="bio" class="settings-input" rows="4">{{ user.bio }}</textarea>
|
<input type="text" id="location" class="settings-input w-full bg-gray-800/60 border border-gray-700/60 text-white rounded-lg p-3 focus:ring-2 focus:ring-purple-500 focus:border-transparent transition-all" value="{{ user.location }}" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="settings-group">
|
<div class="settings-group mb-4">
|
||||||
<label class="settings-label" for="location">Standort</label>
|
<label class="settings-label block text-gray-300 mb-2" for="website">Website</label>
|
||||||
<input type="text" id="location" class="settings-input" value="{{ user.location }}" />
|
<input type="url" id="website" class="settings-input w-full bg-gray-800/60 border border-gray-700/60 text-white rounded-lg p-3 focus:ring-2 focus:ring-purple-500 focus:border-transparent transition-all" value="{{ user.website }}" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="settings-group">
|
<button id="save-profile-btn" class="profile-action-btn primary mt-4">
|
||||||
<label class="settings-label" for="website">Website</label>
|
|
||||||
<input type="url" id="website" class="settings-input" value="{{ user.website }}" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<button class="profile-action-btn primary mt-4">
|
|
||||||
<i class="fas fa-save mr-1"></i> Speichern
|
<i class="fas fa-save mr-1"></i> Speichern
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="settings-card">
|
<div class="settings-card bg-white/10 backdrop-blur-md rounded-xl p-6 mb-6 border border-white/10">
|
||||||
<div class="settings-card-header">Datenschutz und Sicherheit</div>
|
<div class="settings-card-header text-xl font-bold mb-4 text-purple-300">Datenschutz und Sicherheit</div>
|
||||||
<div class="settings-card-body">
|
<div class="settings-card-body">
|
||||||
<div class="settings-group">
|
<div class="settings-group mb-4">
|
||||||
<label class="settings-label" for="email">E-Mail-Adresse</label>
|
<label class="settings-label block text-gray-300 mb-2" for="email">E-Mail-Adresse</label>
|
||||||
<input type="email" id="email" class="settings-input" value="{{ user.email }}" />
|
<input type="email" id="email" class="settings-input w-full bg-gray-800/60 border border-gray-700/60 text-white rounded-lg p-3 focus:ring-2 focus:ring-purple-500 focus:border-transparent transition-all" value="{{ user.email }}" readonly />
|
||||||
|
<p class="text-xs text-gray-500 mt-1">Die E-Mail-Adresse kann derzeit nicht geändert werden.</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="settings-group">
|
<div class="settings-group mb-4">
|
||||||
<label class="settings-label" for="password">Neues Passwort</label>
|
<label class="settings-label block text-gray-300 mb-2" for="password">Neues Passwort</label>
|
||||||
<input type="password" id="password" class="settings-input" placeholder="Neues Passwort eingeben" />
|
<input type="password" id="password" class="settings-input w-full bg-gray-800/60 border border-gray-700/60 text-white rounded-lg p-3 focus:ring-2 focus:ring-purple-500 focus:border-transparent transition-all" placeholder="Neues Passwort eingeben" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="settings-group">
|
<div class="settings-group mb-4">
|
||||||
<label class="settings-label" for="password_confirm">Passwort bestätigen</label>
|
<label class="settings-label block text-gray-300 mb-2" for="password_confirm">Passwort bestätigen</label>
|
||||||
<input type="password" id="password_confirm" class="settings-input" placeholder="Passwort wiederholen" />
|
<input type="password" id="password_confirm" class="settings-input w-full bg-gray-800/60 border border-gray-700/60 text-white rounded-lg p-3 focus:ring-2 focus:ring-purple-500 focus:border-transparent transition-all" placeholder="Passwort wiederholen" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button class="profile-action-btn primary mt-4">
|
<button id="update-password-btn" class="profile-action-btn primary mt-4">
|
||||||
<i class="fas fa-lock mr-1"></i> Passwort aktualisieren
|
<i class="fas fa-lock mr-1"></i> Passwort aktualisieren
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -655,6 +694,12 @@
|
|||||||
const tabs = document.querySelectorAll('.profile-tab');
|
const tabs = document.querySelectorAll('.profile-tab');
|
||||||
const tabContents = document.querySelectorAll('.tab-content');
|
const tabContents = document.querySelectorAll('.tab-content');
|
||||||
|
|
||||||
|
// Standardmäßig den ersten Tab aktivieren
|
||||||
|
if (tabs.length > 0 && tabContents.length > 0) {
|
||||||
|
tabs[0].classList.add('active');
|
||||||
|
tabContents[0].classList.remove('hidden');
|
||||||
|
}
|
||||||
|
|
||||||
tabs.forEach(tab => {
|
tabs.forEach(tab => {
|
||||||
tab.addEventListener('click', function() {
|
tab.addEventListener('click', function() {
|
||||||
// Alle Tabs deaktivieren
|
// Alle Tabs deaktivieren
|
||||||
@@ -706,6 +751,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
countElement.textContent = count;
|
countElement.textContent = count;
|
||||||
|
|
||||||
|
// Hier könnte ein AJAX-Request erfolgen, um die Reaktion zu speichern
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -726,7 +773,7 @@
|
|||||||
const avatarEditBtn = document.querySelector('.avatar-edit');
|
const avatarEditBtn = document.querySelector('.avatar-edit');
|
||||||
if (avatarEditBtn) {
|
if (avatarEditBtn) {
|
||||||
avatarEditBtn.addEventListener('click', function() {
|
avatarEditBtn.addEventListener('click', function() {
|
||||||
// Dateiauwahl öffnen
|
// Dateiauswahl öffnen
|
||||||
const fileInput = document.createElement('input');
|
const fileInput = document.createElement('input');
|
||||||
fileInput.type = 'file';
|
fileInput.type = 'file';
|
||||||
fileInput.accept = 'image/*';
|
fileInput.accept = 'image/*';
|
||||||
@@ -738,13 +785,27 @@
|
|||||||
fileInput.addEventListener('change', function() {
|
fileInput.addEventListener('change', function() {
|
||||||
if (this.files && this.files[0]) {
|
if (this.files && this.files[0]) {
|
||||||
// Anzeigen des gewählten Bildes
|
// Anzeigen des gewählten Bildes
|
||||||
const avatarImg = document.querySelector('.avatar');
|
const avatarImg = document.querySelector('.avatar') || document.querySelector('.default-avatar');
|
||||||
|
|
||||||
// FileReader zum Einlesen des Bildes
|
// FileReader zum Einlesen des Bildes
|
||||||
const reader = new FileReader();
|
const reader = new FileReader();
|
||||||
reader.onload = function(e) {
|
reader.onload = function(e) {
|
||||||
// Vorschau anzeigen
|
// Vorschau anzeigen
|
||||||
|
if (avatarImg.tagName.toLowerCase() === 'img') {
|
||||||
avatarImg.src = e.target.result;
|
avatarImg.src = e.target.result;
|
||||||
|
} else {
|
||||||
|
// Falls es ein div mit SVG ist, ersetzen wir es durch ein Image
|
||||||
|
const imgElement = document.createElement('img');
|
||||||
|
imgElement.src = e.target.result;
|
||||||
|
imgElement.classList.add('avatar');
|
||||||
|
imgElement.alt = "Profilbild";
|
||||||
|
|
||||||
|
const avatarContainer = document.querySelector('.avatar-container');
|
||||||
|
if (avatarContainer) {
|
||||||
|
avatarContainer.innerHTML = '';
|
||||||
|
avatarContainer.appendChild(imgElement);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Avatar-URL im Einstellungsbereich speichern
|
// Avatar-URL im Einstellungsbereich speichern
|
||||||
const avatarUrlInput = document.createElement('input');
|
const avatarUrlInput = document.createElement('input');
|
||||||
@@ -778,59 +839,11 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Einstellungen-Formular-Handling
|
// Profil Speichern-Button
|
||||||
const saveSettingsBtn = document.querySelectorAll('.settings-card .profile-action-btn.primary');
|
const saveProfileBtn = document.getElementById('save-profile-btn');
|
||||||
|
|
||||||
saveSettingsBtn.forEach(btn => {
|
if (saveProfileBtn) {
|
||||||
btn.addEventListener('click', function() {
|
saveProfileBtn.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
|
// Sammle Daten aus den Eingabefeldern
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
formData.append('action', 'update_profile');
|
formData.append('action', 'update_profile');
|
||||||
@@ -888,9 +901,61 @@
|
|||||||
showNotification(data?.message || 'Fehler beim Aktualisieren des Profils', 'error');
|
showNotification(data?.message || 'Fehler beim Aktualisieren des Profils', 'error');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Passwort Update Button
|
||||||
|
const updatePasswordBtn = document.getElementById('update-password-btn');
|
||||||
|
|
||||||
|
if (updatePasswordBtn) {
|
||||||
|
updatePasswordBtn.addEventListener('click', function() {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentPassword !== newPassword) {
|
||||||
|
showNotification('Die Passwörter stimmen nicht überein', 'error');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// AJAX-Anfrage senden
|
||||||
|
const formData = new FormData();
|
||||||
|
formData.append('action', 'update_password');
|
||||||
|
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> Aktualisieren...';
|
||||||
|
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');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Gedanken-Karten mit Hover-Effekten und Border-Farben
|
// Gedanken-Karten mit Hover-Effekten und Border-Farben
|
||||||
const thoughtItems = document.querySelectorAll('.thought-item');
|
const thoughtItems = document.querySelectorAll('.thought-item');
|
||||||
@@ -909,7 +974,7 @@
|
|||||||
// Border-Farben anwenden
|
// Border-Farben anwenden
|
||||||
const borderElem = item.querySelector('.thought-border');
|
const borderElem = item.querySelector('.thought-border');
|
||||||
if (borderElem && borderElem.dataset.color) {
|
if (borderElem && borderElem.dataset.color) {
|
||||||
borderElem.style.borderLeftColor = borderElem.dataset.color;
|
borderElem.style.borderLeft = `4px solid ${borderElem.dataset.color}`;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user