A secure, role-based administration interface for managing MecHack content, media, users, and system settings. Built with Next.js App Router, TypeScript, Tailwind CSS, and Supabase. Includes a polished UX with a smooth top-loading progress bar and consistent design system.
- Overview
- Key Features
- Architecture
- Tech Stack
- Getting Started
- Environment Variables
- Project Structure
- Routing & Modules
- Authentication & Roles
- Media Library
- Audit Logs
- Styling & UI
- Quality & Scripts
- Deployment
- Troubleshooting
- License
The Admin Panel is a separate Next.js application designed for editors and administrators. It uses server-first data fetching with Supabase SSR clients, protects routes via middleware, and enforces role-based access (Admin, Superadmin). The UI is clean, responsive, and optimized for daily content workflows.
- Content Management
- Create, edit, publish: News, Projects, Events
- Rich text editing (TipTap with image support)
- Slug generation and basic SEO fields
- Users & Roles
- Role-based access: Admin, Superadmin
- Superadmin-only sections (e.g., Users management)
- Media Library
- Drag & drop uploads to Supabase Storage
- Folder-like organization (news, projects, events, uploads)
- Grid/List views, sort and search
- Observability & System
- Audit trail via
/api/auditendpoint - Top loader progress indicator for navigation
- Audit trail via
- UX & Productivity
- Keyboard-friendly forms
- Consistent components and layout
- Dark mode support via theme toggle
- Next.js 15 App Router (
/src/app) with server components - Supabase SSR integration for secure, cookie-based sessions
- Middleware protection for authenticated and role-guarded routes
- Modular feature directories:
content/,media/,users/,settings/, etc.
Supabase Clients
- Server:
src/lib/supabase/server.ts - Browser:
src/lib/supabase/client.ts
Middleware
src/middleware.tsverifies session cookies and redirects unauthenticated users to/auth/sign-in- Fetches
profiles.roleand restricts access to admin-only routes - Redirects non-admins to the public website (configurable)
- Framework: Next.js 15, React 19, TypeScript 5
- Data: Supabase (Auth, Postgres, Storage)
- UI: Tailwind CSS 3, Radix Primitives, custom components
- Charts: ApexCharts, Recharts
- Forms: React Hook Form + Zod
- Editor: TipTap (+ image extension)
- Requirements
- Node.js 20 LTS (recommended) or >=18.17
- npm 9+ (or yarn/pnpm/bun)
- Install dependencies
cd admin-panel
npm install- Environment variables
Create
admin-panel/.env.local:
NEXT_PUBLIC_SUPABASE_URL=your_supabase_url
NEXT_PUBLIC_SUPABASE_ANON_KEY=your_supabase_anon_key
# Where to send users when they are not allowed in admin (e.g., public website)
NEXT_PUBLIC_PUBLIC_WEBSITE_URL=https://your-public-site.exampleDo not expose service role keys in the frontend.
- Run the dev server
npm run dev
# open http://localhost:3000- Build & start
npm run build
npm startadmin-panel/
├─ public/ # Static assets (logo, images)
├─ src/
│ ├─ app/
│ │ ├─ (home)/ # Dashboard overview
│ │ ├─ auth/ # Sign-in, change password
│ │ ├─ content/
│ │ │ ├─ news/ # News list + form
│ │ │ ├─ projects/ # Projects list + form
│ │ │ └─ events/ # Events list + form
│ │ ├─ media/ # Media library
│ │ ├─ users/ # Users (superadmin-only)
│ │ ├─ settings/ # Settings sections
│ │ ├─ api/ # Route handlers (audit, auth, deploy, ...)
│ │ ├─ layout.tsx # Global layout with AppFrame
│ │ └─ AppFrame.tsx # Header, Sidebar, shell
│ ├─ components/ # UI building blocks
│ ├─ hooks/ # Hooks (use-role, etc.)
│ ├─ lib/ # Supabase, profile utils, helpers
│ ├─ services/ # Charts/services
│ ├─ css/ # Global styles
│ └─ types/ # Type definitions
├─ middleware.ts # Auth + RBAC guard
├─ next.config.mjs
├─ package.json
└─ README.md
- Auth:
/auth/sign-in - Dashboard:
/ - Content:
- News:
/content/news,/content/news/new,/content/news/[id]/edit - Projects:
/content/projects,/content/projects/new,/content/projects/[id]/edit - Events:
/content/events,/content/events/new,/content/events/[id]/edit
- News:
- Media Library:
/media - Users (superadmin):
/users - Settings:
/pages/settingsand nested sections
- Sessions are validated via Supabase cookies (SSR)
- Middleware rules (
src/middleware.ts):- Public-only routes:
/auth/sign-in,/auth/forgot-password,/auth/reset-password - All other routes require a valid session
- Profiles are fetched from
profilestable to readrole - Allowed roles:
admin,superadmin - Superadmin-only prefixes:
/users,/system(reserved) - Non-authorized users are redirected to
NEXT_PUBLIC_PUBLIC_WEBSITE_URL
- Public-only routes:
- Backed by Supabase Storage bucket:
media - Drag & drop uploads with automatic public URLs
- Logical folders:
news/,projects/,events/,uploads/ - Grid/List views, search, sort, pagination-like navigation
POST /api/auditrecords user actions (for authenticated users)GET /api/auditreturns the latest logs (superadmin only)- Captures basic metadata (IP, user agent) for traceability
- Tailwind CSS 3 with custom CSS variables and Satoshi font
- Accessible components via Radix primitives
- Smooth top progress via
nextjs-toploader - Dark mode supported via theme toggle
Scripts
npm run dev # Start dev server
npm run build # Production build
npm run start # Start production server
npm run lint # ESLintConventions
- TypeScript-first; prefer explicit, descriptive names
- Early returns and flat control flow
- Keep components focused; favor composition over bloating
- Accessibility: label interactive controls, keyboard-friendly
Vercel (recommended)
- Import the repository into Vercel
- Set environment variables
- Deploy; Next.js middleware works out-of-the-box
Manual
npm run build
npm start- Redirect loop on protected routes: ensure auth cookies are present and valid
- Getting redirected to website: your profile
roleis notadmin/superadmin - Storage upload fails: verify Supabase Storage bucket
mediaand RLS - Missing images: check
next.config.mjsimage remote patterns if using external hosts - Env vars not loading: confirm
.env.localis placed underadmin-panel/
MIT © MecHack
