feat(admin): add hidden admin panel, ban system, ads, and legal pages

- Admin panel at /p/[ADMIN_SECRET]/* — middleware returns 404 for wrong/missing secret
- tRPC adminRouter: getStats, listPosts, deletePost, listComments, deleteComment,
  listUsers, banUser/unbanUser, listAds, createAd/updateAd/deleteAd, getActiveAds,
  listModerators, grantRole/revokeRole, getModerationLog, getActiveBan
- Prisma schema: AdminRole, UserBan, Advertisement, ModerationLog models added
- Ban enforcement: (app)/layout.tsx checks active ban on every request → /banned
- Feed ad injection: active ads shown every 7th post in FeedList (AdCard component)
- Clerk middleware.ts: protects all routes; /p/[secret] validated before auth check
- Impressum + Datenschutz pages: contact data base64-obfuscated, decoded client-side only
- shadcn Switch component added
- ADMIN_SECRET + ADMIN_OWNER_ID documented in .env.example
This commit is contained in:
admin committed 2026-06-21 15:21:07 +02:00
1 parent e407064866
commit b5f02fe7a4
18 files changed
+1815 -6

No files matched your search

+8
View File
@@ -21,3 +21,11 @@ CLERK_SECRET_KEY="sk_test_xxxxxxxxxxxxxxxxxxxx"
NEXT_PUBLIC_SUPABASE_URL="https://xxxxxxxxxxxxxxxxxxxx.supabase.co"
# Supabase Dashboard -> Project Settings -> API -> service_role (secret!)
SUPABASE_SERVICE_ROLE_KEY="eyJxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
# ── Admin Panel ───────────────────────────────────────────────
# NEVER use NEXT_PUBLIC_ prefix — these MUST stay server-only!
# ADMIN_SECRET: random UUID path segment (/p/[secret]/) — generate with:
# node -e "console.log(require('crypto').randomUUID())"
ADMIN_SECRET="your-random-uuid-here"
# ADMIN_OWNER_ID: Your Clerk user ID (Clerk dashboard). Bootstraps the super-admin.
ADMIN_OWNER_ID="user_xxxxxxxxxxxxxxxxxxxx"