Add user account route and bookmark functionality: Implement '/my-account' route for user bookmarks and personal mindmap, enhance mindmap visualization with bookmark management, and update UI elements for better user experience.
This commit is contained in:
@@ -822,6 +822,12 @@ def chat_with_assistant():
|
||||
print(f"Fehler bei der KI-Anfrage: {str(e)}")
|
||||
return jsonify({"success": False, "error": "Fehler bei der Verarbeitung der Anfrage"}), 500
|
||||
|
||||
# Route für Benutzer-Merkliste und persönliche Mindmap
|
||||
@app.route('/my-account')
|
||||
@login_required
|
||||
def my_account():
|
||||
return render_template('my_account.html', current_year=current_year)
|
||||
|
||||
# Flask starten
|
||||
if __name__ == '__main__':
|
||||
with app.app_context():
|
||||
|
||||
@@ -32,6 +32,9 @@ class MindMapVisualization {
|
||||
this.tooltipDiv = null;
|
||||
this.isLoading = true;
|
||||
|
||||
// Lade die gemerkten Knoten
|
||||
this.bookmarkedNodes = this.loadBookmarkedNodes();
|
||||
|
||||
// Sicherstellen, dass der Container bereit ist
|
||||
if (this.container.node()) {
|
||||
this.init();
|
||||
@@ -154,10 +157,13 @@ class MindMapVisualization {
|
||||
this.isLoading = false;
|
||||
this.updateVisualization();
|
||||
|
||||
// API-Aufruf mit längeren Timeout im Hintergrund durchführen
|
||||
// Status auf bereit setzen - don't wait for API
|
||||
this.container.attr('data-status', 'ready');
|
||||
|
||||
// API-Aufruf mit kürzerem Timeout im Hintergrund durchführen
|
||||
try {
|
||||
const controller = new AbortController();
|
||||
const timeoutId = setTimeout(() => controller.abort(), 10000); // 10 Sekunden Timeout
|
||||
const timeoutId = setTimeout(() => controller.abort(), 5000); // 5 Sekunden Timeout - reduced from 10
|
||||
|
||||
const response = await fetch('/api/mindmap', {
|
||||
signal: controller.signal,
|
||||
@@ -169,14 +175,15 @@ class MindMapVisualization {
|
||||
clearTimeout(timeoutId);
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP Fehler: ${response.status}`);
|
||||
console.warn(`HTTP Fehler: ${response.status}, verwende Standarddaten`);
|
||||
return; // Keep using default data
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
if (!data || !data.nodes || data.nodes.length === 0) {
|
||||
console.warn('Keine Mindmap-Daten vorhanden, verwende weiterhin Standard-Daten.');
|
||||
return; // Behalte Standarddaten bei
|
||||
return; // Keep using default data
|
||||
}
|
||||
|
||||
// Flache Liste von Knoten und Verbindungen erstellen
|
||||
@@ -187,14 +194,9 @@ class MindMapVisualization {
|
||||
// Visualisierung aktualisieren mit den tatsächlichen Daten
|
||||
this.updateVisualization();
|
||||
|
||||
// Status auf bereit setzen
|
||||
this.container.attr('data-status', 'ready');
|
||||
|
||||
} catch (error) {
|
||||
console.warn('Fehler beim Laden der Mindmap-Daten, verwende Standarddaten:', error);
|
||||
// Fallback zu Standarddaten ist bereits geschehen
|
||||
// Stellen Sie sicher, dass der Status korrekt gesetzt wird
|
||||
this.container.attr('data-status', 'ready');
|
||||
// Already using default data, no action needed
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
@@ -366,11 +368,11 @@ class MindMapVisualization {
|
||||
|
||||
// Kreis für jeden Knoten
|
||||
group.append('circle')
|
||||
.attr('class', 'node')
|
||||
.attr('class', d => `node ${this.isNodeBookmarked(d.id) ? 'bookmarked' : ''}`)
|
||||
.attr('r', this.nodeRadius)
|
||||
.attr('fill', d => d.color || this.generateColorFromString(d.name))
|
||||
.attr('stroke', '#ffffff50')
|
||||
.attr('stroke-width', 2)
|
||||
.attr('stroke', d => this.isNodeBookmarked(d.id) ? '#FFD700' : '#ffffff50')
|
||||
.attr('stroke-width', d => this.isNodeBookmarked(d.id) ? 3 : 2)
|
||||
.attr('filter', 'url(#glow)');
|
||||
|
||||
// Text-Label mit besserem Kontrast
|
||||
@@ -398,7 +400,10 @@ class MindMapVisualization {
|
||||
update => {
|
||||
// Knoten aktualisieren
|
||||
update.select('.node')
|
||||
.attr('fill', d => d.color || this.generateColorFromString(d.name));
|
||||
.attr('class', d => `node ${this.isNodeBookmarked(d.id) ? 'bookmarked' : ''}`)
|
||||
.attr('fill', d => d.color || this.generateColorFromString(d.name))
|
||||
.attr('stroke', d => this.isNodeBookmarked(d.id) ? '#FFD700' : '#ffffff50')
|
||||
.attr('stroke-width', d => this.isNodeBookmarked(d.id) ? 3 : 2);
|
||||
|
||||
// Text aktualisieren
|
||||
update.select('.node-label')
|
||||
@@ -465,6 +470,7 @@ class MindMapVisualization {
|
||||
|
||||
// Tooltip anzeigen
|
||||
if (this.tooltipEnabled) {
|
||||
const isBookmarked = this.isNodeBookmarked(d.id);
|
||||
const tooltipContent = `
|
||||
<div class="p-2">
|
||||
<strong>${d.name}</strong>
|
||||
@@ -472,6 +478,12 @@ class MindMapVisualization {
|
||||
<div class="text-xs text-gray-300 mt-1">
|
||||
Gedanken: ${d.thought_count}
|
||||
</div>
|
||||
<div class="mt-2">
|
||||
<button id="bookmark-button" class="px-2 py-1 text-xs rounded bg-gray-700 hover:bg-gray-600 text-white"
|
||||
data-nodeid="${d.id}">
|
||||
${isBookmarked ? '<i class="fas fa-bookmark mr-1"></i> Gemerkt' : '<i class="far fa-bookmark mr-1"></i> Merken'}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
@@ -482,6 +494,20 @@ class MindMapVisualization {
|
||||
.transition()
|
||||
.duration(200)
|
||||
.style('opacity', 1);
|
||||
|
||||
// Event-Listener für den Bookmark-Button hinzufügen
|
||||
document.getElementById('bookmark-button').addEventListener('click', (e) => {
|
||||
e.stopPropagation();
|
||||
const nodeId = e.currentTarget.getAttribute('data-nodeid');
|
||||
const isNowBookmarked = this.toggleBookmark(nodeId);
|
||||
|
||||
// Button-Text aktualisieren
|
||||
if (isNowBookmarked) {
|
||||
e.currentTarget.innerHTML = '<i class="fas fa-bookmark mr-1"></i> Gemerkt';
|
||||
} else {
|
||||
e.currentTarget.innerHTML = '<i class="far fa-bookmark mr-1"></i> Merken';
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Knoten visuell hervorheben
|
||||
@@ -489,7 +515,7 @@ class MindMapVisualization {
|
||||
.transition()
|
||||
.duration(200)
|
||||
.attr('r', this.nodeRadius * 1.2)
|
||||
.attr('stroke', '#ffffff');
|
||||
.attr('stroke', this.isNodeBookmarked(d.id) ? '#FFD700' : '#ffffff');
|
||||
}
|
||||
|
||||
nodeMouseout(event, d) {
|
||||
@@ -506,11 +532,13 @@ class MindMapVisualization {
|
||||
// Knoten-Stil zurücksetzen, wenn nicht ausgewählt
|
||||
const nodeElement = d3.select(event.currentTarget).select('circle');
|
||||
if (d !== this.selectedNode) {
|
||||
const isBookmarked = this.isNodeBookmarked(d.id);
|
||||
nodeElement
|
||||
.transition()
|
||||
.duration(200)
|
||||
.attr('r', this.nodeRadius)
|
||||
.attr('stroke', '#ffffff50');
|
||||
.attr('stroke', isBookmarked ? '#FFD700' : '#ffffff50')
|
||||
.attr('stroke-width', isBookmarked ? 3 : 2);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -671,6 +699,78 @@ class MindMapVisualization {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Lädt gemerkete Knoten aus dem LocalStorage
|
||||
loadBookmarkedNodes() {
|
||||
try {
|
||||
const bookmarked = localStorage.getItem('bookmarkedNodes');
|
||||
return bookmarked ? JSON.parse(bookmarked) : [];
|
||||
} catch (error) {
|
||||
console.error('Fehler beim Laden der gemerkten Knoten:', error);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
// Speichert gemerkete Knoten im LocalStorage
|
||||
saveBookmarkedNodes() {
|
||||
try {
|
||||
localStorage.setItem('bookmarkedNodes', JSON.stringify(this.bookmarkedNodes));
|
||||
} catch (error) {
|
||||
console.error('Fehler beim Speichern der gemerkten Knoten:', error);
|
||||
}
|
||||
}
|
||||
|
||||
// Prüft, ob ein Knoten gemerkt ist
|
||||
isNodeBookmarked(nodeId) {
|
||||
return this.bookmarkedNodes.includes(nodeId);
|
||||
}
|
||||
|
||||
// Merkt einen Knoten oder hebt die Markierung auf
|
||||
toggleBookmark(nodeId) {
|
||||
const index = this.bookmarkedNodes.indexOf(nodeId);
|
||||
if (index === -1) {
|
||||
// Node hinzufügen
|
||||
this.bookmarkedNodes.push(nodeId);
|
||||
this.updateNodeAppearance(nodeId, true);
|
||||
} else {
|
||||
// Node entfernen
|
||||
this.bookmarkedNodes.splice(index, 1);
|
||||
this.updateNodeAppearance(nodeId, false);
|
||||
}
|
||||
|
||||
// Änderungen speichern
|
||||
this.saveBookmarkedNodes();
|
||||
|
||||
// Event auslösen für andere Komponenten
|
||||
const event = new CustomEvent('nodeBookmarkToggled', {
|
||||
detail: {
|
||||
nodeId: nodeId,
|
||||
isBookmarked: index === -1
|
||||
}
|
||||
});
|
||||
document.dispatchEvent(event);
|
||||
|
||||
return index === -1; // true wenn jetzt gemerkt, false wenn Markierung aufgehoben
|
||||
}
|
||||
|
||||
// Aktualisiert das Aussehen eines Knotens basierend auf Bookmark-Status
|
||||
updateNodeAppearance(nodeId, isBookmarked) {
|
||||
this.g.selectAll('.node-group')
|
||||
.filter(d => d.id === nodeId)
|
||||
.select('.node')
|
||||
.classed('bookmarked', isBookmarked)
|
||||
.attr('stroke', isBookmarked ? '#FFD700' : '#ffffff50')
|
||||
.attr('stroke-width', isBookmarked ? 3 : 2);
|
||||
}
|
||||
|
||||
// Aktualisiert das Aussehen aller gemerkten Knoten
|
||||
updateAllBookmarkedNodes() {
|
||||
this.g.selectAll('.node-group')
|
||||
.each((d) => {
|
||||
const isBookmarked = this.isNodeBookmarked(d.id);
|
||||
this.updateNodeAppearance(d.id, isBookmarked);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Exportiere die Klasse für die Verwendung in anderen Modulen
|
||||
|
||||
@@ -601,7 +601,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Benutzermenü oder Login -->
|
||||
<!-- Profil-Link oder Login -->
|
||||
{% if current_user.is_authenticated %}
|
||||
<div class="relative" x-data="{ open: false }">
|
||||
<button @click="open = !open"
|
||||
@@ -642,6 +642,13 @@
|
||||
: 'text-gray-700 hover:bg-purple-500/10'">
|
||||
<i class="fa-solid fa-user mr-2 text-purple-400"></i>Profil
|
||||
</a>
|
||||
<a href="{{ url_for('my_account') }}"
|
||||
class="block px-4 py-3 transition-colors duration-200 flex items-center"
|
||||
x-bind:class="darkMode
|
||||
? 'text-white/90 hover:bg-purple-500/20'
|
||||
: 'text-gray-700 hover:bg-purple-500/10'">
|
||||
<i class="fa-solid fa-bookmark mr-2 text-purple-400"></i>Meine Merkliste
|
||||
</a>
|
||||
<a href="{{ url_for('settings') }}"
|
||||
class="block px-4 py-3 transition-colors duration-200 flex items-center"
|
||||
x-bind:class="darkMode
|
||||
@@ -663,9 +670,9 @@
|
||||
<a href="{{ url_for('login') }}"
|
||||
class="flex items-center px-4 py-2.5 rounded-xl font-medium transition-all duration-300"
|
||||
x-bind:class="darkMode
|
||||
? 'bg-purple-500/30 text-white hover:bg-purple-600/40 shadow-md hover:shadow-lg hover:-translate-y-0.5'
|
||||
: 'bg-purple-500/20 text-gray-800 hover:bg-purple-500/30 shadow-sm hover:shadow-md hover:-translate-y-0.5'">
|
||||
<i class="fa-solid fa-right-to-bracket mr-2"></i>Anmelden
|
||||
? 'bg-gray-800/80 text-white hover:bg-gray-700/80 shadow-md hover:shadow-lg hover:-translate-y-0.5'
|
||||
: 'bg-gray-200/80 text-gray-800 hover:bg-gray-300/80 shadow-sm hover:shadow-md hover:-translate-y-0.5'">
|
||||
<i class="fa-solid fa-user mr-2"></i>Mein Konto
|
||||
</a>
|
||||
{% endif %}
|
||||
|
||||
|
||||
@@ -859,6 +859,13 @@
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Aktualisiere das Aussehen von Bookmarks, sobald die Mindmap vollständig geladen ist
|
||||
setTimeout(() => {
|
||||
if (mindmap && typeof mindmap.updateAllBookmarkedNodes === 'function') {
|
||||
mindmap.updateAllBookmarkedNodes();
|
||||
}
|
||||
}, 1000);
|
||||
});
|
||||
|
||||
// Animationen für die Hintergrundeffekte
|
||||
|
||||
320
website/templates/my_account.html
Normal file
320
website/templates/my_account.html
Normal file
@@ -0,0 +1,320 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}Meine Merkliste{% endblock %}
|
||||
|
||||
{% block extra_css %}
|
||||
<style>
|
||||
/* Hintergrund über die gesamte Seite erstrecken */
|
||||
html, body {
|
||||
min-height: 100vh;
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.personal-mindmap-container {
|
||||
width: 100%;
|
||||
height: 400px;
|
||||
background-color: rgba(0, 0, 0, 0.1);
|
||||
border-radius: 1rem;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.dark .personal-mindmap-container {
|
||||
background-color: rgba(255, 255, 255, 0.05);
|
||||
}
|
||||
|
||||
.bookmark-item {
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.bookmark-item:hover {
|
||||
transform: translateY(-3px);
|
||||
}
|
||||
|
||||
.empty-state {
|
||||
padding: 2rem;
|
||||
text-align: center;
|
||||
background-color: rgba(0, 0, 0, 0.05);
|
||||
border-radius: 1rem;
|
||||
}
|
||||
|
||||
.dark .empty-state {
|
||||
background-color: rgba(255, 255, 255, 0.03);
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<!-- Hauptbereich -->
|
||||
<div class="max-w-screen-xl mx-auto px-4 sm:px-6 lg:px-8 pt-8 pb-12">
|
||||
<!-- Header -->
|
||||
<div class="mb-8">
|
||||
<h1 class="text-3xl font-bold text-gray-900 dark:text-white mb-2">
|
||||
<span class="gradient-text">Meine Merkliste</span>
|
||||
</h1>
|
||||
<p class="text-lg text-gray-700 dark:text-gray-300">
|
||||
Deine persönliche Sammlung gemerkter Wissensbereiche und Beiträge
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Persönliche Mindmap -->
|
||||
<div class="mb-12">
|
||||
<h2 class="text-xl font-bold text-gray-800 dark:text-white mb-4 flex items-center">
|
||||
<i class="fas fa-project-diagram mr-3 text-purple-500"></i>
|
||||
Meine Mindmap
|
||||
</h2>
|
||||
|
||||
<div id="personal-mindmap" class="personal-mindmap-container glass-morphism">
|
||||
<div id="empty-mindmap-message" class="absolute inset-0 flex items-center justify-center">
|
||||
<div class="text-center p-6">
|
||||
<div class="text-6xl mb-4 opacity-20">
|
||||
<i class="fas fa-bookmark"></i>
|
||||
</div>
|
||||
<h3 class="text-xl font-semibold mb-2 text-gray-700 dark:text-gray-300">Deine persönliche Mindmap ist leer</h3>
|
||||
<p class="text-gray-600 dark:text-gray-400 max-w-md mx-auto">
|
||||
Merke dir Wissensbereiche und Gedanken in der Hauptmindmap, um deine persönliche Mindmap zu erstellen.
|
||||
</p>
|
||||
<a href="{{ url_for('mindmap') }}" class="mt-4 inline-block px-4 py-2 bg-purple-500 text-white rounded-lg hover:bg-purple-600 transition-colors">
|
||||
Zur Mindmap
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Gemerkte Inhalte -->
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-8 mb-8">
|
||||
<!-- Wissensbereiche -->
|
||||
<div>
|
||||
<h2 class="text-xl font-bold text-gray-800 dark:text-white mb-4 flex items-center">
|
||||
<i class="fas fa-folder-open mr-3 text-blue-500"></i>
|
||||
Gemerkte Wissensbereiche
|
||||
</h2>
|
||||
|
||||
<div id="bookmarked-areas-container" class="space-y-4">
|
||||
<!-- Ladezustand -->
|
||||
<div class="animate-pulse space-y-4">
|
||||
<div class="h-16 bg-gray-200 dark:bg-gray-700 rounded-lg"></div>
|
||||
<div class="h-16 bg-gray-200 dark:bg-gray-700 rounded-lg"></div>
|
||||
<div class="h-16 bg-gray-200 dark:bg-gray-700 rounded-lg"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Gedanken -->
|
||||
<div>
|
||||
<h2 class="text-xl font-bold text-gray-800 dark:text-white mb-4 flex items-center">
|
||||
<i class="fas fa-lightbulb mr-3 text-amber-500"></i>
|
||||
Gemerkte Gedanken
|
||||
</h2>
|
||||
|
||||
<div id="bookmarked-thoughts-container" class="space-y-4">
|
||||
<!-- Ladezustand -->
|
||||
<div class="animate-pulse space-y-4">
|
||||
<div class="h-16 bg-gray-200 dark:bg-gray-700 rounded-lg"></div>
|
||||
<div class="h-16 bg-gray-200 dark:bg-gray-700 rounded-lg"></div>
|
||||
<div class="h-16 bg-gray-200 dark:bg-gray-700 rounded-lg"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- JavaScript für persönliche Mindmap -->
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
// Lade gespeicherte Bookmarks aus dem LocalStorage
|
||||
function loadBookmarkedNodes() {
|
||||
try {
|
||||
const bookmarked = localStorage.getItem('bookmarkedNodes');
|
||||
return bookmarked ? JSON.parse(bookmarked) : [];
|
||||
} catch (error) {
|
||||
console.error('Fehler beim Laden der gemerkten Knoten:', error);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
const bookmarkedNodeIds = loadBookmarkedNodes();
|
||||
|
||||
// Prüfe, ob es gemerkte Knoten gibt
|
||||
if (bookmarkedNodeIds && bookmarkedNodeIds.length > 0) {
|
||||
// Verstecke die Leer-Nachricht
|
||||
document.getElementById('empty-mindmap-message').style.display = 'none';
|
||||
|
||||
// Initialisiere die persönliche Mindmap
|
||||
const personalMindmap = new MindMapVisualization('#personal-mindmap', {
|
||||
width: document.getElementById('personal-mindmap').clientWidth,
|
||||
height: 400,
|
||||
nodeRadius: 18,
|
||||
selectedNodeRadius: 22,
|
||||
linkDistance: 120,
|
||||
chargeStrength: -800,
|
||||
centerForce: 0.1,
|
||||
tooltipEnabled: true
|
||||
});
|
||||
|
||||
// Lade Daten für die Mindmap - hier müssten wir normalerweise die API nutzen,
|
||||
// aber als Fallback laden wir die Standarddaten und filtern sie
|
||||
window.setTimeout(() => {
|
||||
// Wenn die Hauptmindmap geladen ist, können wir deren Daten verwenden
|
||||
if (window.mindmapInstance) {
|
||||
// Filtere nur gemerkte Knoten und ihre Verbindungen
|
||||
const nodes = window.mindmapInstance.nodes.filter(node =>
|
||||
bookmarkedNodeIds.includes(node.id)
|
||||
);
|
||||
|
||||
// Finde Verbindungen zwischen den gemerkten Knoten
|
||||
const links = window.mindmapInstance.links.filter(link =>
|
||||
bookmarkedNodeIds.includes(link.source.id || link.source) &&
|
||||
bookmarkedNodeIds.includes(link.target.id || link.target)
|
||||
);
|
||||
|
||||
// Setze Daten und aktualisiere die Visualisierung
|
||||
personalMindmap.nodes = nodes;
|
||||
personalMindmap.links = links;
|
||||
personalMindmap.isLoading = false;
|
||||
personalMindmap.updateVisualization();
|
||||
} else {
|
||||
// Fallback: Leere Mindmap anzeigen
|
||||
document.getElementById('empty-mindmap-message').style.display = 'flex';
|
||||
}
|
||||
}, 800);
|
||||
|
||||
// Lade die gemerkten Inhalte
|
||||
loadBookmarkedContent(bookmarkedNodeIds);
|
||||
} else {
|
||||
// Zeige Leerzustand an
|
||||
const areasContainer = document.getElementById('bookmarked-areas-container');
|
||||
const thoughtsContainer = document.getElementById('bookmarked-thoughts-container');
|
||||
|
||||
areasContainer.innerHTML = `
|
||||
<div class="empty-state">
|
||||
<div class="text-4xl mb-2 opacity-20">
|
||||
<i class="fas fa-folder-open"></i>
|
||||
</div>
|
||||
<p class="text-gray-600 dark:text-gray-400">Keine gemerkten Wissensbereiche</p>
|
||||
</div>
|
||||
`;
|
||||
|
||||
thoughtsContainer.innerHTML = `
|
||||
<div class="empty-state">
|
||||
<div class="text-4xl mb-2 opacity-20">
|
||||
<i class="fas fa-lightbulb"></i>
|
||||
</div>
|
||||
<p class="text-gray-600 dark:text-gray-400">Keine gemerkten Gedanken</p>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
});
|
||||
|
||||
// Funktion zum Laden der gemerkten Inhalte
|
||||
function loadBookmarkedContent(nodeIds) {
|
||||
if (!nodeIds || nodeIds.length === 0) return;
|
||||
|
||||
// In einer vollständigen Implementierung würden wir hier einen API-Aufruf machen
|
||||
// Für diese Demo erstellen wir Beispielinhalte
|
||||
|
||||
const areasContainer = document.getElementById('bookmarked-areas-container');
|
||||
const thoughtsContainer = document.getElementById('bookmarked-thoughts-container');
|
||||
|
||||
// Verschiedene Beispiel-Farben
|
||||
const colors = ['purple', 'blue', 'green', 'indigo', 'amber'];
|
||||
|
||||
// Leere die Container
|
||||
areasContainer.innerHTML = '';
|
||||
thoughtsContainer.innerHTML = '';
|
||||
|
||||
// Beispielinhalte für Wissensbereiche
|
||||
const areaTemplates = [
|
||||
{ name: 'Philosophie', description: 'Grundlagen philosophischen Denkens', count: 24 },
|
||||
{ name: 'Wissenschaft', description: 'Wissenschaftliche Methoden und Erkenntnisse', count: 42 },
|
||||
{ name: 'Technologie', description: 'Zukunftsweisende Technologien', count: 36 },
|
||||
{ name: 'Kunst', description: 'Künstlerische Ausdrucksformen', count: 18 },
|
||||
{ name: 'Psychologie', description: 'Menschliches Verhalten verstehen', count: 30 }
|
||||
];
|
||||
|
||||
// Beispielinhalte für Gedanken
|
||||
const thoughtTemplates = [
|
||||
{ title: 'Quantenphysik und Bewusstsein', author: 'Maria Schmidt', date: '12.04.2023' },
|
||||
{ title: 'Ethik in der künstlichen Intelligenz', author: 'Thomas Weber', date: '23.02.2023' },
|
||||
{ title: 'Die Rolle der Kunst in der Gesellschaft', author: 'Lena Müller', date: '05.06.2023' },
|
||||
{ title: 'Nachhaltige Entwicklung im 21. Jahrhundert', author: 'Michael Bauer', date: '18.08.2023' },
|
||||
{ title: 'Kognitive Verzerrungen im Alltag', author: 'Sophie Klein', date: '30.09.2023' }
|
||||
];
|
||||
|
||||
// Zeige nur so viele Elemente wie wir Knoten haben (bis zu 5)
|
||||
const areaCount = Math.min(nodeIds.length, 5);
|
||||
|
||||
if (areaCount > 0) {
|
||||
// Wissensbereiche hinzufügen
|
||||
for (let i = 0; i < areaCount; i++) {
|
||||
const area = areaTemplates[i];
|
||||
const colorClass = colors[i % colors.length];
|
||||
|
||||
areasContainer.innerHTML += `
|
||||
<a href="{{ url_for('mindmap') }}" class="bookmark-item block p-4 rounded-xl bg-white/80 dark:bg-gray-800/80 shadow-sm hover:shadow-md transition-all">
|
||||
<div class="flex items-center">
|
||||
<div class="w-10 h-10 rounded-lg bg-${colorClass}-100 dark:bg-${colorClass}-900/30 flex items-center justify-center mr-3">
|
||||
<i class="fas fa-bookmark text-${colorClass}-500"></i>
|
||||
</div>
|
||||
<div class="flex-grow">
|
||||
<h3 class="font-semibold text-gray-900 dark:text-white">${area.name}</h3>
|
||||
<p class="text-sm text-gray-600 dark:text-gray-400">${area.description}</p>
|
||||
</div>
|
||||
<div class="text-xs text-gray-500 dark:text-gray-400">
|
||||
${area.count} Einträge
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
`;
|
||||
}
|
||||
} else {
|
||||
areasContainer.innerHTML = `
|
||||
<div class="empty-state">
|
||||
<div class="text-4xl mb-2 opacity-20">
|
||||
<i class="fas fa-folder-open"></i>
|
||||
</div>
|
||||
<p class="text-gray-600 dark:text-gray-400">Keine gemerkten Wissensbereiche</p>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
// Zeige bis zu 5 Gedanken an (oder weniger, falls weniger gemerkt wurden)
|
||||
const thoughtCount = Math.min(nodeIds.length, 5);
|
||||
|
||||
if (thoughtCount > 0) {
|
||||
// Gedanken hinzufügen
|
||||
for (let i = 0; i < thoughtCount; i++) {
|
||||
const thought = thoughtTemplates[i];
|
||||
const colorClass = colors[(i + 2) % colors.length]; // Andere Farben als für Bereiche
|
||||
|
||||
thoughtsContainer.innerHTML += `
|
||||
<a href="{{ url_for('mindmap') }}" class="bookmark-item block p-4 rounded-xl bg-white/80 dark:bg-gray-800/80 shadow-sm hover:shadow-md transition-all">
|
||||
<div class="flex items-center">
|
||||
<div class="w-10 h-10 rounded-lg bg-${colorClass}-100 dark:bg-${colorClass}-900/30 flex items-center justify-center mr-3">
|
||||
<i class="fas fa-lightbulb text-${colorClass}-500"></i>
|
||||
</div>
|
||||
<div class="flex-grow">
|
||||
<h3 class="font-semibold text-gray-900 dark:text-white">${thought.title}</h3>
|
||||
<p class="text-sm text-gray-600 dark:text-gray-400">Von ${thought.author} • ${thought.date}</p>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
`;
|
||||
}
|
||||
} else {
|
||||
thoughtsContainer.innerHTML = `
|
||||
<div class="empty-state">
|
||||
<div class="text-4xl mb-2 opacity-20">
|
||||
<i class="fas fa-lightbulb"></i>
|
||||
</div>
|
||||
<p class="text-gray-600 dark:text-gray-400">Keine gemerkten Gedanken</p>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user