feat: admin dashboard
This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
# Prabhupāda Says — Admin
|
||||
|
||||
A separate Next.js 16 + Tailwind v4 admin panel that talks to the existing Go
|
||||
BFF. It reuses the BFF's cookie session (no separate auth system) and every
|
||||
action is gated server-side by the new `/api/v1/admin/*` endpoints, which
|
||||
require `role = "admin"`.
|
||||
|
||||
## Features
|
||||
|
||||
- Email/password login (with the BFF's OTP step when required) + forgot/reset password
|
||||
- Users — search, paginate, **send a notification** to an individual user
|
||||
- Posts — search, paginate
|
||||
- Collections — search, paginate
|
||||
- Feedback — paginate, filter (all/open/resolved), **reply** (emails the submitter)
|
||||
- Reports — posts / comments / accounts tabs, search, paginate, **resolve**
|
||||
|
||||
## Prerequisites
|
||||
|
||||
The BFF must be running with migration `0038_admin_panel` applied (it runs
|
||||
automatically on BFF startup) and these env vars set **on the BFF**:
|
||||
|
||||
```
|
||||
ADMIN_URL=http://localhost:3001 # this app's origin — added to CORS
|
||||
# (production: ADMIN_URL=https://admin.prabhupadasays.org)
|
||||
```
|
||||
|
||||
Without `ADMIN_URL`, the browser's credentialed requests from this origin are
|
||||
blocked by CORS.
|
||||
|
||||
## Setup
|
||||
|
||||
```bash
|
||||
cd spsays-admin
|
||||
cp .env.example .env.local # set NEXT_PUBLIC_BFF_URL
|
||||
yarn install
|
||||
yarn dev # http://localhost:3001
|
||||
```
|
||||
|
||||
## Make yourself an admin
|
||||
|
||||
The panel only admits users whose role is `admin`. Promote your account once,
|
||||
directly in Postgres:
|
||||
|
||||
```sql
|
||||
UPDATE users SET role = 'admin' WHERE email = 'you@example.com';
|
||||
```
|
||||
|
||||
Then sign in at `/login` with that account's email + password.
|
||||
|
||||
## Production notes
|
||||
|
||||
- Deploy on its own subdomain, e.g. `admin.prabhupadasays.org`, and set
|
||||
`ADMIN_URL` on the BFF to that origin. The session cookie is shared because
|
||||
the BFF sets it on `.prabhupadasays.org`.
|
||||
- The app sets `robots: noindex` and should additionally be access-restricted
|
||||
at the edge if desired — the BFF's `RequireAdmin` is the real security
|
||||
boundary, but defense in depth doesn't hurt.
|
||||
|
||||
## How it maps to the BFF
|
||||
|
||||
| Screen | Endpoint |
|
||||
| ----------- | ------------------------------------------ |
|
||||
| Login | `POST /auth/login` (+ `verify-login-otp`) |
|
||||
| Forgot/Reset| `POST /auth/forgot-password` / `reset-password` |
|
||||
| Users | `GET /admin/users`, `POST /admin/users/{id}/notify` |
|
||||
| Posts | `GET /admin/posts` |
|
||||
| Collections | `GET /admin/collections` |
|
||||
| Feedback | `GET /admin/feedback`, `POST /admin/feedback/{id}/reply` |
|
||||
| Reports | `GET /admin/reports?type=`, `POST /admin/reports/{type}/{id}/resolve` |
|
||||
Reference in New Issue
Block a user