Compare commits
3 Commits
10747a8336
...
e5f485d9d7
| Author | SHA1 | Date | |
|---|---|---|---|
| e5f485d9d7 | |||
| cf3fc09a63 | |||
| 7eb958f3c8 |
113
COMMON_ERRORS.md
113
COMMON_ERRORS.md
@@ -3,15 +3,20 @@
|
|||||||
- Implementierung von Content Security Policy (CSP) - UNTER KEINEN UMSTÄNDEN!
|
- Implementierung von Content Security Policy (CSP) - UNTER KEINEN UMSTÄNDEN!
|
||||||
- Implementierung von Cross-Site Request Forgery (CSRF) Schutz
|
- Implementierung von Cross-Site Request Forgery (CSRF) Schutz
|
||||||
- Implementierung von Security Headers
|
- Implementierung von Security Headers
|
||||||
|
- Verwendung von TypeScript anstelle von JavaScript
|
||||||
|
- Implementierung von OAuth oder anderen externen Authentifizierungsmethoden
|
||||||
|
|
||||||
# HÄUFIGE FEHLER:
|
# HÄUFIGE FEHLER:
|
||||||
- Verwendung der falschen Datenbank (die korrekte ist: database/systades.db)
|
- Verwendung der falschen Datenbank (die korrekte ist: database/systades.db)
|
||||||
- Falsche Pfadangaben bei statischen Dateien
|
- Falsche Pfadangaben bei statischen Dateien
|
||||||
- Vergessen der deutschen Spracheinstellungen in Templates
|
- Vergessen der deutschen Spracheinstellungen in Templates
|
||||||
- Nicht beachten der vorhandenen Projektstruktur
|
- Nicht beachten der vorhandenen Projektstruktur
|
||||||
|
- Falsche Einbindung der Neural Network Background Animation
|
||||||
|
- Verwendung von englischen Variablennamen in deutschen Funktionen
|
||||||
|
- Vergessen der Mindmap-Datenstruktur gemäß der Roadmap
|
||||||
|
|
||||||
# Häufige Fehler und Lösungen
|
# Häufige Fehler und Lösungen
|
||||||
|
D
|
||||||
## Content Security Policy (CSP)
|
## Content Security Policy (CSP)
|
||||||
|
|
||||||
### Problem: Externe Ressourcen werden nicht geladen
|
### Problem: Externe Ressourcen werden nicht geladen
|
||||||
@@ -29,6 +34,35 @@
|
|||||||
```html
|
```html
|
||||||
<link href="{{ url_for('static', filename='css/tailwind.min.css') }}" rel="stylesheet">
|
<link href="{{ url_for('static', filename='css/tailwind.min.css') }}" rel="stylesheet">
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Problem: CSP-Fehler (script-src-elem 'none', font-src 'none', etc.)
|
||||||
|
**Fehler:** Skripte werden aufgrund von CSP-Einschränkungen blockiert.
|
||||||
|
|
||||||
|
**Lösung:**
|
||||||
|
1. WICHTIG: CSP-Einschränkungen NICHT implementieren! Diese sind im Projekt unerwünscht.
|
||||||
|
|
||||||
|
2. Falls CSP-Header bereits vorhanden sind, entfernen Sie diese aus der Anwendung:
|
||||||
|
```python
|
||||||
|
# Entfernen Sie diesen Code, falls vorhanden:
|
||||||
|
# @app.after_request
|
||||||
|
# def add_security_headers(response):
|
||||||
|
# response.headers['Content-Security-Policy'] = '...'
|
||||||
|
# return response
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Stellen Sie sicher, dass externe Ressourcen direkt geladen werden:
|
||||||
|
```html
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
|
||||||
|
<script src="{{ url_for('static', filename='js/alpine.min.js') }}" defer></script>
|
||||||
|
```
|
||||||
|
|
||||||
|
4. Für Inline-Skripte keine Nonce verwenden:
|
||||||
|
```html
|
||||||
|
<script>
|
||||||
|
// Inline-JavaScript-Code ohne Einschränkungen
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
### Problem: Tailwind CSS CDN wird blockiert
|
### Problem: Tailwind CSS CDN wird blockiert
|
||||||
**Fehler:** Tailwind CSS kann nicht von CDN geladen werden.
|
**Fehler:** Tailwind CSS kann nicht von CDN geladen werden.
|
||||||
|
|
||||||
@@ -61,4 +95,79 @@
|
|||||||
|
|
||||||
**Lösung:**
|
**Lösung:**
|
||||||
1. Standard-Admin-Benutzer erstellen: `python TOOLS.py user:admin`
|
1. Standard-Admin-Benutzer erstellen: `python TOOLS.py user:admin`
|
||||||
2. Passwort zurücksetzen: `python TOOLS.py user:reset-pw -u USERNAME -p NEWPASSWORD`
|
2. Passwort zurücksetzen: `python TOOLS.py user:reset-pw -u USERNAME -p NEWPASSWORD`
|
||||||
|
|
||||||
|
## Neural Network Background
|
||||||
|
|
||||||
|
### Problem: Hintergrund-Animation wird nicht angezeigt
|
||||||
|
**Fehler:** Die Neural Network Animation im Hintergrund erscheint nicht.
|
||||||
|
|
||||||
|
**Lösung:**
|
||||||
|
1. Überprüfen Sie, ob die Datei `static/neural-network-background.js` korrekt eingebunden ist:
|
||||||
|
```html
|
||||||
|
<script src="{{ url_for('static', filename='neural-network-background.js') }}"></script>
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Initialisieren Sie die Animation im Template:
|
||||||
|
```html
|
||||||
|
<script>
|
||||||
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
const background = new NeuralNetworkBackground();
|
||||||
|
background.initialize();
|
||||||
|
background.animate();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Stellen Sie sicher, dass keine CSS-Regeln die Animation überdecken:
|
||||||
|
```css
|
||||||
|
#neural-network-background {
|
||||||
|
z-index: -10;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Mindmap-Funktionalität
|
||||||
|
|
||||||
|
### Problem: Mindmap-Daten werden nicht geladen
|
||||||
|
**Fehler:** Die dynamische Mindmap zeigt keine Daten an.
|
||||||
|
|
||||||
|
**Lösung:**
|
||||||
|
1. Überprüfen Sie die API-Endpunkte für die Mindmap-Daten:
|
||||||
|
```python
|
||||||
|
@app.route('/api/mindmap/nodes', methods=['GET'])
|
||||||
|
def get_mindmap_nodes():
|
||||||
|
# Implementierung...
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Stellen Sie sicher, dass die AJAX-Anfragen korrekt implementiert sind:
|
||||||
|
```javascript
|
||||||
|
fetch('/api/mindmap/nodes')
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
// Verarbeitung der Mindmap-Daten
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Überprüfen Sie die Datenbankeinträge für Mindmap-Knoten und -Verbindungen.
|
||||||
|
|
||||||
|
## ChatGPT-Assistent
|
||||||
|
|
||||||
|
### Problem: Assistent reagiert nicht auf Eingaben
|
||||||
|
**Fehler:** Der ChatGPT-Assistent verarbeitet keine Benutzereingaben.
|
||||||
|
|
||||||
|
**Lösung:**
|
||||||
|
1. Überprüfen Sie die Einbindung der JavaScript-Datei:
|
||||||
|
```html
|
||||||
|
<script src="{{ url_for('static', filename='js/modules/chatgpt-assistant.js') }}"></script>
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Stellen Sie sicher, dass der Assistent korrekt initialisiert wird:
|
||||||
|
```javascript
|
||||||
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
const assistant = new ChatGPTAssistant();
|
||||||
|
assistant.initialize();
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Überprüfen Sie die API-Endpunkte für die Kommunikation mit dem Assistenten.
|
||||||
Binary file not shown.
2
app.py
2
app.py
@@ -73,7 +73,7 @@ def inject_globals():
|
|||||||
'current_year': datetime.now().year
|
'current_year': datetime.now().year
|
||||||
}
|
}
|
||||||
|
|
||||||
# Kontext-Prozessor für alle Templates
|
# Context-Prozessor für alle Templates
|
||||||
@app.context_processor
|
@app.context_processor
|
||||||
def inject_current_year():
|
def inject_current_year():
|
||||||
return {'current_year': datetime.now().year}
|
return {'current_year': datetime.now().year}
|
||||||
|
|||||||
20
static/css/tailwind.min.css
vendored
20
static/css/tailwind.min.css
vendored
@@ -1,16 +1,6 @@
|
|||||||
/*
|
/**
|
||||||
* Tailwind CSS v3.4.16
|
* Failed to bundle using Rollup v2.79.2: the file imports a not supported node.js built-in module "fs".
|
||||||
*
|
* If you believe this to be an issue with jsDelivr, and not with the package itself, please open an issue at https://github.com/jsdelivr/jsdelivr
|
||||||
* This is a placeholder file. For production, you should:
|
|
||||||
* 1. Install Tailwind CSS as a PostCSS plugin: https://tailwindcss.com/docs/installation
|
|
||||||
* 2. Run the Tailwind CLI to compile this file with your custom configuration
|
|
||||||
* 3. Replace this file with the compiled CSS
|
|
||||||
*
|
|
||||||
* The actual file should be generated using:
|
|
||||||
* npx tailwindcss -i ./src/input.css -o ./static/css/tailwind.min.css --minify
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Base Tailwind imports */
|
throw new Error('Failed to bundle using Rollup v2.79.2: the file imports a not supported node.js built-in module "fs". If you believe this to be an issue with jsDelivr, and not with the package itself, please open an issue at https://github.com/jsdelivr/jsdelivr');
|
||||||
@tailwind base;
|
|
||||||
@tailwind components;
|
|
||||||
@tailwind utilities;
|
|
||||||
15
static/js/alpine.min.js
vendored
15
static/js/alpine.min.js
vendored
File diff suppressed because one or more lines are too long
@@ -2,9 +2,6 @@
|
|||||||
* MindMap - Hauptdatei für globale JavaScript-Funktionen
|
* MindMap - Hauptdatei für globale JavaScript-Funktionen
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Import des ChatGPT-Assistenten
|
|
||||||
import ChatGPTAssistant from './modules/chatgpt-assistant.js';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hauptmodul für die MindMap-Anwendung
|
* Hauptmodul für die MindMap-Anwendung
|
||||||
* Verwaltet die globale Anwendungslogik
|
* Verwaltet die globale Anwendungslogik
|
||||||
@@ -38,10 +35,12 @@ const MindMap = {
|
|||||||
console.log('MindMap-Anwendung wird initialisiert...');
|
console.log('MindMap-Anwendung wird initialisiert...');
|
||||||
|
|
||||||
// Initialisiere den ChatGPT-Assistenten
|
// Initialisiere den ChatGPT-Assistenten
|
||||||
const assistant = new ChatGPTAssistant();
|
if (typeof ChatGPTAssistant !== 'undefined') {
|
||||||
assistant.init();
|
const assistant = new ChatGPTAssistant();
|
||||||
// Speichere als Teil von MindMap
|
assistant.init();
|
||||||
this.assistant = assistant;
|
// Speichere als Teil von MindMap
|
||||||
|
this.assistant = assistant;
|
||||||
|
}
|
||||||
|
|
||||||
// Seiten-spezifische Initialisierer aufrufen
|
// Seiten-spezifische Initialisierer aufrufen
|
||||||
if (this.currentPage && this.pageInitializers[this.currentPage]) {
|
if (this.currentPage && this.pageInitializers[this.currentPage]) {
|
||||||
@@ -74,6 +73,12 @@ const MindMap = {
|
|||||||
try {
|
try {
|
||||||
console.log('Initialisiere Mindmap...');
|
console.log('Initialisiere Mindmap...');
|
||||||
|
|
||||||
|
// Prüfe, ob MindMapVisualization geladen ist
|
||||||
|
if (typeof MindMapVisualization === 'undefined') {
|
||||||
|
console.error('MindMapVisualization-Klasse ist nicht definiert!');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Initialisiere die Mindmap
|
// Initialisiere die Mindmap
|
||||||
const mindmap = new MindMapVisualization('#mindmap-container', {
|
const mindmap = new MindMapVisualization('#mindmap-container', {
|
||||||
height: mindmapContainer.clientHeight || 600,
|
height: mindmapContainer.clientHeight || 600,
|
||||||
@@ -226,7 +231,4 @@ const MindMap = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Globale Export für andere Module
|
// Globale Export für andere Module
|
||||||
window.MindMap = MindMap;
|
window.MindMap = MindMap;
|
||||||
|
|
||||||
// Export als Modul
|
|
||||||
export default MindMap;
|
|
||||||
@@ -568,5 +568,5 @@ class ChatGPTAssistant {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Exportiere die Klasse für die Verwendung in anderen Modulen
|
// Mache die Klasse global verfügbar
|
||||||
export default ChatGPTAssistant;
|
window.ChatGPTAssistant = ChatGPTAssistant;
|
||||||
@@ -3,12 +3,18 @@
|
|||||||
* Spezifische Funktionen für die Mindmap-Seite
|
* Spezifische Funktionen für die Mindmap-Seite
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// Füge das Modul zum globalen MindMap-Objekt hinzu
|
||||||
|
if (!window.MindMap) {
|
||||||
|
window.MindMap = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Registriere den Initialisierer im MindMap-Objekt
|
||||||
|
if (window.MindMap) {
|
||||||
|
window.MindMap.pageInitializers = window.MindMap.pageInitializers || {};
|
||||||
|
window.MindMap.pageInitializers.mindmap = initMindmapPage;
|
||||||
|
}
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
// Registriere den Initialisierer im MindMap-Objekt
|
|
||||||
if (window.MindMap) {
|
|
||||||
window.MindMap.pageInitializers.mindmap = initMindmapPage;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Prüfe, ob wir auf der Mindmap-Seite sind und initialisiere
|
// Prüfe, ob wir auf der Mindmap-Seite sind und initialisiere
|
||||||
if (document.body.dataset.page === 'mindmap') {
|
if (document.body.dataset.page === 'mindmap') {
|
||||||
initMindmapPage();
|
initMindmapPage();
|
||||||
@@ -461,13 +467,13 @@ function initMindmapPage() {
|
|||||||
|
|
||||||
// Erfolgsbenachrichtigung
|
// Erfolgsbenachrichtigung
|
||||||
if (window.MindMap && window.MindMap.showNotification) {
|
if (window.MindMap && window.MindMap.showNotification) {
|
||||||
MindMap.showNotification('Gedanke erfolgreich gespeichert.', 'success');
|
window.MindMap.showNotification('Gedanke erfolgreich gespeichert.', 'success');
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Fehler beim Speichern:', error);
|
console.error('Fehler beim Speichern:', error);
|
||||||
if (window.MindMap && window.MindMap.showNotification) {
|
if (window.MindMap && window.MindMap.showNotification) {
|
||||||
MindMap.showNotification('Fehler beim Speichern des Gedankens.', 'error');
|
window.MindMap.showNotification('Fehler beim Speichern des Gedankens.', 'error');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -483,7 +489,7 @@ function initMindmapPage() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Zeigt die Kommentare zu einem Gedanken an
|
* Füge globale Funktionen für das Mindmap-Objekt hinzu
|
||||||
*/
|
*/
|
||||||
window.showComments = async function(thoughtId) {
|
window.showComments = async function(thoughtId) {
|
||||||
try {
|
try {
|
||||||
@@ -505,7 +511,11 @@ window.showComments = async function(thoughtId) {
|
|||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Fehler beim Laden der Kommentare:', error);
|
console.error('Fehler beim Laden der Kommentare:', error);
|
||||||
MindMap.showNotification('Fehler beim Laden der Kommentare.', 'error');
|
if (window.MindMap && window.MindMap.showNotification) {
|
||||||
|
window.MindMap.showNotification('Fehler beim Laden der Kommentare.', 'error');
|
||||||
|
} else {
|
||||||
|
alert('Fehler beim Laden der Kommentare.');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -532,7 +542,11 @@ window.showRelations = async function(thoughtId) {
|
|||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Fehler beim Laden der Beziehungen:', error);
|
console.error('Fehler beim Laden der Beziehungen:', error);
|
||||||
MindMap.showNotification('Fehler beim Laden der Beziehungen.', 'error');
|
if (window.MindMap && window.MindMap.showNotification) {
|
||||||
|
window.MindMap.showNotification('Fehler beim Laden der Beziehungen.', 'error');
|
||||||
|
} else {
|
||||||
|
alert('Fehler beim Laden der Beziehungen.');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -14,9 +14,11 @@
|
|||||||
<meta name="keywords" content="systades, wissen, visualisierung, lernen, gedanken, theorie">
|
<meta name="keywords" content="systades, wissen, visualisierung, lernen, gedanken, theorie">
|
||||||
<meta name="author" content="Systades-Team">
|
<meta name="author" content="Systades-Team">
|
||||||
|
|
||||||
<!-- Tailwind CSS - CDN Version -->
|
<!-- Tailwind CSS - Beide Optionen verfügbar -->
|
||||||
<script src="https://cdn.tailwindcss.com" nonce="{{ csp_nonce }}"></script>
|
<script src="https://cdn.tailwindcss.com"></script>
|
||||||
<script nonce="{{ csp_nonce }}">
|
<!-- Alternative lokale Version, falls die CDN-Version blockiert wird -->
|
||||||
|
<link href="{{ url_for('static', filename='css/tailwind.min.css') }}" rel="stylesheet">
|
||||||
|
<script>
|
||||||
tailwind.config = {
|
tailwind.config = {
|
||||||
darkMode: 'class',
|
darkMode: 'class',
|
||||||
theme: {
|
theme: {
|
||||||
@@ -79,88 +81,32 @@
|
|||||||
<!-- Base-Styles ausgelagert in eigene Datei -->
|
<!-- Base-Styles ausgelagert in eigene Datei -->
|
||||||
<link href="{{ url_for('static', filename='css/base-styles.css') }}" rel="stylesheet">
|
<link href="{{ url_for('static', filename='css/base-styles.css') }}" rel="stylesheet">
|
||||||
|
|
||||||
<!-- Alpine.js - Self-hosted -->
|
<!-- Alpine.js - CDN Version -->
|
||||||
<script src="{{ url_for('static', filename='js/alpine.min.js') }}" defer nonce="{{ csp_nonce }}"></script>
|
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.12.3/dist/cdn.min.js"></script>
|
||||||
|
|
||||||
<!-- Neural Network Background CSS -->
|
<!-- Neural Network Background CSS -->
|
||||||
<link href="{{ url_for('static', filename='css/neural-network-background.css') }}" rel="stylesheet">
|
<link href="{{ url_for('static', filename='css/neural-network-background.css') }}" rel="stylesheet">
|
||||||
|
|
||||||
<!-- Neural Network Background Script -->
|
<!-- D3.js für Visualisierungen -->
|
||||||
<script src="{{ url_for('static', filename='neural-network-background.js') }}" nonce="{{ csp_nonce }}"></script>
|
<script src="https://d3js.org/d3.v7.min.js"></script>
|
||||||
|
|
||||||
<!-- Hauptmodul laden (als ES6 Modul) -->
|
<!-- Marked.js für Markdown-Parsing -->
|
||||||
<script type="module" nonce="{{ csp_nonce }}">
|
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
|
||||||
import MindMap from "{{ url_for('static', filename='js/main.js') }}";
|
|
||||||
// Alpine.js-Integration
|
<!-- ChatGPT Assistant -->
|
||||||
document.addEventListener('alpine:init', () => {
|
<script src="{{ url_for('static', filename='js/modules/chatgpt-assistant.js') }}"></script>
|
||||||
Alpine.data('layout', () => ({
|
|
||||||
darkMode: true, // Default to dark mode
|
<!-- MindMap Visualization Module -->
|
||||||
mobileMenuOpen: false, // Mobile Menü standardmäßig geschlossen
|
<script src="{{ url_for('static', filename='js/modules/mindmap.js') }}"></script>
|
||||||
userMenuOpen: false,
|
|
||||||
showSettingsModal: false,
|
<!-- MindMap Page Module -->
|
||||||
|
<script src="{{ url_for('static', filename='js/modules/mindmap-page.js') }}"></script>
|
||||||
init() {
|
|
||||||
this.fetchDarkModeFromSession();
|
<!-- Neural Network Background Script -->
|
||||||
},
|
<script src="{{ url_for('static', filename='neural-network-background.js') }}"></script>
|
||||||
|
|
||||||
fetchDarkModeFromSession() {
|
<!-- Hauptmodul laden (als traditionelles Skript) -->
|
||||||
// Lade den Dark Mode-Status vom Server
|
<script src="{{ url_for('static', filename='js/main.js') }}"></script>
|
||||||
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);
|
|
||||||
|
|
||||||
// Speichere den Dark Mode-Status auf dem Server
|
|
||||||
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) {
|
|
||||||
// Zusätzlich im localStorage speichern für sofortige Reaktion bei Seitenwechsel
|
|
||||||
localStorage.setItem('darkMode', this.darkMode ? 'dark' : 'light');
|
|
||||||
// Event auslösen für andere Komponenten
|
|
||||||
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);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
});
|
|
||||||
|
|
||||||
// Setze einen globalen Alpine-Initialisierer
|
|
||||||
window.addEventListener('DOMContentLoaded', () => {
|
|
||||||
// Fallback für Alpine-Initialisierung
|
|
||||||
if (typeof Alpine !== 'undefined' && !document.body.hasAttribute('x-data')) {
|
|
||||||
document.body.setAttribute('x-data', 'layout()');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// MindMap global verfügbar machen (für Alpine.js und andere nicht-Module Skripte)
|
|
||||||
window.MindMap = MindMap;
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<!-- Seitenspezifische Styles -->
|
<!-- Seitenspezifische Styles -->
|
||||||
{% block extra_css %}{% endblock %}
|
{% block extra_css %}{% endblock %}
|
||||||
@@ -243,7 +189,57 @@
|
|||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body data-page="{{ request.endpoint }}" class="relative overflow-x-hidden dark bg-gray-900 text-white" x-data="layout()">
|
<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 -->
|
<!-- App-Container -->
|
||||||
<div id="app-container" class="flex flex-col min-h-screen">
|
<div id="app-container" class="flex flex-col min-h-screen">
|
||||||
<!-- Hauptnavigation -->
|
<!-- Hauptnavigation -->
|
||||||
@@ -597,11 +593,9 @@
|
|||||||
{% block scripts %}{% endblock %}
|
{% block scripts %}{% endblock %}
|
||||||
|
|
||||||
<!-- KI-Chat Initialisierung -->
|
<!-- KI-Chat Initialisierung -->
|
||||||
<script type="module" nonce="{{ csp_nonce }}">
|
<script>
|
||||||
// Importiere und initialisiere den ChatGPT-Assistenten direkt, um sicherzustellen,
|
// Initialisiere den ChatGPT-Assistenten direkt, um sicherzustellen,
|
||||||
// dass er auf jeder Seite verfügbar ist, selbst wenn MindMap nicht geladen ist
|
// dass er auf jeder Seite verfügbar ist, selbst wenn MindMap nicht geladen ist
|
||||||
import ChatGPTAssistant from "{{ url_for('static', filename='js/modules/chatgpt-assistant.js') }}";
|
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
// Prüfen, ob der Assistent bereits durch MindMap initialisiert wurde
|
// Prüfen, ob der Assistent bereits durch MindMap initialisiert wurde
|
||||||
if (!window.MindMap || !window.MindMap.assistant) {
|
if (!window.MindMap || !window.MindMap.assistant) {
|
||||||
|
|||||||
@@ -391,7 +391,7 @@
|
|||||||
<div id="mindmap-canvas"></div>
|
<div id="mindmap-canvas"></div>
|
||||||
|
|
||||||
<!-- Control Panel -->
|
<!-- Control Panel -->
|
||||||
<div class="control-panel p-4 w-64" id="control-panel" x-data="{ isExpanded: true }">
|
<div class="control-panel p-4 w-64">
|
||||||
<div class="panel-toggle" @click="isExpanded = !isExpanded">
|
<div class="panel-toggle" @click="isExpanded = !isExpanded">
|
||||||
<i class="fa-solid" :class="isExpanded ? 'fa-chevron-left' : 'fa-chevron-right'"></i>
|
<i class="fa-solid" :class="isExpanded ? 'fa-chevron-left' : 'fa-chevron-right'"></i>
|
||||||
</div>
|
</div>
|
||||||
@@ -432,7 +432,7 @@
|
|||||||
|
|
||||||
<!-- User Mindmaps Section -->
|
<!-- User Mindmaps Section -->
|
||||||
{% if current_user.is_authenticated %}
|
{% if current_user.is_authenticated %}
|
||||||
<div class="user-mindmap-section p-4 w-64" x-data="{ isExpanded: true }">
|
<div class="user-mindmap-section p-4 w-64">
|
||||||
<div class="flex items-center justify-between mb-4">
|
<div class="flex items-center justify-between mb-4">
|
||||||
<h2 class="text-lg font-semibold text-gray-900 dark:text-white">Meine Mindmaps</h2>
|
<h2 class="text-lg font-semibold text-gray-900 dark:text-white">Meine Mindmaps</h2>
|
||||||
<button @click="isExpanded = !isExpanded" class="text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-200">
|
<button @click="isExpanded = !isExpanded" class="text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-200">
|
||||||
|
|||||||
Reference in New Issue
Block a user