Moderation
The 5-status submission workflow, reviewed one submission at a time.
/admin/submissions is where every product goes through you before it's published. The UI at app/admin/submissions/submission-list.tsx is a per-row table — no bulk actions.
The queue
Each row shows the submission's:
- Thumbnail
- Name + tagline
- Tier badge (Free / Boost / Highlight)
- Submitter
- Status
- Action buttons: Accept, Reject, Request revision
The three actions
Accept
Opens a modal where you pick the target week / year for scheduling. Confirm → submission moves to accepted with scheduled_week + scheduled_year set.
For free tier submissions, the user then gets the submission-accepted.tsx email. For Boost tier, this step usually never runs — Boost submissions are auto-accepted at payment time. For Highlight, the product is already published, so you don't see it here.
Reject
Opens a modal for the rejection reason. Confirm → submission moves to rejected, user receives submission-rejected.tsx.
Refund is manual. lib/stripe-refund.ts generates a link to the Stripe Dashboard payment page — you open it and click Refund there. To make this automatic, replace the helper with a direct Stripe API call (see Stripe integration).
Request revision
Opens a modal with checkbox-based reason presets:
- Thumbnail quality
- Name / tagline
- Website URL
- Description
Plus a free-text field for anything not covered. Confirm → submission moves to revision, user receives submission-revision.tsx with the selected reasons and a Sunday deadline.
Filtering
Standard table filters:
- Status (pending / revision / accepted / rejected / draft)
- Tier (free / boost / highlight)
- Sort (newest / oldest)
- Search (name, tagline, submitter)
All filter state lives in the URL via nuqs — bookmark-friendly.
No bulk operations
The shipped UI does not support:
- Selecting multiple rows
- Bulk accept / reject
- Keyboard shortcuts
If you process lots of submissions and want bulk moderation, you'd add checkboxes + a toolbar. The underlying server actions in lib/actions/admin.ts would need minimal changes.
Admin-triggered acceptance of paid tiers
If you want to manually re-accept a Boost or Highlight submission (e.g. after a revision loop), use the same Accept flow. The Stripe-linked status tracking is preserved on the submission row.
Delegation
Promote a second user to admin from /admin/users to share moderation load. All admins see the same queue.