Files
website/templates/social/profile.html

668 lines
21 KiB
HTML

{% extends "base.html" %}
{% block title %}{{ user.display_name or user.username }} - SysTades{% endblock %}
{% block additional_css %}
<style>
.profile-container {
max-width: 1000px;
margin: 0 auto;
padding: 20px;
}
.profile-header {
background: white;
border-radius: 16px;
padding: 30px;
margin-bottom: 25px;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
border: 1px solid #e1e8ed;
position: relative;
overflow: hidden;
}
.profile-header::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
height: 120px;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
z-index: 1;
}
.profile-content {
position: relative;
z-index: 2;
}
.profile-avatar {
width: 120px;
height: 120px;
border-radius: 50%;
background: white;
display: flex;
align-items: center;
justify-content: center;
font-size: 48px;
font-weight: bold;
color: #667eea;
margin: 60px auto 20px auto;
border: 4px solid white;
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
}
.profile-info {
text-align: center;
color: white;
margin-bottom: 30px;
}
.profile-name {
font-size: 28px;
font-weight: 700;
margin: 0 0 8px 0;
}
.profile-username {
font-size: 18px;
opacity: 0.9;
margin: 0 0 15px 0;
}
.profile-bio {
font-size: 16px;
line-height: 1.5;
opacity: 0.95;
max-width: 600px;
margin: 0 auto;
}
.profile-stats {
display: flex;
justify-content: center;
gap: 40px;
background: rgba(255,255,255,0.1);
backdrop-filter: blur(10px);
border-radius: 12px;
padding: 20px;
margin-top: 25px;
}
.stat-item {
text-align: center;
color: white;
}
.stat-number {
font-size: 24px;
font-weight: 700;
display: block;
}
.stat-label {
font-size: 14px;
opacity: 0.9;
margin-top: 4px;
}
.profile-actions {
display: flex;
justify-content: center;
gap: 15px;
margin-top: 25px;
}
.action-btn {
background: white;
color: #667eea;
border: none;
padding: 12px 24px;
border-radius: 25px;
font-weight: 600;
cursor: pointer;
transition: all 0.3s ease;
text-decoration: none;
display: inline-flex;
align-items: center;
gap: 8px;
}
.action-btn:hover {
background: #f0f2f5;
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(0,0,0,0.2);
}
.action-btn.primary {
background: #1877f2;
color: white;
}
.action-btn.primary:hover {
background: #166fe5;
}
.profile-navigation {
background: white;
border-radius: 12px;
margin-bottom: 25px;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
border: 1px solid #e1e8ed;
overflow: hidden;
}
.nav-tabs {
display: flex;
border-bottom: 1px solid #e1e8ed;
}
.nav-tab {
flex: 1;
background: none;
border: none;
padding: 15px 20px;
cursor: pointer;
font-weight: 500;
color: #8a8a8a;
transition: all 0.2s;
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
}
.nav-tab:hover {
background: #f8f9fa;
color: #1d2129;
}
.nav-tab.active {
color: #1877f2;
border-bottom: 2px solid #1877f2;
background: #f0f2f5;
}
.profile-content-area {
background: white;
border-radius: 12px;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
border: 1px solid #e1e8ed;
min-height: 400px;
}
.posts-grid {
padding: 20px;
display: grid;
gap: 20px;
}
.post-card {
background: #f8f9fa;
border-radius: 12px;
padding: 20px;
border: 1px solid #e1e8ed;
transition: all 0.3s ease;
}
.post-card:hover {
background: white;
box-shadow: 0 4px 12px rgba(0,0,0,0.1);
transform: translateY(-2px);
}
.post-meta {
display: flex;
align-items: center;
gap: 15px;
margin-bottom: 15px;
color: #8a8a8a;
font-size: 14px;
}
.post-content {
color: #1d2129;
line-height: 1.6;
margin-bottom: 15px;
}
.post-stats {
display: flex;
gap: 20px;
color: #8a8a8a;
font-size: 14px;
}
.post-stat {
display: flex;
align-items: center;
gap: 6px;
}
.empty-state {
text-align: center;
padding: 60px 20px;
color: #8a8a8a;
}
.empty-state h3 {
margin-bottom: 12px;
color: #1d2129;
}
.about-grid {
padding: 20px;
display: grid;
gap: 20px;
}
.about-section {
background: #f8f9fa;
border-radius: 12px;
padding: 20px;
border: 1px solid #e1e8ed;
}
.about-section h3 {
margin: 0 0 15px 0;
color: #1d2129;
font-size: 18px;
}
.info-row {
display: flex;
align-items: center;
gap: 12px;
margin-bottom: 12px;
color: #1d2129;
}
.info-row i {
color: #1877f2;
width: 20px;
}
/* Responsive */
@media (max-width: 768px) {
.profile-stats {
gap: 20px;
}
.profile-actions {
flex-direction: column;
align-items: center;
}
.nav-tabs {
overflow-x: auto;
}
}
/* Dark Mode */
[data-theme="dark"] .profile-header,
[data-theme="dark"] .profile-navigation,
[data-theme="dark"] .profile-content-area,
[data-theme="dark"] .about-section {
background: #242526;
border-color: #3a3b3c;
color: #e4e6ea;
}
[data-theme="dark"] .post-card {
background: #3a3b3c;
border-color: #4e4f50;
}
[data-theme="dark"] .post-card:hover {
background: #4e4f50;
}
[data-theme="dark"] .nav-tab {
color: #b0b3b8;
}
[data-theme="dark"] .nav-tab:hover {
background: #3a3b3c;
color: #e4e6ea;
}
[data-theme="dark"] .action-btn {
background: #3a3b3c;
color: #e4e6ea;
}
</style>
{% endblock %}
{% block content %}
<div class="profile-container">
<!-- Profile Header -->
<div class="profile-header">
<div class="profile-content">
<div class="profile-avatar">
{{ user.username[0].upper() }}
</div>
<div class="profile-info">
<h1 class="profile-name">{{ user.display_name or user.username }}</h1>
<p class="profile-username">@{{ user.username }}</p>
{% if user.bio %}
<p class="profile-bio">{{ user.bio }}</p>
{% endif %}
</div>
<div class="profile-stats">
<div class="stat-item">
<span class="stat-number">{{ user.post_count }}</span>
<div class="stat-label">Posts</div>
</div>
<div class="stat-item">
<span class="stat-number">{{ user.follower_count }}</span>
<div class="stat-label">Follower</div>
</div>
<div class="stat-item">
<span class="stat-number">{{ user.following_count }}</span>
<div class="stat-label">Folgt</div>
</div>
<div class="stat-item">
<span class="stat-number">{{ user.mindmaps|length if user.mindmaps else 0 }}</span>
<div class="stat-label">Mindmaps</div>
</div>
</div>
{% if user != current_user %}
<div class="profile-actions">
<button
class="action-btn primary"
onclick="followUser({{ user.id }})"
id="followBtn"
>
<i class="fas fa-user-plus"></i>
{% if is_following %}Gefolgt{% else %}Folgen{% endif %}
</button>
<button class="action-btn" onclick="sendMessage({{ user.id }})">
<i class="fas fa-envelope"></i>
Nachricht
</button>
</div>
{% else %}
<div class="profile-actions">
<a href="{{ url_for('settings') }}" class="action-btn">
<i class="fas fa-cog"></i>
Profil bearbeiten
</a>
<a href="{{ url_for('create_mindmap') }}" class="action-btn primary">
<i class="fas fa-plus"></i>
Neue Mindmap
</a>
</div>
{% endif %}
</div>
</div>
<!-- Profile Navigation -->
<div class="profile-navigation">
<div class="nav-tabs">
<button class="nav-tab active" onclick="switchTab('posts')">
<i class="fas fa-th-large"></i>
Posts
</button>
<button class="nav-tab" onclick="switchTab('mindmaps')">
<i class="fas fa-project-diagram"></i>
Mindmaps
</button>
<button class="nav-tab" onclick="switchTab('thoughts')">
<i class="fas fa-lightbulb"></i>
Gedanken
</button>
<button class="nav-tab" onclick="switchTab('about')">
<i class="fas fa-info-circle"></i>
Über
</button>
</div>
</div>
<!-- Profile Content Area -->
<div class="profile-content-area">
<!-- Posts Tab -->
<div id="posts-tab" class="tab-content">
<div class="posts-grid">
{% if posts %}
{% for post in posts %}
<div class="post-card">
<div class="post-meta">
<span><i class="fas fa-clock"></i> {{ post.created_at.strftime('%d.%m.%Y') }}</span>
<span><i class="fas fa-eye"></i> {{ post.view_count }} Aufrufe</span>
</div>
<div class="post-content">
{{ post.content[:300] }}{% if post.content|length > 300 %}...{% endif %}
</div>
<div class="post-stats">
<div class="post-stat">
<i class="fas fa-heart"></i>
<span>{{ post.like_count }}</span>
</div>
<div class="post-stat">
<i class="fas fa-comment"></i>
<span>{{ post.comment_count }}</span>
</div>
<div class="post-stat">
<i class="fas fa-share"></i>
<span>{{ post.share_count or 0 }}</span>
</div>
</div>
</div>
{% endfor %}
{% else %}
<div class="empty-state">
<h3>Noch keine Posts</h3>
<p>{% if user == current_user %}Du hast noch keine Posts erstellt.{% else %}{{ user.username }} hat noch keine Posts veröffentlicht.{% endif %}</p>
{% if user == current_user %}
<a href="{{ url_for('social_feed') }}" class="action-btn primary" style="margin-top: 15px;">
<i class="fas fa-plus"></i>
Ersten Post erstellen
</a>
{% endif %}
</div>
{% endif %}
</div>
</div>
<!-- Mindmaps Tab -->
<div id="mindmaps-tab" class="tab-content" style="display: none;">
<div class="posts-grid">
{% if user.mindmaps %}
{% for mindmap in user.mindmaps %}
<div class="post-card">
<div class="post-meta">
<span><i class="fas fa-clock"></i> {{ mindmap.created_at.strftime('%d.%m.%Y') }}</span>
<span><i class="fas fa-nodes"></i> {{ mindmap.public_nodes|length }} Knoten</span>
</div>
<div class="post-content">
<h4 style="margin: 0 0 10px 0; color: #1877f2;">{{ mindmap.name }}</h4>
<p>{{ mindmap.description or 'Keine Beschreibung verfügbar' }}</p>
</div>
<div class="post-stats">
<a href="{{ url_for('user_mindmap', mindmap_id=mindmap.id) }}" class="action-btn">
<i class="fas fa-eye"></i>
Anzeigen
</a>
</div>
</div>
{% endfor %}
{% else %}
<div class="empty-state">
<h3>Keine Mindmaps</h3>
<p>{% if user == current_user %}Du hast noch keine Mindmaps erstellt.{% else %}{{ user.username }} hat noch keine öffentlichen Mindmaps.{% endif %}</p>
{% if user == current_user %}
<a href="{{ url_for('create_mindmap') }}" class="action-btn primary" style="margin-top: 15px;">
<i class="fas fa-plus"></i>
Erste Mindmap erstellen
</a>
{% endif %}
</div>
{% endif %}
</div>
</div>
<!-- Thoughts Tab -->
<div id="thoughts-tab" class="tab-content" style="display: none;">
<div class="posts-grid">
{% if user.thoughts %}
{% for thought in user.thoughts[:10] %}
<div class="post-card">
<div class="post-meta">
<span><i class="fas fa-clock"></i> {{ thought.created_at.strftime('%d.%m.%Y') }}</span>
<span><i class="fas fa-tag"></i> {{ thought.branch }}</span>
</div>
<div class="post-content">
<h4 style="margin: 0 0 10px 0; color: #1877f2;">{{ thought.title }}</h4>
<p>{{ thought.abstract or thought.content[:200] }}{% if (thought.abstract or thought.content)|length > 200 %}...{% endif %}</p>
</div>
<div class="post-stats">
<div class="post-stat">
<i class="fas fa-star"></i>
<span>{{ thought.average_rating or 0 }}</span>
</div>
<div class="post-stat">
<i class="fas fa-comment"></i>
<span>{{ thought.comments|length }}</span>
</div>
</div>
</div>
{% endfor %}
{% else %}
<div class="empty-state">
<h3>Keine Gedanken</h3>
<p>{% if user == current_user %}Du hast noch keine Gedanken geteilt.{% else %}{{ user.username }} hat noch keine Gedanken veröffentlicht.{% endif %}</p>
</div>
{% endif %}
</div>
</div>
<!-- About Tab -->
<div id="about-tab" class="tab-content" style="display: none;">
<div class="about-grid">
<div class="about-section">
<h3>Grundlegende Informationen</h3>
<div class="info-row">
<i class="fas fa-user"></i>
<span>Mitglied seit {{ user.created_at.strftime('%B %Y') }}</span>
</div>
{% if user.location %}
<div class="info-row">
<i class="fas fa-map-marker-alt"></i>
<span>{{ user.location }}</span>
</div>
{% endif %}
{% if user.website %}
<div class="info-row">
<i class="fas fa-globe"></i>
<a href="{{ user.website }}" target="_blank" rel="noopener">{{ user.website }}</a>
</div>
{% endif %}
{% if user.last_login %}
<div class="info-row">
<i class="fas fa-clock"></i>
<span>Zuletzt aktiv: {{ user.last_login.strftime('%d.%m.%Y') }}</span>
</div>
{% endif %}
</div>
<div class="about-section">
<h3>Aktivitätsstatistiken</h3>
<div class="info-row">
<i class="fas fa-chart-line"></i>
<span>{{ user.post_count }} Posts erstellt</span>
</div>
<div class="info-row">
<i class="fas fa-lightbulb"></i>
<span>{{ user.thoughts|length if user.thoughts else 0 }} Gedanken geteilt</span>
</div>
<div class="info-row">
<i class="fas fa-project-diagram"></i>
<span>{{ user.mindmaps|length if user.mindmaps else 0 }} Mindmaps erstellt</span>
</div>
<div class="info-row">
<i class="fas fa-comments"></i>
<span>Aktives Community-Mitglied</span>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
{% block additional_js %}
<script>
// Tab Navigation
function switchTab(tabName) {
// Alle Tabs verstecken
document.querySelectorAll('.tab-content').forEach(tab => {
tab.style.display = 'none';
});
// Alle Tab-Buttons deaktivieren
document.querySelectorAll('.nav-tab').forEach(btn => {
btn.classList.remove('active');
});
// Gewählten Tab anzeigen
document.getElementById(tabName + '-tab').style.display = 'block';
// Gewählten Tab-Button aktivieren
event.target.classList.add('active');
}
// Follow/Unfollow Funktionalität
async function followUser(userId) {
const button = document.getElementById('followBtn');
try {
const response = await fetch('/api/users/' + userId + '/follow', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
}
});
const data = await response.json();
if (data.success) {
if (data.action === 'followed') {
button.innerHTML = '<i class="fas fa-user-check"></i> Gefolgt';
button.classList.add('following');
} else {
button.innerHTML = '<i class="fas fa-user-plus"></i> Folgen';
button.classList.remove('following');
}
} else {
alert(data.error && data.error.message ? data.error.message : 'Fehler beim Folgen');
}
} catch (error) {
console.error('Fehler beim Folgen:', error);
alert('Ein Fehler ist aufgetreten. Bitte versuche es erneut.');
}
}
// Nachricht senden (Platzhalter)
function sendMessage(userId) {
alert('Nachrichten-Feature wird bald verfügbar sein!');
}
// URL-Parameter für Tab-Navigation
document.addEventListener('DOMContentLoaded', function() {
const urlParams = new URLSearchParams(window.location.search);
const tab = urlParams.get('tab');
if (tab) {
// Tab aus URL aktivieren
const tabButton = document.querySelector('[onclick="switchTab(\'' + tab + '\')"]');
if (tabButton) {
tabButton.click();
}
}
});
</script>
{% endblock %}