Skip to main content

max / makenotwork

8.1 KB · 184 lines History Blame Raw
1 {% extends "base.html" %}
2
3 {% block title %}Moderation — {{ community_name }} — Multithreaded{% endblock %}
4
5 {% block head %}<meta name="robots" content="noindex">{% endblock %}
6
7 {% block header %}{% include "partials/site_header.html" %}{% endblock %}
8
9 {% block content %}
10 <div class="container">
11 <div class="breadcrumb">
12 <a href="/">Forums</a>
13 <span class="sep">/</span>
14 <a href="/p/{{ community_slug }}">{{ community_name }}</a>
15 <span class="sep">/</span>
16 Moderation
17 </div>
18 <div class="page-header">
19 <h1>Moderation</h1>
20 <a href="/p/{{ community_slug }}/moderation/deleted" class="btn-secondary">deleted threads</a>
21 <a href="/p/{{ community_slug }}/moderation/log" class="btn-secondary">mod log</a>
22 </div>
23
24 <div class="settings-section">
25 <h3>Ban User</h3>
26 <form method="post" action="/p/{{ community_slug }}/moderation/ban" class="form-container">
27 {% include "partials/csrf_input.html" %}
28 <div class="form-row">
29 <div class="form-group">
30 <label for="ban-username">Username</label>
31 <input type="text" id="ban-username" name="username" required placeholder="username">
32 </div>
33 <div class="form-group">
34 <label for="ban-duration">Duration</label>
35 <select id="ban-duration" name="duration">
36 <option value="permanent">Permanent</option>
37 <option value="1h">1 hour</option>
38 <option value="1d">1 day</option>
39 <option value="7d">7 days</option>
40 <option value="30d">30 days</option>
41 </select>
42 </div>
43 </div>
44 <div class="form-group">
45 <label for="ban-reason">Reason (optional)</label>
46 <textarea id="ban-reason" name="reason" rows="2" class="textarea-short" maxlength="1024"></textarea>
47 </div>
48 <div class="form-actions">
49 <button type="submit" class="primary">Ban User</button>
50 </div>
51 </form>
52 </div>
53
54 <div class="settings-section">
55 <h3>Mute User</h3>
56 <form method="post" action="/p/{{ community_slug }}/moderation/mute" class="form-container">
57 {% include "partials/csrf_input.html" %}
58 <div class="form-row">
59 <div class="form-group">
60 <label for="mute-username">Username</label>
61 <input type="text" id="mute-username" name="username" required placeholder="username">
62 </div>
63 <div class="form-group">
64 <label for="mute-duration">Duration</label>
65 <select id="mute-duration" name="duration">
66 <option value="permanent">Permanent</option>
67 <option value="1h">1 hour</option>
68 <option value="1d">1 day</option>
69 <option value="7d">7 days</option>
70 <option value="30d">30 days</option>
71 </select>
72 </div>
73 </div>
74 <div class="form-group">
75 <label for="mute-reason">Reason (optional)</label>
76 <textarea id="mute-reason" name="reason" rows="2" class="textarea-short" maxlength="1024"></textarea>
77 </div>
78 <div class="form-actions">
79 <button type="submit" class="primary">Mute User</button>
80 </div>
81 </form>
82 </div>
83
84 <div class="settings-section">
85 <h3>Pending Flags</h3>
86 {% if pending_flags.is_empty() %}
87 <div class="empty-state">No pending flags.</div>
88 {% else %}
89 <table class="settings-table">
90 <thead>
91 <tr>
92 <th>Thread</th>
93 <th>Flagged by</th>
94 <th>Reason</th>
95 <th>Detail</th>
96 <th>When</th>
97 <th>Actions</th>
98 </tr>
99 </thead>
100 <tbody>
101 {% for flag in pending_flags %}
102 <tr>
103 <td><a href="/p/{{ community_slug }}/{{ flag.category_slug }}/{{ flag.thread_id }}#post-{{ flag.post_id }}">{{ flag.thread_title }}</a></td>
104 <td>{{ flag.flagger_username }}</td>
105 <td>{{ flag.reason }}</td>
106 <td>{{ flag.detail.as_deref().unwrap_or("-") }}</td>
107 <td class="settings-mono">{{ flag.created }}</td>
108 <td class="settings-actions">
109 <form method="post" action="/p/{{ community_slug }}/moderation/flags/{{ flag.flag_id }}/dismiss" class="form-inline">
110 {% include "partials/csrf_input.html" %}
111 <button type="submit" class="post-action-link">dismiss</button>
112 </form>
113 <form method="post" action="/p/{{ community_slug }}/moderation/flags/{{ flag.flag_id }}/remove" class="form-inline" data-confirm="Remove this post and resolve all flags on it?">
114 {% include "partials/csrf_input.html" %}
115 <button type="submit" class="post-action-link post-action-delete">remove post</button>
116 </form>
117 </td>
118 </tr>
119 {% endfor %}
120 </tbody>
121 </table>
122 {% if flags_truncated %}
123 <p class="empty-state">Showing the most recent flags only. Resolve some to reveal older ones.</p>
124 {% endif %}
125 {% endif %}
126 </div>
127
128 <div class="settings-section">
129 <h3>Active Bans &amp; Mutes</h3>
130 {% if bans.is_empty() %}
131 <div class="empty-state">No active bans or mutes.</div>
132 {% else %}
133 <table class="settings-table">
134 <thead>
135 <tr>
136 <th>User</th>
137 <th>Type</th>
138 <th>Reason</th>
139 <th>Expires</th>
140 <th>By</th>
141 <th>Actions</th>
142 </tr>
143 </thead>
144 <tbody>
145 {% for ban in bans %}
146 <tr>
147 <td>{{ ban.username }}</td>
148 <td>
149 {% if ban.ban_type == "ban" %}
150 <span class="badge badge-ban">ban</span>
151 {% else %}
152 <span class="badge badge-mute-type">mute</span>
153 {% endif %}
154 </td>
155 <td>{{ ban.reason.as_deref().unwrap_or("-") }}</td>
156 <td class="settings-mono">{{ ban.expires.as_deref().unwrap_or("never") }}</td>
157 <td class="settings-mono">{{ ban.banned_by }}</td>
158 <td class="settings-actions">
159 {% if ban.ban_type == "ban" %}
160 <form method="post" action="/p/{{ community_slug }}/moderation/unban" class="form-inline">
161 {% include "partials/csrf_input.html" %}
162 <input type="hidden" name="username" value="{{ ban.username }}">
163 <button type="submit" class="post-action-link">unban</button>
164 </form>
165 {% else %}
166 <form method="post" action="/p/{{ community_slug }}/moderation/unmute" class="form-inline">
167 {% include "partials/csrf_input.html" %}
168 <input type="hidden" name="username" value="{{ ban.username }}">
169 <button type="submit" class="post-action-link">unmute</button>
170 </form>
171 {% endif %}
172 </td>
173 </tr>
174 {% endfor %}
175 </tbody>
176 </table>
177 {% if bans_truncated %}
178 <p class="empty-state">Showing the most recent bans and mutes only. Lift some to reveal older ones.</p>
179 {% endif %}
180 {% endif %}
181 </div>
182 </div>
183 {% endblock %}
184