report interface refactor

This commit is contained in:
Kyle Drake
2025-08-20 18:08:53 -05:00
parent 4eb41f4591
commit c984251c2c
4 changed files with 183 additions and 40 deletions
+15 -2
View File
@@ -7,12 +7,25 @@ end
get '/admin/reports' do
require_admin
@reports = Report.order(:created_at.desc).all
@page = params[:page] ? params[:page].to_i : 1
@page = 1 if @page < 1
@per_page = 51
@reports = Report.join(:sites, id: :site_id).where(sites__is_deleted: false, sites__is_banned: false).order(:reports__created_at.desc).select_all(:reports).paginate(@page, @per_page)
@pagination_dataset = @reports
erb :'admin/reports'
end
post '/admin/reports' do
post '/admin/reports/:report_id/dismiss' do
require_admin
content_type :json
report = Report[params[:report_id]]
return {success: false, error: 'Report not found'}.to_json if report.nil?
report.destroy
{success: true, message: 'Report dismissed'}.to_json
end
post '/admin/site_files/train' do
@@ -0,0 +1,5 @@
Sequel.migration do
change do
add_column :reports, :site_file_path, String
end
end
+5
View File
@@ -1,4 +1,9 @@
class Report < Sequel::Model
many_to_one :site
many_to_one :reporting_site, class: :Site
def site_file
return nil unless site_file_path && site
site.site_files_dataset.where(path: site_file_path).first
end
end
+158 -38
View File
@@ -4,43 +4,163 @@
</div>
</div>
<div class="content" style="background: white">
<form method="POST" action="/admin/reports">
<%== csrf_token_input_html %>
<table class="table">
<tr>
<th>Site</th>
<th>Type</th>
<th>Comments</th>
<th>Actions</th>
</tr>
<% @reports.each do |report| %>
<tr>
<td>
<a href="<%= report.site.uri %>"><%= report.site.title %></a>
<br>
<img src="<%= report.site.screenshot_url('/index.html', '540x405') %>" alt="Reported site screenshot">
<br>
Reported <%= report.created_at.ago %>
<% if report.reporting_site %>
by <a href="<%= report.reporting_site.uri %>"><%= report.reporting_site.username %></a>
<% end %>
</td>
<td><%= report.type %></td>
<td><%= report.comments[0...100] %></td>
<td>
<select name="sites[<%= report.site_id %>]">
<option value="">No Action</option>
<option value="ban">Ban Site</option>
<option value="nsfw">Mark NSFW</option>
</select>
</td>
</tr>
<% end %>
</table>
<input type="submit" value="Perform Actions" class="btn">
</form>
<div class="content single-Col misc-page">
<article>
<%== flash_display %>
<% if @reports.empty? %>
<div style="text-align: center; padding: 40px;">
<p><em>No reports found.</em></p>
</div>
<% else %>
<div class="row">
<% @reports.each_with_index do |report, index| %>
<div class="col col-33" id="report-<%= report.id %>">
<div class="block" style="height: 100%; display: flex; flex-direction: column;">
<%
# Use the specific site_file_path from report, or default to index.html
if report.site_file_path && !report.site_file_path.empty?
screenshot_path = report.site_file_path
else
screenshot_path = 'index.html'
end
%>
<div style="position: relative; margin-bottom: 10px;">
<a href="<%= report.site.uri + '/' + screenshot_path %>" target="_blank">
<img src="<%= report.site.screenshot_url(screenshot_path, '540x405') %>"
style="width: 100%; height: auto; border: 1px solid #ddd;">
</a>
<% if report.type && !report.type.empty? %>
<span class="alert-error" style="position: absolute; top: 5px; right: 5px; padding: 2px 6px; font-size: 11px; border-radius: 3px;">
<%= report.type.upcase %>
</span>
<% end %>
</div>
<h4><%= report.site.username %></h4>
<small style="word-break: break-all; display: block; margin-bottom: 10px;">
<a href="<%= report.site.uri + '/' + screenshot_path %>" target="_blank"><%= report.site.uri + '/' + screenshot_path %></a>
</small>
<small style="line-height: 1.4; display: block; margin-bottom: 10px;">
<a href="/admin/site/<%= report.site.username %>" target="_blank">Site Info</a> •
<a href="/site/<%= report.site.username %>" target="_blank">Site Profile</a> •
<a href="<%= report.site.uri %>" target="_blank">Site Root</a>
</small>
<p><strong><%= report.type %></strong> • <%= report.created_at.ago %><% if report.reporting_site %> • reported by <a href="<%= report.reporting_site.uri %>" target="_blank"><%= report.reporting_site.username %></a><% end %>
</p>
<div style="background: #f9f9f9; padding: 8px; margin-bottom: 10px; border-left: 3px solid #ddd; font-size: 12px; height: 60px; overflow-y: auto;">
<% if report.comments && !report.comments.empty? %>
<%= report.comments[0..200] %><%= report.comments.length > 200 ? '...' : '' %>
<% else %>
<span style="color: #999; font-style: italic;">No comments</span>
<% end %>
</div>
<small style="color: #666; margin-bottom: 15px; display: block; flex-grow: 1;">
<%= report.site.views.format_large_number %> views
</small>
<div id="actions-<%= report.id %>">
<button class="btn btn-Action" onclick="banSite('<%= report.site.username %>', <%= report.id %>, '<%= report.type %>')" style="margin-right: 5px;">
Ban Site
</button>
<% if !report.site.is_nsfw %>
<button class="btn btn-Action" onclick="markNSFW('<%= report.site.username %>', <%= report.id %>)" style="margin-right: 5px;">
Mark NSFW
</button>
<% end %>
<button class="btn" onclick="dismissReport(<%= report.id %>)">
Dismiss
</button>
</div>
</div>
</div>
<% if (index + 1) % 3 == 0 && index != @reports.length - 1 %>
</div><div class="row">
<% end %>
<% end %>
<%== erb :'_pagination', layout: false %>
</div>
<% end %>
</article>
</div>
<script>
function banSite(username, reportId, reportType) {
var formData = new FormData();
formData.append('usernames', username);
formData.append('csrf_token', '<%= csrf_token %>');
fetch('/admin/ban', {
method: 'POST',
body: formData
}).then(function() {
window.location.reload();
}).catch(function(error) {
alert('Error: ' + error);
});
}
function unbanSite(username, reportId) {
var formData = new FormData();
formData.append('username', username);
formData.append('csrf_token', '<%= csrf_token %>');
fetch('/admin/unban', {
method: 'POST',
body: formData
}).then(function() {
window.location.reload();
}).catch(function(error) {
alert('Error: ' + error);
});
}
function markNSFW(username, reportId) {
var formData = new FormData();
formData.append('username', username);
formData.append('csrf_token', '<%= csrf_token %>');
fetch('/admin/mark_nsfw', {
method: 'POST',
body: formData
}).then(function() {
// After marking as NSFW, dismiss the report
var dismissData = new FormData();
dismissData.append('csrf_token', '<%= csrf_token %>');
return fetch('/admin/reports/' + reportId + '/dismiss', {
method: 'POST',
body: dismissData
});
}).then(function() {
window.location.reload();
}).catch(function(error) {
alert('Error: ' + error);
});
}
function dismissReport(reportId) {
var formData = new FormData();
formData.append('csrf_token', '<%= csrf_token %>');
fetch('/admin/reports/' + reportId + '/dismiss', {
method: 'POST',
body: formData
}).then(function(response) {
if (response.ok) {
window.location.reload();
}
}).catch(function(error) {
alert('Error: ' + error);
});
}
</script>