Falsafa
FrontendHigh-Level Design

Admin Panel

Admin layout, server-side auth guard, stats dashboard, content moderation (books, comments, reports), user management, and system notification CRUD.

The admin panel is a sub-application under /admin/ with its own layout, auth guard, and set of API routes. Access is restricted to users with the admin or moderator role.

Layout and Access Control

The admin layout (app/admin/layout.tsx) is a Next.js layout file that wraps all /admin/* routes. Every request to an admin page goes through two checks:

  1. Authentication check - calls auth() and redirects to /library?error=unauthenticated if the user is not logged in.
  2. Role check - calls checkIsStaff() from auth.ts, which queries user_roles using the admin client. Non-staff users are redirected to /library?error=unauthorized.

The layout renders:

  • An <AdminSidebar> (server component) with a navigation menu and user info.
  • An <AdminLayout> (client component) that manages the mobile sidebar overlay.

Pages inside the admin layout do not import AppLayout - the admin layout provides its own shell.

Dashboard

/admin/ displays aggregate statistics and recent activity. The stats are fetched from GET /api/admin/stats, which runs three aggregate queries:

  • Total books count
  • Total users count
  • Total purchases count

The admin dashboard also shows a recent-activity timeline populated from the purchases and books tables, joined with user profiles.

Content Moderation

Books

/admin/books displays a searchable, filterable table of all books. Each row shows the title, author, language, and status. Admins can:

  • Approve a book - updates books.status to "processed".
  • Reject a book - updates books.status to "failed".
  • Delete a book - removes the book and its characters. Uses the admin client to bypass RLS.

Categories

/admin/categories is a full CRUD interface for the categories table. Categories have a name, slug, image URL, and an optional image upload. Admin API routes use getAdminClient() for all category mutations.

Comments

/admin/comments displays all book_comments with the associated book title, user profile, and content. Moderators can delete comments. Comments are fetched via the admin client (bypassing RLS so all comments are visible regardless of ownership).

Reports

/admin/reports lists user-submitted reports on books, comments, or other users. Reports have status tracking (pending/resolved/dismissed). Admins can:

  • Resolve a report - marks it as handled.
  • Dismiss a report - marks it as reviewed with no action.

User Management

/admin/users lists all profiles with their role and status. The view is searchable by name and email. Admins can:

  • Change a user's role between user, moderator, and admin.
  • Block or unblock a user (updating the status field in profiles).
  • View the user's email, display name, and current role.

All mutations go through the admin client to bypass RLS.

System Notifications

/admin/notifications is a CRUD interface for system-wide notifications. Notifications have:

  • A title and message body
  • A type (info, warning, error, success)
  • An optional target user ID (if null, the notification is broadcast to all users)
  • Read/unread tracking per recipient

When an admin creates a notification targeting all users, the frontend inserts individual rows into the notifications table for every user with an active profile. The notification bell in the AppLayout sidebar polls for unread count.

Platform Settings

/admin/settings shows a key-value settings panel backed by the settings table. Each setting is a row with a key and value (both JSON). Settings are fetched and updated via GET/PUT /api/admin/settings.

On this page