Files
f0ckm/views/mod/approve.html
T
2026-09-28 19:03:31 +02:00

113 lines
4.9 KiB
HTML

@include(snippets/header)
<div class="pagewrapper">
<div id="main">
@include(snippets/admin-back)
<div class="container mq">
<header class="mq-header">
<div>
<h1 class="mq-title">Approval Queue</h1>
<div class="mq-subtitle">{{ total }} upload@if(total !== 1)s@endif waiting for approval.</div>
</div>
</header>
@if(pending.length > 0)
<div class="mq-grid">
@each(pending as post)
<div class="mq-card">
<div class="mq-media">
@if(post.mime === 'video/youtube')
<div class="embed-responsive embed-responsive-16by9">
<iframe class="embed-responsive-item" src="https://www.youtube.com/embed/{!! post.dest.replace('yt:', '') !!}" frameborder="0" allowfullscreen></iframe>
</div>
@elseif(post.mime.startsWith('video'))
<video controls loop muted preload="none" poster="/mod/pending/t/{!! post.id !!}.webp">
<source src="/mod/pending/b/{!! post.dest !!}" type="{!! post.mime !!}">
</video>
@elseif(post.mime === 'application/pdf')
<div class="embed-responsive embed-responsive-16by9">
<iframe class="embed-responsive-item" src="/mod/pending/b/{!! post.dest !!}#toolbar=0" loading="lazy" style="border: none;"></iframe>
</div>
@else
<img src="/mod/pending/t/{!! post.id !!}.webp" alt="Preview" loading="lazy">
@endif
</div>
<div class="mq-body">
<div class="mq-meta">
<span><strong>#{!! post.id !!}</strong></span>
<span>by <strong>{!! post.username !!}</strong></span>
<span>{!! post.mime !!}</span>
</div>
<div class="mq-tags">
@each(post.tags as tag)
<span class="badge {!! tag.badge !!}">{!! tag.tag !!}</span>
@endeach
</div>
<div class="mq-actions">
<button type="button" data-id="{!! post.id !!}" class="mq-btn mq-btn-primary btn-approve-async">Approve</button>
<button type="button" data-id="{!! post.id !!}" class="mq-btn mq-btn-danger btn-deny-async">Deny</button>
<button type="button" data-id="{!! post.id !!}" class="mq-btn mq-btn-ghost mq-btn-rating btn-rating-toggle-async"><i class="fa-solid fa-shield-halved"></i> Toggle rating</button>
</div>
</div>
</div>
@endeach
</div>
@else
<div class="mq-empty"><strong>No pending uploads.</strong>Go touch grass?</div>
@endif
@if(pages > 1)
<div class="mq-pager">
@if(page > 1)
<a href="/mod/approve?page={!! page - 1 !!}" class="mq-btn mq-btn-ghost">&laquo; Prev</a>
@endif
<span>Page {!! page !!} of {!! pages !!}</span>
@if(page < pages)
<a href="/mod/approve?page={!! page + 1 !!}" class="mq-btn mq-btn-ghost">Next &raquo;</a>
@endif
</div>
@endif
</div>
{{-- Inside #main so AJAX navigation (which only swaps #main) brings the styles, modal and scripts along --}}
@include(snippets/mod-cards)
<script>
(() => {
// Approve → public
document.querySelectorAll('.btn-approve-async').forEach(btn => {
btn.addEventListener('click', async e => {
e.preventDefault();
btn.disabled = true;
try {
await mq.post('/mod/approve', { id: btn.dataset.id });
mq.flash('{!! t('toast.approve_success') !!}', 'success');
mq.removeCard(btn.closest('.mq-card'));
} catch (err) {
mq.flash(err.message || '{!! t('toast.approve_error') !!}', 'error');
btn.disabled = false;
}
});
});
// Deny → soft deleted (uploader is notified with the reason)
document.querySelectorAll('.btn-deny-async').forEach(btn => {
btn.addEventListener('click', e => {
e.preventDefault();
mq.confirm({
heading: 'Deny upload',
body: 'Deny this upload? It moves to Soft Deleted and the uploader is notified with your reason.',
confirmLabel: 'Deny',
withReason: true,
action: async (reason) => {
await mq.post('/mod/deny', { id: btn.dataset.id, reason });
mq.flash('Upload denied', 'success');
mq.removeCard(btn.closest('.mq-card'));
}
});
});
});
})();
</script>
</div>
</div>
@include(snippets/footer)