762 lines
31 KiB
HTML
762 lines
31 KiB
HTML
{% 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>
|
|
|
|
<!-- Meine erstellten Mindmaps -->
|
|
<div class="mb-12">
|
|
<div class="flex justify-between items-center mb-4">
|
|
<h2 class="text-xl font-bold text-gray-800 dark:text-white flex items-center">
|
|
<i class="fas fa-brain mr-3 text-green-500"></i>
|
|
Meine erstellten Mindmaps
|
|
</h2>
|
|
<button id="create-mindmap-btn" class="px-4 py-2 bg-green-500 text-white rounded-lg hover:bg-green-600 transition-colors flex items-center">
|
|
<i class="fas fa-plus mr-2"></i> Neue Mindmap erstellen
|
|
</button>
|
|
</div>
|
|
<div id="user-mindmaps-container" class="space-y-4">
|
|
<!-- Hier werden die Mindmaps des Benutzers geladen -->
|
|
<p class="text-gray-600 dark:text-gray-400">Lade Mindmaps...</p>
|
|
</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>
|
|
|
|
<!-- Modal zum Erstellen einer neuen Mindmap -->
|
|
<div id="create-mindmap-modal" class="fixed inset-0 bg-gray-600 bg-opacity-50 overflow-y-auto h-full w-full flex items-center justify-center hidden z-50">
|
|
<div class="relative mx-auto p-5 border w-full max-w-md shadow-lg rounded-md bg-white dark:bg-gray-800">
|
|
<div class="mt-3 text-center">
|
|
<h3 class="text-lg leading-6 font-medium text-gray-900 dark:text-white">Neue Mindmap erstellen</h3>
|
|
<div class="mt-2 px-7 py-3">
|
|
<form id="create-mindmap-form">
|
|
<div class="mb-4">
|
|
<label for="mindmap-name" class="block text-sm font-medium text-gray-700 dark:text-gray-300 text-left">Name</label>
|
|
<input type="text" name="name" id="mindmap-name" class="mt-1 block w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm dark:bg-gray-700 dark:text-white" required>
|
|
</div>
|
|
<div class="mb-4">
|
|
<label for="mindmap-description" class="block text-sm font-medium text-gray-700 dark:text-gray-300 text-left">Beschreibung (optional)</label>
|
|
<textarea name="description" id="mindmap-description" rows="3" class="mt-1 block w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm dark:bg-gray-700 dark:text-white"></textarea>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
<div class="items-center px-4 py-3">
|
|
<button id="submit-create-mindmap" class="px-4 py-2 bg-green-500 text-white text-base font-medium rounded-md w-full shadow-sm hover:bg-green-600 focus:outline-none focus:ring-2 focus:ring-green-300">
|
|
Erstellen
|
|
</button>
|
|
<button id="cancel-create-mindmap" class="mt-2 px-4 py-2 bg-gray-300 text-gray-800 dark:bg-gray-600 dark:text-gray-200 text-base font-medium rounded-md w-full shadow-sm hover:bg-gray-400 dark:hover:bg-gray-500 focus:outline-none focus:ring-2 focus:ring-gray-300">
|
|
Abbrechen
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- JavaScript für persönliche Mindmap und CRUD -->
|
|
<script>
|
|
</script>
|
|
<script nonce="{{ csp_nonce }}">
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
// Modal-Logik
|
|
const createMindmapBtn = document.getElementById('create-mindmap-btn');
|
|
const createMindmapModal = document.getElementById('create-mindmap-modal');
|
|
const cancelCreateMindmapBtn = document.getElementById('cancel-create-mindmap');
|
|
const submitCreateMindmapBtn = document.getElementById('submit-create-mindmap');
|
|
const createMindmapForm = document.getElementById('create-mindmap-form');
|
|
|
|
if (createMindmapBtn) {
|
|
createMindmapBtn.addEventListener('click', () => {
|
|
createMindmapModal.classList.remove('hidden');
|
|
});
|
|
}
|
|
|
|
if (cancelCreateMindmapBtn) {
|
|
cancelCreateMindmapBtn.addEventListener('click', () => {
|
|
createMindmapModal.classList.add('hidden');
|
|
createMindmapForm.reset();
|
|
});
|
|
}
|
|
|
|
// Schließen bei Klick außerhalb des Modals
|
|
if (createMindmapModal) {
|
|
createMindmapModal.addEventListener('click', (event) => {
|
|
if (event.target === createMindmapModal) {
|
|
createMindmapModal.classList.add('hidden');
|
|
createMindmapForm.reset();
|
|
}
|
|
});
|
|
}
|
|
|
|
// Funktion zum Anzeigen von Benachrichtigungen
|
|
function showNotification(message, type = 'success') {
|
|
const notificationArea = document.getElementById('notification-area') || createNotificationArea();
|
|
const notificationId = `notif-${Date.now()}`;
|
|
constbgColor = type === 'success' ? 'bg-green-500' : (type === 'error' ? 'bg-red-500' : 'bg-blue-500');
|
|
|
|
const notificationElement = `
|
|
<div id="${notificationId}" class="p-4 mb-4 text-sm text-white rounded-lg ${bgColor} animate-fadeIn" role="alert">
|
|
<span class="font-medium">${type.charAt(0).toUpperCase() + type.slice(1)}:</span> ${message}
|
|
</div>
|
|
`;
|
|
notificationArea.insertAdjacentHTML('beforeend', notificationElement);
|
|
|
|
setTimeout(() => {
|
|
const el = document.getElementById(notificationId);
|
|
if (el) {
|
|
el.classList.add('animate-fadeOut');
|
|
setTimeout(() => el.remove(), 500);
|
|
}
|
|
}, 5000);
|
|
}
|
|
|
|
function createNotificationArea() {
|
|
const area = document.createElement('div');
|
|
area.id = 'notification-area';
|
|
area.className = 'fixed top-5 right-5 z-50 w-auto max-w-sm';
|
|
document.body.appendChild(area);
|
|
// Add some basic animation styles
|
|
const style = document.createElement('style');
|
|
style.textContent = `
|
|
.animate-fadeIn { animation: fadeIn 0.5s ease-out; }
|
|
.animate-fadeOut { animation: fadeOut 0.5s ease-in forwards; }
|
|
@keyframes fadeIn { from { opacity: 0; transform: translateY(-20px); } to { opacity: 1; transform: translateY(0); } }
|
|
@keyframes fadeOut { from { opacity: 1; transform: translateY(0); } to { opacity: 0; transform: translateY(-20px); } }
|
|
`;
|
|
document.head.appendChild(style);
|
|
return area;
|
|
}
|
|
|
|
|
|
// CRUD-Funktionen für UserMindmaps
|
|
const mindmapsContainer = document.getElementById('user-mindmaps-container');
|
|
|
|
async function fetchUserMindmaps() {
|
|
if (!mindmapsContainer) return;
|
|
mindmapsContainer.innerHTML = '<p class="text-gray-600 dark:text-gray-400">Lade Mindmaps...</p>';
|
|
try {
|
|
const response = await fetch('/api/mindmaps');
|
|
if (!response.ok) {
|
|
throw new Error(`HTTP error! status: ${response.status}`);
|
|
}
|
|
const mindmaps = await response.json();
|
|
renderMindmaps(mindmaps);
|
|
} catch (error) {
|
|
console.error('Fehler beim Laden der Mindmaps:', error);
|
|
mindmapsContainer.innerHTML = '<p class="text-red-500">Fehler beim Laden der Mindmaps.</p>';
|
|
showNotification('Fehler beim Laden der Mindmaps.', 'error');
|
|
}
|
|
}
|
|
|
|
function renderMindmaps(mindmaps) {
|
|
if (!mindmapsContainer) return;
|
|
if (mindmaps.length === 0) {
|
|
mindmapsContainer.innerHTML = '<p class="text-gray-600 dark:text-gray-400">Du hast noch keine eigenen Mindmaps erstellt.</p>';
|
|
return;
|
|
}
|
|
|
|
mindmapsContainer.innerHTML = ''; // Container leeren
|
|
const ul = document.createElement('ul');
|
|
ul.className = 'space-y-3';
|
|
|
|
mindmaps.forEach(mindmap => {
|
|
const li = document.createElement('li');
|
|
li.className = 'p-4 rounded-xl bg-white/80 dark:bg-gray-800/80 shadow-sm hover:shadow-md transition-all flex justify-between items-center';
|
|
|
|
const mindmapLink = document.createElement('a');
|
|
mindmapLink.href = `/user_mindmap/${mindmap.id}`;
|
|
mindmapLink.className = 'flex-grow';
|
|
|
|
const textDiv = document.createElement('div');
|
|
const nameH3 = document.createElement('h3');
|
|
nameH3.className = 'font-semibold text-gray-900 dark:text-white';
|
|
nameH3.textContent = mindmap.name;
|
|
textDiv.appendChild(nameH3);
|
|
|
|
if (mindmap.description) {
|
|
const descP = document.createElement('p');
|
|
descP.className = 'text-sm text-gray-600 dark:text-gray-400';
|
|
descP.textContent = mindmap.description;
|
|
textDiv.appendChild(descP);
|
|
}
|
|
mindmapLink.appendChild(textDiv);
|
|
li.appendChild(mindmapLink);
|
|
|
|
const actionsDiv = document.createElement('div');
|
|
actionsDiv.className = 'flex space-x-2 ml-4';
|
|
|
|
const editButton = document.createElement('a');
|
|
editButton.href = `/edit_mindmap/${mindmap.id}`; // oder JavaScript-basiertes Editieren
|
|
editButton.className = 'px-3 py-1 bg-blue-500 text-white rounded hover:bg-blue-600 text-sm flex items-center';
|
|
editButton.innerHTML = '<i class="fas fa-edit mr-1"></i> Bearbeiten';
|
|
// Hier könnte auch ein Event-Listener für ein Modal zum Bearbeiten hinzugefügt werden
|
|
// editButton.addEventListener('click', (e) => { e.preventDefault(); openEditModal(mindmap); });
|
|
actionsDiv.appendChild(editButton);
|
|
|
|
const deleteButton = document.createElement('button');
|
|
deleteButton.className = 'px-3 py-1 bg-red-500 text-white rounded hover:bg-red-600 text-sm flex items-center delete-mindmap-btn';
|
|
deleteButton.innerHTML = '<i class="fas fa-trash mr-1"></i> Löschen';
|
|
deleteButton.dataset.mindmapId = mindmap.id;
|
|
actionsDiv.appendChild(deleteButton);
|
|
|
|
li.appendChild(actionsDiv);
|
|
ul.appendChild(li);
|
|
});
|
|
mindmapsContainer.appendChild(ul);
|
|
|
|
// Event Listener für Löschen-Buttons hinzufügen
|
|
document.querySelectorAll('.delete-mindmap-btn').forEach(button => {
|
|
button.addEventListener('click', async (event) => {
|
|
const mindmapId = event.currentTarget.dataset.mindmapId;
|
|
if (confirm('Bist du sicher, dass du diese Mindmap löschen möchtest?')) {
|
|
try {
|
|
const response = await fetch(`/api/mindmaps/${mindmapId}`, {
|
|
method: 'DELETE',
|
|
headers: {
|
|
'Content-Type': 'application/json'
|
|
}
|
|
});
|
|
if (!response.ok) {
|
|
const errorData = await response.json();
|
|
throw new Error(errorData.error || `HTTP error! status: ${response.status}`);
|
|
}
|
|
showNotification('Mindmap erfolgreich gelöscht.', 'success');
|
|
fetchUserMindmaps(); // Liste aktualisieren
|
|
} catch (error) {
|
|
console.error('Fehler beim Löschen der Mindmap:', error);
|
|
showNotification(`Fehler beim Löschen: ${error.message}`, 'error');
|
|
}
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
if (submitCreateMindmapBtn) {
|
|
submitCreateMindmapBtn.addEventListener('click', async () => {
|
|
const name = document.getElementById('mindmap-name').value;
|
|
const description = document.getElementById('mindmap-description').value;
|
|
|
|
if (!name.trim()) {
|
|
showNotification('Der Name der Mindmap darf nicht leer sein.', 'error');
|
|
return;
|
|
}
|
|
|
|
try {
|
|
const response = await fetch('/api/mindmaps', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json'
|
|
},
|
|
body: JSON.stringify({ name, description, is_private: false }), // is_private standardmäßig auf false setzen
|
|
});
|
|
if (!response.ok) {
|
|
const errorData = await response.json();
|
|
throw new Error(errorData.error || `HTTP error! status: ${response.status}`);
|
|
}
|
|
const newMindmap = await response.json();
|
|
showNotification(`Mindmap "${newMindmap.name}" erfolgreich erstellt. Weiterleitung...`, 'success');
|
|
createMindmapModal.classList.add('hidden');
|
|
createMindmapForm.reset();
|
|
// fetchUserMindmaps(); // Liste wird auf der neuen Seite ohnehin neu geladen oder ist nicht direkt sichtbar.
|
|
// Weiterleitung zur Bearbeitungsseite der neuen Mindmap
|
|
window.location.href = `/edit_mindmap/${newMindmap.id}`;
|
|
} catch (error) {
|
|
console.error('Fehler beim Erstellen der Mindmap:', error);
|
|
showNotification(`Fehler beim Erstellen: ${error.message}`, 'error');
|
|
}
|
|
});
|
|
}
|
|
|
|
// Initiale Ladefunktion für Mindmaps
|
|
fetchUserMindmaps();
|
|
|
|
// Bestehendes Skript für Bookmarks etc.
|
|
// 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
|
|
const emptyMindmapMessage = document.getElementById('empty-mindmap-message');
|
|
if (emptyMindmapMessage) {
|
|
emptyMindmapMessage.style.display = 'none';
|
|
}
|
|
|
|
// Initialisiere die persönliche Mindmap
|
|
const personalMindmapContainer = document.getElementById('personal-mindmap');
|
|
if (personalMindmapContainer && typeof MindMapVisualization !== 'undefined') {
|
|
const personalMindmap = new MindMapVisualization('#personal-mindmap', {
|
|
width: personalMindmapContainer.clientWidth,
|
|
height: 400,
|
|
nodeRadius: 18,
|
|
selectedNodeRadius: 22,
|
|
linkDistance: 120,
|
|
chargeStrength: -800,
|
|
centerForce: 0.1,
|
|
tooltipEnabled: true
|
|
});
|
|
|
|
// Lade Daten für die Mindmap
|
|
window.setTimeout(() => {
|
|
if (window.mindmapInstance) {
|
|
const nodes = window.mindmapInstance.nodes.filter(node =>
|
|
bookmarkedNodeIds.includes(node.id)
|
|
);
|
|
const links = window.mindmapInstance.links.filter(link =>
|
|
bookmarkedNodeIds.includes(link.source.id || link.source) &&
|
|
bookmarkedNodeIds.includes(link.target.id || link.target)
|
|
);
|
|
personalMindmap.nodes = nodes;
|
|
personalMindmap.links = links;
|
|
personalMindmap.isLoading = false;
|
|
personalMindmap.updateVisualization();
|
|
} else {
|
|
if (emptyMindmapMessage) emptyMindmapMessage.style.display = 'flex';
|
|
}
|
|
}, 800);
|
|
}
|
|
loadBookmarkedContent(bookmarkedNodeIds);
|
|
} else {
|
|
// Zeige Leerzustand an
|
|
const areasContainer = document.getElementById('bookmarked-areas-container');
|
|
const thoughtsContainer = document.getElementById('bookmarked-thoughts-container');
|
|
|
|
if (areasContainer) {
|
|
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>
|
|
`;
|
|
}
|
|
|
|
if (thoughtsContainer) {
|
|
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 (bleibt größtenteils gleich)
|
|
function loadBookmarkedContent(nodeIds) {
|
|
if (!nodeIds || nodeIds.length === 0) return;
|
|
|
|
const areasContainer = document.getElementById('bookmarked-areas-container');
|
|
const thoughtsContainer = document.getElementById('bookmarked-thoughts-container');
|
|
|
|
const colors = ['purple', 'blue', 'green', 'indigo', 'amber'];
|
|
|
|
if (areasContainer) areasContainer.innerHTML = '';
|
|
if (thoughtsContainer) thoughtsContainer.innerHTML = '';
|
|
|
|
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 }
|
|
];
|
|
|
|
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' }
|
|
];
|
|
|
|
const areaCount = Math.min(nodeIds.length, 5);
|
|
|
|
if (areasContainer && areaCount > 0) {
|
|
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 if (areasContainer) {
|
|
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>
|
|
`;
|
|
}
|
|
|
|
const thoughtCount = Math.min(nodeIds.length, 5);
|
|
|
|
if (thoughtsContainer && thoughtCount > 0) {
|
|
for (let i = 0; i < thoughtCount; i++) {
|
|
const thought = thoughtTemplates[i];
|
|
const colorClass = colors[(i + 2) % colors.length];
|
|
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 if (thoughtsContainer) {
|
|
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>
|
|
<!-- 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 %} |