{% extends "base.html" %}
{% block extra_head %}
<link rel="stylesheet" href="{{ static_url('/static/css/feed.css') }}">
<link rel="stylesheet" href="{{ static_url('/static/css/profile.css') }}">
<link rel="stylesheet" href="{{ static_url('/static/css/projects.css') }}">
<link rel="stylesheet" href="{{ static_url('/static/css/gists.css') }}">
{% endblock %}
{% block content %}
<div class="profile-layout">
<aside class="profile-sidebar">
<div class="profile-card">
<div class="profile-avatar-wrap">
<img src="{{ avatar_url('multiavatar', profile_user['username'], 80) }}" class="avatar-img avatar-lg" alt="{{ profile_user['username'] }}" id="profile-avatar-preview" loading="lazy">
</div>
<h1 class="profile-name">{{ profile_user['username'] }}</h1>
{% if is_admin(user) and profile_user.get('role') %}
<div class="profile-role">{{ profile_user['role'] }}</div>
{% endif %}
<div class="profile-stats">
<div class="profile-stat">
<span class="profile-stat-value">{{ posts_count }}</span>
<span class="profile-stat-label">Posts</span>
</div>
<div class="profile-stat">
<span class="profile-stat-value">{{ profile_user.get('level', 1) }}</span>
<span class="profile-stat-label">Level</span>
</div>
<div class="profile-stat">
<span class="profile-stat-value">{{ profile_user.get('stars', 0) }}</span>
<span class="profile-stat-label">Stars</span>
</div>
<div class="profile-stat">
<a href="/leaderboard" class="profile-stat-value">{% if rank %}#{{ rank }}{% else %}-{% endif %}</a>
<span class="profile-stat-label">Rank</span>
</div>
</div>
<div class="profile-level-bar">
<div class="level-label">
<span>Progress to next level</span>
<span>{{ profile_user.get('xp', 0) % 100 }}%</span>
</div>
<div class="bar">
<div class="bar-fill" style="width: {{ profile_user.get('xp', 0) % 100 }}%;"></div>
</div>
</div>
<div class="profile-badges">
{% for badge in badges %}
{% set meta = badge_info(badge['badge_name']) %}
<span class="profile-badge" title="{{ meta['description'] }}"><span class="profile-badge-icon">{{ meta['icon'] }}</span>{{ badge['badge_name'] }}</span>
{% else %}
{% set meta = badge_info('Member') %}
<span class="profile-badge" title="{{ meta['description'] }}"><span class="profile-badge-icon">{{ meta['icon'] }}</span>Member</span>
{% endfor %}
</div>
</div>
{% if not is_self(user, profile_user['uid']) %}
<div class="profile-actions">
<a href="{% if user %}/messages?with_uid={{ profile_user['uid'] }}{% else %}/auth/login{% endif %}" class="btn btn-secondary btn-sm full-width justify-center{% if not user %} login-required{% endif %}"{% if not user %} title="Log in to participate"{% endif %}><span class="icon">&#x2709;&#xFE0F;</span>Send Message</a>
{% if is_following %}
<form method="POST" action="/follow/unfollow/{{ profile_user['username'] }}">
<button type="submit" class="btn btn-secondary btn-sm full-width"{{ guest_disabled(user) }}><span class="icon">&#x2796;</span>Unfollow</button>
</form>
{% else %}
<form method="POST" action="/follow/{{ profile_user['username'] }}">
<button type="submit" class="btn btn-primary btn-sm full-width"{{ guest_disabled(user) }}><span class="icon">&#x2795;</span>Follow</button>
</form>
{% endif %}
</div>
{% endif %}
{% if is_self(user, profile_user['uid']) %}
<div class="profile-info">
<form method="POST" action="/profile/update">
<div class="profile-info-row">
<span class="profile-info-label">Bio</span>
<div class="flex-center-gap">
<span class="profile-info-value bio-display" id="display-bio">{{ profile_user.get('bio', '') or 'Not set' }}</span>
<button type="button" class="profile-info-edit" data-edit-field="bio">&#x270E;</button>
</div>
</div>
<div class="auth-field hidden input-edit-field" id="input-bio">
<textarea name="bio" maxlength="500" rows="2" class="input-sm">{{ profile_user.get('bio', '') }}</textarea>
</div>
<div class="profile-info-row">
<span class="profile-info-label">Location</span>
<div class="flex-center-gap">
<span class="profile-info-value" id="display-location">{{ profile_user.get('location', '') or 'Not set' }}</span>
<button type="button" class="profile-info-edit" data-edit-field="location">&#x270E;</button>
</div>
</div>
<div class="auth-field hidden input-edit-field" id="input-location">
<input type="text" name="location" maxlength="200" value="{{ profile_user.get('location', '') }}" class="input-sm">
</div>
<div class="profile-info-row">
<span class="profile-info-label">Git Link</span>
<div class="flex-center-gap">
<span class="profile-info-value" id="display-git_link">{{ profile_user.get('git_link', '') or 'Not set' }}</span>
<button type="button" class="profile-info-edit" data-edit-field="git_link">&#x270E;</button>
</div>
</div>
<div class="auth-field hidden input-edit-field" id="input-git_link">
<input type="url" name="git_link" maxlength="500" value="{{ profile_user.get('git_link', '') }}" class="input-sm">
</div>
<div class="profile-info-row">
<span class="profile-info-label">Website</span>
<div class="flex-center-gap">
<span class="profile-info-value" id="display-website">{{ profile_user.get('website', '') or 'Not set' }}</span>
<button type="button" class="profile-info-edit" data-edit-field="website">&#x270E;</button>
</div>
</div>
<div class="auth-field hidden input-edit-field" id="input-website">
<input type="url" name="website" maxlength="500" value="{{ profile_user.get('website', '') }}" class="input-sm">
</div>
<button type="submit" class="btn btn-primary btn-sm full-width save-btn-top">Save Changes</button>
</form>
</div>
{% else %}
<div class="profile-info">
<div class="profile-info-row">
<span class="profile-info-label">Bio</span>
<span class="profile-info-value">{{ profile_user.get('bio', '') or 'Not set' }}</span>
</div>
<div class="profile-info-row">
<span class="profile-info-label">Location</span>
<span class="profile-info-value">{{ profile_user.get('location', '') or 'Not set' }}</span>
</div>
<div class="profile-info-row">
<span class="profile-info-label">Git Link</span>
<span class="profile-info-value">{{ profile_user.get('git_link', '') or 'Not set' }}</span>
</div>
<div class="profile-info-row">
<span class="profile-info-label">Website</span>
<span class="profile-info-value">{{ profile_user.get('website', '') or 'Not set' }}</span>
</div>
</div>
{% endif %}
{% if can_view_api_key %}
<div class="api-key-card" data-api-key-card>
<div class="api-key-head">
<span class="api-key-title">API Key</span>
<a href="/docs/authentication.html" class="api-key-docs">Docs</a>
</div>
<code class="api-key-value" data-api-key data-key="{{ api_key }}" data-masked="true">{{ '•' * 12 }}</code>
<div class="api-key-actions">
<button type="button" class="btn btn-sm" data-api-key-reveal>Reveal</button>
<button type="button" class="btn btn-sm" data-api-key-copy>Copy</button>
{% if is_owner %}
<button type="button" class="btn btn-sm btn-primary" data-regen-api-key>Regenerate</button>
{% endif %}
</div>
<p class="api-key-hint">Use this key with <code>X-API-KEY</code>, <code>Authorization: Bearer</code>, or HTTP Basic auth on any request. {% if is_owner %}Regenerating immediately invalidates the old key.{% endif %}</p>
</div>
{% endif %}
{% if can_manage_customization %}
<div class="customization-card" data-customization data-username="{{ profile_user['username'] }}">
<div class="customization-head">
<span class="customization-title">{% if is_owner %}My customizations{% else %}{{ profile_user['username'] }}'s customizations{% endif %}</span>
</div>
<div class="customization-row">
<span class="customization-label">Site-wide custom CSS and JS</span>
<form method="POST" action="/profile/{{ profile_user['username'] }}/customization/global" data-customization-form>
<input type="hidden" name="value" value="{{ 1 if cust_disable_global else 0 }}">
<button type="submit" class="btn btn-sm {% if cust_disable_global %}btn-primary{% endif %}" data-customization-toggle="global" data-confirm="{% if cust_disable_global %}Re-enable your site-wide custom CSS and JS?{% else %}Disable your site-wide custom CSS and JS? Your saved code is kept and can be re-enabled.{% endif %}">{% if cust_disable_global %}Enable{% else %}Disable{% endif %}</button>
</form>
</div>
<div class="customization-row">
<span class="customization-label">Per-page custom CSS and JS</span>
<form method="POST" action="/profile/{{ profile_user['username'] }}/customization/pagetype" data-customization-form>
<input type="hidden" name="value" value="{{ 1 if cust_disable_pagetype else 0 }}">
<button type="submit" class="btn btn-sm {% if cust_disable_pagetype %}btn-primary{% endif %}" data-customization-toggle="pagetype" data-confirm="{% if cust_disable_pagetype %}Re-enable your per-page custom CSS and JS?{% else %}Disable your per-page custom CSS and JS? Your saved code is kept and can be re-enabled.{% endif %}">{% if cust_disable_pagetype %}Enable{% else %}Disable{% endif %}</button>
</form>
</div>
<p class="customization-hint">Disabling hides your custom code without deleting it.</p>
</div>
{% endif %}
{% if is_owner %}
<div class="customization-card" data-ai-correction data-username="{{ profile_user['username'] }}">
<div class="customization-head">
<span class="customization-title">AI content correction</span>
</div>
<div class="customization-row">
<span class="customization-label">Enable correction</span>
<label class="ai-correction-switch">
<input type="checkbox" data-ai-correction-toggle {% if ai_correction_enabled %}checked{% endif %}>
</label>
</div>
<div class="customization-row">
<span class="customization-label">Apply mode</span>
<select data-ai-correction-sync class="input-sm">
<option value="async" {% if not ai_correction_sync %}selected{% endif %}>In background (faster, applies after saving)</option>
<option value="sync" {% if ai_correction_sync %}selected{% endif %}>Synchronously (wait while saving)</option>
</select>
</div>
<textarea data-ai-correction-prompt class="input-sm ai-correction-prompt" maxlength="2000" rows="3">{{ ai_correction_prompt }}</textarea>
<div class="customization-row">
<button type="button" class="btn btn-sm btn-primary" data-ai-correction-save>Save</button>
<span class="ai-correction-status" data-ai-correction-status></span>
</div>
<p class="customization-hint">Corrections apply to new and edited content using your API key, on posts, comments, projects, gists, direct messages and your bio. Code and source files are never changed. In background mode the correction is applied just after saving; in synchronous mode the save waits for the correction to finish.</p>
</div>
<div class="customization-card" data-ai-modifier data-username="{{ profile_user['username'] }}">
<div class="customization-head">
<span class="customization-title">AI modifier</span>
</div>
<div class="customization-row">
<span class="customization-label">Enable modifier</span>
<label class="ai-correction-switch">
<input type="checkbox" data-ai-modifier-toggle {% if ai_modifier_enabled %}checked{% endif %}>
</label>
</div>
<div class="customization-row">
<span class="customization-label">Apply mode</span>
<select data-ai-modifier-sync class="input-sm">
<option value="async" {% if not ai_modifier_sync %}selected{% endif %}>In background (applies after saving)</option>
<option value="sync" {% if ai_modifier_sync %}selected{% endif %}>Synchronously (wait while saving)</option>
</select>
</div>
<textarea data-ai-modifier-prompt class="input-sm ai-correction-prompt" maxlength="2000" rows="3">{{ ai_modifier_prompt }}</textarea>
<div class="customization-row">
<button type="button" class="btn btn-sm btn-primary" data-ai-modifier-save>Save</button>
<span class="ai-correction-status" data-ai-modifier-status></span>
</div>
<p class="customization-hint">Runs only when your text contains an inline `@ai instruction` directive: it executes that instruction and removes the `@ai` marker, using your API key. Applies to posts, comments, projects, gists, direct messages and your bio. Code and source files are never touched.</p>
</div>
{% endif %}
</aside>
<div class="profile-content">
<a href="/feed" class="back-link">&larr; Back</a>
<div class="profile-heatmap-card">
<div class="heatmap-header">
<h3 class="heatmap-title">Contributions</h3>
<span class="streak-info"><span class="icon">&#x1F525;</span> {{ streak.current }} day streak &middot; Longest {{ streak.longest }}</span>
</div>
<div class="heatmap-scroll">
<div class="heatmap-inner">
<div class="heatmap-months">
{% for month in heatmap_months %}<span>{{ month }}</span>{% endfor %}
</div>
<div class="heatmap-grid">
{% for week in heatmap %}
<div class="heatmap-week">
{% for day in week %}
<span class="heatmap-cell level-{{ day.level }}" title="{{ day.count }} on {{ day.date }}"></span>
{% endfor %}
</div>
{% endfor %}
</div>
</div>
</div>
</div>
{% if is_admin(user) %}
<div class="ai-usage-card" data-ai-usage data-uid="{{ profile_user['uid'] }}">
<div class="ai-usage-head">
<h3 class="ai-usage-title">AI usage (last 24h)</h3>
<span class="ai-usage-updated" data-ai-usage-updated></span>
</div>
{% if ai_quota %}
<div class="ai-quota" data-ai-quota>
<div class="ai-quota-bar">
<span class="ai-quota-fill {% if not ai_quota.unlimited and ai_quota.used_pct >= 90 %}ai-quota-danger{% endif %}" style="width: {{ 0 if ai_quota.unlimited else ai_quota.used_pct }}%"></span>
</div>
<div class="ai-quota-meta">
<span class="ai-quota-pct">{% if ai_quota.unlimited %}No daily spend cap{% else %}{{ ai_quota.used_pct }}% of daily quota used{% endif %}</span>
<span class="ai-quota-detail">${{ '%.4f'|format(ai_quota.spent_usd) }} / {% if ai_quota.unlimited %}no cap{% else %}${{ '%.2f'|format(ai_quota.limit_usd) }}{% endif %} &middot; {{ ai_quota.turns }} Devii turns</span>
</div>
</div>
{% endif %}
<div class="ai-usage-body" data-ai-usage-body>
<p class="ai-usage-empty">Loading...</p>
</div>
</div>
{% elif is_self(user, profile_user['uid']) %}
<div class="ai-usage-card ai-quota-only">
<div class="ai-usage-head">
<h3 class="ai-usage-title">AI quota</h3>
</div>
{% if ai_quota %}
<div class="ai-quota" data-ai-quota>
<div class="ai-quota-bar">
<span class="ai-quota-fill {% if not ai_quota.unlimited and ai_quota.used_pct >= 90 %}ai-quota-danger{% endif %}" style="width: {{ 0 if ai_quota.unlimited else ai_quota.used_pct }}%"></span>
</div>
<div class="ai-quota-meta">
<span class="ai-quota-pct">{% if ai_quota.unlimited %}No daily AI spend cap{% else %}{{ ai_quota.used_pct }}% of your daily AI quota used{% endif %}</span>
</div>
</div>
{% else %}
<p class="ai-usage-empty">Quota unavailable.</p>
{% endif %}
</div>
{% endif %}
{% if correction_usage and correction_usage.calls %}
<div class="ai-usage-card correction-usage-card">
<div class="ai-usage-head">
<h3 class="ai-usage-title">AI correction usage</h3>
{% if correction_usage.last_used %}<span class="ai-usage-updated">{{ format_date(correction_usage.last_used) }}</span>{% endif %}
</div>
<div class="correction-usage-stats">
<div class="correction-usage-stat">
<span class="correction-usage-value">{{ "{:,}".format(correction_usage.calls) }}</span>
<span class="correction-usage-label">Corrections</span>
</div>
<div class="correction-usage-stat">
<span class="correction-usage-value">{{ "{:,}".format(correction_usage.total_tokens) }}</span>
<span class="correction-usage-label">Total tokens</span>
</div>
<div class="correction-usage-stat">
<span class="correction-usage-value">{{ "{:,}".format(correction_usage.prompt_tokens) }}</span>
<span class="correction-usage-label">Prompt tokens</span>
</div>
<div class="correction-usage-stat">
<span class="correction-usage-value">{{ "{:,}".format(correction_usage.completion_tokens) }}</span>
<span class="correction-usage-label">Completion tokens</span>
</div>
<div class="correction-usage-stat">
<span class="correction-usage-value">{{ "%.0f"|format(correction_usage.avg_tokens) }}</span>
<span class="correction-usage-label">Avg tokens/call</span>
</div>
<div class="correction-usage-stat">
<span class="correction-usage-value">{{ "%.0f"|format(correction_usage.avg_latency_ms) }} ms</span>
<span class="correction-usage-label">Avg latency</span>
</div>
<div class="correction-usage-stat">
<span class="correction-usage-value">{{ "%.1f"|format(correction_usage.avg_tokens_per_second) }}/s</span>
<span class="correction-usage-label">Avg speed</span>
</div>
<div class="correction-usage-stat">
<span class="correction-usage-value">{{ "%.1f"|format(correction_usage.total_time_s) }} s</span>
<span class="correction-usage-label">Total time</span>
</div>
{% if correction_usage.cost_usd is defined %}
<div class="correction-usage-stat correction-usage-cost">
<span class="correction-usage-value">${{ "%.4f"|format(correction_usage.cost_usd) }}</span>
<span class="correction-usage-label">Total cost</span>
</div>
<div class="correction-usage-stat correction-usage-cost">
<span class="correction-usage-value">${{ "%.5f"|format(correction_usage.avg_cost_usd) }}</span>
<span class="correction-usage-label">Avg cost/call</span>
</div>
{% endif %}
</div>
</div>
{% endif %}
{% if modifier_usage and modifier_usage.calls %}
<div class="ai-usage-card correction-usage-card">
<div class="ai-usage-head">
<h3 class="ai-usage-title">AI modifier usage</h3>
{% if modifier_usage.last_used %}<span class="ai-usage-updated">{{ format_date(modifier_usage.last_used) }}</span>{% endif %}
</div>
<div class="correction-usage-stats">
<div class="correction-usage-stat">
<span class="correction-usage-value">{{ "{:,}".format(modifier_usage.calls) }}</span>
<span class="correction-usage-label">Modifications</span>
</div>
<div class="correction-usage-stat">
<span class="correction-usage-value">{{ "{:,}".format(modifier_usage.total_tokens) }}</span>
<span class="correction-usage-label">Total tokens</span>
</div>
<div class="correction-usage-stat">
<span class="correction-usage-value">{{ "{:,}".format(modifier_usage.prompt_tokens) }}</span>
<span class="correction-usage-label">Prompt tokens</span>
</div>
<div class="correction-usage-stat">
<span class="correction-usage-value">{{ "{:,}".format(modifier_usage.completion_tokens) }}</span>
<span class="correction-usage-label">Completion tokens</span>
</div>
<div class="correction-usage-stat">
<span class="correction-usage-value">{{ "%.0f"|format(modifier_usage.avg_tokens) }}</span>
<span class="correction-usage-label">Avg tokens/call</span>
</div>
<div class="correction-usage-stat">
<span class="correction-usage-value">{{ "%.0f"|format(modifier_usage.avg_latency_ms) }} ms</span>
<span class="correction-usage-label">Avg latency</span>
</div>
<div class="correction-usage-stat">
<span class="correction-usage-value">{{ "%.1f"|format(modifier_usage.avg_tokens_per_second) }}/s</span>
<span class="correction-usage-label">Avg speed</span>
</div>
<div class="correction-usage-stat">
<span class="correction-usage-value">{{ "%.1f"|format(modifier_usage.total_time_s) }} s</span>
<span class="correction-usage-label">Total time</span>
</div>
{% if modifier_usage.cost_usd is defined %}
<div class="correction-usage-stat correction-usage-cost">
<span class="correction-usage-value">${{ "%.4f"|format(modifier_usage.cost_usd) }}</span>
<span class="correction-usage-label">Total cost</span>
</div>
<div class="correction-usage-stat correction-usage-cost">
<span class="correction-usage-value">${{ "%.5f"|format(modifier_usage.avg_cost_usd) }}</span>
<span class="correction-usage-label">Avg cost/call</span>
</div>
{% endif %}
</div>
</div>
{% endif %}
<details class="profile-achievements">
<summary class="profile-achievements-summary">
<span class="profile-achievements-title"><span class="icon">&#x1F3C6;</span> Achievements</span>
<span class="profile-achievements-count">{{ badge_earned }} / {{ badge_total }}</span>
</summary>
{% for group in achievements %}
<div class="achievement-group">
<h3 class="achievement-group-title">{{ group['group'] }} <span class="achievement-group-count">{{ group['earned'] }}/{{ group['total'] }}</span></h3>
<div class="achievement-grid">
{% for item in group['items'] %}
<div class="achievement {% if item['earned'] %}earned{% else %}locked{% endif %}" title="{{ item['description'] }}">
<span class="achievement-icon">{{ item['icon'] }}</span>
<span class="achievement-body">
<span class="achievement-name">{{ item['name'] }}</span>
<span class="achievement-desc">{{ item['description'] }}</span>
</span>
</div>
{% endfor %}
</div>
</div>
{% endfor %}
</details>
<div class="profile-tabs" data-profile-tabs>
<a href="/profile/{{ profile_user['username'] }}?tab=posts" class="profile-tab {% if current_tab == 'posts' %}active{% endif %}" data-menu-icon="&#x1F4DD;" data-menu-label="Posts"><span class="icon">&#x1F4DD;</span> Posts</a>
<a href="/profile/{{ profile_user['username'] }}?tab=projects" class="profile-tab {% if current_tab == 'projects' %}active{% endif %}" data-menu-icon="&#x1F680;" data-menu-label="Projects"><span class="icon">&#x1F680;</span> Projects</a>
<a href="/profile/{{ profile_user['username'] }}?tab=gists" class="profile-tab {% if current_tab == 'gists' %}active{% endif %}" data-menu-icon="&#x1F4DD;" data-menu-label="Gists"><span class="icon">&#x1F4DD;</span> Gists</a>
<a href="/profile/{{ profile_user['username'] }}?tab=media" class="profile-tab {% if current_tab == 'media' %}active{% endif %}" data-menu-icon="&#x1F5BC;&#xFE0F;" data-menu-label="Media"><span class="icon">&#x1F5BC;&#xFE0F;</span> Media</a>
<a href="/profile/{{ profile_user['username'] }}?tab=activity" class="profile-tab {% if current_tab == 'activity' %}active{% endif %}" data-menu-icon="&#x1F4CA;" data-menu-label="Activity"><span class="icon">&#x1F4CA;</span> Activity</a>
<a href="/profile/{{ profile_user['username'] }}?tab=followers" class="profile-tab {% if current_tab == 'followers' %}active{% endif %}" data-menu-icon="&#x1F465;" data-menu-label="Followers ({{ followers_count }})"><span class="icon">&#x1F465;</span> Followers ({{ followers_count }})</a>
<a href="/profile/{{ profile_user['username'] }}?tab=following" class="profile-tab {% if current_tab == 'following' %}active{% endif %}" data-menu-icon="&#x1F464;" data-menu-label="Following ({{ following_count }})"><span class="icon">&#x1F464;</span> Following ({{ following_count }})</a>
{% if is_owner or viewer_is_admin %}
<a href="/profile/{{ profile_user['username'] }}?tab=notifications" class="profile-tab {% if current_tab == 'notifications' %}active{% endif %}" data-menu-icon="&#x1F514;" data-menu-label="Notifications"><span class="icon">&#x1F514;</span> Notifications</a>
{% endif %}
<button type="button" class="profile-tab profile-tabs-more" aria-haspopup="menu" aria-label="More tabs" hidden><span class="icon">&#x22EF;</span> More</button>
</div>
<div class="profile-posts">
{% if current_tab == 'posts' %}
{% for item in posts %}
{% set _author = profile_user %}{% set _time = item.time_ago %}{% set _show_share = false %}{% set _show_comment_form = false %}{% include "_post_card.html" %}
{% else %}
<div class="empty-state">No posts yet.</div>
{% endfor %}
{% elif current_tab == 'projects' %}
{% for p in projects %}
<a href="/projects/{{ p['slug'] or p['uid'] }}" class="project-card">
<div class="project-card-header">
<h3 class="project-card-title">{{ p['title'] }}</h3>
</div>
<div class="project-card-meta">
<span class="project-status {% if p.get('status') == 'Released' %}released{% else %}dev{% endif %}">
&#x25CF; {{ p.get('status', 'In Development') }}
</span>
<span>{{ p.get('project_type', 'software')|replace('_', ' ')|capitalize }}</span>
</div>
<div class="project-card-desc rendered-content" data-render>{{ p.get('description', '')[:200] }}</div>
{% if p.get('platforms') %}
<div class="project-card-platforms">
{% for plat in p['platforms'].split(',') %}
<span class="platform-tag">{{ plat.strip() }}</span>
{% endfor %}
</div>
{% endif %}
</a>
{% else %}
<div class="empty-state">No projects yet.</div>
{% endfor %}
{% elif current_tab == 'gists' %}
{% for entry in gists %}
{% set g = entry.gist %}
<a href="/gists/{{ g['slug'] or g['uid'] }}" class="gist-card">
<div class="gist-card-header">
<h3 class="gist-card-title">{{ g['title'] }}</h3>
<span class="gist-card-star">&#x2606; {{ g.get('stars', 0) }}</span>
</div>
<div class="gist-card-meta">
<span class="gist-language-badge">&#x1F4DD; {{ language_name(g['language']) }}</span>
</div>
{% if g.get('description') %}
<div class="gist-card-desc">{{ g['description'][:200] }}{% if g['description']|length > 200 %}...{% endif %}</div>
{% endif %}
<div class="gist-card-footer">
<span>{{ dt_ago(entry.gist.created_at) if entry.gist.created_at else entry.time_ago }}</span>
</div>
</a>
{% else %}
<div class="empty-state">No gists yet.</div>
{% endfor %}
{% elif current_tab == 'media' %}
{% include "_media_gallery.html" %}
{% set pagination = media_pagination %}
{% set pagination_query = "tab=media&" %}
{% include "_pagination.html" %}
{% elif current_tab == 'followers' or current_tab == 'following' %}
{% for person in people %}
<div class="follow-row">
<a href="/profile/{{ person['username'] }}" class="follow-user">
<img src="{{ avatar_url('multiavatar', person['username'], 40) }}" class="avatar-img avatar-md" alt="{{ person['username'] }}" loading="lazy">
<div class="follow-user-info">
<span class="follow-user-name">{{ person['username'] }}</span>
{% if person['bio'] %}<span class="follow-user-bio">{{ person['bio'] }}</span>{% endif %}
</div>
</a>
{% if user and not person['is_self'] %}
{% if person['is_following'] %}
<form method="post" action="/follow/unfollow/{{ person['username'] }}">
<button type="submit" class="btn btn-ghost btn-sm"{{ guest_disabled(user) }}>Following</button>
</form>
{% else %}
<form method="post" action="/follow/{{ person['username'] }}">
<button type="submit" class="btn btn-primary btn-sm"{{ guest_disabled(user) }}>Follow</button>
</form>
{% endif %}
{% endif %}
</div>
{% else %}
<div class="empty-state">{% if current_tab == 'followers' %}No followers yet.{% else %}Not following anyone yet.{% endif %}</div>
{% endfor %}
{% if follow_pagination and follow_pagination.total_pages > 1 %}
<div class="follow-pagination">
{% if follow_pagination.has_prev %}<a class="btn btn-ghost btn-sm" href="/profile/{{ profile_user['username'] }}?tab={{ current_tab }}&page={{ follow_pagination.prev_page }}">Previous</a>{% endif %}
<span class="follow-page-label">Page {{ follow_pagination.page }} of {{ follow_pagination.total_pages }}</span>
{% if follow_pagination.has_next %}<a class="btn btn-ghost btn-sm" href="/profile/{{ profile_user['username'] }}?tab={{ current_tab }}&page={{ follow_pagination.next_page }}">Next</a>{% endif %}
</div>
{% endif %}
{% elif current_tab == 'notifications' %}
{% if is_owner or viewer_is_admin %}
<div class="notif-prefs" data-notif-prefs data-username="{{ profile_user['username'] }}">
<div class="notif-prefs-intro">
{% if not is_owner %}<p class="notif-prefs-admin">Editing notification settings for <strong>{{ profile_user['username'] }}</strong>.</p>{% endif %}
<p>Choose how you want to be notified for each event. <strong>In-app</strong> shows the notification on DevPlace; <strong>Push</strong> sends it to your subscribed devices.</p>
</div>
<table class="notif-prefs-table">
<thead>
<tr>
<th>Notification</th>
<th class="notif-prefs-col">In-app</th>
<th class="notif-prefs-col">Push</th>
</tr>
</thead>
<tbody>
{% for pref in notification_prefs %}
<tr>
<td>
<span class="notif-prefs-label">{{ pref.label }}</span>
<span class="notif-prefs-desc">{{ pref.description }}</span>
</td>
<td class="notif-prefs-col">
<label class="notif-switch">
<input type="checkbox" data-notif-toggle data-type="{{ pref.key }}" data-channel="in_app" {% if pref.in_app %}checked{% endif %}>
<span class="notif-switch-track"></span>
</label>
</td>
<td class="notif-prefs-col">
<label class="notif-switch">
<input type="checkbox" data-notif-toggle data-type="{{ pref.key }}" data-channel="push" {% if pref.push %}checked{% endif %}>
<span class="notif-switch-track"></span>
</label>
</td>
</tr>
{% endfor %}
</tbody>
</table>
<div class="notif-prefs-actions">
<button type="button" class="btn btn-ghost btn-sm" data-notif-reset>Reset to defaults</button>
</div>
</div>
{% else %}
<div class="empty-state">Not available.</div>
{% endif %}
{% else %}
{% for act in activities %}
<div class="post-card activity-card">
<div class="activity-row">
<span class="activity-icon">
{% if act['type'] == 'post' %}&#x1F4DD;{% else %}&#x1F4AC;{% endif %}
</span>
<span class="activity-type">
{% if act['type'] == 'post' %}Posted{% else %}Commented{% endif %}
</span>
<span class="activity-time">{{ dt_ago(act['created_at']) if act['created_at'] else act['time_ago'] }}</span>
</div>
<p class="activity-content">{{ act['content'] }}</p>
</div>
{% else %}
<div class="empty-state">No activity yet.</div>
{% endfor %}
{% endif %}
</div>
</div>
</div>
{% endblock %}
{% block extra_js %}
<script type="module">
import { ProfileTabs } from "{{ static_url('/static/js/ProfileTabs.js') }}";
const tabs = document.querySelector("[data-profile-tabs]");
if (tabs) {
new ProfileTabs(tabs);
}
</script>
{% endblock %}