{% extends "base.html" %}
{% block extra_head %}
<link rel="stylesheet" href="/static/css/feed.css">
<style>
.topnav {
position: fixed;
top: 0;
left: 0;
right: 0;
height: var(--nav-height);
background: var(--bg-secondary);
border-bottom: 1px solid var(--border);
z-index: 1000;
display: flex;
align-items: center;
}
.topnav-inner {
max-width: var(--max-content);
margin: 0 auto;
padding: 0 1rem;
width: 100%;
display: flex;
align-items: center;
gap: 2rem;
}
.topnav-logo {
font-size: 1.25rem;
font-weight: 800;
color: var(--text-primary);
letter-spacing: -0.02em;
}
.topnav-logo span {
color: var(--accent);
}
.topnav-links {
display: flex;
gap: 0.25rem;
}
.topnav-link {
padding: 0.5rem 0.75rem;
border-radius: var(--radius);
font-size: 0.875rem;
font-weight: 500;
color: var(--text-secondary);
transition: all 0.2s;
}
.topnav-link:hover {
color: var(--text-primary);
background: var(--bg-card);
}
.topnav-link.active {
color: var(--accent);
background: var(--accent-light);
}
.topnav-right {
margin-left: auto;
display: flex;
align-items: center;
gap: 1rem;
}
.topnav-icon {
position: relative;
padding: 0.375rem;
color: var(--text-secondary);
font-size: 1.25rem;
transition: color 0.2s;
}
.topnav-icon:hover {
color: var(--text-primary);
}
.nav-badge {
position: absolute;
top: 0;
right: 0;
min-width: 16px;
height: 16px;
padding: 0 4px;
border-radius: 8px;
background: var(--accent);
color: #fff;
font-size: 0.6875rem;
font-weight: 700;
display: flex;
align-items: center;
justify-content: center;
}
.topnav-user {
display: flex;
align-items: center;
gap: 0.5rem;
padding: 0.375rem;
border-radius: var(--radius);
transition: background 0.2s;
}
.topnav-user:hover {
background: var(--bg-card);
}
.topnav-user-info {
display: flex;
flex-direction: column;
line-height: 1.2;
}
.topnav-user-name {
font-size: 0.8125rem;
font-weight: 600;
color: var(--text-primary);
}
.topnav-user-role {
font-size: 0.6875rem;
color: var(--text-muted);
}
</style>
{% endblock %}
{% block content %}
<div class="feed-layout">
<aside class="feed-sidebar">
<h3>Topics</h3>
<div class="feed-categories">
<a href="/feed" class="feed-category {% if not current_topic %}active{% endif %}">
<span class="dot" style="background: var(--text-muted);"></span>
All
</a>
<a href="/feed?topic=devlog" class="feed-category {% if current_topic == 'devlog' %}active{% endif %}">
<span class="dot" style="background: #7c4dff;"></span>
Devlog
</a>
<a href="/feed?topic=showcase" class="feed-category {% if current_topic == 'showcase' %}active{% endif %}">
<span class="dot" style="background: #00bfa5;"></span>
Showcase
</a>
<a href="/feed?topic=question" class="feed-category {% if current_topic == 'question' %}active{% endif %}">
<span class="dot" style="background: #448aff;"></span>
Question
</a>
<a href="/feed?topic=rant" class="feed-category {% if current_topic == 'rant' %}active{% endif %}">
<span class="dot" style="background: #ff5252;"></span>
Rant
</a>
<a href="/feed?topic=fun" class="feed-category {% if current_topic == 'fun' %}active{% endif %}">
<span class="dot" style="background: #ffab00;"></span>
Fun
</a>
</div>
</aside>
<div class="feed-main">
<div class="feed-nav">
<a href="/feed?tab=all" class="feed-nav-btn {% if current_tab == 'all' or not current_tab %}active{% endif %}">All</a>
<a href="/feed?tab=trending" class="feed-nav-btn {% if current_tab == 'trending' %}active{% endif %}">Trending</a>
<a href="/feed?tab=recent" class="feed-nav-btn {% if current_tab == 'recent' %}active{% endif %}">Recent</a>
<a href="/feed?tab=following" class="feed-nav-btn {% if current_tab == 'following' %}active{% endif %}">Following</a>
<div class="feed-nav-actions">
<button class="btn-ghost btn-icon" title="Refresh">&#x21BB;</button>
<button class="btn-ghost btn-icon" title="Notifications">&#x1F514;</button>
</div>
</div>
<div class="feed-posts">
{% for item in posts %}
<article class="post-card fade-in">
<div class="post-header">
<img src="{{ avatar_url(item.author.get('avatar_style', 'initials') if item.author else 'initials', item.author['username'] if item.author else '?', 32) }}" class="avatar-img avatar-sm" alt="{{ item.author['username'] if item.author else '?' }}">
<div class="post-author-wrap">
<span class="post-author">{{ item.author['username'] if item.author else 'Unknown' }}</span>
{% if item.author and item.author.get('role') %}
<span class="post-author-role">{{ item.author['role'] }}</span>
{% endif %}
</div>
<span class="post-time">{{ item.time_ago }}</span>
</div>
<div class="post-topic">
<span class="badge badge-{{ item.post['topic'] }}">{{ item.post['topic'] }}</span>
</div>
{% if item.post.get('title') %}
<h3 class="post-title">{{ item.post['title'] }}</h3>
{% endif %}
<p class="post-content">{{ item.post['content'][:300] }}{% if item.post['content']|length > 300 %}...{% endif %}</p>
<div class="post-actions">
<form method="POST" action="/votes/post/{{ item.post['uid'] }}" style="display:inline;">
<input type="hidden" name="value" value="1">
<button type="submit" class="post-action-btn vote-up" data-vote="1" data-target="{{ item.post['uid'] }}" data-type="post">
+{{ item.post.get('stars', 0) }}
</button>
</form>
<a href="/posts/{{ item.post['uid'] }}" class="post-action-btn">
&#x1F4AC; {{ item.comment_count }}
</a>
<a href="/posts/{{ item.post['uid'] }}" class="post-action-btn share">
&#x2197;&#xFE0E; Open
</a>
<button class="post-action-btn">&#x1F517; Share</button>
</div>
</article>
{% else %}
<div class="empty-state">No posts yet. Be the first!</div>
{% endfor %}
</div>
</div>
<aside class="feed-right">
<div class="daily-topic-card">
<div class="daily-topic-label">Daily Topic</div>
<h4>Anthropic details how it improved Claude's safety...</h4>
<p>New techniques in AI safety research show promising results.</p>
<div class="topic-links">
<a href="#">Read More</a>
<a href="#">Source</a>
</div>
</div>
<div class="community-stats">
<h3>Community</h3>
<div class="stat-row">
<span class="label">Total Members</span>
<span class="value">{{ total_members }}</span>
</div>
<div class="stat-row">
<span class="label">Posts Today</span>
<span class="value">{{ posts_today }}</span>
</div>
<div class="stat-row">
<span class="label">Total Projects</span>
<span class="value">{{ total_projects }}</span>
</div>
<div style="margin-top: 0.75rem; padding-top: 0.75rem; border-top: 1px solid var(--border);">
<h3 style="font-size: 0.75rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.1em; color: var(--text-muted); margin-bottom: 0.5rem;">Top Authors</h3>
{% for author in top_authors %}
<div class="stat-row">
<span class="label">
<img src="{{ avatar_url(author.get('avatar_style', 'initials'), author['username'], 20) }}" class="avatar-img" style="width: 20px; height: 20px; vertical-align: middle; margin-right: 0.375rem;" alt="{{ author['username'] }}">
{{ author['username'] }}
</span>
<span class="value">{{ author.get('stars', 0) }}</span>
</div>
{% endfor %}
</div>
</div>
</aside>
</div>
<a href="#" class="feed-fab" data-modal="create-post-modal" title="Create New Post">+</a>
<div class="modal-overlay" id="create-post-modal" style="display: none; position: fixed; inset: 0; background: rgba(0,0,0,0.7); z-index: 2000; align-items: center; justify-content: center;">
<div class="card" style="width: 100%; max-width: 560px; margin: 1rem; max-height: 90vh; overflow-y: auto;">
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 1rem;">
<h3 style="font-size: 1.125rem; font-weight: 700;">Create New Post</h3>
<button type="button" class="modal-close btn-ghost btn-icon" style="font-size: 1.25rem;">&times;</button>
</div>
<form id="create-post-form" method="POST" action="/posts/create" enctype="multipart/form-data">
<div style="display: flex; gap: 0.375rem; flex-wrap: wrap; margin-bottom: 1rem;">
{% for t in ['devlog', 'showcase', 'question', 'rant', 'fun', 'random'] %}
<label style="display: flex; align-items: center; gap: 0.25rem; padding: 0.375rem 0.75rem; border-radius: 999px; font-size: 0.75rem; font-weight: 600; cursor: pointer; background: var(--bg-card-hover); transition: all 0.2s;">
<input type="radio" name="topic" value="{{ t }}" {% if t == 'random' %}checked{% endif %} style="width: auto; accent-color: var(--accent);">
{{ t|capitalize }}
</label>
{% endfor %}
</div>
<div class="auth-field" style="margin-bottom: 0.75rem;">
<label for="post-content">What are you sharing?</label>
<textarea id="post-content" name="content" required maxlength="2000" placeholder="What's on your mind?" style="min-height: 120px;"></textarea>
<small style="color: var(--text-muted); font-size: 0.75rem;"><span id="post-content-count">0/2000</span></small>
</div>
<div class="auth-field" style="margin-bottom: 0.75rem;">
<label for="post-title">Title (optional)</label>
<input type="text" id="post-title" name="title" maxlength="500" placeholder="Post title">
<small style="color: var(--text-muted); font-size: 0.75rem;"><span id="post-title-count">0/500</span></small>
</div>
<div class="auth-field" style="margin-bottom: 1rem;">
<label for="project_uid">Link to Project (Optional)</label>
<select id="project_uid" name="project_uid">
<option value="">No project</option>
{% for p in get_user_projects(user['uid']) %}
<option value="{{ p['uid'] }}">{{ p['title'] }}</option>
{% endfor %}
</select>
</div>
<div class="auth-field" style="margin-bottom: 1rem;">
<label>Add an image (optional)</label>
<div style="border: 1px dashed var(--border); border-radius: var(--radius); padding: 2rem; text-align: center; color: var(--text-muted); font-size: 0.8125rem;">
Drop image here or click to browse
</div>
</div>
<div style="display: flex; gap: 0.75rem; justify-content: flex-end;">
<button type="button" class="modal-close btn btn-secondary">Cancel</button>
<button type="submit" class="btn btn-primary">Post</button>
</div>
</form>
</div>
</div>
<script>
document.querySelector("[data-modal]").addEventListener("click", function() {
document.getElementById("create-post-modal").style.display = "flex";
});
document.querySelectorAll(".modal-close").forEach(function(btn) {
btn.addEventListener("click", function() {
var modal = this.closest(".modal-overlay");
if (modal) modal.style.display = "none";
});
});
document.getElementById("create-post-modal").addEventListener("click", function(e) {
if (e.target === this) this.style.display = "none";
});
</script>
{% endblock %}