chore: automatic commit 2025-04-30 15:41

This commit is contained in:
2025-04-30 15:41:00 +02:00
parent 779449559d
commit 84667bca00
2 changed files with 509 additions and 228 deletions

View File

@@ -40,8 +40,8 @@
--light-bg: #f9fafb;
--light-text: #1e293b;
--light-heading: #0f172a;
--light-primary: #3b82f6;
--light-primary-hover: #4f46e5;
--light-primary: #7c3aed;
--light-primary-hover: #6d28d9;
--light-secondary: #6b7280;
--light-border: #e5e7eb;
--light-card-bg: rgba(255, 255, 255, 0.92);
@@ -523,4 +523,232 @@ body:not(.dark) .navbar {
background-color: var(--light-navbar-bg);
box-shadow: var(--light-shadow);
border-bottom: 1px solid var(--light-border);
}
/* Erweiterte Light-Mode-spezifische Stile */
body:not(.dark) .glass-effect {
background-color: rgba(255, 255, 255, 0.7);
backdrop-filter: blur(12px);
-webkit-backdrop-filter: blur(12px);
border: 1px solid rgba(209, 213, 219, 0.3);
}
body:not(.dark) .card {
background-color: rgba(255, 255, 255, 0.85);
border: 1px solid var(--light-border);
box-shadow: var(--light-shadow);
transition: all 0.3s ease;
}
body:not(.dark) .card:hover {
box-shadow: 0 8px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
transform: translateY(-2px);
}
/* Light Mode Buttons */
body:not(.dark) .btn-primary {
background-color: var(--light-primary);
color: white;
border: none;
transition: all 0.2s ease;
}
body:not(.dark) .btn-primary:hover {
background-color: var(--light-primary-hover);
box-shadow: 0 4px 12px rgba(124, 58, 237, 0.2);
}
body:not(.dark) .btn-secondary {
background-color: #f3f4f6;
color: var(--light-text);
border: 1px solid #e5e7eb;
}
body:not(.dark) .btn-secondary:hover {
background-color: #e5e7eb;
}
body:not(.dark) .btn-outline {
background-color: transparent;
color: var(--light-primary);
border: 1px solid var(--light-primary);
}
body:not(.dark) .btn-outline:hover {
background-color: rgba(124, 58, 237, 0.05);
}
/* Light Mode Formulare */
body:not(.dark) input,
body:not(.dark) select,
body:not(.dark) textarea {
background-color: white;
border: 1px solid #d1d5db;
color: #1f2937;
}
body:not(.dark) input:focus,
body:not(.dark) select:focus,
body:not(.dark) textarea:focus {
border-color: var(--light-primary);
box-shadow: 0 0 0 2px rgba(124, 58, 237, 0.2);
}
/* Light Mode Navigation */
body:not(.dark) .sidebar {
background-color: white;
border-right: 1px solid #e5e7eb;
}
body:not(.dark) .sidebar-link {
color: #4b5563;
}
body:not(.dark) .sidebar-link:hover {
background-color: #f3f4f6;
color: var(--light-primary);
}
body:not(.dark) .sidebar-link.active {
background-color: rgba(124, 58, 237, 0.08);
color: var(--light-primary);
font-weight: 500;
}
/* Light Mode Tabellen */
body:not(.dark) table {
border-color: #e5e7eb;
}
body:not(.dark) th {
background-color: #f9fafb;
color: #111827;
font-weight: 600;
}
body:not(.dark) tr:nth-child(even) {
background-color: #f9fafb;
}
body:not(.dark) tr:hover {
background-color: #f3f4f6;
}
/* Light Mode Icons */
body:not(.dark) .icon {
color: #6b7280;
}
body:not(.dark) .icon-primary {
color: var(--light-primary);
}
/* Light Mode Alerts/Benachrichtigungen */
body:not(.dark) .alert-info {
background-color: #eff6ff;
border-left: 4px solid #3b82f6;
color: #1e40af;
}
body:not(.dark) .alert-success {
background-color: #ecfdf5;
border-left: 4px solid #10b981;
color: #065f46;
}
body:not(.dark) .alert-warning {
background-color: #fffbeb;
border-left: 4px solid #f59e0b;
color: #92400e;
}
body:not(.dark) .alert-error {
background-color: #fef2f2;
border-left: 4px solid #ef4444;
color: #b91c1c;
}
/* Light Mode Badge */
body:not(.dark) .badge {
background-color: #e5e7eb;
color: #374151;
}
body:not(.dark) .badge-primary {
background-color: rgba(124, 58, 237, 0.1);
color: var(--light-primary);
}
/* Light Mode Mindmap spezifisch */
body:not(.dark) #cy {
background-color: rgba(255, 255, 255, 0.7);
border: 1px solid #e5e7eb;
}
body:not(.dark) .node {
border: 2px solid white;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
}
body:not(.dark) .node:hover,
body:not(.dark) .node.selected {
box-shadow: 0 0 0 2px rgba(124, 58, 237, 0.5), 0 4px 8px rgba(0, 0, 0, 0.1);
}
body:not(.dark) .edge {
opacity: 0.7;
}
body:not(.dark) .edge:hover,
body:not(.dark) .edge.selected {
opacity: 1;
}
/* Footer im Light Mode */
body:not(.dark) footer {
background-color: rgba(249, 250, 251, 0.7);
border-top: 1px solid #e5e7eb;
}
/* Alpine.js Transitions im Light Mode */
body:not(.dark) [x-cloak] {
display: none !important;
}
/* Suchfeldstyling im Light Mode */
body:not(.dark) .search-container input {
background-color: white;
border: 1px solid #d1d5db;
color: #1f2937;
}
body:not(.dark) .search-container input:focus {
border-color: var(--light-primary);
box-shadow: 0 0 0 2px rgba(124, 58, 237, 0.2);
}
body:not(.dark) .search-results {
background-color: white;
border: 1px solid #e5e7eb;
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
}
body:not(.dark) .search-result-item:hover {
background-color: #f3f4f6;
}
/* Profile und Benutzermenü im Light Mode */
body:not(.dark) .avatar {
border: 2px solid white;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
}
body:not(.dark) .user-dropdown {
background-color: white;
border: 1px solid #e5e7eb;
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
}
body:not(.dark) .user-dropdown-item:hover {
background-color: #f3f4f6;
}

View File

@@ -1,234 +1,287 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Interaktive Mindmap</title>
{% extends "base.html" %}
{% block title %}Mindmap{% endblock %}
{% block extra_css %}
<style>
/* Spezifische Stile für die Mindmap-Seite */
#cy {
width: 100%;
height: 600px;
background-color: var(--bg-secondary);
transition: background-color 0.3s ease;
border-radius: 10px;
overflow: hidden;
position: relative;
}
<!-- Cytoscape.js -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/cytoscape/3.26.0/cytoscape.min.js"></script>
.mindmap-container {
position: relative;
border-radius: 10px;
overflow: hidden;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
transition: all 0.3s ease;
}
<!-- Socket.IO -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.7.2/socket.io.min.js"></script>
.dark .mindmap-container {
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.2);
}
<!-- Feather Icons (optional) -->
<script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script>
.mindmap-toolbar {
display: flex;
gap: 0.5rem;
flex-wrap: wrap;
padding: 0.75rem;
background-color: var(--bg-secondary);
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
transition: background-color 0.3s ease;
}
<style>
* {
box-sizing: border-box;
margin: 0;
padding: 0;
body:not(.dark) .mindmap-toolbar {
border-bottom: 1px solid rgba(0, 0, 0, 0.1);
}
.btn {
display: flex;
align-items: center;
gap: 0.5rem;
font-size: 0.875rem;
border-radius: 0.375rem;
transition: all 0.3s ease;
}
.category-filters {
display: flex;
gap: 0.5rem;
flex-wrap: wrap;
padding: 0.75rem;
background-color: var(--bg-secondary);
transition: background-color 0.3s ease;
}
.category-filter {
border: none;
border-radius: 0.25rem;
padding: 0.25rem 0.75rem;
font-size: 0.75rem;
cursor: pointer;
transition: opacity 0.2s;
color: white;
}
.category-filter:not(.active) {
opacity: 0.6;
}
.category-filter:hover:not(.active) {
opacity: 0.8;
}
/* Kontextmenü */
#context-menu {
position: absolute;
border-radius: 0.375rem;
z-index: 1000;
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1);
overflow: hidden;
}
.dark #context-menu {
background-color: #232837;
border: 1px solid rgba(255, 255, 255, 0.1);
}
body:not(.dark) #context-menu {
background-color: white;
border: 1px solid rgba(0, 0, 0, 0.1);
}
#context-menu .menu-item {
padding: 0.5rem 1rem;
cursor: pointer;
transition: background-color 0.2s ease;
}
.dark #context-menu .menu-item:hover {
background-color: rgba(255, 255, 255, 0.05);
}
body:not(.dark) #context-menu .menu-item:hover {
background-color: rgba(0, 0, 0, 0.05);
}
/* Zusätzliches Layout */
.mindmap-section {
display: grid;
grid-template-columns: 1fr;
gap: 1.5rem;
}
@media (min-width: 1024px) {
.mindmap-section {
grid-template-columns: 2fr 1fr;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background-color: #f9fafb;
color: #111827;
line-height: 1.5;
}
.container {
display: flex;
flex-direction: column;
height: 100vh;
width: 100%;
}
.header {
background-color: #1f2937;
color: white;
padding: 1rem;
display: flex;
justify-content: space-between;
align-items: center;
}
.header h1 {
font-size: 1.5rem;
font-weight: 500;
}
.toolbar {
background-color: #f3f4f6;
padding: 0.75rem;
display: flex;
gap: 0.5rem;
border-bottom: 1px solid #e5e7eb;
}
.btn {
background-color: #3b82f6;
color: white;
border: none;
border-radius: 0.25rem;
padding: 0.5rem 1rem;
font-size: 0.875rem;
cursor: pointer;
transition: background-color 0.2s;
display: flex;
align-items: center;
gap: 0.5rem;
}
.btn:hover {
background-color: #2563eb;
}
.btn-secondary {
background-color: #6b7280;
}
.btn-secondary:hover {
background-color: #4b5563;
}
.btn-danger {
background-color: #ef4444;
}
.btn-danger:hover {
background-color: #dc2626;
}
.search-container {
flex: 1;
display: flex;
margin-left: 1rem;
}
.search-input {
width: 100%;
max-width: 300px;
padding: 0.5rem;
border: 1px solid #d1d5db;
border-radius: 0.25rem;
font-size: 0.875rem;
}
#cy {
flex: 1;
width: 100%;
position: relative;
}
.category-filters {
display: flex;
gap: 0.5rem;
flex-wrap: wrap;
padding: 0.75rem;
background-color: #ffffff;
border-bottom: 1px solid #e5e7eb;
}
.category-filter {
border: none;
border-radius: 0.25rem;
padding: 0.25rem 0.75rem;
font-size: 0.75rem;
cursor: pointer;
transition: opacity 0.2s;
color: white;
}
.category-filter:not(.active) {
opacity: 0.6;
}
.category-filter:hover:not(.active) {
opacity: 0.8;
}
.footer {
background-color: #f3f4f6;
padding: 0.75rem;
text-align: center;
font-size: 0.75rem;
color: #6b7280;
border-top: 1px solid #e5e7eb;
}
/* Kontextmenü Styling */
#context-menu {
position: absolute;
background-color: white;
border: 1px solid #e5e7eb;
border-radius: 0.25rem;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
z-index: 1000;
}
#context-menu .menu-item {
padding: 0.5rem 1rem;
cursor: pointer;
}
#context-menu .menu-item:hover {
background-color: #f3f4f6;
}
</style>
</head>
<body>
<div class="container">
<header class="header">
<h1>Interaktive Mindmap</h1>
<div class="search-container">
<input type="text" id="search-mindmap" class="search-input" placeholder="Suchen...">
</div>
</header>
<div class="toolbar">
<button id="addNode" class="btn">
<i data-feather="plus-circle"></i>
Knoten hinzufügen
</button>
<button id="addEdge" class="btn">
<i data-feather="git-branch"></i>
Verbindung erstellen
</button>
<button id="editNode" class="btn btn-secondary">
<i data-feather="edit-2"></i>
Knoten bearbeiten
</button>
<button id="deleteNode" class="btn btn-danger">
<i data-feather="trash-2"></i>
Knoten löschen
</button>
<button id="deleteEdge" class="btn btn-danger">
<i data-feather="scissors"></i>
Verbindung löschen
</button>
<button id="reLayout" class="btn btn-secondary">
<i data-feather="refresh-cw"></i>
Layout neu anordnen
</button>
<button id="exportMindmap" class="btn btn-secondary">
<i data-feather="download"></i>
Exportieren
</button>
</div>
<div id="category-filters" class="category-filters">
<!-- Wird dynamisch befüllt -->
</div>
<div id="cy"></div>
<footer class="footer">
Mindmap-Anwendung © 2023
</footer>
}
</style>
{% endblock %}
{% block content %}
<div class="container mx-auto px-4">
<div class="mb-8">
<h1 class="text-3xl font-bold mb-2 gradient-text">Interaktive Mindmap</h1>
<p class="text-gray-500 dark:text-gray-400">Visualisieren und erkunden Sie Wissensnetze und Gedankenkonstrukte</p>
</div>
<!-- Unsere Mindmap JS -->
<script src="{{ url_for('static', filename='js/mindmap.js') }}"></script>
<!-- Icons initialisieren -->
<script>
document.addEventListener('DOMContentLoaded', () => {
if (typeof feather !== 'undefined') {
feather.replace();
}
<div class="mindmap-section">
<!-- Linke Spalte: Mindmap -->
<div class="mindmap-container">
<!-- Suchleiste -->
<div class="mindmap-toolbar">
<div class="flex-1">
<input type="text" id="search-mindmap"
class="w-full max-w-md px-3 py-2 rounded-lg"
x-bind:class="darkMode ? 'bg-gray-800 border border-gray-700 text-white' : 'bg-white border border-gray-300 text-gray-700'"
placeholder="In der Mindmap suchen...">
</div>
<button id="addNode" class="btn"
x-bind:class="darkMode ? 'bg-primary-600 hover:bg-primary-700 text-white' : 'bg-primary-500 hover:bg-primary-600 text-white'">
<i class="fa-solid fa-plus"></i>
<span class="hidden sm:inline">Knoten hinzufügen</span>
</button>
<button id="addEdge" class="btn"
x-bind:class="darkMode ? 'bg-primary-600 hover:bg-primary-700 text-white' : 'bg-primary-500 hover:bg-primary-600 text-white'">
<i class="fa-solid fa-link"></i>
<span class="hidden sm:inline">Verbindung</span>
</button>
<button id="reLayout" class="btn"
x-bind:class="darkMode ? 'bg-gray-700 hover:bg-gray-600 text-white' : 'bg-gray-200 hover:bg-gray-300 text-gray-700'">
<i class="fa-solid fa-compass-drafting"></i>
<span class="hidden sm:inline">Anordnen</span>
</button>
<div class="relative" x-data="{ open: false }">
<button @click="open = !open" class="btn"
x-bind:class="darkMode ? 'bg-gray-700 hover:bg-gray-600 text-white' : 'bg-gray-200 hover:bg-gray-300 text-gray-700'">
<i class="fa-solid fa-ellipsis-vertical"></i>
</button>
<div x-show="open" @click.away="open = false"
x-transition:enter="transition ease-out duration-200"
x-transition:enter-start="opacity-0 scale-95"
x-transition:enter-end="opacity-100 scale-100"
x-transition:leave="transition ease-in duration-150"
x-transition:leave-start="opacity-100 scale-100"
x-transition:leave-end="opacity-0 scale-95"
class="absolute right-0 mt-2 w-48 origin-top-right z-10 rounded-md shadow-lg"
x-bind:class="darkMode ? 'bg-gray-800' : 'bg-white'">
<div class="py-1">
<button id="editNode" class="block w-full text-left px-4 py-2 text-sm hover:bg-gray-700"
x-bind:class="darkMode ? 'text-gray-300 hover:bg-gray-700' : 'text-gray-700 hover:bg-gray-100'">
<i class="fa-solid fa-edit mr-2"></i>Knoten bearbeiten
</button>
<button id="deleteNode" class="block w-full text-left px-4 py-2 text-sm hover:bg-red-600/20"
x-bind:class="darkMode ? 'text-gray-300 hover:bg-red-600/20' : 'text-gray-700 hover:bg-red-100'">
<i class="fa-solid fa-trash-alt mr-2"></i>Knoten löschen
</button>
<button id="deleteEdge" class="block w-full text-left px-4 py-2 text-sm hover:bg-red-600/20"
x-bind:class="darkMode ? 'text-gray-300 hover:bg-red-600/20' : 'text-gray-700 hover:bg-red-100'">
<i class="fa-solid fa-unlink mr-2"></i>Verbindung löschen
</button>
<button id="exportMindmap" class="block w-full text-left px-4 py-2 text-sm"
x-bind:class="darkMode ? 'text-gray-300 hover:bg-gray-700' : 'text-gray-700 hover:bg-gray-100'">
<i class="fa-solid fa-file-export mr-2"></i>Exportieren
</button>
</div>
</div>
</div>
</div>
<!-- Kategoriefilter -->
<div id="category-filters" class="category-filters"></div>
<!-- Mindmap-Visualisierung -->
<div id="cy"></div>
</div>
<!-- Rechte Spalte: Detail-Ansicht und Interaktionen -->
<div class="space-y-6">
<!-- Knoteninformationen -->
<div class="card p-5"
x-bind:class="darkMode ? 'bg-gray-800/80 border border-gray-700' : 'bg-white/90 border border-gray-200'">
<h2 class="text-xl font-semibold mb-3"
x-bind:class="darkMode ? 'text-white' : 'text-gray-800'">
<i class="fa-solid fa-circle-info mr-2"></i>Information
</h2>
<div id="node-details">
<p class="text-sm"
x-bind:class="darkMode ? 'text-gray-300' : 'text-gray-600'">
Wählen Sie einen Knoten aus der Mindmap aus, um Details anzuzeigen.
</p>
</div>
</div>
<!-- Verbundene Gedanken -->
<div class="card p-5"
x-bind:class="darkMode ? 'bg-gray-800/80 border border-gray-700' : 'bg-white/90 border border-gray-200'">
<div class="flex justify-between items-center mb-3">
<h2 class="text-xl font-semibold"
x-bind:class="darkMode ? 'text-white' : 'text-gray-800'">
<i class="fa-solid fa-lightbulb mr-2"></i>Gedanken
</h2>
<button class="btn-sm"
x-bind:class="darkMode ? 'bg-primary-600 hover:bg-primary-700 text-white' : 'bg-primary-500 hover:bg-primary-600 text-white'">
<i class="fa-solid fa-plus mr-1"></i>Neu
</button>
</div>
<div id="thoughts-container">
<p class="text-sm"
x-bind:class="darkMode ? 'text-gray-300' : 'text-gray-600'">
Wählen Sie einen Knoten aus, um zugehörige Gedanken zu sehen.
</p>
</div>
</div>
<!-- Schnellhilfe -->
<div class="card p-5"
x-bind:class="darkMode ? 'bg-gray-800/80 border border-gray-700' : 'bg-white/90 border border-gray-200'">
<h2 class="text-xl font-semibold mb-3"
x-bind:class="darkMode ? 'text-white' : 'text-gray-800'">
<i class="fa-solid fa-circle-question mr-2"></i>Schnellhilfe
</h2>
<ul class="text-sm space-y-2"
x-bind:class="darkMode ? 'text-gray-300' : 'text-gray-600'">
<li><i class="fa-solid fa-mouse mr-2"></i>Klicken Sie auf einen Knoten, um ihn auszuwählen</li>
<li><i class="fa-solid fa-arrows-up-down-left-right mr-2"></i>Ziehen Sie die Maus, um die Ansicht zu verschieben</li>
<li><i class="fa-solid fa-magnifying-glass-plus mr-2"></i>Mausrad zum Zoomen</li>
<li><i class="fa-solid fa-right-click mr-2"></i>Rechtsklick für Kontextmenü</li>
</ul>
</div>
</div>
</div>
</div>
<!-- Cytoscape.js für die Mindmap-Visualisierung -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/cytoscape/3.26.0/cytoscape.min.js"></script>
<!-- Socket.IO für Echtzeitaktualisierungen -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.7.2/socket.io.min.js"></script>
{% endblock %}
{% block scripts %}
<script>
document.addEventListener('DOMContentLoaded', function() {
// Verarbeite Dark-Mode-Umschaltungen für die Mindmap-Visualisierung
document.addEventListener('darkModeToggled', function(event) {
// Hier könnten wir das Mindmap-Styling basierend auf Dark/Light-Mode aktualisieren
// z.B. Hintergrundfarben, Knotenfarben etc.
console.log('Dark Mode für Mindmap aktualisiert:', event.detail.isDark);
});
</script>
</body>
</html>
// Weitere Mindmap-spezifische Initialisierung
// Sollte mit dem vorhandenen mindmap.js-Modul funktionieren
});
</script>
{% endblock %}