feat: update environment config and add community preview template

This commit is contained in:
2025-05-02 08:01:23 +01:00
parent 613c38ccb2
commit 4c3e476338
5 changed files with 188 additions and 21 deletions

1
.env
View File

@@ -4,6 +4,7 @@
# Flask
FLASK_APP=app.py
FLASK_ENV=development
FLASK_DEBUG=1
SECRET_KEY=your-secret-key-replace-in-production
# OpenAI API

Binary file not shown.

57
app.py
View File

@@ -1477,20 +1477,49 @@ def refresh_mindmap():
'error': 'Datenbankverbindung konnte nicht hergestellt werden'
}), 500
# Route zur Mindmap HTML-Seite
@app.route('/mindmap')
def mindmap_page():
return render_template('mindmap.html')
# Community-Forum-Routen
# Weiterleitung für Groß-/Kleinschreibung
@app.route('/Community')
def Community():
# Direkte Umleitung ohne url_for zu verwenden, um Kreisverweise zu vermeiden
return redirect('/')
# Vermeidung der direkten Community-Route, die Probleme verursacht
@app.route('/community')
@login_required
def community():
"""Hauptseite des Community-Forums"""
forum_categories = ForumCategory.query.filter_by(is_active=True).all()
"""Vermeidet direkten Zugriff auf Community-Forum"""
return redirect('/')
# Alternative Route für Community-Forum, die über das Menü erreichbar ist
@app.route('/forum')
def forum():
"""Alternative Route zum Community-Forum"""
if not current_user.is_authenticated:
# Wenn Benutzer nicht angemeldet ist, zeige eine Vorschauversion
forum_categories = ForumCategory.query.filter_by(is_active=True).limit(5).all()
categories_data = []
for category in forum_categories:
total_posts = ForumPost.query.filter_by(category_id=category.id, parent_id=None).count()
total_replies = ForumPost.query.filter(
ForumPost.category_id == category.id,
ForumPost.parent_id != None
).count()
categories_data.append({
'category': category,
'total_posts': total_posts,
'total_replies': total_replies,
'latest_post': None
})
return render_template('community/preview.html', categories_data=categories_data)
# Statistiken für jede Kategorie berechnen
# Angemeldete Benutzer bekommen die vollständige Version
forum_categories = ForumCategory.query.filter_by(is_active=True).all()
categories_data = []
for category in forum_categories:
total_posts = ForumPost.query.filter_by(category_id=category.id, parent_id=None).count()
@@ -1510,7 +1539,7 @@ def community():
return render_template('community/index.html', categories_data=categories_data)
@app.route('/community/category/<int:category_id>')
@app.route('/forum/category/<int:category_id>')
@login_required
def forum_category(category_id):
"""Zeigt alle Themen in einer bestimmten Kategorie an"""
@@ -1540,7 +1569,7 @@ def forum_category(category_id):
threads_data=threads_data,
node=category.node)
@app.route('/community/post/<int:post_id>')
@app.route('/forum/post/<int:post_id>')
@login_required
def forum_post(post_id):
"""Zeigt einen Beitrag und alle seine Antworten an"""
@@ -1563,7 +1592,7 @@ def forum_post(post_id):
replies=replies,
category=post.category)
@app.route('/community/new-post/<int:category_id>', methods=['GET', 'POST'])
@app.route('/forum/new-post/<int:category_id>', methods=['GET', 'POST'])
@login_required
def new_post(category_id):
"""Erstellt einen neuen Beitrag in einer Kategorie"""
@@ -1592,7 +1621,7 @@ def new_post(category_id):
return render_template('community/new_post.html', category=category)
@app.route('/community/reply/<int:post_id>', methods=['POST'])
@app.route('/forum/reply/<int:post_id>', methods=['POST'])
@login_required
def reply_to_post(post_id):
"""Antwortet auf einen bestehenden Beitrag"""
@@ -1623,7 +1652,7 @@ def reply_to_post(post_id):
flash('Deine Antwort wurde erfolgreich hinzugefügt.', 'success')
return redirect(url_for('forum_post', post_id=post_id))
@app.route('/community/edit-post/<int:post_id>', methods=['GET', 'POST'])
@app.route('/forum/edit-post/<int:post_id>', methods=['GET', 'POST'])
@login_required
def edit_post(post_id):
"""Bearbeitet einen bestehenden Beitrag"""
@@ -1653,7 +1682,7 @@ def edit_post(post_id):
return render_template('community/edit_post.html', post=post)
@app.route('/community/delete-post/<int:post_id>', methods=['POST'])
@app.route('/forum/delete-post/<int:post_id>', methods=['POST'])
@login_required
def delete_post(post_id):
"""Löscht einen Beitrag"""
@@ -1680,7 +1709,7 @@ def delete_post(post_id):
flash('Der Beitrag wurde erfolgreich gelöscht.', 'success')
return redirect(redirect_url)
@app.route('/community/toggle-pin/<int:post_id>', methods=['POST'])
@app.route('/forum/toggle-pin/<int:post_id>', methods=['POST'])
@login_required
def toggle_pin_post(post_id):
"""Fixiert oder löst einen Beitrag von der Fixierung"""
@@ -1704,7 +1733,7 @@ def toggle_pin_post(post_id):
flash(f'Der Beitrag ist jetzt {status}.', 'success')
return redirect(url_for('forum_post', post_id=post_id))
@app.route('/community/toggle-lock/<int:post_id>', methods=['POST'])
@app.route('/forum/toggle-lock/<int:post_id>', methods=['POST'])
@login_required
def toggle_lock_post(post_id):
"""Sperrt oder entsperrt einen Beitrag für weitere Antworten"""

View File

@@ -278,11 +278,11 @@
: '{{ '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('community') }}"
<a href="{{ url_for('forum') }}"
class="nav-link flex items-center"
x-bind:class="darkMode
? '{{ 'nav-link-active' if request.endpoint == 'community' else '' }}'
: '{{ 'nav-link-light-active' if request.endpoint == 'community' else 'nav-link-light' }}'">
? '{{ 'nav-link-active' if request.endpoint == 'forum' else '' }}'
: '{{ 'nav-link-light-active' if request.endpoint == 'forum' else 'nav-link-light' }}'">
<i class="fa-solid fa-users mr-2"></i>Community
</a>
<a href="{{ url_for('search_thoughts_page') }}"
@@ -456,11 +456,11 @@
: '{{ '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('community') }}"
<a href="{{ url_for('forum') }}"
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 == 'community' else 'text-white/80 hover:bg-gray-800/80 hover:text-white' }}'
: '{{ 'bg-purple-500/10 text-gray-900' if request.endpoint == 'community' else 'text-gray-700 hover:bg-gray-100 hover:text-gray-900' }}'">
? '{{ 'bg-purple-500/20 text-white' if request.endpoint == 'forum' else 'text-white/80 hover:bg-gray-800/80 hover:text-white' }}'
: '{{ 'bg-purple-500/10 text-gray-900' if request.endpoint == 'forum' else 'text-gray-700 hover:bg-gray-100 hover:text-gray-900' }}'">
<i class="fa-solid fa-users w-5 mr-3"></i>Community
</a>
<a href="{{ url_for('search_thoughts_page') }}"
@@ -541,7 +541,7 @@
:class="darkMode ? 'text-gray-300 hover:text-white' : 'text-gray-600 hover:text-gray-900'">
Mindmap
</a>
<a href="{{ url_for('community') }}" class="text-sm transition-all duration-200"
<a href="{{ url_for('forum') }}" class="text-sm transition-all duration-200"
:class="darkMode ? 'text-gray-300 hover:text-white' : 'text-gray-600 hover:text-gray-900'">
Community
</a>

View File

@@ -0,0 +1,137 @@
{% extends 'base.html' %}
{% block title %}Community Forum Vorschau{% endblock %}
{% block extra_css %}
<style>
.forum-category {
transition: all 0.3s ease;
}
.forum-category:hover {
transform: translateY(-2px);
}
.category-icon {
font-size: 1.5rem;
width: 2.5rem;
height: 2.5rem;
display: flex;
align-items: center;
justify-content: center;
border-radius: 0.75rem;
}
</style>
{% endblock %}
{% block content %}
<div class="container mx-auto px-4 py-8">
<!-- Seitenüberschrift -->
<div class="mb-8 text-center">
<h1 class="text-3xl font-bold mb-2 gradient-text">Community Forum</h1>
<p class="text-lg opacity-75">Diskutiere mit anderen Nutzern über die Hauptthemenbereiche der Mindmap</p>
</div>
<!-- Login-Aufforderung -->
<div class="rounded-xl p-6 text-center mb-8 bg-indigo-50 dark:bg-indigo-900/30 border border-indigo-100 dark:border-indigo-700/30">
<h3 class="text-xl font-semibold mb-3">
<i class="fas fa-lock mr-2 text-indigo-500"></i>
Anmeldung erforderlich
</h3>
<p class="mb-4">Um am Community-Forum teilzunehmen und alle Funktionen nutzen zu können, musst du dich anmelden oder registrieren.</p>
<div class="flex justify-center gap-4 mt-4">
<a href="{{ url_for('login', next=url_for('forum')) }}" class="px-4 py-2 bg-indigo-500 hover:bg-indigo-600 text-white rounded-lg transition-colors">
<i class="fas fa-sign-in-alt mr-2"></i>Anmelden
</a>
<a href="{{ url_for('register') }}" class="px-4 py-2 bg-purple-500 hover:bg-purple-600 text-white rounded-lg transition-colors">
<i class="fas fa-user-plus mr-2"></i>Registrieren
</a>
</div>
</div>
<!-- Forumskategorien Vorschau -->
<div class="grid grid-cols-1 md:grid-cols-2 gap-6 mb-8">
{% if categories_data %}
{% for cat_data in categories_data %}
<div class="forum-category block">
<div class="rounded-xl p-5 h-full"
x-bind:class="darkMode ? 'bg-gray-800/60 border border-white/10' : 'bg-white border border-gray-200 shadow-md'">
<div class="flex items-start">
<!-- Kategorie-Icon -->
<div class="category-icon mr-4 text-white"
style="background-color: {{ cat_data.category.node.color_code or '#6d28d9' }}">
<i class="fas {{ cat_data.category.node.icon or 'fa-folder' }}"></i>
</div>
<!-- Kategorie-Info -->
<div class="flex-grow">
<h3 class="text-xl font-semibold mb-2">{{ cat_data.category.title }}</h3>
<p class="opacity-75 text-sm mb-3">{{ cat_data.category.description }}</p>
<!-- Statistik -->
<div class="flex flex-wrap gap-4 text-sm opacity-80">
<div class="flex items-center">
<i class="fas fa-comment-alt mr-2"></i>
<span>{{ cat_data.total_posts }} Themen</span>
</div>
<div class="flex items-center">
<i class="fas fa-reply mr-2"></i>
<span>{{ cat_data.total_replies }} Antworten</span>
</div>
</div>
</div>
<!-- Pfeil-Icon -->
<div class="ml-2">
<i class="fas fa-lock opacity-50"></i>
</div>
</div>
</div>
</div>
{% endfor %}
{% else %}
<div class="col-span-2 text-center py-8">
<div class="text-3xl mb-3 opacity-30"><i class="fas fa-exclamation-circle"></i></div>
<h3 class="text-xl font-semibold mb-2">Keine Forum-Kategorien gefunden</h3>
<p class="opacity-75">Es sind derzeit keine Kategorien für Diskussionen verfügbar.</p>
</div>
{% endif %}
</div>
<!-- Hinweis zur Nutzung -->
<div class="rounded-xl p-6 text-center mb-8"
x-bind:class="darkMode ? 'bg-indigo-900/30 border border-indigo-700/30' : 'bg-indigo-50 border border-indigo-100'">
<h3 class="text-xl font-semibold mb-3">
<i class="fas fa-lightbulb mr-2 text-yellow-500"></i>
So funktioniert das Forum
</h3>
<p class="mb-4">Das Community-Forum ist nach den Hauptknotenpunkten der Systades-Mindmap strukturiert.
In deinen Beiträgen kannst du Knotenpunkte mit <code>@Knotenname</code> verlinken.</p>
<div class="grid grid-cols-1 md:grid-cols-3 gap-4 mt-6">
<div class="p-4 rounded-lg"
x-bind:class="darkMode ? 'bg-indigo-800/40' : 'bg-white border border-indigo-100'">
<div class="text-2xl mb-2"><i class="fas fa-users text-indigo-400"></i></div>
<h4 class="font-medium mb-1">Fachliche Diskussionen</h4>
<p class="text-sm opacity-75">Tausche dich mit anderen zu spezifischen Themen aus</p>
</div>
<div class="p-4 rounded-lg"
x-bind:class="darkMode ? 'bg-indigo-800/40' : 'bg-white border border-indigo-100'">
<div class="text-2xl mb-2"><i class="fas fa-link text-indigo-400"></i></div>
<h4 class="font-medium mb-1">Wissensvernetzung</h4>
<p class="text-sm opacity-75">Verknüpfe Inhalte durch Knotenreferenzen</p>
</div>
<div class="p-4 rounded-lg"
x-bind:class="darkMode ? 'bg-indigo-800/40' : 'bg-white border border-indigo-100'">
<div class="text-2xl mb-2"><i class="fas fa-markdown text-indigo-400"></i></div>
<h4 class="font-medium mb-1">Markdown Support</h4>
<p class="text-sm opacity-75">Formatiere deine Beiträge mit Markdown</p>
</div>
</div>
</div>
</div>
{% endblock %}
{% block scripts %}
<script>
// Hier können bei Bedarf forumspezifische Scripts eingefügt werden
</script>
{% endblock %}