chore: automatic commit 2025-04-30 12:48
This commit is contained in:
308
templates/admin.html
Normal file
308
templates/admin.html
Normal file
@@ -0,0 +1,308 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}Admin-Bereich{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container mx-auto px-4 py-8">
|
||||
<h1 class="text-3xl font-bold mb-8 text-gray-800 dark:text-white">Admin-Bereich</h1>
|
||||
|
||||
<!-- Tabs für verschiedene Bereiche -->
|
||||
<div x-data="{ activeTab: 'users' }" class="mb-8">
|
||||
<div class="flex space-x-2 mb-6 overflow-x-auto">
|
||||
<button
|
||||
@click="activeTab = 'users'"
|
||||
:class="activeTab === 'users' ? 'bg-primary-600 text-white' : 'bg-white/10 text-gray-700 dark:text-gray-200'"
|
||||
class="px-4 py-2 rounded-lg font-medium transition-all">
|
||||
<i class="fas fa-users mr-2"></i> Benutzer
|
||||
</button>
|
||||
<button
|
||||
@click="activeTab = 'nodes'"
|
||||
:class="activeTab === 'nodes' ? 'bg-primary-600 text-white' : 'bg-white/10 text-gray-700 dark:text-gray-200'"
|
||||
class="px-4 py-2 rounded-lg font-medium transition-all">
|
||||
<i class="fas fa-project-diagram mr-2"></i> Mindmap-Knoten
|
||||
</button>
|
||||
<button
|
||||
@click="activeTab = 'thoughts'"
|
||||
:class="activeTab === 'thoughts' ? 'bg-primary-600 text-white' : 'bg-white/10 text-gray-700 dark:text-gray-200'"
|
||||
class="px-4 py-2 rounded-lg font-medium transition-all">
|
||||
<i class="fas fa-lightbulb mr-2"></i> Gedanken
|
||||
</button>
|
||||
<button
|
||||
@click="activeTab = 'stats'"
|
||||
:class="activeTab === 'stats' ? 'bg-primary-600 text-white' : 'bg-white/10 text-gray-700 dark:text-gray-200'"
|
||||
class="px-4 py-2 rounded-lg font-medium transition-all">
|
||||
<i class="fas fa-chart-bar mr-2"></i> Statistiken
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Benutzer-Tab -->
|
||||
<div x-show="activeTab === 'users'" class="glass-morphism rounded-lg p-6">
|
||||
<div class="flex justify-between items-center mb-6">
|
||||
<h2 class="text-xl font-bold text-gray-800 dark:text-white">Benutzerverwaltung</h2>
|
||||
<button class="btn-outline">
|
||||
<i class="fas fa-plus mr-2"></i> Neuer Benutzer
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="overflow-x-auto">
|
||||
<table class="w-full">
|
||||
<thead>
|
||||
<tr class="text-left border-b border-gray-200 dark:border-gray-700">
|
||||
<th class="px-4 py-2 text-gray-700 dark:text-gray-300">ID</th>
|
||||
<th class="px-4 py-2 text-gray-700 dark:text-gray-300">Benutzername</th>
|
||||
<th class="px-4 py-2 text-gray-700 dark:text-gray-300">E-Mail</th>
|
||||
<th class="px-4 py-2 text-gray-700 dark:text-gray-300">Admin</th>
|
||||
<th class="px-4 py-2 text-gray-700 dark:text-gray-300">Gedanken</th>
|
||||
<th class="px-4 py-2 text-gray-700 dark:text-gray-300">Aktionen</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for user in users %}
|
||||
<tr class="border-b border-gray-100 dark:border-gray-800 hover:bg-gray-50 dark:hover:bg-dark-700/30">
|
||||
<td class="px-4 py-3 text-gray-700 dark:text-gray-300">{{ user.id }}</td>
|
||||
<td class="px-4 py-3 text-gray-700 dark:text-gray-300 font-medium">{{ user.username }}</td>
|
||||
<td class="px-4 py-3 text-gray-700 dark:text-gray-300">{{ user.email }}</td>
|
||||
<td class="px-4 py-3 text-gray-700 dark:text-gray-300">
|
||||
{% if user.is_admin %}
|
||||
<span class="bg-green-100 text-green-800 dark:bg-green-900/30 dark:text-green-300 px-2 py-1 rounded text-xs">Admin</span>
|
||||
{% else %}
|
||||
<span class="bg-blue-100 text-blue-800 dark:bg-blue-900/30 dark:text-blue-300 px-2 py-1 rounded text-xs">User</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td class="px-4 py-3 text-gray-700 dark:text-gray-300">{{ user.thoughts|length }}</td>
|
||||
<td class="px-4 py-3 flex space-x-2">
|
||||
<button class="text-blue-600 hover:text-blue-800 dark:text-blue-400 dark:hover:text-blue-300">
|
||||
<i class="fas fa-edit"></i>
|
||||
</button>
|
||||
<button class="text-red-600 hover:text-red-800 dark:text-red-400 dark:hover:text-red-300">
|
||||
<i class="fas fa-trash-alt"></i>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Mindmap-Knoten-Tab -->
|
||||
<div x-show="activeTab === 'nodes'" class="glass-morphism rounded-lg p-6">
|
||||
<div class="flex justify-between items-center mb-6">
|
||||
<h2 class="text-xl font-bold text-gray-800 dark:text-white">Mindmap-Knoten Verwaltung</h2>
|
||||
<button class="btn-outline">
|
||||
<i class="fas fa-plus mr-2"></i> Neuer Knoten
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="overflow-x-auto">
|
||||
<table class="w-full">
|
||||
<thead>
|
||||
<tr class="text-left border-b border-gray-200 dark:border-gray-700">
|
||||
<th class="px-4 py-2 text-gray-700 dark:text-gray-300">ID</th>
|
||||
<th class="px-4 py-2 text-gray-700 dark:text-gray-300">Name</th>
|
||||
<th class="px-4 py-2 text-gray-700 dark:text-gray-300">Elternknoten</th>
|
||||
<th class="px-4 py-2 text-gray-700 dark:text-gray-300">Gedanken</th>
|
||||
<th class="px-4 py-2 text-gray-700 dark:text-gray-300">Aktionen</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for node in nodes %}
|
||||
<tr class="border-b border-gray-100 dark:border-gray-800 hover:bg-gray-50 dark:hover:bg-dark-700/30">
|
||||
<td class="px-4 py-3 text-gray-700 dark:text-gray-300">{{ node.id }}</td>
|
||||
<td class="px-4 py-3 text-gray-700 dark:text-gray-300 font-medium">{{ node.name }}</td>
|
||||
<td class="px-4 py-3 text-gray-700 dark:text-gray-300">
|
||||
{% if node.parent %}
|
||||
{{ node.parent.name }}
|
||||
{% else %}
|
||||
<span class="text-gray-400 dark:text-gray-500">Wurzelknoten</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td class="px-4 py-3 text-gray-700 dark:text-gray-300">{{ node.thoughts|length }}</td>
|
||||
<td class="px-4 py-3 flex space-x-2">
|
||||
<button class="text-blue-600 hover:text-blue-800 dark:text-blue-400 dark:hover:text-blue-300">
|
||||
<i class="fas fa-edit"></i>
|
||||
</button>
|
||||
<button class="text-red-600 hover:text-red-800 dark:text-red-400 dark:hover:text-red-300">
|
||||
<i class="fas fa-trash-alt"></i>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Gedanken-Tab -->
|
||||
<div x-show="activeTab === 'thoughts'" class="glass-morphism rounded-lg p-6">
|
||||
<div class="flex justify-between items-center mb-6">
|
||||
<h2 class="text-xl font-bold text-gray-800 dark:text-white">Gedanken-Verwaltung</h2>
|
||||
<div class="flex space-x-2">
|
||||
<div class="relative">
|
||||
<input type="text" placeholder="Suchen..." class="form-input pl-10 pr-4 py-2 rounded-lg bg-white/10 border border-gray-200/20 dark:border-gray-700/20 focus:outline-none focus:ring-2 focus:ring-primary-500 text-gray-700 dark:text-gray-200">
|
||||
<div class="absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-500">
|
||||
<i class="fas fa-search"></i>
|
||||
</div>
|
||||
</div>
|
||||
<button class="btn-outline">
|
||||
<i class="fas fa-filter mr-2"></i> Filter
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="overflow-x-auto">
|
||||
<table class="w-full">
|
||||
<thead>
|
||||
<tr class="text-left border-b border-gray-200 dark:border-gray-700">
|
||||
<th class="px-4 py-2 text-gray-700 dark:text-gray-300">ID</th>
|
||||
<th class="px-4 py-2 text-gray-700 dark:text-gray-300">Titel</th>
|
||||
<th class="px-4 py-2 text-gray-700 dark:text-gray-300">Autor</th>
|
||||
<th class="px-4 py-2 text-gray-700 dark:text-gray-300">Datum</th>
|
||||
<th class="px-4 py-2 text-gray-700 dark:text-gray-300">Bewertung</th>
|
||||
<th class="px-4 py-2 text-gray-700 dark:text-gray-300">Aktionen</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for thought in thoughts %}
|
||||
<tr class="border-b border-gray-100 dark:border-gray-800 hover:bg-gray-50 dark:hover:bg-dark-700/30">
|
||||
<td class="px-4 py-3 text-gray-700 dark:text-gray-300">{{ thought.id }}</td>
|
||||
<td class="px-4 py-3 text-gray-700 dark:text-gray-300 font-medium">{{ thought.title }}</td>
|
||||
<td class="px-4 py-3 text-gray-700 dark:text-gray-300">{{ thought.author.username }}</td>
|
||||
<td class="px-4 py-3 text-gray-700 dark:text-gray-300">{{ thought.timestamp.strftime('%d.%m.%Y') }}</td>
|
||||
<td class="px-4 py-3 text-gray-700 dark:text-gray-300">
|
||||
<div class="flex items-center">
|
||||
<span class="mr-2">{{ "%.1f"|format(thought.average_rating) }}</span>
|
||||
<div class="flex">
|
||||
{% for i in range(5) %}
|
||||
{% if i < thought.average_rating|int %}
|
||||
<i class="fas fa-star text-yellow-400"></i>
|
||||
{% elif i < (thought.average_rating|int + 0.5) %}
|
||||
<i class="fas fa-star-half-alt text-yellow-400"></i>
|
||||
{% else %}
|
||||
<i class="far fa-star text-yellow-400"></i>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-4 py-3 flex space-x-2">
|
||||
<button class="text-blue-600 hover:text-blue-800 dark:text-blue-400 dark:hover:text-blue-300">
|
||||
<i class="fas fa-eye"></i>
|
||||
</button>
|
||||
<button class="text-blue-600 hover:text-blue-800 dark:text-blue-400 dark:hover:text-blue-300">
|
||||
<i class="fas fa-edit"></i>
|
||||
</button>
|
||||
<button class="text-red-600 hover:text-red-800 dark:text-red-400 dark:hover:text-red-300">
|
||||
<i class="fas fa-trash-alt"></i>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Statistiken-Tab -->
|
||||
<div x-show="activeTab === 'stats'" class="glass-morphism rounded-lg p-6">
|
||||
<h2 class="text-xl font-bold mb-6 text-gray-800 dark:text-white">Systemstatistiken</h2>
|
||||
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 mb-8">
|
||||
<div class="glass-effect p-4 rounded-lg">
|
||||
<div class="flex items-center mb-2">
|
||||
<div class="bg-blue-500/20 p-3 rounded-lg mr-3">
|
||||
<i class="fas fa-users text-blue-500"></i>
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="text-sm font-medium text-gray-600 dark:text-gray-300">Benutzer</h3>
|
||||
<p class="text-2xl font-bold text-gray-800 dark:text-white">{{ users|length }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="glass-effect p-4 rounded-lg">
|
||||
<div class="flex items-center mb-2">
|
||||
<div class="bg-purple-500/20 p-3 rounded-lg mr-3">
|
||||
<i class="fas fa-project-diagram text-purple-500"></i>
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="text-sm font-medium text-gray-600 dark:text-gray-300">Knoten</h3>
|
||||
<p class="text-2xl font-bold text-gray-800 dark:text-white">{{ nodes|length }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="glass-effect p-4 rounded-lg">
|
||||
<div class="flex items-center mb-2">
|
||||
<div class="bg-green-500/20 p-3 rounded-lg mr-3">
|
||||
<i class="fas fa-lightbulb text-green-500"></i>
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="text-sm font-medium text-gray-600 dark:text-gray-300">Gedanken</h3>
|
||||
<p class="text-2xl font-bold text-gray-800 dark:text-white">{{ thoughts|length }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="glass-effect p-4 rounded-lg">
|
||||
<div class="flex items-center mb-2">
|
||||
<div class="bg-red-500/20 p-3 rounded-lg mr-3">
|
||||
<i class="fas fa-comments text-red-500"></i>
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="text-sm font-medium text-gray-600 dark:text-gray-300">Kommentare</h3>
|
||||
<p class="text-2xl font-bold text-gray-800 dark:text-white">
|
||||
{% set comment_count = 0 %}
|
||||
{% for thought in thoughts %}
|
||||
{% set comment_count = comment_count + thought.comments|length %}
|
||||
{% endfor %}
|
||||
{{ comment_count }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
<div class="glass-effect p-4 rounded-lg">
|
||||
<h3 class="text-lg font-bold mb-4 text-gray-800 dark:text-white">Aktive Benutzer</h3>
|
||||
<div class="h-64 flex items-center justify-center bg-gray-100/20 dark:bg-dark-700/20 rounded">
|
||||
<p class="text-gray-500 dark:text-gray-400">Hier würde ein Aktivitätsdiagramm angezeigt werden</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="glass-effect p-4 rounded-lg">
|
||||
<h3 class="text-lg font-bold mb-4 text-gray-800 dark:text-white">Gedanken pro Kategorie</h3>
|
||||
<div class="h-64 flex items-center justify-center bg-gray-100/20 dark:bg-dark-700/20 rounded">
|
||||
<p class="text-gray-500 dark:text-gray-400">Hier würde eine Verteilungsstatistik angezeigt werden</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- System-Log (immer sichtbar) -->
|
||||
<div class="mt-8">
|
||||
<h2 class="text-xl font-bold mb-4 text-gray-800 dark:text-white">System-Log</h2>
|
||||
<div class="glass-morphism rounded-lg p-4 h-32 overflow-y-auto font-mono text-sm text-gray-700 dark:text-gray-300">
|
||||
<div class="text-green-500">[INFO] [{{ now.strftime('%Y-%m-%d %H:%M:%S') }}] System gestartet</div>
|
||||
<div class="text-blue-500">[INFO] [{{ now.strftime('%Y-%m-%d %H:%M:%S') }}] Admin-Bereich aufgerufen von {{ current_user.username }}</div>
|
||||
<div class="text-yellow-500">[WARN] [{{ now.strftime('%Y-%m-%d %H:%M:%S') }}] Hohe Serverauslastung erkannt</div>
|
||||
<div class="text-gray-500">[INFO] [{{ now.strftime('%Y-%m-%d %H:%M:%S') }}] Backup erfolgreich erstellt</div>
|
||||
<div class="text-red-500">[ERROR] [{{ now.strftime('%Y-%m-%d %H:%M:%S') }}] API-Zugriffsfehler (Timeout) bei externer Anfrage</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_js %}
|
||||
<script>
|
||||
// Admin-spezifische JavaScript-Funktionen
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
console.log('Admin-Bereich geladen');
|
||||
|
||||
// Beispiel für AJAX-Ladeverhalten von Daten
|
||||
// Kann später durch echte API-Calls ersetzt werden
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
71
templates/agb.html
Normal file
71
templates/agb.html
Normal file
@@ -0,0 +1,71 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}AGB{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="max-w-3xl mx-auto">
|
||||
<div class="card p-6 md:p-8">
|
||||
<h1 class="text-3xl font-bold mb-6 gradient-text">Allgemeine Geschäftsbedingungen</h1>
|
||||
|
||||
<section class="mb-8">
|
||||
<h2 class="text-xl font-bold mb-4">1. Geltungsbereich</h2>
|
||||
<p class="mb-4">Diese Allgemeinen Geschäftsbedingungen (nachfolgend "AGB") gelten für die Nutzung der MindMap-Plattform (nachfolgend "Plattform"), die von der MindMap GmbH, Musterstraße 123, 12345 Musterstadt (nachfolgend "Anbieter") betrieben wird.</p>
|
||||
<p class="mb-4">Mit der Registrierung und/oder Nutzung der Plattform erkennt der Nutzer diese AGB an. Die Nutzung der Plattform ist nur zulässig, wenn der Nutzer diese AGB akzeptiert.</p>
|
||||
</section>
|
||||
|
||||
<section class="mb-8">
|
||||
<h2 class="text-xl font-bold mb-4">2. Leistungsbeschreibung</h2>
|
||||
<p class="mb-4">Die Plattform bietet dem Nutzer die Möglichkeit, komplexe Informationen in Form von Mindmaps zu visualisieren, zu organisieren und zu teilen. Der genaue Funktionsumfang ergibt sich aus der jeweiligen Leistungsbeschreibung auf der Website des Anbieters.</p>
|
||||
<p class="mb-4">Der Anbieter ist berechtigt, die angebotenen Dienste zu ändern, neue Dienste unentgeltlich oder entgeltlich verfügbar zu machen und die Bereitstellung unentgeltlicher Dienste einzustellen. Der Anbieter wird hierbei jeweils auf die berechtigten Interessen des Nutzers Rücksicht nehmen.</p>
|
||||
</section>
|
||||
|
||||
<section class="mb-8">
|
||||
<h2 class="text-xl font-bold mb-4">3. Registrierung und Nutzerkonto</h2>
|
||||
<p class="mb-4">Die Nutzung bestimmter Funktionen der Plattform setzt die Registrierung eines Nutzerkontos voraus. Die Registrierung ist nur volljährigen und voll geschäftsfähigen natürlichen Personen erlaubt.</p>
|
||||
<p class="mb-4">Der Nutzer verpflichtet sich, bei der Registrierung wahrheitsgemäße und vollständige Angaben zu machen und diese Daten stets aktuell zu halten. Es ist nicht gestattet, mehrere Nutzerkonten zu erstellen.</p>
|
||||
<p class="mb-4">Der Nutzer ist verpflichtet, seine Zugangsdaten geheim zu halten und vor dem Zugriff durch unbefugte Dritte zu schützen. Der Anbieter wird den Nutzer niemals nach seinem Passwort fragen.</p>
|
||||
</section>
|
||||
|
||||
<section class="mb-8">
|
||||
<h2 class="text-xl font-bold mb-4">4. Nutzungsrechte</h2>
|
||||
<p class="mb-4">Der Anbieter gewährt dem Nutzer für die Dauer der Vertragslaufzeit ein einfaches, nicht übertragbares Recht zur Nutzung der Plattform im vertraglich vereinbarten Umfang.</p>
|
||||
<p class="mb-4">Der Nutzer räumt dem Anbieter an den von ihm auf der Plattform eingestellten Inhalten ein einfaches, übertragbares, unterlizenzierbares, räumlich und zeitlich unbeschränktes Nutzungsrecht ein, soweit dies für den Betrieb der Plattform erforderlich ist.</p>
|
||||
<p class="mb-4">Der Nutzer garantiert, dass er über alle Rechte an den von ihm eingestellten Inhalten verfügt und durch diese keine Rechte Dritter verletzt werden.</p>
|
||||
</section>
|
||||
|
||||
<section class="mb-8">
|
||||
<h2 class="text-xl font-bold mb-4">5. Pflichten des Nutzers</h2>
|
||||
<p class="mb-4">Der Nutzer verpflichtet sich, die Plattform nur im Einklang mit diesen AGB und den geltenden Gesetzen zu nutzen. Insbesondere ist es dem Nutzer untersagt:</p>
|
||||
<ul class="list-disc pl-6 mb-4 space-y-2">
|
||||
<li>die Plattform für rechtswidrige oder betrügerische Zwecke zu nutzen</li>
|
||||
<li>rechtswidrige, beleidigende, diskriminierende oder anderweitig anstößige Inhalte zu verbreiten</li>
|
||||
<li>Schadsoftware, Viren oder andere schädliche Computercodes zu verbreiten</li>
|
||||
<li>die normale Funktion der Plattform zu stören oder übermäßig zu belasten</li>
|
||||
<li>auf die Plattform mit automatisierten Mitteln zuzugreifen (wie z.B. Bots, Scraper)</li>
|
||||
<li>die Plattform zu reverse-engineeren, zu dekompilieren oder zu disassemblieren</li>
|
||||
</ul>
|
||||
<p class="mb-4">Der Anbieter behält sich das Recht vor, bei Verstößen gegen diese Pflichten entsprechende Maßnahmen zu ergreifen, einschließlich der Sperrung des Nutzerkontos.</p>
|
||||
</section>
|
||||
|
||||
<section class="mb-8">
|
||||
<h2 class="text-xl font-bold mb-4">6. Verfügbarkeit und Wartung</h2>
|
||||
<p class="mb-4">Der Anbieter ist bemüht, eine hohe Verfügbarkeit der Plattform zu gewährleisten, kann jedoch keine unterbrechungsfreie Verfügbarkeit garantieren. Insbesondere können Wartungsarbeiten, Sicherheits- oder Kapazitätsprobleme sowie Ereignisse, die außerhalb des Einflussbereichs des Anbieters liegen, zu vorübergehenden Unterbrechungen führen.</p>
|
||||
<p class="mb-4">Der Anbieter wird planmäßige Wartungsarbeiten, sofern möglich, vorher ankündigen und zu Zeiten durchführen, in denen die Nutzung der Plattform typischerweise gering ist.</p>
|
||||
</section>
|
||||
|
||||
<section class="mb-8">
|
||||
<h2 class="text-xl font-bold mb-4">7. Haftung</h2>
|
||||
<p class="mb-4">Der Anbieter haftet unbeschränkt für Vorsatz und grobe Fahrlässigkeit sowie nach dem Produkthaftungsgesetz. Für leichte Fahrlässigkeit haftet der Anbieter nur bei Verletzung einer wesentlichen Vertragspflicht und der Höhe nach beschränkt auf die bei Vertragsschluss vorhersehbaren und vertragstypischen Schäden. Wesentliche Vertragspflichten sind solche, deren Erfüllung die ordnungsgemäße Durchführung des Vertrags überhaupt erst ermöglicht und auf deren Einhaltung der Nutzer regelmäßig vertrauen darf.</p>
|
||||
<p class="mb-4">Diese Haftungsbeschränkung gilt nicht für Schäden aus der Verletzung des Lebens, des Körpers oder der Gesundheit.</p>
|
||||
</section>
|
||||
|
||||
<section class="mb-8">
|
||||
<h2 class="text-xl font-bold mb-4">8. Schlussbestimmungen</h2>
|
||||
<p class="mb-4">Es gilt das Recht der Bundesrepublik Deutschland unter Ausschluss des UN-Kaufrechts.</p>
|
||||
<p class="mb-4">Sollten einzelne Bestimmungen dieser AGB unwirksam sein oder werden, bleibt die Wirksamkeit der übrigen Bestimmungen unberührt.</p>
|
||||
<p class="mb-4">Der Anbieter behält sich vor, diese AGB jederzeit zu ändern. Änderungen werden dem Nutzer rechtzeitig vor ihrem Inkrafttreten mitgeteilt. Die Änderungen gelten als akzeptiert, wenn der Nutzer ihnen nicht innerhalb von vier Wochen nach Erhalt der Mitteilung widerspricht.</p>
|
||||
<p class="mb-4">Stand: Mai 2023</p>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
614
templates/base.html
Normal file
614
templates/base.html
Normal file
@@ -0,0 +1,614 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="de" class="dark">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Systades - {% block title %}{% endblock %}</title>
|
||||
|
||||
<!-- Favicon -->
|
||||
<link rel="icon" href="{{ url_for('static', filename='img/favicon.svg') }}" type="image/svg+xml">
|
||||
<link rel="icon" href="{{ url_for('static', filename='img/favicon.ico') }}" sizes="any">
|
||||
|
||||
<!-- Meta Tags -->
|
||||
<meta name="description" content="Eine interaktive Plattform zum Visualisieren, Erforschen und Teilen von Wissen">
|
||||
<meta name="keywords" content="systades, wissen, visualisierung, lernen, gedanken, theorie">
|
||||
<meta name="author" content="Systades-Team">
|
||||
|
||||
<!-- Tailwind CSS - CDN für Entwicklung und Produktion (laut Vorgabe) -->
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<!-- Alternative lokale Version, falls die CDN-Version blockiert wird -->
|
||||
<script>
|
||||
tailwind = window.tailwind || {};
|
||||
tailwind.config = {
|
||||
darkMode: 'class',
|
||||
theme: {
|
||||
extend: {
|
||||
fontFamily: {
|
||||
sans: ['Inter', 'ui-sans-serif', 'system-ui', '-apple-system', 'sans-serif'],
|
||||
mono: ['JetBrains Mono', 'ui-monospace', 'monospace']
|
||||
},
|
||||
colors: {
|
||||
primary: {
|
||||
50: '#f5f3ff',
|
||||
100: '#ede9fe',
|
||||
200: '#ddd6fe',
|
||||
300: '#c4b5fd',
|
||||
400: '#a78bfa',
|
||||
500: '#8b5cf6',
|
||||
600: '#7c3aed',
|
||||
700: '#6d28d9',
|
||||
800: '#5b21b6',
|
||||
900: '#4c1d95'
|
||||
},
|
||||
secondary: {
|
||||
50: '#ecfdf5',
|
||||
100: '#d1fae5',
|
||||
200: '#a7f3d0',
|
||||
300: '#6ee7b7',
|
||||
400: '#34d399',
|
||||
500: '#10b981',
|
||||
600: '#059669',
|
||||
700: '#047857',
|
||||
800: '#065f46',
|
||||
900: '#064e3b'
|
||||
},
|
||||
dark: {
|
||||
500: '#374151',
|
||||
600: '#1f2937',
|
||||
700: '#111827',
|
||||
800: '#0e1220',
|
||||
900: '#0a0e19'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<!-- Local Font Files -->
|
||||
<link href="{{ url_for('static', filename='fonts/inter.css') }}" rel="stylesheet">
|
||||
<link href="{{ url_for('static', filename='fonts/jetbrains-mono.css') }}" rel="stylesheet">
|
||||
|
||||
<!-- Icons - Self-hosted Font Awesome -->
|
||||
<link href="{{ url_for('static', filename='css/all.min.css') }}" rel="stylesheet">
|
||||
|
||||
<!-- Assistent CSS -->
|
||||
<link href="{{ url_for('static', filename='css/assistant.css') }}" rel="stylesheet">
|
||||
|
||||
<!-- Basis-Stylesheet -->
|
||||
<link href="{{ url_for('static', filename='style.css') }}" rel="stylesheet">
|
||||
|
||||
<!-- Base-Styles ausgelagert in eigene Datei -->
|
||||
<link href="{{ url_for('static', filename='css/base-styles.css') }}" rel="stylesheet">
|
||||
|
||||
<!-- Alpine.js - CDN Version -->
|
||||
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.12.3/dist/cdn.min.js"></script>
|
||||
|
||||
<!-- Neural Network Background CSS -->
|
||||
<link href="{{ url_for('static', filename='css/neural-network-background.css') }}" rel="stylesheet">
|
||||
|
||||
<!-- D3.js für Visualisierungen -->
|
||||
<script src="https://d3js.org/d3.v7.min.js"></script>
|
||||
|
||||
<!-- Marked.js für Markdown-Parsing -->
|
||||
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
|
||||
|
||||
<!-- ChatGPT Assistant -->
|
||||
<script src="{{ url_for('static', filename='js/modules/chatgpt-assistant.js') }}"></script>
|
||||
|
||||
<!-- MindMap Visualization Module -->
|
||||
<script src="{{ url_for('static', filename='js/modules/mindmap.js') }}"></script>
|
||||
|
||||
<!-- MindMap Page Module -->
|
||||
<script src="{{ url_for('static', filename='js/modules/mindmap-page.js') }}"></script>
|
||||
|
||||
<!-- Neural Network Background Script -->
|
||||
<script src="{{ url_for('static', filename='neural-network-background.js') }}"></script>
|
||||
|
||||
<!-- Hauptmodul laden (als traditionelles Skript) -->
|
||||
<script src="{{ url_for('static', filename='js/main.js') }}"></script>
|
||||
|
||||
<!-- Seitenspezifische Styles -->
|
||||
{% block extra_css %}{% endblock %}
|
||||
|
||||
<!-- Custom dark mode styles -->
|
||||
<!-- ► ► Farb‑Token strikt getrennt ◄ ◄ -->
|
||||
<style>
|
||||
/* Light‑Mode */
|
||||
:root {
|
||||
--bg-primary:#f4f6fa;
|
||||
--bg-secondary:#e9ecf3;
|
||||
--text-primary:#232837;
|
||||
--text-secondary:#475569;
|
||||
--accent-primary:#7c3aed;
|
||||
--accent-secondary:#8b5cf6;
|
||||
--glow-effect:0 0 8px rgba(139,92,246,.08);
|
||||
}
|
||||
/* Dark‑Mode */
|
||||
.dark {
|
||||
--bg-primary:#181c24;
|
||||
--bg-secondary:#232837;
|
||||
--text-primary:#f9fafb;
|
||||
--text-secondary:#e5e7eb;
|
||||
--accent-primary:#6d28d9;
|
||||
--accent-secondary:#8b5cf6;
|
||||
--glow-effect:0 0 8px rgba(124,58,237,.15);
|
||||
}
|
||||
|
||||
body {
|
||||
@apply min-h-screen bg-[color:var(--bg-primary)] text-[color:var(--text-primary)] transition-colors duration-300;
|
||||
}
|
||||
|
||||
/* Utilities */
|
||||
.mystical-glow { text-shadow: var(--glow-effect); }
|
||||
.gradient-text {
|
||||
background:linear-gradient(135deg,var(--accent-primary),var(--accent-secondary));
|
||||
-webkit-background-clip:text; background-clip:text; color:transparent; text-shadow:none;
|
||||
}
|
||||
.glass-morphism { backdrop-filter: blur(10px); }
|
||||
.glass-navbar { @apply glass-morphism border backdrop-blur-xl; }
|
||||
.light .glass-navbar { background-color:rgba(255,255,255,.8); border-color:rgba(0,0,0,.05); }
|
||||
.dark .glass-navbar { background-color:rgba(10,14,25,.8); border-color:rgba(255,255,255,.05); }
|
||||
</style>
|
||||
</head>
|
||||
<body data-page="{{ request.endpoint }}" class="relative overflow-x-hidden dark bg-gray-900 text-white" x-data="{
|
||||
darkMode: true,
|
||||
mobileMenuOpen: false,
|
||||
userMenuOpen: false,
|
||||
showSettingsModal: false,
|
||||
|
||||
init() {
|
||||
this.fetchDarkModeFromSession();
|
||||
},
|
||||
|
||||
fetchDarkModeFromSession() {
|
||||
fetch('/api/get_dark_mode')
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
this.darkMode = data.darkMode === 'true';
|
||||
document.querySelector('html').classList.toggle('dark', this.darkMode);
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Fehler beim Laden der Dark Mode-Einstellung:', error);
|
||||
});
|
||||
},
|
||||
|
||||
toggleDarkMode() {
|
||||
this.darkMode = !this.darkMode;
|
||||
document.querySelector('html').classList.toggle('dark', this.darkMode);
|
||||
|
||||
fetch('/api/set_dark_mode', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({ darkMode: this.darkMode })
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
localStorage.setItem('darkMode', this.darkMode ? 'dark' : 'light');
|
||||
document.dispatchEvent(new CustomEvent('darkModeToggled', {
|
||||
detail: { isDark: this.darkMode }
|
||||
}));
|
||||
} else {
|
||||
console.error('Fehler beim Speichern der Dark Mode-Einstellung:', data.error);
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Fehler beim Speichern der Dark Mode-Einstellung:', error);
|
||||
});
|
||||
}
|
||||
}">
|
||||
<!-- App-Container -->
|
||||
<div id="app-container" class="flex flex-col min-h-screen">
|
||||
<!-- Hauptnavigation -->
|
||||
<nav class="sticky top-0 left-0 right-0 z-50 transition-all duration-300 py-4 px-5 border-b glass-morphism"
|
||||
x-bind:class="darkMode ? 'glass-navbar-dark border-white/10' : 'glass-navbar-light border-gray-200/50'">
|
||||
<div class="container mx-auto flex justify-between items-center">
|
||||
<!-- Logo -->
|
||||
<a href="{{ url_for('index') }}" class="flex items-center group">
|
||||
<span class="text-2xl font-bold gradient-text transform transition-transform group-hover:scale-105">Systades</span>
|
||||
</a>
|
||||
|
||||
<!-- Hauptnavigation - Desktop -->
|
||||
<div class="hidden md:flex items-center space-x-5">
|
||||
<a href="{{ url_for('index') }}"
|
||||
class="nav-link flex items-center"
|
||||
x-bind:class="darkMode
|
||||
? '{{ 'nav-link-active' if request.endpoint == 'index' else '' }}'
|
||||
: '{{ 'nav-link-light-active' if request.endpoint == 'index' else 'nav-link-light' }}'">
|
||||
<i class="fa-solid fa-home mr-2"></i>Start
|
||||
</a>
|
||||
<a href="{{ url_for('mindmap') }}"
|
||||
class="nav-link flex items-center"
|
||||
x-bind:class="darkMode
|
||||
? '{{ 'nav-link-active' if request.endpoint == 'mindmap' else '' }}'
|
||||
: '{{ 'nav-link-light-active' if request.endpoint == 'mindmap' else 'nav-link-light' }}'">
|
||||
<i class="fa-solid fa-diagram-project mr-2"></i>Mindmap
|
||||
</a>
|
||||
<a href="{{ url_for('search_thoughts_page') }}"
|
||||
class="nav-link flex items-center"
|
||||
x-bind:class="darkMode
|
||||
? '{{ 'nav-link-active' if request.endpoint == 'search_thoughts_page' else '' }}'
|
||||
: '{{ 'nav-link-light-active' if request.endpoint == 'search_thoughts_page' else 'nav-link-light' }}'">
|
||||
<i class="fa-solid fa-search mr-2"></i>Suche
|
||||
</a>
|
||||
<!-- KI-Assistent Button -->
|
||||
<button onclick="window.MindMap && window.MindMap.assistant && window.MindMap.assistant.toggleAssistant(true)"
|
||||
class="nav-link flex items-center"
|
||||
x-bind:class="darkMode
|
||||
? 'bg-gradient-to-r from-purple-900/90 to-indigo-800/90 text-white font-medium px-4 py-2 rounded-xl hover:shadow-lg hover:shadow-purple-800/30 transition-all duration-300'
|
||||
: 'bg-gradient-to-r from-purple-600/30 to-indigo-500/30 text-gray-800 font-medium px-4 py-2 rounded-xl hover:shadow-md transition-all duration-300'">
|
||||
<i class="fa-solid fa-robot mr-2"></i>KI-Chat
|
||||
</button>
|
||||
{% if current_user.is_authenticated %}
|
||||
<a href="{{ url_for('profile') }}"
|
||||
class="nav-link flex items-center"
|
||||
x-bind:class="darkMode
|
||||
? '{{ 'nav-link-active' if request.endpoint == 'profile' else '' }}'
|
||||
: '{{ 'nav-link-light-active' if request.endpoint == 'profile' else 'nav-link-light' }}'">
|
||||
<i class="fa-solid fa-user mr-2"></i>Profil
|
||||
</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<!-- Rechte Seite -->
|
||||
<div class="flex items-center space-x-4">
|
||||
<!-- Dark Mode Toggle Switch -->
|
||||
<div class="flex items-center cursor-pointer" @click="toggleDarkMode">
|
||||
<div class="relative w-12 h-6">
|
||||
<input type="checkbox" id="darkModeToggle" class="sr-only" x-model="darkMode">
|
||||
<div class="block w-12 h-6 rounded-full transition-colors duration-300"
|
||||
x-bind:class="darkMode ? 'bg-purple-800/50' : 'bg-gray-400/50'"></div>
|
||||
<div class="dot absolute left-1 top-1 w-4 h-4 rounded-full transition-transform duration-300 shadow-md"
|
||||
x-bind:class="darkMode ? 'bg-purple-600 transform translate-x-6' : 'bg-white'"></div>
|
||||
</div>
|
||||
<div class="ml-3 hidden sm:block"
|
||||
x-bind:class="darkMode ? 'text-white/90' : 'text-gray-700'">
|
||||
<span x-text="darkMode ? 'Dunkel' : 'Hell'"></span>
|
||||
</div>
|
||||
<div class="ml-2 sm:hidden"
|
||||
x-bind:class="darkMode ? 'text-white/90' : 'text-gray-700'">
|
||||
<i class="fa-solid" :class="darkMode ? 'fa-sun' : 'fa-moon'"></i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Profil-Link oder Login -->
|
||||
{% if current_user.is_authenticated %}
|
||||
<div class="relative" x-data="{ open: false }">
|
||||
<button @click="open = !open"
|
||||
class="flex items-center space-x-2 p-2 rounded-full transition-all duration-300 cursor-pointer"
|
||||
x-bind:class="darkMode
|
||||
? 'bg-gray-800/80 text-white/90 hover:bg-gray-700/80'
|
||||
: 'bg-gray-200/80 text-gray-700 hover:bg-gray-300/80'">
|
||||
<div class="w-9 h-9 rounded-full flex items-center justify-center text-white font-medium text-sm overflow-hidden"
|
||||
style="background: linear-gradient(135deg, #8b5cf6, #6366f1);">
|
||||
{% if current_user.avatar %}
|
||||
<img src="{{ current_user.avatar }}" alt="{{ current_user.username }}" class="w-full h-full object-cover">
|
||||
{% else %}
|
||||
{{ current_user.username[0].upper() }}
|
||||
{% endif %}
|
||||
</div>
|
||||
<span class="text-sm hidden lg:block">{{ current_user.username }}</span>
|
||||
<i class="fa-solid fa-chevron-down text-xs hidden lg:block transition-transform duration-200"
|
||||
x-bind:class="open ? 'transform rotate-180' : ''"></i>
|
||||
</button>
|
||||
|
||||
<!-- Dropdown-Menü -->
|
||||
<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-52 rounded-2xl overflow-hidden shadow-lg transform origin-top-right z-50"
|
||||
x-bind:class="darkMode
|
||||
? 'bg-gray-800/95 backdrop-blur-md border border-white/10'
|
||||
: 'bg-white/95 backdrop-blur-md border border-gray-200/50'">
|
||||
<a href="{{ url_for('profile') }}"
|
||||
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-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
|
||||
? 'text-white/90 hover:bg-purple-500/20'
|
||||
: 'text-gray-700 hover:bg-purple-500/10'">
|
||||
<i class="fa-solid fa-gear mr-2 text-purple-400"></i>Einstellungen
|
||||
</a>
|
||||
<div class="my-2 h-px" x-bind:class="darkMode ? 'bg-white/10' : 'bg-gray-200'"></div>
|
||||
<a href="{{ url_for('logout') }}"
|
||||
class="block px-4 py-3 transition-colors duration-200 flex items-center"
|
||||
x-bind:class="darkMode
|
||||
? 'text-white/90 hover:bg-red-500/20'
|
||||
: 'text-gray-700 hover:bg-red-500/10'">
|
||||
<i class="fa-solid fa-right-from-bracket mr-2 text-red-400"></i>Abmelden
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="flex items-center space-x-2">
|
||||
<a href="{{ url_for('login') }}"
|
||||
class="py-2 px-4 rounded-lg transition-all duration-300"
|
||||
x-bind:class="darkMode
|
||||
? 'text-white/90 hover:bg-dark-700/80'
|
||||
: 'text-gray-700 hover:bg-gray-100/80'">
|
||||
<i class="fa-solid fa-sign-in-alt mr-2"></i>Login
|
||||
</a>
|
||||
<a href="{{ url_for('register') }}"
|
||||
class="py-2 px-4 rounded-lg transition-all duration-300 font-medium"
|
||||
x-bind:class="darkMode
|
||||
? 'bg-purple-800/80 text-white hover:bg-purple-700/80'
|
||||
: 'bg-purple-600/20 text-gray-700 hover:bg-purple-600/30'">
|
||||
Registrieren
|
||||
</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<!-- Mobilmenü-Button -->
|
||||
<button @click="mobileMenuOpen = !mobileMenuOpen"
|
||||
class="md:hidden rounded-xl p-2.5 transition-colors duration-200 focus:outline-none"
|
||||
x-bind:class="darkMode
|
||||
? 'text-white/90 hover:bg-gray-700/50'
|
||||
: 'text-gray-700 hover:bg-gray-200/80'">
|
||||
<i class="fa-solid" :class="mobileMenuOpen ? 'fa-times' : 'fa-bars'"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<!-- Mobile Menü -->
|
||||
<div x-show="mobileMenuOpen"
|
||||
x-cloak
|
||||
x-transition:enter="transition ease-out duration-200"
|
||||
x-transition:enter-start="opacity-0 -translate-y-4"
|
||||
x-transition:enter-end="opacity-100 translate-y-0"
|
||||
x-transition:leave="transition ease-in duration-150"
|
||||
x-transition:leave-start="opacity-100 translate-y-0"
|
||||
x-transition:leave-end="opacity-0 -translate-y-4"
|
||||
class="md:hidden w-full z-40 border-b"
|
||||
x-bind:class="darkMode
|
||||
? 'bg-gray-900/90 backdrop-blur-lg border-white/10'
|
||||
: 'bg-white/90 backdrop-blur-lg border-gray-200'">
|
||||
<div class="px-4 py-4 space-y-3">
|
||||
<a href="{{ url_for('index') }}"
|
||||
class="block py-3.5 px-4 rounded-xl transition-all duration-200 flex items-center"
|
||||
x-bind:class="darkMode
|
||||
? '{{ 'bg-purple-500/20 text-white' if request.endpoint == 'index' else 'text-white/80 hover:bg-gray-800/80 hover:text-white' }}'
|
||||
: '{{ 'bg-purple-500/10 text-gray-900' if request.endpoint == 'index' else 'text-gray-700 hover:bg-gray-100 hover:text-gray-900' }}'">
|
||||
<i class="fa-solid fa-home w-5 mr-3"></i>Start
|
||||
</a>
|
||||
<a href="{{ url_for('mindmap') }}"
|
||||
class="block py-3.5 px-4 rounded-xl transition-all duration-200 flex items-center"
|
||||
x-bind:class="darkMode
|
||||
? '{{ 'bg-purple-500/20 text-white' if request.endpoint == 'mindmap' else 'text-white/80 hover:bg-gray-800/80 hover:text-white' }}'
|
||||
: '{{ 'bg-purple-500/10 text-gray-900' if request.endpoint == 'mindmap' else 'text-gray-700 hover:bg-gray-100 hover:text-gray-900' }}'">
|
||||
<i class="fa-solid fa-diagram-project w-5 mr-3"></i>Mindmap
|
||||
</a>
|
||||
<a href="{{ url_for('search_thoughts_page') }}"
|
||||
class="block py-3.5 px-4 rounded-xl transition-all duration-200 flex items-center"
|
||||
x-bind:class="darkMode
|
||||
? '{{ 'bg-purple-500/20 text-white' if request.endpoint == 'search_thoughts_page' else 'text-white/80 hover:bg-gray-800/80 hover:text-white' }}'
|
||||
: '{{ 'bg-purple-500/10 text-gray-900' if request.endpoint == 'search_thoughts_page' else 'text-gray-700 hover:bg-gray-100 hover:text-gray-900' }}'">
|
||||
<i class="fa-solid fa-search w-5 mr-3"></i>Suche
|
||||
</a>
|
||||
<!-- KI-Button für Mobilmenü -->
|
||||
<button onclick="window.MindMap && window.MindMap.assistant && window.MindMap.assistant.toggleAssistant(true); mobileMenuOpen = false;"
|
||||
class="block w-full text-left py-3.5 px-4 rounded-xl transition-all duration-200 flex items-center"
|
||||
x-bind:class="darkMode
|
||||
? 'bg-gradient-to-r from-purple-600/30 to-blue-500/30 text-white hover:from-purple-600/40 hover:to-blue-500/40'
|
||||
: 'bg-gradient-to-r from-purple-500/10 to-blue-400/10 text-gray-900 hover:from-purple-500/20 hover:to-blue-400/20'">
|
||||
<i class="fa-solid fa-robot w-5 mr-3"></i>KI-Chat
|
||||
</button>
|
||||
{% if current_user.is_authenticated %}
|
||||
<a href="{{ url_for('profile') }}"
|
||||
class="block py-3.5 px-4 rounded-xl transition-all duration-200 flex items-center"
|
||||
x-bind:class="darkMode
|
||||
? '{{ 'bg-purple-500/20 text-white' if request.endpoint == 'profile' else 'text-white/80 hover:bg-gray-800/80 hover:text-white' }}'
|
||||
: '{{ 'bg-purple-500/10 text-gray-900' if request.endpoint == 'profile' else 'text-gray-700 hover:bg-gray-100 hover:text-gray-900' }}'">
|
||||
<i class="fa-solid fa-user w-5 mr-3"></i>Profil
|
||||
</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Hauptinhalt -->
|
||||
<main class="flex-grow pt-6">
|
||||
{% block content %}{% endblock %}
|
||||
</main>
|
||||
|
||||
<!-- Footer -->
|
||||
<footer class="mt-12 py-10 transition-colors duration-300 rounded-t-3xl mx-4 sm:mx-6 md:mx-8"
|
||||
:class="darkMode ? 'bg-gray-900/60 backdrop-blur-xl border-t border-white/10' : 'bg-white/60 backdrop-blur-xl border-t border-gray-200/50'">
|
||||
<div class="container mx-auto px-4">
|
||||
<div class="grid grid-cols-1 md:grid-cols-3 gap-10">
|
||||
<!-- Logo und Beschreibung -->
|
||||
<div class="text-center md:text-left flex flex-col">
|
||||
<a href="{{ url_for('index') }}" class="text-2xl font-bold mb-4 gradient-text inline-block transform transition-transform hover:scale-105">Systades</a>
|
||||
<p class="mt-2 text-sm max-w-md"
|
||||
:class="darkMode ? 'text-gray-300' : 'text-gray-600'">
|
||||
Eine interaktive Plattform zum Visualisieren, Erforschen und Teilen von Wissen und Gedanken in einem strukturierten Format.
|
||||
</p>
|
||||
<!-- Social Media Icons -->
|
||||
<div class="flex items-center space-x-4 mt-6 justify-center md:justify-start">
|
||||
<a href="#" class="transition-all duration-200 transform hover:scale-110 hover:-translate-y-1"
|
||||
:class="darkMode ? 'text-purple-400 hover:text-purple-300' : 'text-purple-600 hover:text-purple-500'">
|
||||
<i class="fab fa-twitter text-xl"></i>
|
||||
</a>
|
||||
<a href="#" class="transition-all duration-200 transform hover:scale-110 hover:-translate-y-1"
|
||||
:class="darkMode ? 'text-purple-400 hover:text-purple-300' : 'text-purple-600 hover:text-purple-500'">
|
||||
<i class="fab fa-linkedin text-xl"></i>
|
||||
</a>
|
||||
<a href="#" class="transition-all duration-200 transform hover:scale-110 hover:-translate-y-1"
|
||||
:class="darkMode ? 'text-purple-400 hover:text-purple-300' : 'text-purple-600 hover:text-purple-500'">
|
||||
<i class="fab fa-github text-xl"></i>
|
||||
</a>
|
||||
<a href="#" class="transition-all duration-200 transform hover:scale-110 hover:-translate-y-1"
|
||||
:class="darkMode ? 'text-purple-400 hover:text-purple-300' : 'text-purple-600 hover:text-purple-500'">
|
||||
<i class="fab fa-discord text-xl"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Links -->
|
||||
<div class="grid grid-cols-2 gap-8">
|
||||
<div class="flex flex-col space-y-3">
|
||||
<h3 class="font-semibold text-lg mb-2"
|
||||
:class="darkMode ? 'text-white' : 'text-gray-800'">Navigation</h3>
|
||||
<a href="{{ url_for('index') }}" class="text-sm transition-all duration-200"
|
||||
:class="darkMode ? 'text-gray-300 hover:text-white' : 'text-gray-600 hover:text-gray-900'">
|
||||
Startseite
|
||||
</a>
|
||||
<a href="{{ url_for('mindmap') }}" class="text-sm transition-all duration-200"
|
||||
:class="darkMode ? 'text-gray-300 hover:text-white' : 'text-gray-600 hover:text-gray-900'">
|
||||
Mindmap
|
||||
</a>
|
||||
{% if current_user.is_authenticated %}
|
||||
<a href="{{ url_for('profile') }}" class="text-sm transition-all duration-200"
|
||||
:class="darkMode ? 'text-gray-300 hover:text-white' : 'text-gray-600 hover:text-gray-900'">
|
||||
Profil
|
||||
</a>
|
||||
<a href="{{ url_for('my_account') }}" class="text-sm transition-all duration-200"
|
||||
:class="darkMode ? 'text-gray-300 hover:text-white' : 'text-gray-600 hover:text-gray-900'">
|
||||
Meine Merkliste
|
||||
</a>
|
||||
{% else %}
|
||||
<a href="{{ url_for('login') }}" class="text-sm transition-all duration-200"
|
||||
:class="darkMode ? 'text-gray-300 hover:text-white' : 'text-gray-600 hover:text-gray-900'">
|
||||
Anmelden
|
||||
</a>
|
||||
<a href="{{ url_for('register') }}" class="text-sm transition-all duration-200"
|
||||
:class="darkMode ? 'text-gray-300 hover:text-white' : 'text-gray-600 hover:text-gray-900'">
|
||||
Registrieren
|
||||
</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col space-y-3">
|
||||
<h3 class="font-semibold text-lg mb-2"
|
||||
:class="darkMode ? 'text-white' : 'text-gray-800'">Rechtliches</h3>
|
||||
<a href="{{ url_for('impressum') }}" class="text-sm transition-all duration-200"
|
||||
:class="darkMode ? 'text-gray-300 hover:text-white' : 'text-gray-600 hover:text-gray-900'">
|
||||
Impressum
|
||||
</a>
|
||||
<a href="{{ url_for('ueber_uns') }}" class="text-sm transition-all duration-200"
|
||||
:class="darkMode ? 'text-gray-300 hover:text-white' : 'text-gray-600 hover:text-gray-900'">
|
||||
Über uns
|
||||
</a>
|
||||
<a href="{{ url_for('datenschutz') }}" class="text-sm transition-all duration-200"
|
||||
:class="darkMode ? 'text-gray-300 hover:text-white' : 'text-gray-600 hover:text-gray-900'">
|
||||
Datenschutz
|
||||
</a>
|
||||
<a href="{{ url_for('agb') }}" class="text-sm transition-all duration-200"
|
||||
:class="darkMode ? 'text-gray-300 hover:text-white' : 'text-gray-600 hover:text-gray-900'">
|
||||
AGB
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Newsletter Anmeldung -->
|
||||
<div class="flex flex-col">
|
||||
<h3 class="font-semibold text-lg mb-4"
|
||||
:class="darkMode ? 'text-white' : 'text-gray-800'">Newsletter</h3>
|
||||
<p class="text-sm mb-4"
|
||||
:class="darkMode ? 'text-gray-300' : 'text-gray-600'">
|
||||
Bleibe auf dem Laufenden mit unseren neuesten Funktionen und Updates.
|
||||
</p>
|
||||
<form class="flex flex-col space-y-3">
|
||||
<input type="email" placeholder="Deine E-Mail Adresse"
|
||||
class="px-4 py-2.5 rounded-xl transition-all duration-200 focus:outline-none focus:ring-2 focus:ring-purple-500"
|
||||
:class="darkMode ? 'bg-gray-800/80 text-white border border-gray-700 focus:bg-gray-800' : 'bg-white/80 text-gray-800 border border-gray-300 focus:bg-white'" />
|
||||
<button type="submit"
|
||||
class="px-4 py-2.5 rounded-xl font-medium transition-all duration-300 bg-gradient-to-r from-purple-600 to-indigo-600 text-white shadow-md hover:shadow-lg hover:-translate-y-0.5">
|
||||
Abonnieren
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Untere Linie -->
|
||||
<div class="mt-10 pt-6 border-t flex flex-col md:flex-row justify-between items-center"
|
||||
:class="darkMode ? 'border-gray-800/50 text-gray-400' : 'border-gray-300/50 text-gray-600'">
|
||||
<div class="text-xs md:text-sm mb-3 md:mb-0">
|
||||
© {{ current_year }} Systades. Alle Rechte vorbehalten.
|
||||
</div>
|
||||
<div class="text-xs md:text-sm">
|
||||
Designed with <i class="fas fa-heart text-pink-500"></i> in Deutschland
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
<!-- Hilfsscripts -->
|
||||
{% block scripts %}{% endblock %}
|
||||
|
||||
<!-- KI-Chat Initialisierung -->
|
||||
<script>
|
||||
// Initialisiere den ChatGPT-Assistenten direkt, um sicherzustellen,
|
||||
// dass er auf jeder Seite verfügbar ist, selbst wenn MindMap nicht geladen ist
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
// Prüfen, ob der Assistent bereits durch MindMap initialisiert wurde
|
||||
if (!window.MindMap || !window.MindMap.assistant) {
|
||||
console.log('KI-Assistent wird direkt initialisiert...');
|
||||
const assistant = new ChatGPTAssistant();
|
||||
assistant.init();
|
||||
|
||||
// Speichere in window.MindMap, falls es existiert, oder erstelle es
|
||||
if (!window.MindMap) {
|
||||
window.MindMap = {};
|
||||
}
|
||||
window.MindMap.assistant = assistant;
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<!-- Dark/Light-Mode persistent und robust -->
|
||||
<script>
|
||||
(function() {
|
||||
function applyMode(mode) {
|
||||
if (mode === 'dark') {
|
||||
document.documentElement.classList.add('dark');
|
||||
localStorage.setItem('colorMode', 'dark');
|
||||
} else {
|
||||
document.documentElement.classList.remove('dark');
|
||||
localStorage.setItem('colorMode', 'light');
|
||||
}
|
||||
}
|
||||
// Beim Laden: Präferenz aus localStorage oder System übernehmen
|
||||
const stored = localStorage.getItem('colorMode');
|
||||
if (stored === 'dark' || stored === 'light') {
|
||||
applyMode(stored);
|
||||
} else {
|
||||
// Systempräferenz als Fallback
|
||||
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
|
||||
applyMode(prefersDark ? 'dark' : 'light');
|
||||
}
|
||||
// Umschalter für alle Mode-Toggles
|
||||
window.toggleColorMode = function() {
|
||||
const isDark = document.documentElement.classList.contains('dark');
|
||||
applyMode(isDark ? 'light' : 'dark');
|
||||
};
|
||||
// Optional: globales Event für andere Skripte
|
||||
window.addEventListener('storage', function(e) {
|
||||
if (e.key === 'colorMode') applyMode(e.newValue);
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
64
templates/datenschutz.html
Normal file
64
templates/datenschutz.html
Normal file
@@ -0,0 +1,64 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}Datenschutz{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="max-w-3xl mx-auto">
|
||||
<div class="card p-6 md:p-8">
|
||||
<h1 class="text-3xl font-bold mb-6 gradient-text">Datenschutzerklärung</h1>
|
||||
|
||||
<section class="mb-8">
|
||||
<h2 class="text-xl font-bold mb-4">1. Datenschutz auf einen Blick</h2>
|
||||
|
||||
<h3 class="text-lg font-bold mb-2">Allgemeine Hinweise</h3>
|
||||
<p class="mb-4">Die folgenden Hinweise geben einen einfachen Überblick darüber, was mit Ihren personenbezogenen Daten passiert, wenn Sie diese Website besuchen. Personenbezogene Daten sind alle Daten, mit denen Sie persönlich identifiziert werden können. Ausführliche Informationen zum Thema Datenschutz entnehmen Sie unserer unter diesem Text aufgeführten Datenschutzerklärung.</p>
|
||||
|
||||
<h3 class="text-lg font-bold mb-2">Datenerfassung auf dieser Website</h3>
|
||||
<p class="mb-4"><strong>Wer ist verantwortlich für die Datenerfassung auf dieser Website?</strong></p>
|
||||
<p class="mb-4">Die Datenverarbeitung auf dieser Website erfolgt durch den Websitebetreiber. Dessen Kontaktdaten können Sie dem Impressum dieser Website entnehmen.</p>
|
||||
|
||||
<p class="mb-4"><strong>Wie erfassen wir Ihre Daten?</strong></p>
|
||||
<p class="mb-4">Ihre Daten werden zum einen dadurch erhoben, dass Sie uns diese mitteilen. Hierbei kann es sich z. B. um Daten handeln, die Sie in ein Kontaktformular eingeben.</p>
|
||||
<p class="mb-4">Andere Daten werden automatisch oder nach Ihrer Einwilligung beim Besuch der Website durch unsere IT-Systeme erfasst. Das sind vor allem technische Daten (z. B. Internetbrowser, Betriebssystem oder Uhrzeit des Seitenaufrufs). Die Erfassung dieser Daten erfolgt automatisch, sobald Sie diese Website betreten.</p>
|
||||
|
||||
<p class="mb-4"><strong>Wofür nutzen wir Ihre Daten?</strong></p>
|
||||
<p class="mb-4">Ein Teil der Daten wird erhoben, um eine fehlerfreie Bereitstellung der Website zu gewährleisten. Andere Daten können zur Analyse Ihres Nutzerverhaltens verwendet werden.</p>
|
||||
|
||||
<p class="mb-4"><strong>Welche Rechte haben Sie bezüglich Ihrer Daten?</strong></p>
|
||||
<p class="mb-4">Sie haben jederzeit das Recht, unentgeltlich Auskunft über Herkunft, Empfänger und Zweck Ihrer gespeicherten personenbezogenen Daten zu erhalten. Sie haben außerdem ein Recht, die Berichtigung oder Löschung dieser Daten zu verlangen. Wenn Sie eine Einwilligung zur Datenverarbeitung erteilt haben, können Sie diese Einwilligung jederzeit für die Zukunft widerrufen. Außerdem haben Sie das Recht, unter bestimmten Umständen die Einschränkung der Verarbeitung Ihrer personenbezogenen Daten zu verlangen.</p>
|
||||
</section>
|
||||
|
||||
<section class="mb-8">
|
||||
<h2 class="text-xl font-bold mb-4">2. Allgemeine Hinweise und Pflichtinformationen</h2>
|
||||
|
||||
<h3 class="text-lg font-bold mb-2">Datenschutz</h3>
|
||||
<p class="mb-4">Die Betreiber dieser Seiten nehmen den Schutz Ihrer persönlichen Daten sehr ernst. Wir behandeln Ihre personenbezogenen Daten vertraulich und entsprechend der gesetzlichen Datenschutzvorschriften sowie dieser Datenschutzerklärung.</p>
|
||||
<p class="mb-4">Wenn Sie diese Website benutzen, werden verschiedene personenbezogene Daten erhoben. Personenbezogene Daten sind Daten, mit denen Sie persönlich identifiziert werden können. Die vorliegende Datenschutzerklärung erläutert, welche Daten wir erheben und wofür wir sie nutzen. Sie erläutert auch, wie und zu welchem Zweck das geschieht.</p>
|
||||
<p class="mb-4">Wir weisen darauf hin, dass die Datenübertragung im Internet (z. B. bei der Kommunikation per E-Mail) Sicherheitslücken aufweisen kann. Ein lückenloser Schutz der Daten vor dem Zugriff durch Dritte ist nicht möglich.</p>
|
||||
|
||||
<h3 class="text-lg font-bold mb-2">Hinweis zur verantwortlichen Stelle</h3>
|
||||
<p class="mb-4">Die verantwortliche Stelle für die Datenverarbeitung auf dieser Website ist:</p>
|
||||
<p class="mb-4">
|
||||
MindMap GmbH<br>
|
||||
Musterstraße 123<br>
|
||||
12345 Musterstadt<br>
|
||||
Deutschland
|
||||
</p>
|
||||
<p class="mb-4">
|
||||
Telefon: +49 (0) 123 456789<br>
|
||||
E-Mail: info@mindmap-example.com
|
||||
</p>
|
||||
<p class="mb-4">Verantwortliche Stelle ist die natürliche oder juristische Person, die allein oder gemeinsam mit anderen über die Zwecke und Mittel der Verarbeitung von personenbezogenen Daten (z. B. Namen, E-Mail-Adressen o. Ä.) entscheidet.</p>
|
||||
</section>
|
||||
|
||||
<section class="mb-8">
|
||||
<h2 class="text-xl font-bold mb-4">3. Datenerfassung auf dieser Website</h2>
|
||||
|
||||
<h3 class="text-lg font-bold mb-2">Cookies</h3>
|
||||
<p class="mb-4">Unsere Internetseiten verwenden so genannte "Cookies". Cookies sind kleine Datenpakete und richten auf Ihrem Endgerät keinen Schaden an. Sie werden entweder vorübergehend für die Dauer einer Sitzung (Session-Cookies) oder dauerhaft (permanente Cookies) auf Ihrem Endgerät gespeichert. Session-Cookies werden nach Ende Ihres Besuchs automatisch gelöscht. Permanente Cookies bleiben auf Ihrem Endgerät gespeichert, bis Sie diese selbst löschen oder eine automatische Löschung durch Ihren Webbrowser erfolgt.</p>
|
||||
<p class="mb-4">Cookies können von uns (First-Party-Cookies) oder von Drittunternehmen stammen (sog. Third-Party-Cookies). Third-Party-Cookies ermöglichen die Einbindung bestimmter Dienstleistungen von Drittunternehmen innerhalb von Webseiten (z. B. Cookies zur Abwicklung von Zahlungsdienstleistungen).</p>
|
||||
<p class="mb-4">Die meisten Browser bieten Ihnen die Möglichkeit, das Setzen von Cookies für bestimmte Webseiten zu verbieten oder Cookies jedes Mal vor dem Akzeptieren anzuzeigen. Ebenso können Sie jederzeit mitgeteilt bekommen, sobald Ihr Browser ein neues Cookie empfängt.</p>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
33
templates/errors/403.html
Normal file
33
templates/errors/403.html
Normal file
@@ -0,0 +1,33 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}403 - Zugriff verweigert{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="min-h-[75vh] flex flex-col items-center justify-center px-4 py-12 bg-gradient-to-b from-gray-50 to-gray-100 dark:from-gray-900 dark:to-gray-800">
|
||||
<div class="glass-effect max-w-2xl w-full p-6 md:p-10 rounded-xl border border-gray-300/20 dark:border-gray-700/30 shadow-xl transform transition-all duration-300 hover:shadow-2xl">
|
||||
<div class="text-center">
|
||||
<div class="flex justify-center mb-6">
|
||||
<div class="relative">
|
||||
<h1 class="text-7xl md:text-8xl font-extrabold text-primary-600 dark:text-primary-400 opacity-90">403</h1>
|
||||
<div class="absolute -top-4 -right-4 w-12 h-12 bg-red-500 rounded-full flex items-center justify-center animate-pulse">
|
||||
<i class="fa-solid fa-lock text-white text-xl"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<h2 class="text-2xl md:text-3xl font-semibold mb-4 text-gray-800 dark:text-gray-200">Zugriff verweigert</h2>
|
||||
<p class="text-gray-600 dark:text-gray-300 mb-8 max-w-lg mx-auto text-base md:text-lg">Sie haben nicht die erforderlichen Berechtigungen, um auf diese Seite zuzugreifen. Bitte melden Sie sich an oder nutzen Sie ein Konto mit entsprechenden Rechten.</p>
|
||||
<div class="flex flex-col sm:flex-row gap-4 justify-center">
|
||||
<a href="{{ url_for('index') }}" class="btn-primary transform transition-transform duration-300 hover:scale-105 px-6 py-3 rounded-lg">
|
||||
<i class="fa-solid fa-home mr-2"></i>Zur Startseite
|
||||
</a>
|
||||
<a href="javascript:history.back()" class="btn-secondary transform transition-transform duration-300 hover:scale-105 px-6 py-3 rounded-lg">
|
||||
<i class="fa-solid fa-arrow-left mr-2"></i>Zurück
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-8 text-sm text-gray-500 dark:text-gray-400">
|
||||
<p>Benötigen Sie Hilfe? <a href="#" class="text-primary-600 dark:text-primary-400 hover:underline">Kontaktieren Sie uns</a></p>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
33
templates/errors/404.html
Normal file
33
templates/errors/404.html
Normal file
@@ -0,0 +1,33 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}404 - Seite nicht gefunden{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="min-h-[75vh] flex flex-col items-center justify-center px-4 py-12 bg-gradient-to-b from-gray-50 to-gray-100 dark:from-gray-900 dark:to-gray-800">
|
||||
<div class="glass-effect max-w-2xl w-full p-6 md:p-10 rounded-xl border border-gray-300/20 dark:border-gray-700/30 shadow-xl transform transition-all duration-300 hover:shadow-2xl">
|
||||
<div class="text-center">
|
||||
<div class="flex justify-center mb-6">
|
||||
<div class="relative">
|
||||
<h1 class="text-7xl md:text-8xl font-extrabold text-primary-600 dark:text-primary-400 opacity-90">404</h1>
|
||||
<div class="absolute -top-4 -right-4 w-12 h-12 bg-yellow-500 rounded-full flex items-center justify-center animate-pulse">
|
||||
<i class="fa-solid fa-question text-white text-xl"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<h2 class="text-2xl md:text-3xl font-semibold mb-4 text-gray-800 dark:text-gray-200">Seite nicht gefunden</h2>
|
||||
<p class="text-gray-600 dark:text-gray-300 mb-8 max-w-lg mx-auto text-base md:text-lg">Die gesuchte Seite existiert nicht oder wurde verschoben. Bitte prüfen Sie die URL oder nutzen Sie die Navigation.</p>
|
||||
<div class="flex flex-col sm:flex-row gap-4 justify-center">
|
||||
<a href="{{ url_for('index') }}" class="btn-primary transform transition-transform duration-300 hover:scale-105 px-6 py-3 rounded-lg">
|
||||
<i class="fa-solid fa-home mr-2"></i>Zur Startseite
|
||||
</a>
|
||||
<a href="javascript:history.back()" class="btn-secondary transform transition-transform duration-300 hover:scale-105 px-6 py-3 rounded-lg">
|
||||
<i class="fa-solid fa-arrow-left mr-2"></i>Zurück
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-8 text-sm text-gray-500 dark:text-gray-400">
|
||||
<p>Benötigen Sie Hilfe? <a href="#" class="text-primary-600 dark:text-primary-400 hover:underline">Kontaktieren Sie uns</a></p>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
33
templates/errors/429.html
Normal file
33
templates/errors/429.html
Normal file
@@ -0,0 +1,33 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}429 - Zu viele Anfragen{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="min-h-[75vh] flex flex-col items-center justify-center px-4 py-12 bg-gradient-to-b from-gray-50 to-gray-100 dark:from-gray-900 dark:to-gray-800">
|
||||
<div class="glass-effect max-w-2xl w-full p-6 md:p-10 rounded-xl border border-gray-300/20 dark:border-gray-700/30 shadow-xl transform transition-all duration-300 hover:shadow-2xl">
|
||||
<div class="text-center">
|
||||
<div class="flex justify-center mb-6">
|
||||
<div class="relative">
|
||||
<h1 class="text-7xl md:text-8xl font-extrabold text-primary-600 dark:text-primary-400 opacity-90">429</h1>
|
||||
<div class="absolute -top-4 -right-4 w-12 h-12 bg-orange-500 rounded-full flex items-center justify-center animate-pulse">
|
||||
<i class="fa-solid fa-hourglass-half text-white text-xl"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<h2 class="text-2xl md:text-3xl font-semibold mb-4 text-gray-800 dark:text-gray-200">Zu viele Anfragen</h2>
|
||||
<p class="text-gray-600 dark:text-gray-300 mb-8 max-w-lg mx-auto text-base md:text-lg">Sie haben zu viele Anfragen in kurzer Zeit gestellt. Bitte warten Sie einen Moment und versuchen Sie es dann erneut.</p>
|
||||
<div class="flex flex-col sm:flex-row gap-4 justify-center">
|
||||
<a href="{{ url_for('index') }}" class="btn-primary transform transition-transform duration-300 hover:scale-105 px-6 py-3 rounded-lg">
|
||||
<i class="fa-solid fa-home mr-2"></i>Zur Startseite
|
||||
</a>
|
||||
<a href="javascript:history.back()" class="btn-secondary transform transition-transform duration-300 hover:scale-105 px-6 py-3 rounded-lg">
|
||||
<i class="fa-solid fa-arrow-left mr-2"></i>Zurück
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-8 text-sm text-gray-500 dark:text-gray-400">
|
||||
<p>Benötigen Sie Hilfe? <a href="#" class="text-primary-600 dark:text-primary-400 hover:underline">Kontaktieren Sie uns</a></p>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
33
templates/errors/500.html
Normal file
33
templates/errors/500.html
Normal file
@@ -0,0 +1,33 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}500 - Serverfehler{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="min-h-[75vh] flex flex-col items-center justify-center px-4 py-12 bg-gradient-to-b from-gray-50 to-gray-100 dark:from-gray-900 dark:to-gray-800">
|
||||
<div class="glass-effect max-w-2xl w-full p-6 md:p-10 rounded-xl border border-gray-300/20 dark:border-gray-700/30 shadow-xl transform transition-all duration-300 hover:shadow-2xl">
|
||||
<div class="text-center">
|
||||
<div class="flex justify-center mb-6">
|
||||
<div class="relative">
|
||||
<h1 class="text-7xl md:text-8xl font-extrabold text-primary-600 dark:text-primary-400 opacity-90">500</h1>
|
||||
<div class="absolute -top-4 -right-4 w-12 h-12 bg-red-600 rounded-full flex items-center justify-center animate-pulse">
|
||||
<i class="fa-solid fa-exclamation-triangle text-white text-xl"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<h2 class="text-2xl md:text-3xl font-semibold mb-4 text-gray-800 dark:text-gray-200">Interner Serverfehler</h2>
|
||||
<p class="text-gray-600 dark:text-gray-300 mb-8 max-w-lg mx-auto text-base md:text-lg">Es ist ein Fehler auf unserem Server aufgetreten. Unser Team wurde informiert und arbeitet bereits an einer Lösung. Bitte versuchen Sie es später erneut.</p>
|
||||
<div class="flex flex-col sm:flex-row gap-4 justify-center">
|
||||
<a href="{{ url_for('index') }}" class="btn-primary transform transition-transform duration-300 hover:scale-105 px-6 py-3 rounded-lg">
|
||||
<i class="fa-solid fa-home mr-2"></i>Zur Startseite
|
||||
</a>
|
||||
<a href="javascript:history.back()" class="btn-secondary transform transition-transform duration-300 hover:scale-105 px-6 py-3 rounded-lg">
|
||||
<i class="fa-solid fa-arrow-left mr-2"></i>Zurück
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-8 text-sm text-gray-500 dark:text-gray-400">
|
||||
<p>Benötigen Sie Hilfe? <a href="#" class="text-primary-600 dark:text-primary-400 hover:underline">Kontaktieren Sie uns</a></p>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
64
templates/impressum.html
Normal file
64
templates/impressum.html
Normal file
@@ -0,0 +1,64 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}Impressum{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="max-w-3xl mx-auto">
|
||||
<div class="card p-6 md:p-8">
|
||||
<h1 class="text-3xl font-bold mb-6 gradient-text">Impressum</h1>
|
||||
|
||||
<section class="mb-8">
|
||||
<h2 class="text-xl font-bold mb-4">Angaben gemäß § 5 TMG und § 55 RStV</h2>
|
||||
<p class="mb-4">
|
||||
Diese Website wird privat betrieben von:<br>
|
||||
Marwin Medczinski<br>
|
||||
Fasanenstraße 30<br>
|
||||
16761 Hennigsdorf<br>
|
||||
Deutschland
|
||||
</p>
|
||||
|
||||
|
||||
</p>
|
||||
|
||||
<p class="mb-4">
|
||||
<strong>Kontakt:</strong><br>
|
||||
Telefon: +49 (0) 173 8041824<br>
|
||||
E-Mail: medczinski.marwin@gmx.de
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section class="mb-8">
|
||||
<h2 class="text-xl font-bold mb-4">Inhaltlich Verantwortlicher gemäß § 55 Abs. 2 RStV</h2>
|
||||
<p class="mb-4">
|
||||
Marwin Medczinski<br>
|
||||
Fasanenstraße 30<br>
|
||||
16761 Hennigsdorf
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section class="mb-8">
|
||||
<h2 class="text-xl font-bold mb-4">Hinweis zur Streitbeilegung</h2>
|
||||
<p class="mb-4">Die Europäische Kommission stellt eine Plattform zur Online-Streitbeilegung (OS) bereit: <a href="https://ec.europa.eu/consumers/odr/" target="_blank" class="text-purple-600 hover:text-purple-800">https://ec.europa.eu/consumers/odr/</a></p>
|
||||
<p class="mb-4">Ich bin nicht bereit oder verpflichtet, an Streitbeilegungsverfahren vor einer Verbraucherschlichtungsstelle teilzunehmen.</p>
|
||||
</section>
|
||||
|
||||
<section class="mb-8">
|
||||
<h2 class="text-xl font-bold mb-4">Haftungsausschluss</h2>
|
||||
|
||||
<h3 class="text-lg font-bold mb-2">Haftung für Inhalte</h3>
|
||||
<p class="mb-4">Die Inhalte dieser Seiten wurden mit größter Sorgfalt erstellt. Für die Richtigkeit, Vollständigkeit und Aktualität der Inhalte kann ich jedoch keine Gewähr übernehmen. Als Diensteanbieter bin ich gemäß § 7 Abs.1 TMG für eigene Inhalte auf diesen Seiten nach den allgemeinen Gesetzen verantwortlich. Nach §§ 8 bis 10 TMG bin ich als Diensteanbieter jedoch nicht verpflichtet, übermittelte oder gespeicherte fremde Informationen zu überwachen oder nach Umständen zu forschen, die auf eine rechtswidrige Tätigkeit hinweisen.</p>
|
||||
<p class="mb-4">Verpflichtungen zur Entfernung oder Sperrung der Nutzung von Informationen nach den allgemeinen Gesetzen bleiben hiervon unberührt. Eine diesbezügliche Haftung ist jedoch erst ab dem Zeitpunkt der Kenntnis einer konkreten Rechtsverletzung möglich. Bei Bekanntwerden von entsprechenden Rechtsverletzungen werde ich diese Inhalte umgehend entfernen.</p>
|
||||
|
||||
<h3 class="text-lg font-bold mb-2">Haftung für Links</h3>
|
||||
<p class="mb-4">Diese Website enthält Links zu externen Webseiten Dritter, auf deren Inhalte ich keinen Einfluss habe. Deshalb kann ich für diese fremden Inhalte auch keine Gewähr übernehmen. Für die Inhalte der verlinkten Seiten ist stets der jeweilige Anbieter oder Betreiber der Seiten verantwortlich. Die verlinkten Seiten wurden zum Zeitpunkt der Verlinkung auf mögliche Rechtsverstöße überprüft. Rechtswidrige Inhalte waren zum Zeitpunkt der Verlinkung nicht erkennbar.</p>
|
||||
<p class="mb-4">Eine permanente inhaltliche Kontrolle der verlinkten Seiten ist jedoch ohne konkrete Anhaltspunkte einer Rechtsverletzung nicht zumutbar. Bei Bekanntwerden von Rechtsverletzungen werde ich derartige Links umgehend entfernen.</p>
|
||||
</section>
|
||||
|
||||
<section class="mb-8">
|
||||
<h2 class="text-xl font-bold mb-4">Urheberrecht</h2>
|
||||
<p class="mb-4">Die durch mich erstellten Inhalte und Werke auf diesen Seiten unterliegen dem deutschen Urheberrecht. Die Vervielfältigung, Bearbeitung, Verbreitung und jede Art der Verwertung außerhalb der Grenzen des Urheberrechtes bedürfen meiner schriftlichen Zustimmung. Downloads und Kopien dieser Seite sind nur für den privaten, nicht kommerziellen Gebrauch gestattet.</p>
|
||||
<p>Soweit die Inhalte auf dieser Seite nicht von mir erstellt wurden, werden die Urheberrechte Dritter beachtet. Insbesondere werden Inhalte Dritter als solche gekennzeichnet. Sollten Sie trotzdem auf eine Urheberrechtsverletzung aufmerksam werden, bitte ich um einen entsprechenden Hinweis. Bei Bekanntwerden von Rechtsverletzungen werde ich derartige Inhalte umgehend entfernen.</p>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
520
templates/index.html
Normal file
520
templates/index.html
Normal file
@@ -0,0 +1,520 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}Wissensnetzwerk{% endblock %}
|
||||
|
||||
{% block extra_css %}
|
||||
<style>
|
||||
/* Full height and width for the page */
|
||||
html, body {
|
||||
min-height: 100vh;
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
/* Remove gradient backgrounds */
|
||||
.hero-gradient, .bg-fade {
|
||||
background: none !important;
|
||||
clip-path: none !important;
|
||||
}
|
||||
|
||||
/* Style elements */
|
||||
.mystical-line {
|
||||
height: 1px;
|
||||
background: linear-gradient(to right, transparent, rgba(109, 40, 217, 0.2), transparent);
|
||||
}
|
||||
|
||||
.dark .mystical-line {
|
||||
background: linear-gradient(to right, transparent, rgba(139, 92, 246, 0.2), transparent);
|
||||
}
|
||||
|
||||
/* Text reveal animation */
|
||||
@keyframes textReveal {
|
||||
0% { clip-path: polygon(0 0, 0 0, 0 100%, 0 100%); }
|
||||
100% { clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%); }
|
||||
}
|
||||
|
||||
.text-reveal {
|
||||
animation: textReveal 1s cubic-bezier(0.77, 0, 0.18, 1) forwards;
|
||||
}
|
||||
|
||||
.delay-1 { animation-delay: 0.2s; }
|
||||
.delay-2 { animation-delay: 0.4s; }
|
||||
.delay-3 { animation-delay: 0.6s; }
|
||||
|
||||
/* Home page specific styles */
|
||||
.featured-card {
|
||||
transition: transform 0.5s ease, box-shadow 0.5s ease;
|
||||
border: 1px solid;
|
||||
border-color: rgba(139, 92, 246, 0.1);
|
||||
}
|
||||
|
||||
.dark .featured-card {
|
||||
border-color: rgba(109, 40, 217, 0.2);
|
||||
background-color: rgba(17, 24, 39, 0.7);
|
||||
}
|
||||
|
||||
.featured-card:hover {
|
||||
transform: translateY(-5px);
|
||||
}
|
||||
|
||||
.dark .featured-card:hover {
|
||||
box-shadow: 0 5px 15px rgba(109, 40, 217, 0.2);
|
||||
border-color: rgba(109, 40, 217, 0.3);
|
||||
}
|
||||
|
||||
.featured-card:hover {
|
||||
box-shadow: 0 5px 15px rgba(139, 92, 246, 0.1);
|
||||
border-color: rgba(139, 92, 246, 0.2);
|
||||
}
|
||||
|
||||
/* Chat section styles */
|
||||
.embedded-chat {
|
||||
height: 350px;
|
||||
border-radius: 1rem;
|
||||
overflow: hidden;
|
||||
transition: all 0.3s ease;
|
||||
border: 1px solid;
|
||||
}
|
||||
|
||||
.dark .embedded-chat {
|
||||
background-color: rgba(17, 24, 39, 0.7);
|
||||
border-color: rgba(109, 40, 217, 0.2);
|
||||
}
|
||||
|
||||
.embedded-chat {
|
||||
background-color: rgba(255, 255, 255, 0.7);
|
||||
border-color: rgba(139, 92, 246, 0.1);
|
||||
}
|
||||
|
||||
#embedded-chat-messages {
|
||||
height: 250px;
|
||||
overflow-y: auto;
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
/* Chat typing indicator */
|
||||
.typing-dots span {
|
||||
display: inline-block;
|
||||
width: 5px;
|
||||
height: 5px;
|
||||
border-radius: 50%;
|
||||
margin-right: 3px;
|
||||
background-color: currentColor;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.typing-dots span:nth-child(1) {
|
||||
animation: dot-pulse 1.2s infinite ease-in-out;
|
||||
}
|
||||
|
||||
.typing-dots span:nth-child(2) {
|
||||
animation: dot-pulse 1.2s infinite ease-in-out 0.2s;
|
||||
}
|
||||
|
||||
.typing-dots span:nth-child(3) {
|
||||
animation: dot-pulse 1.2s infinite ease-in-out 0.4s;
|
||||
}
|
||||
|
||||
@keyframes dot-pulse {
|
||||
0%, 100% { transform: scale(1); opacity: 0.5; }
|
||||
50% { transform: scale(1.3); opacity: 1; }
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<!-- Hero Section -->
|
||||
<section class="relative pt-20 pb-24">
|
||||
<!-- Hero Content -->
|
||||
<div class="max-w-screen-xl mx-auto px-4 sm:px-6 lg:px-8 relative z-10">
|
||||
<div class="text-center mb-16">
|
||||
<h1 class="hero-heading mb-8 text-gray-900 dark:text-white">
|
||||
<div class="overflow-hidden">
|
||||
<span class="gradient-text inline-block text-reveal">Wissen</span>
|
||||
</div>
|
||||
<div class="overflow-hidden mt-2">
|
||||
<span class="inline-block text-reveal delay-1">neu</span>
|
||||
</div>
|
||||
<div class="mt-2 relative overflow-hidden">
|
||||
<span class="relative inline-block text-reveal delay-2">vernetzen
|
||||
<div class="absolute -bottom-2 left-0 right-0 h-1 bg-gradient-to-r from-purple-500/0 via-purple-500/70 to-purple-500/0 rounded-full"></div>
|
||||
</span>
|
||||
</div>
|
||||
</h1>
|
||||
<div class="overflow-hidden">
|
||||
<p class="text-xl md:text-2xl text-gray-700 dark:text-gray-300 max-w-3xl mx-auto mb-12 text-reveal delay-3">
|
||||
Erkunde komplexe Ideen visuell, schaffe Verbindungen und teile deine Gedanken
|
||||
in einem interaktiven Wissensnetzwerk.
|
||||
</p>
|
||||
</div>
|
||||
<div class="flex flex-col sm:flex-row gap-5 justify-center">
|
||||
<a href="{{ url_for('mindmap') }}" class="mystical-button mystical-button-primary group transition-all duration-300">
|
||||
<span class="flex items-center justify-center">
|
||||
<i class="fa-solid fa-diagram-project mr-3 text-purple-200 group-hover:text-white transition-all duration-300"></i>
|
||||
<span class="relative">
|
||||
Mindmap erkunden
|
||||
<span class="absolute -bottom-1 left-0 w-0 h-0.5 bg-white group-hover:w-full transition-all duration-300"></span>
|
||||
</span>
|
||||
</span>
|
||||
</a>
|
||||
{% if not current_user.is_authenticated %}
|
||||
<a href="{{ url_for('register') }}" class="mystical-button mystical-button-secondary group transition-all duration-300">
|
||||
<span class="flex items-center justify-center">
|
||||
<i class="fa-solid fa-user-plus mr-3 group-hover:text-accent-secondary-dark dark:group-hover:text-accent-secondary-light transition-all duration-300"></i>
|
||||
<span class="relative">
|
||||
Konto erstellen
|
||||
<span class="absolute -bottom-1 left-0 w-0 h-0.5 bg-accent-primary-light dark:bg-accent-primary-dark group-hover:w-full transition-all duration-300"></span>
|
||||
</span>
|
||||
</span>
|
||||
</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Central logo and name -->
|
||||
<div class="relative w-full max-w-4xl mx-auto h-40 sm:h-60 mb-16">
|
||||
<div class="absolute inset-0 flex items-center justify-center">
|
||||
<div class="text-center">
|
||||
<div class="text-3xl font-bold gradient-text mb-2 animate-float">Systades</div>
|
||||
<div class="text-lg text-gray-700 dark:text-gray-300">WISSEN VERNETZEN</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Features Section -->
|
||||
<section class="py-20 relative">
|
||||
<div class="mystical-line absolute top-0 left-1/2 transform -translate-x-1/2 w-1/3"></div>
|
||||
|
||||
<div class="max-w-screen-xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div class="text-center mb-16">
|
||||
<h2 class="section-heading mb-4 text-gray-900 dark:text-white">Was ist <span class="gradient-text">Systades?</span></h2>
|
||||
<p class="text-lg text-gray-700 dark:text-gray-300 max-w-3xl mx-auto">
|
||||
Ein modernes Werkzeug zum Visualisieren, Erforschen und Teilen von Wissen in einem interaktiven
|
||||
Netzwerk, das dir hilft, Verbindungen zu entdecken und dein Wissen zu organisieren.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Feature Cards -->
|
||||
<div class="grid grid-cols-1 md:grid-cols-3 gap-8 mb-12">
|
||||
<!-- Feature 1: Visualize -->
|
||||
<div class="featured-card rounded-2xl p-6 bg-white/80 dark:bg-gray-800/30 backdrop-blur-sm">
|
||||
<div class="mb-4 text-purple-600 dark:text-purple-400">
|
||||
<i class="fa-solid fa-diagram-project text-3xl"></i>
|
||||
</div>
|
||||
<h3 class="text-xl font-semibold mb-2 text-gray-900 dark:text-white">Visualisiere Wissen</h3>
|
||||
<p class="text-gray-700 dark:text-gray-300">
|
||||
Organisiere Gedanken und Ideen in einem interaktiven Netzwerk, das komplexe Beziehungen
|
||||
visuell darstellt und neue Verbindungen offenbart.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Feature 2: Connect -->
|
||||
<div class="featured-card rounded-2xl p-6 bg-white/80 dark:bg-gray-800/30 backdrop-blur-sm">
|
||||
<div class="mb-4 text-indigo-600 dark:text-indigo-400">
|
||||
<i class="fa-solid fa-network-wired text-3xl"></i>
|
||||
</div>
|
||||
<h3 class="text-xl font-semibold mb-2 text-gray-900 dark:text-white">Verknüpfe Gedanken</h3>
|
||||
<p class="text-gray-700 dark:text-gray-300">
|
||||
Entdecke Zusammenhänge zwischen scheinbar unzusammenhängenden Ideen und schaffe dein
|
||||
persönliches Wissensnetzwerk über verschiedene Bereiche hinweg.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Feature 3: Share -->
|
||||
<div class="featured-card rounded-2xl p-6 bg-white/80 dark:bg-gray-800/30 backdrop-blur-sm">
|
||||
<div class="mb-4 text-purple-600 dark:text-purple-400">
|
||||
<i class="fa-solid fa-share-nodes text-3xl"></i>
|
||||
</div>
|
||||
<h3 class="text-xl font-semibold mb-2 text-gray-900 dark:text-white">Teile und Entdecke</h3>
|
||||
<p class="text-gray-700 dark:text-gray-300">
|
||||
Tausche Erkenntnisse mit anderen aus und erweitere dein Wissen durch die
|
||||
Perspektiven und Gedanken der Community.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- AI Assistant Preview -->
|
||||
<section class="py-20 relative">
|
||||
<div class="mystical-line absolute top-0 left-1/2 transform -translate-x-1/2 w-1/3"></div>
|
||||
|
||||
<div class="max-w-screen-xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div class="text-center mb-12">
|
||||
<h2 class="section-heading mb-4 text-gray-900 dark:text-white">Dein <span class="gradient-text">KI-Assistent</span></h2>
|
||||
<p class="text-lg text-gray-700 dark:text-gray-300 max-w-3xl mx-auto">
|
||||
Unser integrierter KI-Assistent hilft dir, Wissen zu organisieren, Verbindungen zu finden und
|
||||
Einsichten zu gewinnen.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Chat Interface Preview -->
|
||||
<div class="max-w-3xl mx-auto">
|
||||
<div class="embedded-chat" id="demo-chat">
|
||||
<!-- Chat Header -->
|
||||
<div class="p-4 border-b border-gray-200 dark:border-gray-700 flex items-center justify-between">
|
||||
<div class="flex items-center">
|
||||
<div class="w-8 h-8 rounded-full bg-gradient-to-r from-purple-600 to-indigo-600 flex items-center justify-center text-white mr-3">
|
||||
<i class="fa-solid fa-robot text-sm"></i>
|
||||
</div>
|
||||
<span class="font-medium text-gray-800 dark:text-gray-200">Systades Assistent (4o-mini)</span>
|
||||
</div>
|
||||
<div>
|
||||
<button id="open-real-assistant" class="text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200">
|
||||
<i class="fa-solid fa-expand"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Chat Messages -->
|
||||
<div id="embedded-chat-messages" class="border-b border-gray-200 dark:border-gray-700">
|
||||
<!-- Assistant Message -->
|
||||
<div class="mb-4 flex">
|
||||
<div class="w-8 h-8 rounded-full bg-gradient-to-r from-purple-600 to-indigo-600 flex items-center justify-center text-white mr-2 flex-shrink-0">
|
||||
<i class="fa-solid fa-robot text-sm"></i>
|
||||
</div>
|
||||
<div class="bg-gray-100 dark:bg-gray-800 rounded-lg p-3 max-w-[80%]">
|
||||
<div class="text-gray-700 dark:text-gray-300 markdown-content">
|
||||
<p>Hallo! Ich bin dein Systades-Assistent. Wie kann ich dir heute helfen?</p>
|
||||
<p>Du kannst mir Fragen zu:</p>
|
||||
<ul>
|
||||
<li><strong>Gedanken</strong> in der Datenbank</li>
|
||||
<li><strong>Kategorien</strong> und Wissensgebieten</li>
|
||||
<li><strong>Mindmaps</strong> und Visualisierungsmöglichkeiten</li>
|
||||
</ul>
|
||||
<p>stellen.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- User Message -->
|
||||
<div class="mb-4 flex justify-end">
|
||||
<div class="bg-purple-100 dark:bg-purple-900/30 rounded-lg p-3 max-w-[80%]">
|
||||
<p class="text-gray-800 dark:text-gray-200">
|
||||
Kann ich mit deiner Hilfe eine Mindmap zum Thema Künstliche Intelligenz erstellen?
|
||||
</p>
|
||||
</div>
|
||||
<div class="w-8 h-8 rounded-full bg-gray-300 dark:bg-gray-600 flex items-center justify-center text-gray-700 dark:text-gray-300 ml-2 flex-shrink-0">
|
||||
<i class="fa-solid fa-user text-sm"></i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Assistant Response -->
|
||||
<div class="mb-4 flex" id="demo-ai-response">
|
||||
<div class="w-8 h-8 rounded-full bg-gradient-to-r from-purple-600 to-indigo-600 flex items-center justify-center text-white mr-2 flex-shrink-0">
|
||||
<i class="fa-solid fa-robot text-sm"></i>
|
||||
</div>
|
||||
<div class="bg-gray-100 dark:bg-gray-800 rounded-lg p-3 max-w-[80%]">
|
||||
<div class="text-gray-700 dark:text-gray-300 markdown-content">
|
||||
<p>Ja, natürlich! Ich kann dir dabei helfen, eine Mindmap zum Thema <strong>Künstliche Intelligenz</strong> zu erstellen.</p>
|
||||
<p>Du kannst wie folgt vorgehen:</p>
|
||||
<ol>
|
||||
<li>Gehe zur <strong>Mindmap</strong>-Ansicht</li>
|
||||
<li>Suche nach dem Knoten "Künstliche Intelligenz" unter der Kategorie "Technologie"</li>
|
||||
<li>Füge diesen Knoten zu deiner persönlichen Mindmap hinzu</li>
|
||||
<li>Ergänze verwandte Themen wie <em>Machine Learning, Neural Networks oder Data Science</em></li>
|
||||
</ol>
|
||||
<p>Soll ich dir noch mehr spezifische Informationen zu KI-Teilgebieten geben?</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Chat Input -->
|
||||
<div class="p-4">
|
||||
<div class="flex">
|
||||
<input type="text" placeholder="Stelle eine Frage..." class="mystical-input flex-grow" disabled>
|
||||
<button class="ml-2 bg-gradient-to-r from-purple-600 to-indigo-600 text-white p-2 rounded-lg disabled:opacity-50" disabled>
|
||||
<i class="fa-solid fa-paper-plane"></i>
|
||||
</button>
|
||||
</div>
|
||||
<!-- Quick Queries -->
|
||||
<div class="mt-3 flex flex-wrap gap-2">
|
||||
<span class="text-xs text-gray-500 dark:text-gray-400 mr-1">Beispiele:</span>
|
||||
<button data-question="Was sind die wichtigsten Grundlagen der Künstlichen Intelligenz?" class="quick-query-btn text-xs px-2 py-1 rounded-full bg-gray-200 dark:bg-gray-700 text-gray-700 dark:text-gray-300 hover:bg-gray-300 dark:hover:bg-gray-600 cursor-pointer transition-colors">KI-Grundlagen</button>
|
||||
<button data-question="Wie kann ich eine Mindmap zum Thema Neuronale Netzwerke erstellen?" class="quick-query-btn text-xs px-2 py-1 rounded-full bg-gray-200 dark:bg-gray-700 text-gray-700 dark:text-gray-300 hover:bg-gray-300 dark:hover:bg-gray-600 cursor-pointer transition-colors">Mindmap erstellen</button>
|
||||
<button data-question="Zeige mir alle verfügbaren Kategorien in der Datenbank" class="quick-query-btn text-xs px-2 py-1 rounded-full bg-gray-200 dark:bg-gray-700 text-gray-700 dark:text-gray-300 hover:bg-gray-300 dark:hover:bg-gray-600 cursor-pointer transition-colors">Datenbank durchsuchen</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Try it Button -->
|
||||
<div class="text-center mt-10">
|
||||
<button onclick="window.MindMap && window.MindMap.assistant && window.MindMap.assistant.sendQuestion('Hallo! Ich möchte mehr über die Funktionen der Wissensdatenbank erfahren. Was kann ich hier alles machen?')"
|
||||
class="mystical-button mystical-button-primary inline-flex items-center">
|
||||
<i class="fa-solid fa-robot mr-2"></i>
|
||||
KI-Assistenten ausprobieren
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Getting Started Section -->
|
||||
<section class="py-20 relative">
|
||||
<div class="mystical-line absolute top-0 left-1/2 transform -translate-x-1/2 w-1/3"></div>
|
||||
|
||||
<div class="max-w-screen-xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div class="text-center mb-12">
|
||||
<h2 class="section-heading mb-4 text-gray-900 dark:text-white">So <span class="gradient-text">funktioniert's</span></h2>
|
||||
<p class="text-lg text-gray-700 dark:text-gray-300 max-w-3xl mx-auto">
|
||||
In wenigen einfachen Schritten kannst du mit Systades beginnen, dein Wissen zu organisieren.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Step Cards -->
|
||||
<div class="grid grid-cols-1 md:grid-cols-3 gap-8">
|
||||
<!-- Step 1 -->
|
||||
<div class="featured-card rounded-2xl p-6 bg-white/80 dark:bg-gray-800/30 backdrop-blur-sm relative overflow-hidden">
|
||||
<div class="absolute top-4 right-4 w-10 h-10 rounded-full bg-purple-100 dark:bg-purple-900/30 flex items-center justify-center text-purple-600 dark:text-purple-400 font-bold">
|
||||
1
|
||||
</div>
|
||||
<h3 class="text-xl font-semibold mb-4 text-gray-900 dark:text-white">Konto erstellen</h3>
|
||||
<p class="text-gray-700 dark:text-gray-300 mb-4">
|
||||
Registriere dich für ein kostenloses Konto, um deine persönliche Wissenslandschaft zu erstellen.
|
||||
</p>
|
||||
{% if not current_user.is_authenticated %}
|
||||
<a href="{{ url_for('register') }}" class="text-purple-600 dark:text-purple-400 hover:underline">
|
||||
Jetzt registrieren <i class="fa-solid fa-arrow-right ml-1"></i>
|
||||
</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<!-- Step 2 -->
|
||||
<div class="featured-card rounded-2xl p-6 bg-white/80 dark:bg-gray-800/30 backdrop-blur-sm relative overflow-hidden">
|
||||
<div class="absolute top-4 right-4 w-10 h-10 rounded-full bg-purple-100 dark:bg-purple-900/30 flex items-center justify-center text-purple-600 dark:text-purple-400 font-bold">
|
||||
2
|
||||
</div>
|
||||
<h3 class="text-xl font-semibold mb-4 text-gray-900 dark:text-white">Mindmap erkunden</h3>
|
||||
<p class="text-gray-700 dark:text-gray-300 mb-4">
|
||||
Entdecke die öffentliche Wissensmindmap und füge Knoten zu deiner persönlichen Landschaft hinzu.
|
||||
</p>
|
||||
<a href="{{ url_for('mindmap') }}" class="text-purple-600 dark:text-purple-400 hover:underline">
|
||||
Zur Mindmap <i class="fa-solid fa-arrow-right ml-1"></i>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- Step 3 -->
|
||||
<div class="featured-card rounded-2xl p-6 bg-white/80 dark:bg-gray-800/30 backdrop-blur-sm relative overflow-hidden">
|
||||
<div class="absolute top-4 right-4 w-10 h-10 rounded-full bg-purple-100 dark:bg-purple-900/30 flex items-center justify-center text-purple-600 dark:text-purple-400 font-bold">
|
||||
3
|
||||
</div>
|
||||
<h3 class="text-xl font-semibold mb-4 text-gray-900 dark:text-white">Gedanken teilen</h3>
|
||||
<p class="text-gray-700 dark:text-gray-300 mb-4">
|
||||
Teile deine eigenen Gedanken, verbinde sie mit vorhandenen Knoten und baue das kollektive Wissen aus.
|
||||
</p>
|
||||
{% if current_user.is_authenticated %}
|
||||
<a href="{{ url_for('profile') }}" class="text-purple-600 dark:text-purple-400 hover:underline">
|
||||
Zum Profil <i class="fa-solid fa-arrow-right ml-1"></i>
|
||||
</a>
|
||||
{% else %}
|
||||
<a href="{{ url_for('login') }}" class="text-purple-600 dark:text-purple-400 hover:underline">
|
||||
Jetzt anmelden <i class="fa-solid fa-arrow-right ml-1"></i>
|
||||
</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Call to Action -->
|
||||
<section class="py-20 relative">
|
||||
<div class="mystical-line absolute top-0 left-1/2 transform -translate-x-1/2 w-1/3"></div>
|
||||
|
||||
<div class="max-w-3xl mx-auto px-4 sm:px-6 lg:px-8 text-center">
|
||||
<h2 class="section-heading mb-6 text-gray-900 dark:text-white">Bereit, dein <span class="gradient-text">Wissen zu vernetzen</span>?</h2>
|
||||
<p class="text-lg text-gray-700 dark:text-gray-300 mb-8">
|
||||
Tritt unserer wachsenden Community bei und entdecke eine neue Art, Wissen zu organisieren und zu teilen.
|
||||
</p>
|
||||
<div class="flex flex-col sm:flex-row gap-4 justify-center">
|
||||
<a href="{{ url_for('mindmap') }}" class="mystical-button mystical-button-primary">
|
||||
<i class="fa-solid fa-diagram-project mr-2"></i> Mindmap erkunden
|
||||
</a>
|
||||
{% if not current_user.is_authenticated %}
|
||||
<a href="{{ url_for('register') }}" class="mystical-button mystical-button-secondary">
|
||||
<i class="fa-solid fa-user-plus mr-2"></i> Konto erstellen
|
||||
</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_js %}
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
// Expand-Button mit dem echten Assistenten verknüpfen
|
||||
const openRealAssistantBtn = document.getElementById('open-real-assistant');
|
||||
if (openRealAssistantBtn) {
|
||||
openRealAssistantBtn.addEventListener('click', function() {
|
||||
if (window.MindMap && window.MindMap.assistant) {
|
||||
window.MindMap.assistant.toggleAssistant(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Auch die Beispiel-Buttons im Demo-Chat klickbar machen
|
||||
const quickQueryButtons = document.querySelectorAll('.quick-query-btn');
|
||||
quickQueryButtons.forEach(button => {
|
||||
button.addEventListener('click', function() {
|
||||
if (window.MindMap && window.MindMap.assistant) {
|
||||
const question = button.getAttribute('data-question');
|
||||
if (question) {
|
||||
window.MindMap.assistant.sendQuestion(question);
|
||||
} else {
|
||||
// Fallback auf den Button-Text, falls kein data-question Attribut gesetzt ist
|
||||
const queryText = button.textContent.trim();
|
||||
window.MindMap.assistant.sendQuestion(queryText);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Styling für die markdown-content hinzufügen
|
||||
const style = document.createElement('style');
|
||||
style.textContent = `
|
||||
.markdown-content h1, .markdown-content h2, .markdown-content h3,
|
||||
.markdown-content h4, .markdown-content h5, .markdown-content h6 {
|
||||
font-weight: bold;
|
||||
margin-top: 0.5rem;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
.markdown-content h1 { font-size: 1.4rem; }
|
||||
.markdown-content h2 { font-size: 1.3rem; }
|
||||
.markdown-content h3 { font-size: 1.2rem; }
|
||||
.markdown-content h4 { font-size: 1.1rem; }
|
||||
.markdown-content ul, .markdown-content ol {
|
||||
padding-left: 1.5rem;
|
||||
margin: 0.5rem 0;
|
||||
}
|
||||
.markdown-content ul { list-style-type: disc; }
|
||||
.markdown-content ol { list-style-type: decimal; }
|
||||
.markdown-content p { margin: 0.5rem 0; }
|
||||
.markdown-content code {
|
||||
font-family: monospace;
|
||||
background-color: rgba(0, 0, 0, 0.1);
|
||||
padding: 1px 4px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
.markdown-content pre {
|
||||
background-color: rgba(0, 0, 0, 0.1);
|
||||
padding: 0.5rem;
|
||||
border-radius: 4px;
|
||||
overflow-x: auto;
|
||||
margin: 0.5rem 0;
|
||||
}
|
||||
.dark .markdown-content code {
|
||||
background-color: rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
.dark .markdown-content pre {
|
||||
background-color: rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
`;
|
||||
document.head.appendChild(style);
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
11
templates/layout.html
Normal file
11
templates/layout.html
Normal file
@@ -0,0 +1,11 @@
|
||||
<!-- Navigation -->
|
||||
<header class="w-full">
|
||||
<nav class="fixed top-0 z-50 w-full bg-dark-900 border-b border-gray-700">
|
||||
<!-- ... existing code ... -->
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<!-- Main Content Container -->
|
||||
<div class="container mx-auto px-4 pt-20 pb-10">
|
||||
<!-- ... existing code ... -->
|
||||
</div>
|
||||
55
templates/login.html
Normal file
55
templates/login.html
Normal file
@@ -0,0 +1,55 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}Anmelden{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="flex justify-center items-center min-h-screen px-4 py-12">
|
||||
<div class="w-full max-w-md">
|
||||
<div class="bg-white bg-opacity-20 backdrop-blur-lg rounded-xl shadow-xl overflow-hidden transition-all duration-300 hover:shadow-2xl">
|
||||
<div class="p-6 sm:p-8">
|
||||
<h2 class="text-center text-2xl font-bold text-gray-800 mb-6">
|
||||
<i class="fas fa-sign-in-alt mr-2"></i>
|
||||
Anmelden
|
||||
</h2>
|
||||
|
||||
<form method="POST" action="{{ url_for('login') }}" class="space-y-6">
|
||||
<div class="space-y-2">
|
||||
<label for="username" class="block text-sm font-medium text-gray-700">Benutzername</label>
|
||||
<div class="relative rounded-md shadow-sm">
|
||||
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
|
||||
<i class="fas fa-user text-gray-400"></i>
|
||||
</div>
|
||||
<input type="text" id="username" name="username" required
|
||||
class="block w-full pl-10 pr-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition-colors"
|
||||
placeholder="Benutzername eingeben">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="space-y-2">
|
||||
<label for="password" class="block text-sm font-medium text-gray-700">Passwort</label>
|
||||
<div class="relative rounded-md shadow-sm">
|
||||
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
|
||||
<i class="fas fa-lock text-gray-400"></i>
|
||||
</div>
|
||||
<input type="password" id="password" name="password" required
|
||||
class="block w-full pl-10 pr-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition-colors"
|
||||
placeholder="Passwort eingeben">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<button type="submit"
|
||||
class="w-full flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 transition-colors duration-200">
|
||||
<i class="fas fa-sign-in-alt mr-2"></i> Anmelden
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="text-center text-sm text-gray-600">
|
||||
<p>Noch kein Konto? <a href="{{ url_for('register') }}" class="font-medium text-blue-600 hover:text-blue-500 transition-colors">Registrieren</a></p>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
234
templates/mindmap.html
Normal file
234
templates/mindmap.html
Normal file
@@ -0,0 +1,234 @@
|
||||
<!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>
|
||||
|
||||
<!-- Cytoscape.js -->
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/cytoscape/3.26.0/cytoscape.min.js"></script>
|
||||
|
||||
<!-- Socket.IO -->
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.7.2/socket.io.min.js"></script>
|
||||
|
||||
<!-- Feather Icons (optional) -->
|
||||
<script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script>
|
||||
|
||||
<style>
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
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>
|
||||
</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();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
320
templates/my_account.html
Normal file
320
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 %}
|
||||
800
templates/profile.html
Normal file
800
templates/profile.html
Normal file
@@ -0,0 +1,800 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}Profil{% endblock %}
|
||||
|
||||
{% block extra_css %}
|
||||
<style>
|
||||
/* Grundstile für das Profil mit verbessertem Glasmorphismus */
|
||||
.profile-container {
|
||||
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 12px 36px rgba(0, 0, 0, 0.35);
|
||||
padding: 2rem;
|
||||
margin-bottom: 2rem;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.profile-container:hover {
|
||||
border: 1px solid rgba(255, 255, 255, 0.2);
|
||||
box-shadow: 0 16px 48px rgba(0, 0, 0, 0.45);
|
||||
transform: translateY(-3px);
|
||||
}
|
||||
|
||||
/* Verbesserte Profile-Header mit dynamischer User-Anzeige */
|
||||
.profile-header {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 2rem;
|
||||
gap: 2.5rem;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.avatar-container {
|
||||
width: 180px;
|
||||
height: 180px;
|
||||
border-radius: 50%;
|
||||
background: rgba(32, 36, 55, 0.9);
|
||||
backdrop-filter: blur(10px);
|
||||
-webkit-backdrop-filter: blur(10px);
|
||||
border: 3px solid rgba(179, 143, 255, 0.3);
|
||||
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.25), 0 0 15px rgba(179, 143, 255, 0.2);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
transition: all 0.3s ease;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.avatar-container:hover {
|
||||
transform: scale(1.05);
|
||||
border: 3px solid rgba(179, 143, 255, 0.5);
|
||||
box-shadow: 0 12px 45px rgba(0, 0, 0, 0.3), 0 0 25px rgba(179, 143, 255, 0.35);
|
||||
}
|
||||
|
||||
.avatar-container img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
transition: filter 0.3s ease;
|
||||
}
|
||||
|
||||
.avatar-container:hover img {
|
||||
filter: brightness(1.1);
|
||||
}
|
||||
|
||||
.avatar-edit {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
background: rgba(255, 255, 255, 0.2);
|
||||
border-radius: 50%;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.avatar-edit:hover {
|
||||
background: rgba(255, 255, 255, 0.3);
|
||||
}
|
||||
|
||||
.user-info {
|
||||
flex: 1;
|
||||
padding-top: 0.5rem;
|
||||
}
|
||||
|
||||
.user-info h1 {
|
||||
font-size: 2.75rem;
|
||||
font-weight: 800;
|
||||
margin-bottom: 0.75rem;
|
||||
background: linear-gradient(135deg, #b38fff, #58a9ff);
|
||||
-webkit-background-clip: text;
|
||||
background-clip: text;
|
||||
color: transparent;
|
||||
text-shadow: 0 2px 10px rgba(179, 143, 255, 0.3);
|
||||
letter-spacing: 0.3px;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.user-bio {
|
||||
font-size: 1.15rem;
|
||||
line-height: 1.7;
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
max-width: 650px;
|
||||
margin-bottom: 1.5rem;
|
||||
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.user-meta {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 1.5rem;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
font-size: 1rem;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.user-meta span {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
transition: all 0.25s ease;
|
||||
}
|
||||
|
||||
.user-meta span:hover {
|
||||
color: rgba(255, 255, 255, 1);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.user-meta i {
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
/* Benutzer-Aktionsbereich */
|
||||
.profile-actions {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 1rem;
|
||||
margin-top: 2rem;
|
||||
}
|
||||
|
||||
.profile-action-btn {
|
||||
padding: 0.75rem 1.5rem;
|
||||
border-radius: 16px;
|
||||
font-weight: 600;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
transition: all 0.3s ease;
|
||||
background: rgba(32, 36, 55, 0.75);
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
border: 1px solid rgba(255, 255, 255, 0.12);
|
||||
backdrop-filter: blur(15px);
|
||||
-webkit-backdrop-filter: blur(15px);
|
||||
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
.profile-action-btn:hover {
|
||||
transform: translateY(-3px);
|
||||
background: rgba(179, 143, 255, 0.25);
|
||||
border: 1px solid rgba(179, 143, 255, 0.3);
|
||||
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.2), 0 0 15px rgba(179, 143, 255, 0.2);
|
||||
text-shadow: 0 2px 3px rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
|
||||
.profile-action-btn.primary {
|
||||
background: rgba(179, 143, 255, 0.25);
|
||||
color: #ffffff;
|
||||
border: 1px solid rgba(179, 143, 255, 0.3);
|
||||
}
|
||||
|
||||
.profile-action-btn.primary:hover {
|
||||
background: rgba(179, 143, 255, 0.35);
|
||||
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.25), 0 0 20px rgba(179, 143, 255, 0.35);
|
||||
}
|
||||
|
||||
/* Verbesserte Profil-Tabs */
|
||||
.profile-tabs {
|
||||
display: flex;
|
||||
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
|
||||
margin-bottom: 1.5rem;
|
||||
overflow-x: auto;
|
||||
scrollbar-width: thin;
|
||||
scrollbar-color: rgba(179, 143, 255, 0.5) rgba(255, 255, 255, 0.05);
|
||||
}
|
||||
|
||||
.profile-tab {
|
||||
padding: 1rem 1.5rem;
|
||||
font-weight: 600;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
border-bottom: 3px solid transparent;
|
||||
transition: all 0.3s ease;
|
||||
cursor: pointer;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.profile-tab:hover {
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
}
|
||||
|
||||
.profile-tab.active {
|
||||
color: #b38fff;
|
||||
border-bottom: 3px solid #b38fff;
|
||||
background: rgba(179, 143, 255, 0.1);
|
||||
}
|
||||
|
||||
/* Aktivitäten und Beiträge */
|
||||
.activity-feed {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1.25rem;
|
||||
}
|
||||
|
||||
.activity-card {
|
||||
background: rgba(32, 36, 55, 0.7);
|
||||
border-radius: 20px;
|
||||
overflow: hidden;
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
transition: all 0.3s ease;
|
||||
backdrop-filter: blur(15px);
|
||||
-webkit-backdrop-filter: blur(15px);
|
||||
}
|
||||
|
||||
.activity-card:hover {
|
||||
transform: translateY(-3px);
|
||||
border: 1px solid rgba(255, 255, 255, 0.15);
|
||||
box-shadow: 0 12px 30px rgba(0, 0, 0, 0.25), 0 0 15px rgba(179, 143, 255, 0.15);
|
||||
}
|
||||
|
||||
.activity-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;
|
||||
}
|
||||
|
||||
.activity-title {
|
||||
font-size: 1.25rem;
|
||||
font-weight: 700;
|
||||
color: rgba(255, 255, 255, 0.95);
|
||||
}
|
||||
|
||||
.activity-date {
|
||||
font-size: 0.85rem;
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
}
|
||||
|
||||
.activity-content {
|
||||
padding: 1.5rem;
|
||||
color: rgba(255, 255, 255, 0.85);
|
||||
font-size: 1.05rem;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.activity-footer {
|
||||
padding: 1rem 1.5rem;
|
||||
border-top: 1px solid rgba(255, 255, 255, 0.06);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.activity-reactions {
|
||||
display: flex;
|
||||
gap: 0.75rem;
|
||||
}
|
||||
|
||||
.reaction-button {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.35rem;
|
||||
padding: 0.5rem 0.75rem;
|
||||
border-radius: 12px;
|
||||
font-size: 0.9rem;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
border: none;
|
||||
transition: all 0.3s ease;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.reaction-button:hover {
|
||||
background: rgba(179, 143, 255, 0.15);
|
||||
color: rgba(255, 255, 255, 0.95);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.reaction-button.active {
|
||||
background: rgba(179, 143, 255, 0.2);
|
||||
color: #b38fff;
|
||||
}
|
||||
|
||||
.activity-actions {
|
||||
display: flex;
|
||||
gap: 0.75rem;
|
||||
}
|
||||
|
||||
.action-button {
|
||||
padding: 0.5rem 0.75rem;
|
||||
border-radius: 12px;
|
||||
font-size: 0.9rem;
|
||||
background: rgba(179, 143, 255, 0.1);
|
||||
color: #b38fff;
|
||||
border: 1px solid rgba(179, 143, 255, 0.25);
|
||||
transition: all 0.3s ease;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.action-button:hover {
|
||||
background: rgba(179, 143, 255, 0.2);
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1), 0 0 10px rgba(179, 143, 255, 0.2);
|
||||
}
|
||||
|
||||
/* Verbesserte Einstellungskarten */
|
||||
.settings-card {
|
||||
background: rgba(32, 36, 55, 0.7);
|
||||
border-radius: 20px;
|
||||
overflow: hidden;
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
margin-bottom: 1.5rem;
|
||||
backdrop-filter: blur(15px);
|
||||
-webkit-backdrop-filter: blur(15px);
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.settings-card:hover {
|
||||
border: 1px solid rgba(255, 255, 255, 0.15);
|
||||
box-shadow: 0 12px 30px rgba(0, 0, 0, 0.2), 0 0 15px rgba(179, 143, 255, 0.15);
|
||||
}
|
||||
|
||||
.settings-card-header {
|
||||
padding: 1.25rem 1.5rem;
|
||||
border-bottom: 1px solid rgba(255, 255, 255, 0.06);
|
||||
font-size: 1.2rem;
|
||||
font-weight: 700;
|
||||
color: rgba(255, 255, 255, 0.95);
|
||||
}
|
||||
|
||||
.settings-card-body {
|
||||
padding: 1.5rem;
|
||||
}
|
||||
|
||||
.settings-group {
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.settings-label {
|
||||
display: block;
|
||||
margin-bottom: 0.5rem;
|
||||
font-weight: 600;
|
||||
color: rgba(255, 255, 255, 0.85);
|
||||
}
|
||||
|
||||
.settings-input {
|
||||
width: 100%;
|
||||
padding: 0.75rem 1rem;
|
||||
background: rgba(24, 28, 45, 0.6);
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
border-radius: 12px;
|
||||
color: rgba(255, 255, 255, 0.95);
|
||||
font-size: 1rem;
|
||||
transition: all 0.3s ease;
|
||||
backdrop-filter: blur(10px);
|
||||
-webkit-backdrop-filter: blur(10px);
|
||||
}
|
||||
|
||||
.settings-input:focus {
|
||||
border-color: rgba(179, 143, 255, 0.4);
|
||||
box-shadow: 0 0 0 3px rgba(179, 143, 255, 0.15);
|
||||
outline: none;
|
||||
}
|
||||
|
||||
/* Light Mode Anpassungen */
|
||||
html.light .profile-container,
|
||||
html.light .profile-tabs,
|
||||
html.light .activity-card,
|
||||
html.light .settings-card {
|
||||
background: rgba(255, 255, 255, 0.85);
|
||||
border: 1px solid rgba(0, 0, 0, 0.08);
|
||||
box-shadow: 0 8px 30px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
html.light .avatar-container {
|
||||
background: rgba(255, 255, 255, 0.9);
|
||||
border: 3px solid rgba(126, 63, 242, 0.3);
|
||||
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.1), 0 0 15px rgba(126, 63, 242, 0.15);
|
||||
}
|
||||
|
||||
html.light .user-info h1 {
|
||||
background: linear-gradient(135deg, #7e3ff2, #3282f6);
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
html.light .user-bio,
|
||||
html.light .activity-content {
|
||||
color: #1a202c;
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
html.light .user-meta span {
|
||||
color: #4a5568;
|
||||
}
|
||||
|
||||
html.light .stat-item,
|
||||
html.light .settings-input {
|
||||
background: rgba(255, 255, 255, 0.7);
|
||||
border: 1px solid rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
html.light .stat-value {
|
||||
background: linear-gradient(135deg, #7e3ff2, #3282f6);
|
||||
}
|
||||
|
||||
html.light .stat-label {
|
||||
color: #4a5568;
|
||||
}
|
||||
|
||||
html.light .profile-tab {
|
||||
color: #4a5568;
|
||||
}
|
||||
|
||||
html.light .profile-tab:hover {
|
||||
background: rgba(0, 0, 0, 0.03);
|
||||
color: #1a202c;
|
||||
}
|
||||
|
||||
html.light .profile-tab.active {
|
||||
color: #7e3ff2;
|
||||
border-bottom: 3px solid #7e3ff2;
|
||||
background: rgba(126, 63, 242, 0.08);
|
||||
}
|
||||
|
||||
html.light .activity-title,
|
||||
html.light .settings-card-header,
|
||||
html.light .settings-label {
|
||||
color: #1a202c;
|
||||
}
|
||||
|
||||
html.light .activity-date {
|
||||
color: #718096;
|
||||
}
|
||||
|
||||
html.light .activity-footer {
|
||||
border-top: 1px solid rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
html.light .reaction-button {
|
||||
color: #4a5568;
|
||||
background: rgba(0, 0, 0, 0.03);
|
||||
}
|
||||
|
||||
html.light .reaction-button:hover {
|
||||
background: rgba(126, 63, 242, 0.1);
|
||||
color: #7e3ff2;
|
||||
}
|
||||
|
||||
html.light .reaction-button.active {
|
||||
background: rgba(126, 63, 242, 0.15);
|
||||
color: #7e3ff2;
|
||||
}
|
||||
|
||||
html.light .action-button {
|
||||
background: rgba(126, 63, 242, 0.1);
|
||||
color: #7e3ff2;
|
||||
border: 1px solid rgba(126, 63, 242, 0.2);
|
||||
}
|
||||
|
||||
html.light .action-button:hover {
|
||||
background: rgba(126, 63, 242, 0.2);
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container mx-auto px-4 py-10">
|
||||
<!-- Profil-Container -->
|
||||
<div class="profile-container">
|
||||
<!-- User Info Section -->
|
||||
<div class="profile-header">
|
||||
<div class="avatar-container">
|
||||
<img src="{{ user.avatar if user.avatar else url_for('static', filename='img/default-avatar.png') }}" alt="Profilbild" class="avatar">
|
||||
<div class="avatar-edit">
|
||||
<i class="fas fa-camera"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="user-info">
|
||||
<h1>{{ user.username }}</h1>
|
||||
<p class="user-bio">{{ user.bio if user.bio else 'Keine Bio vorhanden. Klicke auf bearbeiten, um eine hinzuzufügen.' }}</p>
|
||||
<div class="user-meta">
|
||||
<span><i class="fas fa-map-marker-alt"></i> {{ user.location if user.location else 'Kein Standort angegeben' }}</span>
|
||||
<span><i class="fas fa-calendar-alt"></i> Mitglied seit {{ user.created_at.strftime('%d.%m.%Y') }}</span>
|
||||
</div>
|
||||
<button class="edit-profile-btn">Profil bearbeiten</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Statistiken -->
|
||||
<div class="profile-stats">
|
||||
<!-- Gedanken -->
|
||||
<div class="stat-item">
|
||||
<div class="stat-icon">
|
||||
<i class="fas fa-lightbulb"></i>
|
||||
</div>
|
||||
<div class="stat-value">{{ stats.thought_count if stats and stats.thought_count else 0 }}</div>
|
||||
<div class="stat-label">Gedanken</div>
|
||||
</div>
|
||||
|
||||
<!-- Verbindungen -->
|
||||
<div class="stat-item">
|
||||
<div class="stat-icon">
|
||||
<i class="fas fa-project-diagram"></i>
|
||||
</div>
|
||||
<div class="stat-value">{{ stats.connections_count if stats and stats.connections_count else 0 }}</div>
|
||||
<div class="stat-label">Verbindungen</div>
|
||||
</div>
|
||||
|
||||
<!-- Follower -->
|
||||
<div class="stat-item">
|
||||
<div class="stat-icon">
|
||||
<i class="fas fa-users"></i>
|
||||
</div>
|
||||
<div class="stat-value">{{ stats.followers_count if stats and stats.followers_count else 0 }}</div>
|
||||
<div class="stat-label">Follower</div>
|
||||
</div>
|
||||
|
||||
<!-- Beiträge -->
|
||||
<div class="stat-item">
|
||||
<div class="stat-icon">
|
||||
<i class="fas fa-comment-dots"></i>
|
||||
</div>
|
||||
<div class="stat-value">{{ stats.contributions_count if stats and stats.contributions_count else 0 }}</div>
|
||||
<div class="stat-label">Beiträge</div>
|
||||
</div>
|
||||
|
||||
<!-- Bewertung -->
|
||||
<div class="stat-item">
|
||||
<div class="stat-icon">
|
||||
<i class="fas fa-star"></i>
|
||||
</div>
|
||||
<div class="stat-value">{{ stats.rating if stats and stats.rating else '0.0' }}</div>
|
||||
<div class="stat-label">Bewertung</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Tabs und Inhaltsbereich -->
|
||||
<div class="glass-card">
|
||||
<!-- Profil-Tabs -->
|
||||
<div class="profile-tabs">
|
||||
<div class="profile-tab active" data-tab="activity">Aktivitäten</div>
|
||||
<div class="profile-tab" data-tab="thoughts">Gedanken</div>
|
||||
<div class="profile-tab" data-tab="collections">Sammlungen</div>
|
||||
<div class="profile-tab" data-tab="connections">Verbindungen</div>
|
||||
<div class="profile-tab" data-tab="settings">Einstellungen</div>
|
||||
</div>
|
||||
|
||||
<!-- Tab-Inhalte -->
|
||||
<div class="p-6">
|
||||
<!-- Aktivitäts-Tab (Standardmäßig angezeigt) -->
|
||||
<div class="tab-content" id="activity-tab">
|
||||
<div class="activity-feed">
|
||||
{% if activities %}
|
||||
{% for activity in activities %}
|
||||
<div class="activity-card">
|
||||
<div class="activity-header">
|
||||
<div class="activity-title">{{ activity.title }}</div>
|
||||
<div class="activity-date">{{ activity.date }}</div>
|
||||
</div>
|
||||
<div class="activity-content">
|
||||
<p>{{ activity.content }}</p>
|
||||
</div>
|
||||
<div class="activity-footer">
|
||||
<div class="activity-reactions">
|
||||
<button class="reaction-button {% if activity.user_liked %}active{% endif %}">
|
||||
<i class="fas fa-thumbs-up"></i> <span>{{ activity.likes }}</span>
|
||||
</button>
|
||||
<button class="reaction-button">
|
||||
<i class="fas fa-comment"></i> <span>{{ activity.comments }}</span>
|
||||
</button>
|
||||
<button class="reaction-button">
|
||||
<i class="fas fa-share"></i> <span>{{ activity.shares }}</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="activity-actions">
|
||||
<button class="action-button">
|
||||
Ansehen
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<div class="text-center py-12">
|
||||
<i class="fas fa-history text-5xl text-gray-400 mb-4"></i>
|
||||
<p class="text-gray-500">Noch keine Aktivitäten vorhanden</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Weitere Tab-Inhalte (werden per JavaScript angezeigt) -->
|
||||
<div class="tab-content hidden" id="thoughts-tab">
|
||||
<div id="thoughts-container">
|
||||
{% if thoughts %}
|
||||
{% for thought in thoughts %}
|
||||
<div class="thought-item">
|
||||
<h3>{{ thought.title }}</h3>
|
||||
<p>{{ thought.content }}</p>
|
||||
<div class="thought-meta">
|
||||
<span>{{ thought.date }}</span>
|
||||
<span>{{ thought.category }}</span>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<div class="text-center py-12">
|
||||
<i class="fas fa-lightbulb text-5xl text-gray-400 mb-4"></i>
|
||||
<p class="text-gray-500">Noch keine Gedanken erstellt</p>
|
||||
<a href="{{ url_for('get_thought') }}" class="mt-4 inline-block px-4 py-2 bg-purple-600 text-white rounded-lg">Ersten Gedanken erstellen</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="tab-content hidden" id="collections-tab">
|
||||
<div id="collections-container">
|
||||
{% if collections %}
|
||||
{% for collection in collections %}
|
||||
<div class="collection-item">
|
||||
<h3>{{ collection.title }}</h3>
|
||||
<p>{{ collection.description }}</p>
|
||||
<div class="collection-meta">
|
||||
<span>{{ collection.thoughts_count }} Gedanken</span>
|
||||
<span>{{ collection.date }}</span>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<div class="text-center py-12">
|
||||
<i class="fas fa-folder-open text-5xl text-gray-400 mb-4"></i>
|
||||
<p class="text-gray-500">Noch keine Sammlungen erstellt</p>
|
||||
<a href="{{ url_for('create_collection') }}" class="mt-4 inline-block px-4 py-2 bg-purple-600 text-white rounded-lg">Erste Sammlung erstellen</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="tab-content hidden" id="connections-tab">
|
||||
<div id="connections-container">
|
||||
{% if connections %}
|
||||
{% for connection in connections %}
|
||||
<div class="connection-item">
|
||||
<div class="connection-nodes">
|
||||
<div class="connection-node">
|
||||
<h4>{{ connection.source.title }}</h4>
|
||||
<p>{{ connection.source.excerpt }}</p>
|
||||
</div>
|
||||
<div class="connection-type">
|
||||
<i class="fas fa-arrow-right"></i>
|
||||
<span>{{ connection.relation_type }}</span>
|
||||
</div>
|
||||
<div class="connection-node">
|
||||
<h4>{{ connection.target.title }}</h4>
|
||||
<p>{{ connection.target.excerpt }}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="connection-meta">
|
||||
<span>{{ connection.date }}</span>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<div class="text-center py-12">
|
||||
<i class="fas fa-project-diagram text-5xl text-gray-400 mb-4"></i>
|
||||
<p class="text-gray-500">Noch keine Verbindungen erstellt</p>
|
||||
<a href="{{ url_for('mindmap') }}" class="mt-4 inline-block px-4 py-2 bg-purple-600 text-white rounded-lg">Verbindungen in der Mindmap erstellen</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="tab-content hidden" id="settings-tab">
|
||||
<!-- Einstellungs-Tab-Inhalt -->
|
||||
<div class="settings-card">
|
||||
<div class="settings-card-header">Profilinformationen</div>
|
||||
<div class="settings-card-body">
|
||||
<div class="settings-group">
|
||||
<label class="settings-label" for="name">Name</label>
|
||||
<input type="text" id="name" class="settings-input" value="{{ user.name }}" />
|
||||
</div>
|
||||
|
||||
<div class="settings-group">
|
||||
<label class="settings-label" for="bio">Über mich</label>
|
||||
<textarea id="bio" class="settings-input" rows="4">{{ user.bio }}</textarea>
|
||||
</div>
|
||||
|
||||
<div class="settings-group">
|
||||
<label class="settings-label" for="location">Standort</label>
|
||||
<input type="text" id="location" class="settings-input" value="{{ user.location }}" />
|
||||
</div>
|
||||
|
||||
<div class="settings-group">
|
||||
<label class="settings-label" for="website">Website</label>
|
||||
<input type="url" id="website" class="settings-input" value="{{ user.website }}" />
|
||||
</div>
|
||||
|
||||
<button class="profile-action-btn primary mt-4">
|
||||
<i class="fas fa-save mr-1"></i> Speichern
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="settings-card">
|
||||
<div class="settings-card-header">Datenschutz und Sicherheit</div>
|
||||
<div class="settings-card-body">
|
||||
<div class="settings-group">
|
||||
<label class="settings-label" for="email">E-Mail-Adresse</label>
|
||||
<input type="email" id="email" class="settings-input" value="{{ user.email }}" />
|
||||
</div>
|
||||
|
||||
<div class="settings-group">
|
||||
<label class="settings-label" for="password">Neues Passwort</label>
|
||||
<input type="password" id="password" class="settings-input" placeholder="Neues Passwort eingeben" />
|
||||
</div>
|
||||
|
||||
<div class="settings-group">
|
||||
<label class="settings-label" for="password_confirm">Passwort bestätigen</label>
|
||||
<input type="password" id="password_confirm" class="settings-input" placeholder="Passwort wiederholen" />
|
||||
</div>
|
||||
|
||||
<button class="profile-action-btn primary mt-4">
|
||||
<i class="fas fa-lock mr-1"></i> Passwort aktualisieren
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_js %}
|
||||
<script nonce="{{ csp_nonce }}">
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
// Profil-Tab-Funktionalität
|
||||
const tabs = document.querySelectorAll('.profile-tab');
|
||||
const tabContents = document.querySelectorAll('.tab-content');
|
||||
|
||||
tabs.forEach(tab => {
|
||||
tab.addEventListener('click', function() {
|
||||
// Alle Tabs deaktivieren
|
||||
tabs.forEach(t => t.classList.remove('active'));
|
||||
|
||||
// Aktuellen Tab aktivieren
|
||||
this.classList.add('active');
|
||||
|
||||
// Alle Tab-Inhalte ausblenden
|
||||
tabContents.forEach(content => content.classList.add('hidden'));
|
||||
|
||||
// Entsprechenden Tab-Inhalt anzeigen
|
||||
const tabId = this.getAttribute('data-tab');
|
||||
document.getElementById(`${tabId}-tab`).classList.remove('hidden');
|
||||
});
|
||||
});
|
||||
|
||||
// Like-Button-Funktionalität
|
||||
const reactionButtons = document.querySelectorAll('.reaction-button');
|
||||
|
||||
reactionButtons.forEach(button => {
|
||||
button.addEventListener('click', function() {
|
||||
// Toggle active-Klasse
|
||||
this.classList.toggle('active');
|
||||
|
||||
// Aktueller Zählerstand
|
||||
const countElement = this.querySelector('span');
|
||||
let count = parseInt(countElement.textContent);
|
||||
|
||||
// Zähler aktualisieren
|
||||
if (this.classList.contains('active')) {
|
||||
count += 1;
|
||||
} else {
|
||||
count -= 1;
|
||||
}
|
||||
|
||||
countElement.textContent = count;
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
115
templates/register.html
Normal file
115
templates/register.html
Normal file
@@ -0,0 +1,115 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}Registrieren{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="flex justify-center items-center mt-10 px-4">
|
||||
<div class="w-full max-w-md">
|
||||
<div class="bg-white bg-opacity-80 backdrop-blur-lg rounded-lg shadow-md border border-white border-opacity-30 p-6 md:p-8 transition-all duration-300 transform hover:shadow-lg">
|
||||
<h2 class="text-center mb-6 text-gray-800 font-bold text-2xl flex items-center justify-center">
|
||||
<i class="fas fa-user-plus mr-2 text-blue-600"></i>
|
||||
Registrieren
|
||||
</h2>
|
||||
|
||||
<form method="POST" action="{{ url_for('register') }}" class="needs-validation space-y-6" novalidate>
|
||||
<div class="space-y-2">
|
||||
<label for="username" class="block text-gray-700 font-medium text-sm">Benutzername</label>
|
||||
<div class="relative flex items-center">
|
||||
<span class="absolute left-3 text-blue-600">
|
||||
<i class="fas fa-user"></i>
|
||||
</span>
|
||||
<input type="text" class="pl-10 w-full rounded-md border border-gray-300 py-2 px-4 focus:border-blue-500 focus:ring focus:ring-blue-200 focus:ring-opacity-50 transition-all duration-200"
|
||||
id="username" name="username" placeholder="Dein Benutzername" required>
|
||||
</div>
|
||||
<div class="invalid-feedback text-red-600 text-sm hidden">
|
||||
Bitte gib einen Benutzernamen ein.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="space-y-2">
|
||||
<label for="email" class="block text-gray-700 font-medium text-sm">E-Mail</label>
|
||||
<div class="relative flex items-center">
|
||||
<span class="absolute left-3 text-blue-600">
|
||||
<i class="fas fa-envelope"></i>
|
||||
</span>
|
||||
<input type="email" class="pl-10 w-full rounded-md border border-gray-300 py-2 px-4 focus:border-blue-500 focus:ring focus:ring-blue-200 focus:ring-opacity-50 transition-all duration-200"
|
||||
id="email" name="email" placeholder="name@beispiel.de" required>
|
||||
</div>
|
||||
<div class="invalid-feedback text-red-600 text-sm hidden">
|
||||
Bitte gib eine gültige E-Mail-Adresse ein.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="space-y-2">
|
||||
<label for="password" class="block text-gray-700 font-medium text-sm">Passwort</label>
|
||||
<div class="relative flex items-center">
|
||||
<span class="absolute left-3 text-blue-600">
|
||||
<i class="fas fa-lock"></i>
|
||||
</span>
|
||||
<input type="password" class="pl-10 w-full rounded-md border border-gray-300 py-2 px-4 focus:border-blue-500 focus:ring focus:ring-blue-200 focus:ring-opacity-50 transition-all duration-200"
|
||||
id="password" name="password" placeholder="Mindestens 8 Zeichen" required>
|
||||
<button class="absolute right-2 text-gray-500 hover:text-gray-700 focus:outline-none" type="button" id="togglePassword">
|
||||
<i class="fas fa-eye"></i>
|
||||
</button>
|
||||
</div>
|
||||
<div class="invalid-feedback text-red-600 text-sm hidden">
|
||||
Bitte gib ein sicheres Passwort ein.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="pt-2">
|
||||
<button type="submit" class="w-full bg-blue-600 hover:bg-blue-700 text-white font-medium py-2 px-4 rounded-md shadow-sm transition-all duration-200 transform hover:scale-[1.02] focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-opacity-50">
|
||||
<i class="fas fa-user-plus mr-2"></i> Konto erstellen
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="text-center mt-4 text-gray-700 text-sm">
|
||||
<p>Bereits registriert? <a href="{{ url_for('login') }}" class="text-blue-600 hover:text-blue-800 font-medium transition-colors duration-200">Anmelden</a></p>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// Formularvalidierung aktivieren
|
||||
(function() {
|
||||
'use strict';
|
||||
var forms = document.querySelectorAll('.needs-validation');
|
||||
Array.prototype.slice.call(forms).forEach(function(form) {
|
||||
form.addEventListener('submit', function(event) {
|
||||
if (!form.checkValidity()) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
// Zeige Fehlermeldungen an
|
||||
form.querySelectorAll(':invalid').forEach(function(input) {
|
||||
input.parentNode.nextElementSibling.classList.remove('hidden');
|
||||
});
|
||||
}
|
||||
form.classList.add('was-validated');
|
||||
}, false);
|
||||
|
||||
// Verstecke Fehlermeldungen bei Eingabe
|
||||
form.querySelectorAll('input').forEach(function(input) {
|
||||
input.addEventListener('input', function() {
|
||||
if (this.checkValidity()) {
|
||||
this.parentNode.nextElementSibling.classList.add('hidden');
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Passwort-Sichtbarkeit umschalten
|
||||
const togglePassword = document.querySelector('#togglePassword');
|
||||
const password = document.querySelector('#password');
|
||||
|
||||
togglePassword.addEventListener('click', function() {
|
||||
const type = password.getAttribute('type') === 'password' ? 'text' : 'password';
|
||||
password.setAttribute('type', type);
|
||||
this.querySelector('i').classList.toggle('fa-eye');
|
||||
this.querySelector('i').classList.toggle('fa-eye-slash');
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
{% endblock %}
|
||||
105
templates/search.html
Normal file
105
templates/search.html
Normal file
@@ -0,0 +1,105 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}Suche{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="flex flex-col md:flex-row gap-6">
|
||||
<!-- Filter-Sidebar -->
|
||||
<div class="w-full md:w-1/3 lg:w-1/4 mb-6">
|
||||
<div class="bg-white/10 backdrop-blur-md rounded-xl p-6 shadow-lg">
|
||||
<h4 class="text-xl font-semibold mb-4">Erweiterte Suche</h4>
|
||||
<form id="search-form">
|
||||
<div class="mb-4">
|
||||
<label class="block text-sm font-medium mb-1">Suchbegriff</label>
|
||||
<div class="flex items-center border rounded-lg overflow-hidden bg-white/5">
|
||||
<span class="px-3 py-2 text-gray-400">
|
||||
<i class="fas fa-search"></i>
|
||||
</span>
|
||||
<input type="text" class="w-full bg-transparent border-0 focus:ring-0 py-2 px-1" name="q" placeholder="Suche...">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-4">
|
||||
<label class="block text-sm font-medium mb-1">Schlagworte</label>
|
||||
<div class="flex items-center border rounded-lg overflow-hidden bg-white/5">
|
||||
<span class="px-3 py-2 text-gray-400">
|
||||
<i class="fas fa-tags"></i>
|
||||
</span>
|
||||
<input type="text" class="w-full bg-transparent border-0 focus:ring-0 py-2 px-1" name="keywords" placeholder="Schlagworte (kommagetrennt)">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-4">
|
||||
<label class="block text-sm font-medium mb-1">Minimale Bewertung</label>
|
||||
<div class="flex items-center border rounded-lg overflow-hidden bg-white/5">
|
||||
<span class="px-3 py-2 text-gray-400">
|
||||
<i class="fas fa-star"></i>
|
||||
</span>
|
||||
<select class="w-full bg-transparent border-0 focus:ring-0 py-2 px-1" name="min_rating">
|
||||
<option value="">Alle</option>
|
||||
<option value="4">4+ Sterne</option>
|
||||
<option value="3">3+ Sterne</option>
|
||||
<option value="2">2+ Sterne</option>
|
||||
<option value="1">1+ Stern</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-4">
|
||||
<label class="block text-sm font-medium mb-1">Quellentyp</label>
|
||||
<div class="flex items-center border rounded-lg overflow-hidden bg-white/5">
|
||||
<span class="px-3 py-2 text-gray-400">
|
||||
<i class="fas fa-file-alt"></i>
|
||||
</span>
|
||||
<select class="w-full bg-transparent border-0 focus:ring-0 py-2 px-1" name="source_type">
|
||||
<option value="">Alle</option>
|
||||
<option value="PDF">PDF</option>
|
||||
<option value="Markdown">Markdown</option>
|
||||
<option value="Text">Text</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-5">
|
||||
<label class="block text-sm font-medium mb-1">Beziehungstyp</label>
|
||||
<div class="flex items-center border rounded-lg overflow-hidden bg-white/5">
|
||||
<span class="px-3 py-2 text-gray-400">
|
||||
<i class="fas fa-project-diagram"></i>
|
||||
</span>
|
||||
<select class="w-full bg-transparent border-0 focus:ring-0 py-2 px-1" name="relation_type">
|
||||
<option value="">Alle</option>
|
||||
<option value="SUPPORTS">Stützt</option>
|
||||
<option value="CONTRADICTS">Widerspricht</option>
|
||||
<option value="BUILDS_UPON">Baut auf auf</option>
|
||||
<option value="GENERALIZES">Verallgemeinert</option>
|
||||
<option value="SPECIFIES">Spezifiziert</option>
|
||||
<option value="INSPIRES">Inspiriert</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="w-full bg-gradient-to-r from-blue-500 to-indigo-600 text-white py-2 px-4 rounded-lg hover:opacity-90 transition-all flex items-center justify-center">
|
||||
<i class="fas fa-search mr-2"></i> Suchen
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Suchergebnisse -->
|
||||
<div class="w-full md:w-2/3 lg:w-3/4">
|
||||
<div class="bg-white/10 backdrop-blur-md rounded-xl p-6 shadow-lg mb-6">
|
||||
<h3 class="text-2xl font-semibold mb-2">Suchergebnisse</h3>
|
||||
<p class="text-gray-300 text-sm">Nutze die Filter links, um deine Suche zu präzisieren.</p>
|
||||
</div>
|
||||
|
||||
<div id="search-results" class="mb-6">
|
||||
<!-- Suchergebnisse werden hier dynamisch eingefügt -->
|
||||
<div class="bg-white/10 backdrop-blur-md rounded-xl p-8 shadow-lg text-center">
|
||||
<i class="fas fa-search text-5xl mb-6 text-blue-400"></i>
|
||||
<h5 class="text-xl font-medium mb-3">Wissen entdecken</h5>
|
||||
<p class="text-gray-300">Gib einen Suchbegriff ein, um in der wissenschaftlichen Wissensdatenbank zu suchen.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
269
templates/settings.html
Normal file
269
templates/settings.html
Normal file
@@ -0,0 +1,269 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}Einstellungen{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="relative mb-6" data-page="settings">
|
||||
<!-- Header Bereich -->
|
||||
<div class="mb-8 p-6 bg-gradient-to-br from-slate-900/80 to-slate-800/60 rounded-lg border border-slate-700/20 shadow-xl">
|
||||
<h1 class="text-4xl md:text-5xl font-bold mb-3">
|
||||
<span class="gradient-text">Einstellungen</span>
|
||||
</h1>
|
||||
<p class="text-lg text-gray-300 max-w-3xl">
|
||||
Verwalten Sie Ihr Konto und passen Sie Ihre Benutzererfahrung an.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Einstellungen Grid Layout -->
|
||||
<div class="grid grid-cols-1 lg:grid-cols-3 gap-6">
|
||||
<!-- Seitennavigation (Desktop) -->
|
||||
<div class="lg:col-span-1 order-2 lg:order-1">
|
||||
<div class="sticky top-6 bg-gradient-to-br from-slate-900/80 to-slate-800/60 rounded-lg border border-slate-700/20 shadow-xl overflow-hidden p-4">
|
||||
<nav>
|
||||
<div class="text-xs uppercase text-gray-400 font-semibold tracking-wider mb-3 px-3">Navigation</div>
|
||||
<ul class="space-y-1">
|
||||
<li>
|
||||
<button id="nav-account" class="w-full text-left px-3 py-2 rounded-md flex items-center text-purple-300 bg-purple-900/20 border-l-2 border-purple-500">
|
||||
<i class="fa-solid fa-user-circle mr-3"></i>
|
||||
<span>Konto</span>
|
||||
</button>
|
||||
</li>
|
||||
<li>
|
||||
<button id="nav-appearance" class="w-full text-left px-3 py-2 rounded-md flex items-center text-gray-300 hover:bg-white/5">
|
||||
<i class="fa-solid fa-palette mr-3"></i>
|
||||
<span>Erscheinungsbild</span>
|
||||
</button>
|
||||
</li>
|
||||
<li>
|
||||
<button id="nav-notifications" class="w-full text-left px-3 py-2 rounded-md flex items-center text-gray-300 hover:bg-white/5">
|
||||
<i class="fa-solid fa-bell mr-3"></i>
|
||||
<span>Benachrichtigungen</span>
|
||||
</button>
|
||||
</li>
|
||||
<li>
|
||||
<button id="nav-privacy" class="w-full text-left px-3 py-2 rounded-md flex items-center text-gray-300 hover:bg-white/5">
|
||||
<i class="fa-solid fa-shield-alt mr-3"></i>
|
||||
<span>Datenschutz</span>
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Hauptinhalt der Einstellungen -->
|
||||
<div class="lg:col-span-2 order-1 lg:order-2">
|
||||
<!-- Konto-Einstellungen -->
|
||||
<div id="section-account" class="bg-gradient-to-br from-slate-900/80 to-slate-800/60 rounded-lg border border-slate-700/20 shadow-xl p-6 mb-6">
|
||||
<h2 class="text-2xl font-bold text-white mb-4 flex items-center">
|
||||
<i class="fa-solid fa-user-circle text-purple-400 mr-3"></i>
|
||||
Konto-Einstellungen
|
||||
</h2>
|
||||
|
||||
<div class="mb-6 p-4 bg-slate-900/50 rounded-lg">
|
||||
<div class="flex items-center">
|
||||
<div class="h-16 w-16 rounded-full bg-gradient-to-r from-purple-500 to-blue-500 flex items-center justify-center text-white text-2xl font-bold">
|
||||
{{ current_user.username[0] | upper }}
|
||||
</div>
|
||||
<div class="ml-4">
|
||||
<h3 class="text-lg font-medium text-white">{{ current_user.username }}</h3>
|
||||
<p class="text-gray-400">{{ current_user.email }}</p>
|
||||
<p class="text-xs text-gray-500 mt-1">
|
||||
Mitglied seit {{ current_user.id | string }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<form method="POST" class="space-y-6">
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
<div>
|
||||
<label for="username" class="block text-sm font-medium text-gray-400 mb-1">Benutzername</label>
|
||||
<input type="text" name="username" id="username" value="{{ current_user.username }}" disabled
|
||||
class="w-full bg-slate-800/80 border border-slate-700 rounded-md py-2 px-3 text-white focus:ring-1 focus:ring-purple-500">
|
||||
<p class="mt-1 text-xs text-gray-500">Der Benutzername kann derzeit nicht geändert werden.</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="email" class="block text-sm font-medium text-gray-400 mb-1">E-Mail-Adresse</label>
|
||||
<input type="email" name="email" id="email" value="{{ current_user.email }}" disabled
|
||||
class="w-full bg-slate-800/80 border border-slate-700 rounded-md py-2 px-3 text-white focus:ring-1 focus:ring-purple-500">
|
||||
<p class="mt-1 text-xs text-gray-500">Die E-Mail-Adresse kann derzeit nicht geändert werden.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="border-t border-slate-700 pt-6">
|
||||
<h3 class="text-lg font-medium text-white mb-4">Passwort ändern</h3>
|
||||
|
||||
<div class="space-y-4">
|
||||
<div>
|
||||
<label for="current_password" class="block text-sm font-medium text-gray-400 mb-1">Aktuelles Passwort</label>
|
||||
<input type="password" name="current_password" id="current_password"
|
||||
class="w-full bg-slate-800/80 border border-slate-700 rounded-md py-2 px-3 text-white focus:ring-1 focus:ring-purple-500">
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="new_password" class="block text-sm font-medium text-gray-400 mb-1">Neues Passwort</label>
|
||||
<input type="password" name="new_password" id="new_password"
|
||||
class="w-full bg-slate-800/80 border border-slate-700 rounded-md py-2 px-3 text-white focus:ring-1 focus:ring-purple-500">
|
||||
<p class="mt-1 text-xs text-gray-500">Mindestens 6 Zeichen</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="confirm_password" class="block text-sm font-medium text-gray-400 mb-1">Passwort bestätigen</label>
|
||||
<input type="password" name="confirm_password" id="confirm_password"
|
||||
class="w-full bg-slate-800/80 border border-slate-700 rounded-md py-2 px-3 text-white focus:ring-1 focus:ring-purple-500">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end">
|
||||
<button type="submit" class="py-2 px-4 rounded-md bg-gradient-to-r from-purple-600 to-blue-600 hover:from-purple-700 hover:to-blue-700 text-white font-medium transition duration-300 transform hover:-translate-y-0.5">
|
||||
Änderungen speichern
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<!-- Erscheinungsbild -->
|
||||
<div id="section-appearance" class="bg-gradient-to-br from-slate-900/80 to-slate-800/60 rounded-lg border border-slate-700/20 shadow-xl p-6 mb-6 hidden">
|
||||
<h2 class="text-2xl font-bold text-white mb-4 flex items-center">
|
||||
<i class="fa-solid fa-palette text-purple-400 mr-3"></i>
|
||||
Erscheinungsbild
|
||||
</h2>
|
||||
|
||||
<div class="space-y-4">
|
||||
<div class="p-4 bg-slate-900/50 rounded-lg">
|
||||
<div class="flex justify-between items-center">
|
||||
<div>
|
||||
<h3 class="text-lg font-medium text-white">Dunkles Design</h3>
|
||||
<p class="text-gray-400">Wechsle zwischen hellem und dunklem Modus</p>
|
||||
</div>
|
||||
<div>
|
||||
<button id="toggle-dark-mode" class="w-14 h-7 flex items-center bg-purple-900/30 rounded-full px-1 transition-all" onclick="toggleDarkMode()">
|
||||
<div id="dark-mode-indicator" class="bg-purple-500 w-5 h-5 rounded-full shadow-md transform transition-transform duration-300 translate-x-7"></div>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Benachrichtigungen -->
|
||||
<div id="section-notifications" class="bg-gradient-to-br from-slate-900/80 to-slate-800/60 rounded-lg border border-slate-700/20 shadow-xl p-6 mb-6 hidden">
|
||||
<h2 class="text-2xl font-bold text-white mb-4 flex items-center">
|
||||
<i class="fa-solid fa-bell text-purple-400 mr-3"></i>
|
||||
Benachrichtigungen
|
||||
</h2>
|
||||
|
||||
<div class="p-4 bg-slate-900/50 rounded-lg">
|
||||
<div class="flex justify-between items-center">
|
||||
<div>
|
||||
<h3 class="text-lg font-medium text-white">E-Mail-Benachrichtigungen</h3>
|
||||
<p class="text-gray-400">Diese Funktion wird in einer zukünftigen Version verfügbar sein.</p>
|
||||
</div>
|
||||
<div>
|
||||
<span class="px-2 py-1 text-xs rounded-full bg-slate-700 text-gray-300">
|
||||
Demnächst
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Datenschutz -->
|
||||
<div id="section-privacy" class="bg-gradient-to-br from-slate-900/80 to-slate-800/60 rounded-lg border border-slate-700/20 shadow-xl p-6 mb-6 hidden">
|
||||
<h2 class="text-2xl font-bold text-white mb-4 flex items-center">
|
||||
<i class="fa-solid fa-shield-alt text-purple-400 mr-3"></i>
|
||||
Datenschutz und Sicherheit
|
||||
</h2>
|
||||
|
||||
<div class="p-4 bg-slate-900/50 rounded-lg">
|
||||
<h3 class="text-lg font-medium text-white mb-2">Datenverarbeitung</h3>
|
||||
<p class="text-gray-400 mb-3">
|
||||
Wir verarbeiten Ihre Daten gemäß unserer Datenschutzrichtlinie.
|
||||
</p>
|
||||
<a href="{{ url_for('datenschutz') }}" class="text-purple-400 hover:text-purple-300 inline-flex items-center">
|
||||
<span>Datenschutzerklärung lesen</span>
|
||||
<i class="fa-solid fa-arrow-right ml-1 text-sm"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_js %}
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
// Navigation-Buttons
|
||||
const navButtons = {
|
||||
'nav-account': 'section-account',
|
||||
'nav-appearance': 'section-appearance',
|
||||
'nav-notifications': 'section-notifications',
|
||||
'nav-privacy': 'section-privacy'
|
||||
};
|
||||
|
||||
// Alle Abschnitte ausblenden außer dem ersten
|
||||
Object.values(navButtons).forEach(sectionId => {
|
||||
if (sectionId !== 'section-account') {
|
||||
document.getElementById(sectionId).classList.add('hidden');
|
||||
}
|
||||
});
|
||||
|
||||
// Klick-Handler für Navigation
|
||||
for (const [navId, sectionId] of Object.entries(navButtons)) {
|
||||
document.getElementById(navId).addEventListener('click', function() {
|
||||
// Alle Abschnitte ausblenden
|
||||
Object.values(navButtons).forEach(id => {
|
||||
document.getElementById(id).classList.add('hidden');
|
||||
});
|
||||
|
||||
// Ausgewählten Abschnitt anzeigen
|
||||
document.getElementById(sectionId).classList.remove('hidden');
|
||||
|
||||
// Aktiven Navigations-Button hervorheben, andere zurücksetzen
|
||||
for (const btnId of Object.keys(navButtons)) {
|
||||
const btn = document.getElementById(btnId);
|
||||
if (btnId === navId) {
|
||||
btn.classList.add('text-purple-300', 'bg-purple-900/20', 'border-l-2', 'border-purple-500');
|
||||
btn.classList.remove('text-gray-300', 'hover:bg-white/5');
|
||||
} else {
|
||||
btn.classList.remove('text-purple-300', 'bg-purple-900/20', 'border-l-2', 'border-purple-500');
|
||||
btn.classList.add('text-gray-300', 'hover:bg-white/5');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Dark Mode Toggle aktualisieren
|
||||
function updateDarkModeToggle() {
|
||||
const isDarkMode = document.documentElement.classList.contains('dark');
|
||||
const indicator = document.getElementById('dark-mode-indicator');
|
||||
|
||||
if (indicator) {
|
||||
if (isDarkMode) {
|
||||
indicator.classList.add('translate-x-7');
|
||||
indicator.classList.remove('translate-x-0');
|
||||
} else {
|
||||
indicator.classList.add('translate-x-0');
|
||||
indicator.classList.remove('translate-x-7');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
updateDarkModeToggle();
|
||||
|
||||
// Globale Funktion für Toggle-Button
|
||||
window.toggleDarkMode = function() {
|
||||
if (typeof MindMap !== 'undefined' && typeof MindMap.toggleDarkMode === 'function') {
|
||||
MindMap.toggleDarkMode();
|
||||
} else {
|
||||
document.documentElement.classList.toggle('dark');
|
||||
}
|
||||
updateDarkModeToggle();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
79
templates/ueber_uns.html
Normal file
79
templates/ueber_uns.html
Normal file
@@ -0,0 +1,79 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}Über uns{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="max-w-3xl mx-auto">
|
||||
<div class="card p-6 md:p-8">
|
||||
<h1 class="text-3xl font-bold mb-6 gradient-text">Über uns</h1>
|
||||
|
||||
<section class="mb-8">
|
||||
<h2 class="text-xl font-bold mb-4">Unsere Vision</h2>
|
||||
<p class="mb-4">
|
||||
Systades ist ein innovatives Projekt, das darauf abzielt, das Teilen und Vernetzen von Wissen und Gedanken zu revolutionieren. Unsere Plattform ermöglicht es Nutzern, ihre Ideen in interaktiven Mindmaps zu organisieren und mit anderen zu teilen, wodurch ein kollaboratives Netzwerk des Wissens entsteht.
|
||||
</p>
|
||||
<p class="mb-4">
|
||||
Wir glauben daran, dass Wissen am wertvollsten ist, wenn es geteilt und vernetzt wird. Durch die Verbindung verschiedener Perspektiven und Denkansätze entstehen neue Erkenntnisse und Innovationen.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section class="mb-8">
|
||||
<h2 class="text-xl font-bold mb-4">Das Team</h2>
|
||||
<p class="mb-4">
|
||||
Till Tomczak und Marwin Medczinski arbeiten gemeinsam daran, Systades kontinuierlich zu verbessern und weiterzuentwickeln.
|
||||
</p>
|
||||
|
||||
<!-- Platz für Team-Mitglieder -->
|
||||
<div class="team-members space-y-6">
|
||||
<!-- Beispiel für ein Team-Mitglied (kann als Vorlage verwendet werden) -->
|
||||
<!--
|
||||
<div class="team-member p-4 border border-gray-200 dark:border-gray-700 rounded-lg">
|
||||
<h3 class="text-lg font-bold mb-2">[Name]</h3>
|
||||
<p class="text-gray-600 dark:text-gray-300 mb-2">[Position/Rolle]</p>
|
||||
<p class="text-sm">[Kurze Beschreibung oder Verantwortlichkeiten]</p>
|
||||
</div>
|
||||
-->
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="mb-8">
|
||||
<h2 class="text-xl font-bold mb-4">Unsere Mission</h2>
|
||||
<p class="mb-4">
|
||||
Wir setzen uns dafür ein, eine Plattform zu schaffen, die:
|
||||
</p>
|
||||
<ul class="list-disc list-inside space-y-2 mb-4">
|
||||
<li>Intuitive Werkzeuge für die Organisation und Visualisierung von Wissen bereitstellt</li>
|
||||
<li>Die Zusammenarbeit und den Austausch zwischen Nutzern fördert</li>
|
||||
<li>Kreativität und innovative Denkansätze unterstützt</li>
|
||||
<li>Einen sicheren und respektvollen Raum für intellektuellen Austausch bietet</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section class="mb-8">
|
||||
<h2 class="text-xl font-bold mb-4">Technologie & Innovation</h2>
|
||||
<p class="mb-4">
|
||||
Systades nutzt modernste Technologien und innovative Ansätze, um eine optimale Nutzererfahrung zu gewährleisten. Unsere Plattform wird kontinuierlich weiterentwickelt, um neue Funktionen und Verbesserungen zu integrieren.
|
||||
</p>
|
||||
<p>
|
||||
Wir legen besonderen Wert auf:
|
||||
</p>
|
||||
<ul class="list-disc list-inside space-y-2 mt-2">
|
||||
<li>Intuitive Benutzeroberfläche</li>
|
||||
<li>Hohe Performance und Zuverlässigkeit</li>
|
||||
<li>Datensicherheit und Privatsphäre</li>
|
||||
<li>Barrierefreiheit und Inklusivität</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2 class="text-xl font-bold mb-4">Kontakt & Feedback</h2>
|
||||
<p class="mb-4">
|
||||
Wir freuen uns über Ihr Feedback und Ihre Ideen zur Verbesserung von Systades. Gemeinsam können wir die Plattform weiter optimieren und an die Bedürfnisse unserer Nutzer anpassen.
|
||||
</p>
|
||||
<p>
|
||||
Kontaktieren Sie uns gerne für Fragen, Anregungen oder Kooperationsmöglichkeiten.
|
||||
</p>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user