Development of Admin Panel for LMS
The LMS admin panel is the operational center of the platform. It manages users, courses, cohorts, payments, configuration, and infrastructure. Unlike an instructor account, the admin panel covers the entire platform and requires fine-grained access control.
Roles and Permissions
Multi-level role-based access control (RBAC):
| Role | Access |
|---|---|
| Super Admin | Full access |
| Platform Manager | Courses, users, analytics (no billing) |
| Finance | Transactions, coupons, refunds only |
| Support | View users, courses; no modifications |
| Course Moderator | Only assigned courses |
// Permission check middleware
function requirePermission(permission: string) {
return (req: Request, res: Response, next: NextFunction) => {
const userPermissions = req.user.role.permissions;
if (!userPermissions.includes(permission) && !userPermissions.includes('*')) {
return res.status(403).json({ error: 'Forbidden' });
}
next();
};
}
// Routes with permissions
router.get('/users', requirePermission('users.read'), usersController.list);
router.delete('/users/:id', requirePermission('users.delete'), usersController.delete);
router.get('/finance/transactions', requirePermission('finance.read'), financeController.list);
User Management
User list with filters (role, status, registration date, course) and search. For 100K+ users—cursor-based pagination, not offset.
User card—complete history: courses, transactions, sessions, change log. Actions: change email/password, assign role, block, impersonation (login as user).
Impersonation—critical support function:
// Login as user
app.post('/admin/impersonate/:userId', requirePermission('users.impersonate'), async (req, res) => {
const targetUser = await db.users.findByPk(req.params.userId);
// Save original user in session
req.session.impersonatorId = req.user.id;
req.session.userId = targetUser.id;
// Log action
await auditLog.create({
action: 'impersonate',
actorId: req.user.id,
targetId: targetUser.id,
ip: req.ip,
});
res.redirect('/dashboard');
});
Course Management
- List all courses with filters (status, category, instructor)
- Quick status change: draft → published → archive
- Course statistics: enrollments, progress, revenue, retention
- Cohort management: creation, bulk student enrollment
- Course cloning for new cohorts
Finance Section
interface TransactionListFilters {
dateFrom?: Date;
dateTo?: Date;
status?: 'succeeded' | 'pending' | 'failed' | 'refunded';
paymentMethod?: string;
userId?: string;
courseId?: string;
minAmount?: number;
}
Functions:
- Transaction list with CSV/Excel export
- Payment refund (Stripe Refund API) with reason
- Promo codes: create, restrictions (course, expiry, usage count, % discount)
- MRR/ARR charts, LTV by cohort
Platform Analytics
-- Dashboard metrics for period
SELECT
COUNT(DISTINCT e.student_id) FILTER (WHERE e.created_at >= $1) AS new_enrollments,
COUNT(DISTINCT e.student_id) FILTER (WHERE cp.last_activity_at >= NOW() - INTERVAL '7 days') AS dau_7d,
COUNT(DISTINCT c.id) FILTER (WHERE c.completed_at >= $1) AS completions,
SUM(t.amount) FILTER (WHERE t.created_at >= $1 AND t.status = 'succeeded') AS revenue
FROM enrollments e
LEFT JOIN course_progress cp ON cp.student_id = e.student_id
LEFT JOIN transactions t ON t.user_id = e.student_id;
Grafana or built-in chart components (Recharts/Chart.js): MAU, new registrations, revenue, % course completion.
Platform Configuration
Settings via admin panel without deployment:
- Email templates (Twig/Handlebars editor with preview)
- Notification settings (which types enabled by default)
- Payment system settings (Stripe/PayPal keys)
- SEO meta tags for course pages
- Feature flags (enable/disable features for % of users)
Audit Log
Every admin action is logged:
CREATE TABLE audit_log (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
actor_id UUID REFERENCES users(id),
action VARCHAR(200) NOT NULL, -- 'user.delete', 'course.publish'
entity_type VARCHAR(100),
entity_id UUID,
old_value JSONB,
new_value JSONB,
ip_address INET,
user_agent TEXT,
created_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE INDEX ON audit_log (actor_id, created_at DESC);
CREATE INDEX ON audit_log (entity_type, entity_id);
UI Framework for Admin Panel
Three options:
- React Admin—ready framework for CRUD interfaces. Fast start, limited customization.
- Tremor / shadcn/ui—component library for custom admin.
- Refine—headless framework, full UI control with ready CRUD logic.
Timeline
Basic admin panel: users, courses, transactions, analytics dashboard—2–3 weeks. Advanced features: impersonation, audit log, feature flags, email editor—another 1–2 weeks.







