Update README and enhance application functionality: Add detailed installation instructions, integrate OpenAI GPT for the AI assistant, implement error handling for various HTTP errors, and improve the admin interface with user management features. Refactor mindmap visualization and enhance UI with modern design elements.
This commit is contained in:
@@ -5,87 +5,212 @@
|
||||
{% block extra_css %}
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/tippy.js@6.3.7/dist/tippy.css">
|
||||
<style>
|
||||
/* Modernes Dark-Mode Design mit Purple-Blue Gradient */
|
||||
.mindmap-header {
|
||||
background: linear-gradient(120deg, rgba(32, 32, 64, 0.7), rgba(24, 24, 48, 0.7));
|
||||
border-radius: 0.75rem;
|
||||
backdrop-filter: blur(10px);
|
||||
border: 1px solid rgba(255, 255, 255, 0.05);
|
||||
/* Globaler Stil - Hintergrund über die gesamte Seite */
|
||||
html, body {
|
||||
background-color: var(--dark-bg) !important;
|
||||
min-height: 100vh;
|
||||
width: 100%;
|
||||
color: #ffffff;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.gradient-text {
|
||||
background: linear-gradient(to right, #a67fff, #5096ff);
|
||||
/* Sicherstellen, dass der Hintergrund die gesamte Seite abdeckt */
|
||||
#app-container, .container, main, .mx-auto, .py-12, body > div, #content-wrapper, #mindmap-container {
|
||||
background-color: var(--dark-bg) !important;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* Verbesserte Glasmorphismus-Stile für Karten */
|
||||
.glass-card, .mindmap-card {
|
||||
background: rgba(24, 28, 45, 0.75);
|
||||
backdrop-filter: blur(20px);
|
||||
-webkit-backdrop-filter: blur(20px);
|
||||
border: 1px solid rgba(255, 255, 255, 0.12);
|
||||
border-radius: 24px;
|
||||
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.35);
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.glass-card:hover, .mindmap-card:hover {
|
||||
transform: translateY(-5px);
|
||||
box-shadow: 0 20px 48px rgba(0, 0, 0, 0.45);
|
||||
border: 1px solid rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
|
||||
/* Feature-Cards-Stil mit besserem Glasmorphismus */
|
||||
.feature-card {
|
||||
background: rgba(24, 28, 45, 0.75);
|
||||
border-radius: 24px;
|
||||
overflow: hidden;
|
||||
backdrop-filter: blur(20px);
|
||||
-webkit-backdrop-filter: blur(20px);
|
||||
border: 1px solid rgba(255, 255, 255, 0.12);
|
||||
box-shadow: 0 12px 36px rgba(0, 0, 0, 0.35);
|
||||
transition: all 0.3s ease;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 1.75rem;
|
||||
}
|
||||
|
||||
.feature-card:hover {
|
||||
transform: translateY(-5px);
|
||||
border: 1px solid rgba(255, 255, 255, 0.25);
|
||||
box-shadow: 0 20px 48px rgba(0, 0, 0, 0.45);
|
||||
background: rgba(28, 32, 52, 0.9);
|
||||
}
|
||||
|
||||
.feature-card-icon {
|
||||
font-size: 2.75rem;
|
||||
margin-bottom: 1.25rem;
|
||||
background: linear-gradient(135deg, #b38fff, #14b8a6);
|
||||
-webkit-background-clip: text;
|
||||
background-clip: text;
|
||||
color: transparent;
|
||||
text-shadow: 0 0 20px rgba(160, 80, 255, 0.3);
|
||||
filter: drop-shadow(0 0 10px rgba(179, 143, 255, 0.6));
|
||||
}
|
||||
|
||||
/* Feature-Card-Text besser lesbar machen */
|
||||
.feature-card h3 {
|
||||
font-size: 1.75rem;
|
||||
font-weight: 700;
|
||||
margin-bottom: 0.9rem;
|
||||
color: #ffffff;
|
||||
text-shadow: 0 2px 3px rgba(0, 0, 0, 0.3);
|
||||
letter-spacing: 0.2px;
|
||||
}
|
||||
|
||||
.feature-card p {
|
||||
color: rgba(255, 255, 255, 0.95);
|
||||
font-size: 1.1rem;
|
||||
line-height: 1.6;
|
||||
font-weight: 400;
|
||||
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.25);
|
||||
letter-spacing: 0.3px;
|
||||
}
|
||||
|
||||
/* Mindmap-Header */
|
||||
.mindmap-header {
|
||||
background: rgba(20, 24, 42, 0.85);
|
||||
border-radius: 24px;
|
||||
backdrop-filter: blur(20px);
|
||||
-webkit-backdrop-filter: blur(20px);
|
||||
border: 1px solid rgba(255, 255, 255, 0.12);
|
||||
box-shadow: 0 12px 36px rgba(0, 0, 0, 0.35);
|
||||
}
|
||||
|
||||
.gradient-text {
|
||||
background: linear-gradient(to right, #b38fff, #58a9ff);
|
||||
-webkit-background-clip: text;
|
||||
background-clip: text;
|
||||
color: transparent;
|
||||
text-shadow: 0 0 25px rgba(179, 143, 255, 0.25);
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
/* D3.js Mindmap spezifische Stile */
|
||||
.mindmap-svg {
|
||||
background: radial-gradient(circle at center, rgba(40, 30, 60, 0.4) 0%, rgba(20, 20, 40, 0.2) 70%);
|
||||
background: rgba(14, 18, 32, 0.3);
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 0.5rem;
|
||||
border-radius: 24px;
|
||||
}
|
||||
|
||||
/* Verbesserte Mindmap-Knoten-Stile */
|
||||
.node {
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.node circle {
|
||||
stroke: rgba(255, 255, 255, 0.12);
|
||||
stroke-width: 2px;
|
||||
fill: rgba(24, 28, 45, 0.85);
|
||||
filter: url(#glass-effect);
|
||||
}
|
||||
|
||||
.node:hover circle {
|
||||
filter: url(#hover-glow);
|
||||
stroke: rgba(255, 255, 255, 0.25);
|
||||
}
|
||||
|
||||
.node.selected circle {
|
||||
filter: url(#selected-glow);
|
||||
stroke: rgba(179, 143, 255, 0.6);
|
||||
stroke-width: 3px;
|
||||
}
|
||||
|
||||
.node-label {
|
||||
font-family: 'Inter', 'SF Pro Display', system-ui, sans-serif;
|
||||
font-weight: 500;
|
||||
font-weight: 600;
|
||||
pointer-events: none;
|
||||
user-select: none;
|
||||
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);
|
||||
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.7);
|
||||
font-size: 16px;
|
||||
letter-spacing: 0.3px;
|
||||
fill: #ffffff;
|
||||
}
|
||||
|
||||
.link {
|
||||
transition: stroke 0.3s ease, opacity 0.3s ease;
|
||||
stroke: rgba(255, 255, 255, 0.3);
|
||||
stroke-width: 2;
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
/* Control Bar */
|
||||
.link:hover, .link.highlighted {
|
||||
stroke: rgba(179, 143, 255, 0.7);
|
||||
opacity: 0.9;
|
||||
stroke-width: 3;
|
||||
}
|
||||
|
||||
/* Control Bar mit verbesserten Glasmorphismus und Lesbarkeit */
|
||||
.controls-bar {
|
||||
background: rgba(20, 20, 40, 0.7);
|
||||
backdrop-filter: blur(10px);
|
||||
border: 1px solid rgba(255, 255, 255, 0.05);
|
||||
border-radius: 0.5rem 0.5rem 0 0;
|
||||
background: rgba(24, 28, 45, 0.85);
|
||||
backdrop-filter: blur(20px);
|
||||
-webkit-backdrop-filter: blur(20px);
|
||||
border: 1px solid rgba(255, 255, 255, 0.12);
|
||||
border-radius: 20px 20px 0 0;
|
||||
}
|
||||
|
||||
/* Tooltip Stile */
|
||||
.tippy-box[data-theme~='mindmap'] {
|
||||
background-color: rgba(20, 20, 40, 0.9);
|
||||
background-color: rgba(24, 28, 45, 0.95);
|
||||
color: #ffffff;
|
||||
border: 1px solid rgba(160, 80, 255, 0.2);
|
||||
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.5), 0 0 10px rgba(160, 80, 255, 0.2);
|
||||
backdrop-filter: blur(10px);
|
||||
border: 1px solid rgba(179, 143, 255, 0.25);
|
||||
box-shadow: 0 12px 30px rgba(0, 0, 0, 0.5), 0 0 15px rgba(179, 143, 255, 0.25);
|
||||
backdrop-filter: blur(20px);
|
||||
-webkit-backdrop-filter: blur(20px);
|
||||
border-radius: 16px;
|
||||
}
|
||||
|
||||
.tippy-box[data-theme~='mindmap'] .tippy-arrow {
|
||||
color: rgba(20, 20, 40, 0.9);
|
||||
color: rgba(24, 28, 45, 0.95);
|
||||
}
|
||||
|
||||
.node-tooltip {
|
||||
font-family: 'Inter', 'SF Pro Display', system-ui, sans-serif;
|
||||
font-size: 14px;
|
||||
line-height: 1.5;
|
||||
padding: 8px 12px;
|
||||
line-height: 1.6;
|
||||
padding: 12px 16px;
|
||||
letter-spacing: 0.3px;
|
||||
}
|
||||
|
||||
.node-tooltip strong {
|
||||
font-weight: 600;
|
||||
color: #a67fff;
|
||||
color: #b38fff;
|
||||
}
|
||||
|
||||
/* Gedanken-Container */
|
||||
.thought-container {
|
||||
border: 1px solid rgba(255, 255, 255, 0.05);
|
||||
border-radius: 0.5rem;
|
||||
backdrop-filter: blur(10px);
|
||||
background: rgba(20, 20, 40, 0.7);
|
||||
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.2);
|
||||
border: 1px solid rgba(255, 255, 255, 0.12);
|
||||
border-radius: 24px;
|
||||
backdrop-filter: blur(20px);
|
||||
-webkit-backdrop-filter: blur(20px);
|
||||
background: rgba(24, 28, 45, 0.85);
|
||||
box-shadow: 0 12px 30px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
/* Angepasste Scrollbar für den Gedanken-Container */
|
||||
@@ -94,17 +219,17 @@
|
||||
}
|
||||
|
||||
.custom-scrollbar::-webkit-scrollbar-track {
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
background: rgba(255, 255, 255, 0.08);
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.custom-scrollbar::-webkit-scrollbar-thumb {
|
||||
background: rgba(160, 80, 255, 0.3);
|
||||
background: rgba(179, 143, 255, 0.5);
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.custom-scrollbar::-webkit-scrollbar-thumb:hover {
|
||||
background: rgba(160, 80, 255, 0.5);
|
||||
background: rgba(179, 143, 255, 0.7);
|
||||
}
|
||||
|
||||
/* Pulse-Animation für leere Gedanken */
|
||||
@@ -121,208 +246,268 @@
|
||||
}
|
||||
}
|
||||
|
||||
/* ASCII-Style Tech Decoration */
|
||||
.ascii-decoration {
|
||||
font-family: monospace;
|
||||
color: rgba(160, 80, 255, 0.15);
|
||||
font-size: 12px;
|
||||
white-space: pre;
|
||||
line-height: 1;
|
||||
user-select: none;
|
||||
position: absolute;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
.top-right-deco {
|
||||
top: 20px;
|
||||
right: 20px;
|
||||
}
|
||||
|
||||
.bottom-left-deco {
|
||||
bottom: 20px;
|
||||
left: 20px;
|
||||
}
|
||||
|
||||
/* Button-Effekte */
|
||||
/* Button-Effekte mit verbesserter Lesbarkeit */
|
||||
.control-btn {
|
||||
transition: all 0.2s ease;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
background: rgba(32, 36, 55, 0.85);
|
||||
color: #ffffff;
|
||||
border: 1px solid rgba(255, 255, 255, 0.15);
|
||||
border-radius: 16px;
|
||||
padding: 0.75rem 1.5rem;
|
||||
font-weight: 600;
|
||||
transition: all 0.3s ease;
|
||||
backdrop-filter: blur(15px);
|
||||
-webkit-backdrop-filter: blur(15px);
|
||||
box-shadow: 0 6px 16px rgba(0, 0, 0, 0.25);
|
||||
font-size: 1rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 0.5rem;
|
||||
letter-spacing: 0.3px;
|
||||
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
.control-btn:hover {
|
||||
background: rgba(160, 80, 255, 0.2);
|
||||
transform: translateY(-1px);
|
||||
background: rgba(179, 143, 255, 0.35);
|
||||
transform: translateY(-3px);
|
||||
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.35), 0 0 15px rgba(179, 143, 255, 0.25);
|
||||
border: 1px solid rgba(255, 255, 255, 0.25);
|
||||
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
.control-btn:active {
|
||||
transform: translateY(1px);
|
||||
box-shadow: 0 3px 8px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.control-btn::after {
|
||||
content: "";
|
||||
display: block;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
pointer-events: none;
|
||||
background-image: radial-gradient(circle, rgba(255, 255, 255, 0.3) 10%, transparent 10.01%);
|
||||
background-repeat: no-repeat;
|
||||
background-position: 50%;
|
||||
transform: scale(10, 10);
|
||||
opacity: 0;
|
||||
transition: transform 0.5s, opacity 0.5s;
|
||||
.control-btn.active {
|
||||
background: rgba(179, 143, 255, 0.4);
|
||||
border: 1px solid rgba(179, 143, 255, 0.5);
|
||||
box-shadow: 0 0 15px rgba(179, 143, 255, 0.3);
|
||||
}
|
||||
|
||||
.control-btn:active::after {
|
||||
transform: scale(0, 0);
|
||||
opacity: 0.3;
|
||||
transition: 0s;
|
||||
/* Glow Effect für Buttons */
|
||||
.btn-glow:hover {
|
||||
box-shadow: 0 0 15px rgba(179, 143, 255, 0.5);
|
||||
}
|
||||
|
||||
/* Light Mode Anpassungen */
|
||||
html.light .mindmap-svg {
|
||||
background: rgba(240, 244, 248, 0.3);
|
||||
}
|
||||
|
||||
html.light .node circle {
|
||||
fill: rgba(255, 255, 255, 0.9);
|
||||
stroke: rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
html.light .node-label {
|
||||
fill: #1a202c;
|
||||
text-shadow: 0 1px 2px rgba(255, 255, 255, 0.7);
|
||||
}
|
||||
|
||||
html.light .link {
|
||||
stroke: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
html.light .glass-card,
|
||||
html.light .mindmap-card,
|
||||
html.light .feature-card,
|
||||
html.light .thought-container,
|
||||
html.light .mindmap-header,
|
||||
html.light .controls-bar {
|
||||
background: rgba(255, 255, 255, 0.85);
|
||||
border: 1px solid rgba(0, 0, 0, 0.08);
|
||||
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
html.light .control-btn {
|
||||
background: rgba(255, 255, 255, 0.9);
|
||||
color: #1a202c;
|
||||
border: 1px solid rgba(0, 0, 0, 0.08);
|
||||
text-shadow: none;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
html.light .control-btn:hover {
|
||||
background: rgba(179, 143, 255, 0.15);
|
||||
box-shadow: 0 8px 16px rgba(0, 0, 0, 0.12);
|
||||
color: #7e3ff2;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
html.light .control-btn.active {
|
||||
background: rgba(179, 143, 255, 0.2);
|
||||
border: 1px solid rgba(126, 63, 242, 0.3);
|
||||
color: #7e3ff2;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
html.light .feature-card h3 {
|
||||
color: #1a202c;
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
html.light .feature-card p {
|
||||
color: #4a5568;
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
html.light .node-tooltip strong {
|
||||
color: #7e3ff2;
|
||||
}
|
||||
|
||||
/* Karten in der Mindmap mit verbesserten Styles */
|
||||
.mindmap-card {
|
||||
background: rgba(24, 28, 45, 0.75);
|
||||
border-radius: 24px;
|
||||
overflow: hidden;
|
||||
backdrop-filter: blur(20px);
|
||||
-webkit-backdrop-filter: blur(20px);
|
||||
border: 1px solid rgba(255, 255, 255, 0.12);
|
||||
box-shadow: 0 12px 36px rgba(0, 0, 0, 0.35);
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.mindmap-card:hover {
|
||||
transform: translateY(-5px);
|
||||
border: 1px solid rgba(255, 255, 255, 0.2);
|
||||
box-shadow: 0 16px 48px rgba(0, 0, 0, 0.45);
|
||||
background: rgba(28, 32, 52, 0.8);
|
||||
}
|
||||
|
||||
.mindmap-card-header {
|
||||
padding: 1.25rem 1.5rem;
|
||||
border-bottom: 1px solid rgba(255, 255, 255, 0.06);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.mindmap-card-body {
|
||||
padding: 1.5rem;
|
||||
}
|
||||
|
||||
.mindmap-card-footer {
|
||||
padding: 1.25rem 1.5rem;
|
||||
border-top: 1px solid rgba(255, 255, 255, 0.06);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
html.light .mindmap-card-header,
|
||||
html.light .mindmap-card-footer {
|
||||
border-color: rgba(0, 0, 0, 0.06);
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="relative mb-6" data-page="mindmap">
|
||||
<!-- ASCII Dekorationen -->
|
||||
<div class="ascii-decoration top-right-deco">
|
||||
┌─┐ ┌─┐ ┌─┐ ┌─┐
|
||||
│ │ │ │ │ │ │ │
|
||||
└─┘ └─┘ └─┘ └─┘
|
||||
</div>
|
||||
<div class="ascii-decoration bottom-left-deco">
|
||||
╔══╗ ╔═══╗ ╔══╗
|
||||
║ ║ ║ ║ ║ ║
|
||||
╚══╝ ╚═══╝ ╚══╝
|
||||
</div>
|
||||
|
||||
<!-- Header Bereich -->
|
||||
<div class="mb-8 p-6 mindmap-header">
|
||||
<h1 class="text-5xl md:text-6xl font-bold mb-3">
|
||||
<span class="gradient-text">Mindmap</span>
|
||||
</h1>
|
||||
<p class="text-lg text-gray-200 max-w-3xl leading-relaxed">
|
||||
Erkunden Sie interaktiv verknüpfte Wissensgebiete und ihre Verbindungen. Fügen Sie eigene Gedanken hinzu und erstellen Sie ein kollaboratives Wissensnetz.
|
||||
</p>
|
||||
<div class="mt-3 flex flex-wrap gap-3">
|
||||
<span class="px-3 py-1 text-xs rounded-full bg-purple-900/50 text-purple-200 border border-purple-700/30">
|
||||
<i class="fa-solid fa-diagram-project mr-1"></i> Interaktiv
|
||||
</span>
|
||||
<span class="px-3 py-1 text-xs rounded-full bg-blue-900/50 text-blue-200 border border-blue-700/30">
|
||||
<i class="fa-solid fa-sitemap mr-1"></i> Wissensvernetzung
|
||||
</span>
|
||||
<span class="px-3 py-1 text-xs rounded-full bg-indigo-900/50 text-indigo-200 border border-indigo-700/30">
|
||||
<i class="fa-solid fa-lightbulb mr-1"></i> Kollaborativ
|
||||
</span>
|
||||
<div class="container mx-auto px-4 py-12">
|
||||
<!-- Feature-Karten-Container -->
|
||||
<div class="grid grid-cols-1 md:grid-cols-3 gap-8 mb-12">
|
||||
<!-- Feature-Karte 1: Visualisiere Wissen -->
|
||||
<div class="feature-card">
|
||||
<div class="feature-card-icon">
|
||||
<i class="fas fa-brain"></i>
|
||||
</div>
|
||||
<h3>Visualisiere Wissen</h3>
|
||||
<p>Sieh Wissen als vernetztes System, entdecke Zusammenhänge und erkenne überraschende Verbindungen zwischen verschiedenen Themengebieten.</p>
|
||||
</div>
|
||||
|
||||
<!-- Feature-Karte 2: Teile Gedanken -->
|
||||
<div class="feature-card">
|
||||
<div class="feature-card-icon">
|
||||
<i class="fas fa-lightbulb"></i>
|
||||
</div>
|
||||
<h3>Teile Gedanken</h3>
|
||||
<p>Füge deine eigenen Ideen und Perspektiven hinzu. Erstelle Verbindungen zu vorhandenen Gedanken und bereichere die wachsende Wissensbasis.</p>
|
||||
</div>
|
||||
|
||||
<!-- Feature-Karte 3: Community -->
|
||||
<div class="feature-card">
|
||||
<div class="feature-card-icon">
|
||||
<i class="fas fa-users"></i>
|
||||
</div>
|
||||
<h3>Community</h3>
|
||||
<p>Sei Teil einer Gemeinschaft, die gemeinsam ein verteiltes Wissensarchiv aufbaut und sich in thematisch fokussierten Bereichen austauscht.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Haupt-Grid-Layout -->
|
||||
<div class="grid grid-cols-1 lg:grid-cols-3 gap-6">
|
||||
<!-- Visualisierungsbereich -->
|
||||
<div class="lg:col-span-2">
|
||||
<div class="rounded-lg overflow-hidden bg-gradient-to-br from-slate-900/60 to-slate-800/40 border border-slate-700/20 shadow-xl">
|
||||
<!-- Mindmap Controls Bar -->
|
||||
<div class="flex items-center justify-between p-4 controls-bar">
|
||||
<div class="relative flex-grow max-w-md">
|
||||
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
|
||||
<i class="fa-solid fa-magnifying-glass text-gray-400"></i>
|
||||
</div>
|
||||
<input type="text" id="mindmap-search"
|
||||
class="bg-slate-800/80 border border-slate-700/50 text-white rounded-md block w-full pl-10 p-2.5 focus:ring-2 focus:ring-purple-500 focus:border-transparent transition-all"
|
||||
placeholder="Knoten suchen...">
|
||||
</div>
|
||||
|
||||
<div class="flex gap-2">
|
||||
<button id="zoom-in" class="control-btn p-2 rounded-md text-gray-200" title="Vergrößern">
|
||||
<i class="fa-solid fa-plus"></i>
|
||||
</button>
|
||||
<button id="zoom-out" class="control-btn p-2 rounded-md text-gray-200" title="Verkleinern">
|
||||
<i class="fa-solid fa-minus"></i>
|
||||
</button>
|
||||
<button id="zoom-reset" class="control-btn p-2 rounded-md text-gray-200" title="Ansicht zurücksetzen">
|
||||
<i class="fa-solid fa-house"></i>
|
||||
</button>
|
||||
<button id="toggle-guide" class="control-btn p-2 rounded-md text-gray-200" title="Anleitung anzeigen">
|
||||
<i class="fa-solid fa-circle-question"></i>
|
||||
</button>
|
||||
|
||||
<!-- Mindmap-Visualisierung Header -->
|
||||
<div class="mindmap-header p-6 mb-6">
|
||||
<h2 class="text-3xl font-bold mb-2 gradient-text">Wissenslandschaft erkunden</h2>
|
||||
<p class="text-gray-300 mb-0">Interagiere mit der Mindmap, um Verbindungen zu entdecken und neue Ideen hinzuzufügen</p>
|
||||
</div>
|
||||
|
||||
<!-- Mindmap-Container -->
|
||||
<div class="glass-card overflow-hidden mb-12">
|
||||
<div id="mindmap-container" class="relative" style="height: 70vh; min-height: 500px;">
|
||||
<!-- Lade-Overlay -->
|
||||
<div class="mindmap-loading absolute inset-0 flex items-center justify-center z-10" style="background: rgba(14, 18, 32, 0.7); backdrop-filter: blur(5px);">
|
||||
<div class="text-center">
|
||||
<div class="inline-block animate-spin rounded-full h-12 w-12 border-t-2 border-b-2 border-purple-500 mb-4"></div>
|
||||
<p class="text-white text-lg">Wissenslandschaft wird geladen...</p>
|
||||
<div class="w-64 h-2 bg-gray-700 rounded-full mt-4 overflow-hidden">
|
||||
<div class="loading-progress h-full bg-gradient-to-r from-purple-500 to-blue-500 rounded-full" style="width: 0%"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Mindmap Container -->
|
||||
<div id="mindmap-container" class="relative w-full h-[600px] bg-gradient-to-br from-slate-900/30 to-indigo-900/10">
|
||||
<!-- Wird durch D3.js befüllt -->
|
||||
</div>
|
||||
|
||||
<!-- Legende -->
|
||||
<div class="p-4 border-t border-white/5 bg-slate-900/70 backdrop-blur">
|
||||
<div class="text-xs text-gray-400 mb-2">Legende</div>
|
||||
<div class="flex flex-wrap gap-4">
|
||||
<div class="flex items-center">
|
||||
<div class="w-3 h-3 rounded-full bg-purple-500 mr-2"></div>
|
||||
<span class="text-sm text-gray-300">Hauptkategorien</span>
|
||||
</div>
|
||||
<div class="flex items-center">
|
||||
<div class="w-3 h-3 rounded-full bg-blue-500 mr-2"></div>
|
||||
<span class="text-sm text-gray-300">Unterkategorien</span>
|
||||
</div>
|
||||
<div class="flex items-center">
|
||||
<div class="w-3 h-3 rounded-full bg-green-500 mr-2"></div>
|
||||
<span class="text-sm text-gray-300">Konzepte</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Anleitung -->
|
||||
<div id="guide-panel" class="mt-4 rounded-lg overflow-hidden bg-gradient-to-br from-slate-900/60 to-slate-800/40 border border-slate-700/20 shadow-xl p-4 hidden">
|
||||
<h3 class="text-lg font-semibold mb-2 text-white">Navigation der Mindmap</h3>
|
||||
<ul class="space-y-1 text-gray-300 text-sm">
|
||||
<li class="flex items-start">
|
||||
<i class="fa-solid fa-circle-dot text-purple-400 mt-1 mr-2"></i>
|
||||
<span><strong>Knoten ansehen:</strong> Bewegen Sie die Maus über einen Knoten, um Details zu sehen.</span>
|
||||
</li>
|
||||
<li class="flex items-start">
|
||||
<i class="fa-solid fa-circle-dot text-purple-400 mt-1 mr-2"></i>
|
||||
<span><strong>Gedanken anzeigen:</strong> Klicken Sie auf einen Knoten, um zugehörige Gedanken anzuzeigen.</span>
|
||||
</li>
|
||||
<li class="flex items-start">
|
||||
<i class="fa-solid fa-circle-dot text-purple-400 mt-1 mr-2"></i>
|
||||
<span><strong>Zoomen:</strong> Nutzen Sie das Mausrad oder die Zoom-Schaltflächen oben.</span>
|
||||
</li>
|
||||
<li class="flex items-start">
|
||||
<i class="fa-solid fa-circle-dot text-purple-400 mt-1 mr-2"></i>
|
||||
<span><strong>Verschieben:</strong> Klicken und ziehen Sie den Hintergrund, um die Ansicht zu verschieben.</span>
|
||||
</li>
|
||||
<li class="flex items-start">
|
||||
<i class="fa-solid fa-circle-dot text-purple-400 mt-1 mr-2"></i>
|
||||
<span><strong>Knoten bewegen:</strong> Ziehen Sie einen Knoten, um seine Position anzupassen.</span>
|
||||
</li>
|
||||
<li class="flex items-start">
|
||||
<i class="fa-solid fa-circle-dot text-purple-400 mt-1 mr-2"></i>
|
||||
<span><strong>Suche:</strong> Nutzen Sie die Suchleiste, um bestimmte Knoten zu finden.</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Gedanken-Bereich -->
|
||||
<div class="lg:col-span-1">
|
||||
<div id="thoughts-container" class="thought-container p-6 h-[600px] overflow-y-auto custom-scrollbar">
|
||||
<div class="text-center p-6">
|
||||
<div class="mb-6 pulse-animation">
|
||||
<i class="fa-solid fa-diagram-project text-6xl text-indigo-400/50"></i>
|
||||
</div>
|
||||
<h3 class="text-xl font-semibold mb-2 text-white">Mindmap erkunden</h3>
|
||||
<p class="text-gray-300 mb-4">Wählen Sie einen Knoten in der Mindmap aus, um zugehörige Gedanken anzuzeigen.</p>
|
||||
<div class="p-4 rounded-lg inline-block bg-gradient-to-r from-purple-900/20 to-indigo-900/20 border border-indigo-500/20">
|
||||
<i class="fa-solid fa-arrow-left text-purple-400 mr-2"></i>
|
||||
<span class="text-gray-200">Klicken Sie auf einen Knoten</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Steuerungsleiste -->
|
||||
<div class="controls-bar p-4 flex flex-wrap items-center justify-between gap-3">
|
||||
<div class="flex flex-wrap gap-2">
|
||||
<button class="control-btn" id="zoom-in-btn">
|
||||
<i class="fas fa-search-plus mr-1"></i> Vergrößern
|
||||
</button>
|
||||
<button class="control-btn" id="zoom-out-btn">
|
||||
<i class="fas fa-search-minus mr-1"></i> Verkleinern
|
||||
</button>
|
||||
<button class="control-btn" id="center-btn">
|
||||
<i class="fas fa-bullseye mr-1"></i> Zentrieren
|
||||
</button>
|
||||
</div>
|
||||
<div class="flex flex-wrap gap-2">
|
||||
<button class="control-btn" id="add-thought-btn">
|
||||
<i class="fas fa-plus-circle mr-1"></i> Gedanke hinzufügen
|
||||
</button>
|
||||
<button class="control-btn" id="connect-btn">
|
||||
<i class="fas fa-link mr-1"></i> Verbinden
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Unterer Bereich: KI-Assistenz, Suche und Lernpfade -->
|
||||
<div class="grid grid-cols-1 md:grid-cols-3 gap-8">
|
||||
<!-- KI-Assistenz -->
|
||||
<div class="feature-card">
|
||||
<div class="feature-card-icon">
|
||||
<i class="fas fa-robot"></i>
|
||||
</div>
|
||||
<h3>KI-Assistenz</h3>
|
||||
<p>Lass dir von künstlicher Intelligenz helfen, neue Zusammenhänge zu entdecken, Inhalte zusammenzufassen und Fragen zu beantworten.</p>
|
||||
</div>
|
||||
|
||||
<!-- Intelligente Suche -->
|
||||
<div class="feature-card">
|
||||
<div class="feature-card-icon">
|
||||
<i class="fas fa-search"></i>
|
||||
</div>
|
||||
<h3>Intelligente Suche</h3>
|
||||
<p>Finde genau die Informationen, die du suchst, mit fortschrittlichen Such- und Filterfunktionen für eine präzise Navigation durch das Wissen.</p>
|
||||
</div>
|
||||
|
||||
<!-- Geführte Pfade -->
|
||||
<div class="feature-card">
|
||||
<div class="feature-card-icon">
|
||||
<i class="fas fa-map-signs"></i>
|
||||
</div>
|
||||
<h3>Geführte Pfade</h3>
|
||||
<p>Folge kuratierten Lernpfaden durch komplexe Themen oder erschaffe selbst Routen für andere, die deinen Gedankengängen folgen möchten.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -330,55 +515,148 @@
|
||||
|
||||
{% block extra_js %}
|
||||
<!-- D3.js für die Mindmap-Visualisierung -->
|
||||
<script src="https://cdn.jsdelivr.net/npm/d3@7.8.5/dist/d3.min.js"></script>
|
||||
<!-- Tippy.js für erweiterte Tooltips -->
|
||||
<script src="https://d3js.org/d3.v7.min.js"></script>
|
||||
<!-- Tippy.js für verbesserte Tooltips -->
|
||||
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.6/dist/umd/popper.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/tippy.js@6.3.7/dist/tippy.umd.min.js"></script>
|
||||
<!-- Mindmap-Module -->
|
||||
<script src="{{ url_for('static', filename='js/modules/mindmap.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='js/modules/mindmap-page.js') }}"></script>
|
||||
<!-- D3-Erweiterungen für spezifische Effekte -->
|
||||
<script src="{{ url_for('static', filename='d3-extensions.js') }}"></script>
|
||||
<!-- Mindmap JS -->
|
||||
<script src="{{ url_for('static', filename='mindmap.js') }}"></script>
|
||||
|
||||
<script>
|
||||
// Zusätzliche Seiten-spezifische Skripte
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
// Setze Seiten-Identifier für den richtigen Initialisierer
|
||||
document.body.dataset.page = 'mindmap';
|
||||
// Initialisiere die Mindmap-Visualisierung
|
||||
const mindmapContainer = document.getElementById('mindmap-container');
|
||||
const containerWidth = mindmapContainer.clientWidth;
|
||||
const containerHeight = mindmapContainer.clientHeight;
|
||||
|
||||
// Toggle für die Anleitung
|
||||
const guidePanel = document.getElementById('guide-panel');
|
||||
const toggleGuideBtn = document.getElementById('toggle-guide');
|
||||
|
||||
toggleGuideBtn.addEventListener('click', function() {
|
||||
guidePanel.classList.toggle('hidden');
|
||||
const mindmap = new MindMapVisualization('#mindmap-container', {
|
||||
width: containerWidth,
|
||||
height: containerHeight,
|
||||
nodeRadius: 22,
|
||||
selectedNodeRadius: 28,
|
||||
linkDistance: 160,
|
||||
chargeStrength: -1200,
|
||||
centerForce: 0.1,
|
||||
tooltipEnabled: true,
|
||||
onNodeClick: function(node) {
|
||||
console.log('Node clicked:', node);
|
||||
// Hier können spezifische Aktionen für Knotenklicks definiert werden
|
||||
}
|
||||
});
|
||||
|
||||
// Zoom-Buttons mit der Mindmap verbinden
|
||||
const zoomIn = document.getElementById('zoom-in');
|
||||
const zoomOut = document.getElementById('zoom-out');
|
||||
const zoomReset = document.getElementById('zoom-reset');
|
||||
// Event-Listener für Steuerungsbuttons
|
||||
document.getElementById('zoom-in-btn').addEventListener('click', function() {
|
||||
// Zoom-In-Funktionalität
|
||||
const svg = d3.select('#mindmap-container svg');
|
||||
const currentZoom = d3.zoomTransform(svg.node());
|
||||
const newScale = currentZoom.k * 1.3;
|
||||
svg.transition().duration(300).call(
|
||||
d3.zoom().transform,
|
||||
d3.zoomIdentity.translate(currentZoom.x, currentZoom.y).scale(newScale)
|
||||
);
|
||||
});
|
||||
|
||||
if (zoomIn && zoomOut && zoomReset && window.mindmapInstance) {
|
||||
zoomIn.addEventListener('click', function() {
|
||||
const currentZoom = d3.zoomTransform(window.mindmapInstance.svg.node()).k;
|
||||
window.mindmapInstance.svg.transition().duration(300).call(
|
||||
d3.zoom().transform,
|
||||
d3.zoomIdentity.scale(currentZoom * 1.3)
|
||||
document.getElementById('zoom-out-btn').addEventListener('click', function() {
|
||||
// Zoom-Out-Funktionalität
|
||||
const svg = d3.select('#mindmap-container svg');
|
||||
const currentZoom = d3.zoomTransform(svg.node());
|
||||
const newScale = currentZoom.k / 1.3;
|
||||
svg.transition().duration(300).call(
|
||||
d3.zoom().transform,
|
||||
d3.zoomIdentity.translate(currentZoom.x, currentZoom.y).scale(newScale)
|
||||
);
|
||||
});
|
||||
|
||||
document.getElementById('center-btn').addEventListener('click', function() {
|
||||
// Zentrieren-Funktionalität
|
||||
const svg = d3.select('#mindmap-container svg');
|
||||
svg.transition().duration(500).call(
|
||||
d3.zoom().transform,
|
||||
d3.zoomIdentity.scale(1)
|
||||
);
|
||||
});
|
||||
|
||||
// Add Thought Button
|
||||
document.getElementById('add-thought-btn').addEventListener('click', function() {
|
||||
// Implementierung für das Hinzufügen eines neuen Gedankens
|
||||
if (mindmap.selectedNode) {
|
||||
const newNodeName = prompt('Gedanke eingeben:');
|
||||
if (newNodeName && newNodeName.trim() !== '') {
|
||||
const newNodeId = 'node_' + Date.now();
|
||||
const newNode = {
|
||||
id: newNodeId,
|
||||
name: newNodeName,
|
||||
description: 'Neuer Gedanke',
|
||||
thought_count: 0
|
||||
};
|
||||
|
||||
// Node zur Mindmap hinzufügen
|
||||
mindmap.nodes.push(newNode);
|
||||
|
||||
// Link zum ausgewählten Knoten erstellen
|
||||
mindmap.links.push({
|
||||
source: mindmap.selectedNode.id,
|
||||
target: newNodeId
|
||||
});
|
||||
|
||||
// Mindmap aktualisieren
|
||||
mindmap.updateVisualization();
|
||||
}
|
||||
} else {
|
||||
alert('Bitte zuerst einen Knoten auswählen, um einen Gedanken hinzuzufügen.');
|
||||
}
|
||||
});
|
||||
|
||||
// Connect Button
|
||||
document.getElementById('connect-btn').addEventListener('click', function() {
|
||||
// Implementierung für das Verbinden von Knoten
|
||||
if (mindmap.selectedNode && mindmap.mouseoverNode && mindmap.selectedNode !== mindmap.mouseoverNode) {
|
||||
// Prüfen, ob Verbindung bereits existiert
|
||||
const existingLink = mindmap.links.find(link =>
|
||||
(link.source.id === mindmap.selectedNode.id && link.target.id === mindmap.mouseoverNode.id) ||
|
||||
(link.source.id === mindmap.mouseoverNode.id && link.target.id === mindmap.selectedNode.id)
|
||||
);
|
||||
});
|
||||
|
||||
if (!existingLink) {
|
||||
// Link erstellen
|
||||
mindmap.links.push({
|
||||
source: mindmap.selectedNode.id,
|
||||
target: mindmap.mouseoverNode.id
|
||||
});
|
||||
|
||||
// Mindmap aktualisieren
|
||||
mindmap.updateVisualization();
|
||||
} else {
|
||||
alert('Diese Verbindung existiert bereits.');
|
||||
}
|
||||
} else {
|
||||
alert('Bitte wähle zwei verschiedene Knoten aus, um sie zu verbinden.');
|
||||
}
|
||||
});
|
||||
|
||||
// Responsive Anpassung bei Fenstergrößenänderung
|
||||
window.addEventListener('resize', function() {
|
||||
const newWidth = mindmapContainer.clientWidth;
|
||||
const newHeight = mindmapContainer.clientHeight;
|
||||
|
||||
zoomOut.addEventListener('click', function() {
|
||||
const currentZoom = d3.zoomTransform(window.mindmapInstance.svg.node()).k;
|
||||
window.mindmapInstance.svg.transition().duration(300).call(
|
||||
d3.zoom().transform,
|
||||
d3.zoomIdentity.scale(currentZoom / 1.3)
|
||||
);
|
||||
});
|
||||
|
||||
zoomReset.addEventListener('click', function() {
|
||||
window.mindmapInstance.svg.transition().duration(300).call(
|
||||
d3.zoom().transform,
|
||||
d3.zoomIdentity.scale(1)
|
||||
);
|
||||
});
|
||||
}
|
||||
if (mindmap.svg) {
|
||||
mindmap.svg
|
||||
.attr('width', newWidth)
|
||||
.attr('height', newHeight);
|
||||
|
||||
mindmap.width = newWidth;
|
||||
mindmap.height = newHeight;
|
||||
|
||||
// Force-Simulation aktualisieren
|
||||
if (mindmap.simulation) {
|
||||
mindmap.simulation
|
||||
.force('center', d3.forceCenter(newWidth / 2, newHeight / 2))
|
||||
.restart();
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user