Researcher / src /web /templates /preferences.html
amarck's picture
Initial commit: Research Intelligence System
a0f27fa
{% extends "base.html" %}
{% block title %}Preferences — Research Intelligence{% endblock %}
{% block content %}
<div class="page-header">
<div style="display:flex; justify-content:space-between; align-items:flex-start; flex-wrap:wrap; gap:0.5rem">
<div>
<h1>Preferences</h1>
<div class="subtitle">
{{ total_prefs }} learned preference{{ 's' if total_prefs != 1 else '' }}
{% if updated_at %} · Last updated {{ updated_at[:16] }}{% endif %}
</div>
</div>
<div style="display:flex; gap:0.5rem">
<button class="btn btn-sm" onclick="this.disabled=true;this.textContent='Recomputing...';fetch('/api/preferences/recompute',{method:'POST'}).then(function(){showToast('Preferences recomputed','success');setTimeout(function(){location.reload()},500)}).catch(function(){showToast('Failed','error')})">Recompute</button>
<button class="btn btn-sm" style="color:var(--red)" onclick="if(confirm('Reset all preferences and signal history?')){this.disabled=true;fetch('/api/preferences/reset',{method:'POST'}).then(function(){showToast('Preferences reset','success');setTimeout(function(){location.reload()},500)}).catch(function(){showToast('Failed','error')})}">Reset All</button>
</div>
</div>
</div>
{# Signal summary #}
<div class="stats-grid" style="grid-template-columns:repeat(5, 1fr); margin-bottom:2rem">
<div class="stat-card stat-card--green">
<div class="label">Saves</div>
<div class="value">{{ signal_counts.get('save', 0) }}</div>
</div>
<div class="stat-card stat-card--blue">
<div class="label">Upvotes</div>
<div class="value">{{ signal_counts.get('upvote', 0) }}</div>
</div>
<div class="stat-card stat-card--purple">
<div class="label">Views</div>
<div class="value">{{ signal_counts.get('view', 0) }}</div>
</div>
<div class="stat-card stat-card--red">
<div class="label">Downvotes</div>
<div class="value">{{ signal_counts.get('downvote', 0) }}</div>
</div>
<div class="stat-card" style="background:var(--bg-card)">
<div class="label">Dismissed</div>
<div class="value">{{ signal_counts.get('dismiss', 0) }}</div>
</div>
</div>
{% if total_prefs == 0 %}
<div class="empty-state">
<h2>No preferences yet</h2>
<p>Rate papers using the arrow buttons to build your preference profile. The system learns from saves, upvotes, downvotes, and dismissals.</p>
</div>
{% else %}
{# Preference groups #}
{% set pref_labels = {'topic': 'Topics', 'keyword': 'Keywords', 'category': 'Categories', 'author': 'Authors', 'axis_pref': 'Axis Preferences'} %}
<div class="pref-groups">
{% for prefix, items in grouped.items() %}
{% set label = pref_labels.get(prefix, prefix | capitalize) %}
<div class="pref-group">
<div class="section-header">
<h2>{{ label }}</h2>
<span class="badge badge--accent">{{ items | length }}</span>
</div>
<div class="pref-list">
{% for item in items[:20] %}
<div class="pref-item">
<span class="pref-item__name">{{ item.name }}</span>
<span class="pref-item__count" title="{{ item.count }} signal{{ 's' if item.count != 1 else '' }}">{{ item.count }}x</span>
<div class="pref-bar-container">
{% set abs_val = (item.value | abs * 100) | round(0) | int %}
{% if item.value > 0 %}
<div class="pref-bar pref-bar--positive" style="width:{{ abs_val }}%"></div>
{% else %}
<div class="pref-bar pref-bar--negative" style="width:{{ abs_val }}%"></div>
{% endif %}
</div>
<span class="pref-item__value {% if item.value > 0 %}pref-positive{% else %}pref-negative{% endif %}">{{ '%+.2f'|format(item.value) }}</span>
</div>
{% endfor %}
</div>
</div>
{% endfor %}
</div>
{% endif %}
{% endblock %}