submissions(#23): admin "Submissions" sub-tab (approve/deny)

The headline: an admin surface to triage the structured submissions.
- profile-modal.html: "Submissions" sub-tab button + #adminSubmissionsSection
  (refresh + loading/empty + list), alongside Whitelist/Blacklist/Blocked
  videos/Moderators.
- ProfileAdminController: adds "submissions" to the sub-tab machinery (button +
  section maps, selectAdminSubtab dispatch, refreshAdminPaneState populate), gates
  the tab on FEATURE_SUBMISSIONS, and wires the list/refresh listeners.
- js/ui/profileModal/submissionsSection.js (extracted to keep the controller under
  the 1200-line cap, like blockedVideosSection.js): populate/render + approve/deny.
  Approve (applications only) → accessControl.addToWhitelist(actor, applicant) +
  markSubmissionResolved(approved) + refresh the whitelist; Deny/Dismiss →
  markSubmissionResolved(denied). Optimistic remove; re-sync on failure. Cards show
  the type badge + claimed applicant + body.
- tailwind.source.css: .submission-card* (token-only).

Gated by FEATURE_SUBMISSIONS (tab hidden when off). Lint + build clean;
profile-modal-controller tests 26/26.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
thePR0M3TH3ANandClaude Opus 4.8 committed 2026-07-06 20:40:06 -04:00
1 parent 28b23e0078
commit 2a21756842
4 files changed
+378 -2

No files matched your search

+54
View File
@@ -3168,6 +3168,60 @@
flex-shrink: 0;
}
/* #23: admin Submissions cards. */
.submission-card {
display: flex;
flex-direction: column;
gap: var(--space-2xs);
padding: var(--space-sm);
border: var(--border-width-hairline) solid var(--color-border-subtle);
border-radius: var(--radius-md);
background-color: var(--color-page-alt);
}
.submission-card + .submission-card {
margin-block-start: var(--space-2xs);
}
.submission-card__head {
display: flex;
align-items: center;
gap: var(--space-sm);
flex-wrap: wrap;
}
.submission-card__type {
padding-block: var(--space-3xs);
padding-inline: var(--space-2xs);
border-radius: var(--radius-full);
font-size: var(--font-size-2xs);
font-weight: 600;
color: var(--color-white);
background-color: var(--color-accent-strong);
}
.submission-card__applicant {
min-inline-size: 0;
font-size: var(--font-size-2xs);
color: var(--color-text-muted);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.submission-card__body {
margin: 0;
font-size: var(--font-size-sm);
color: var(--color-text);
white-space: pre-wrap;
word-break: break-word;
}
.submission-card__actions {
display: flex;
gap: var(--space-2xs);
}
/* #43: always-visible active-identity pill. Rendered after the header in
flow and pulled up with a negative block-start margin so it sits half-on /
half-off the header divider — every pane shows who you're acting as. */