a73x

b38fdd22

add issues list and detail pages

a73x   2026-03-30 19:07

Adds IssuesTemplate/issues handler listing all issues with status
coloring and labels, and IssueDetailTemplate/issue_detail handler
showing title, status, body, close reason, and comments. Reuses
CommentView from patches. Routes: /{repo}/issues, /{repo}/issues/{id}.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

diff --git a/src/server/http/templates/issue_detail.html b/src/server/http/templates/issue_detail.html
new file mode 100644
index 0000000..c00a831
--- /dev/null
+++ b/src/server/http/templates/issue_detail.html
@@ -0,0 +1,36 @@
{% extends "repo_base.html" %}

{% block title %}{{ issue.title }} — {{ repo_name }} — {{ site_title }}{% endblock %}

{% block content %}
<h2>{{ issue.title }}</h2>
<p>
  <span class="status-{{ issue.status }}">{{ issue.status }}</span>
  &nbsp; by <strong>{{ issue.author }}</strong>
</p>
{% if !issue.labels.is_empty() %}
<p style="color: var(--text-muted);">Labels: {{ issue.labels }}</p>
{% endif %}
{% if !issue.assignees.is_empty() %}
<p style="color: var(--text-muted);">Assignees: {{ issue.assignees }}</p>
{% endif %}
{% if !issue.body.is_empty() %}
<pre style="background: var(--bg-code, #f6f8fa); padding: 12px; border-radius: 4px; white-space: pre-wrap;">{{ issue.body }}</pre>
{% endif %}
{% if let Some(reason) = issue.close_reason %}
<p style="color: var(--text-muted);">Close reason: {{ reason }}</p>
{% endif %}

{% if !issue.comments.is_empty() %}
<h3>Comments</h3>
{% for comment in issue.comments %}
<div style="border: 1px solid var(--border, #ddd); border-radius: 4px; padding: 12px; margin-bottom: 12px;">
  <p style="margin: 0 0 8px 0;">
    <strong>{{ comment.author }}</strong>
    &nbsp; <span class="mono" style="color: var(--text-muted); font-size: 0.85em;">{{ comment.timestamp }}</span>
  </p>
  <pre style="margin: 0; white-space: pre-wrap;">{{ comment.body }}</pre>
</div>
{% endfor %}
{% endif %}
{% endblock %}
diff --git a/src/server/http/templates/issues.html b/src/server/http/templates/issues.html
new file mode 100644
index 0000000..1048dea
--- /dev/null
+++ b/src/server/http/templates/issues.html
@@ -0,0 +1,35 @@
{% extends "repo_base.html" %}

{% block title %}Issues — {{ repo_name }} — {{ site_title }}{% endblock %}

{% block content %}
<h2>Issues</h2>
{% if issues.is_empty() %}
<p style="color: var(--text-muted);">No issues.</p>
{% else %}
<table>
  <thead>
    <tr>
      <th>ID</th>
      <th>Status</th>
      <th>Title</th>
      <th>Author</th>
      <th>Labels</th>
      <th>Updated</th>
    </tr>
  </thead>
  <tbody>
    {% for i in issues %}
    <tr>
      <td class="mono"><a href="/{{ repo_name }}/issues/{{ i.id }}">{{ i.short_id }}</a></td>
      <td><span class="status-{{ i.status }}">{{ i.status }}</span></td>
      <td><a href="/{{ repo_name }}/issues/{{ i.id }}">{{ i.title }}</a></td>
      <td style="color: var(--text-muted);">{{ i.author }}</td>
      <td style="color: var(--text-muted);">{{ i.labels }}</td>
      <td class="mono" style="color: var(--text-muted);">{{ i.updated }}</td>
    </tr>
    {% endfor %}
  </tbody>
</table>
{% endif %}
{% endblock %}