Admin Dashboard

Managing users, analytics, and system settings

Admin Dashboard

Comprehensive admin dashboard for managing your SaaS application.

Features

  • User management
  • Analytics and metrics
  • System settings
  • Billing overview
  • Support tickets
  • Activity logs

Access Control

Admin Middleware

// server/middleware/admin.ts
export default defineEventHandler(async (event) => {
  const user = event.context.user
  
  if (!user || user.role !== 'admin') {
    throw createError({
      statusCode: 403,
      message: 'Admin access required'
    })
  }
})

Route Protection

<script setup>
definePageMeta({
  middleware: ['auth', 'admin']
})
</script>

User Management

List Users

// GET /api/admin/users
export default defineEventHandler(async (event) => {
  const query = getQuery(event)
  
  const users = await db
    .select()
    .from(users)
    .limit(query.limit || 50)
    .offset(query.offset || 0)
  
  return users
})

Update User

// PATCH /api/admin/users/:id
export default defineEventHandler(async (event) => {
  const userId = getRouterParam(event, 'id')
  const data = await readBody(event)
  
  await db
    .update(users)
    .set(data)
    .where(eq(users.id, userId))
  
  return { success: true }
})

Ban/Suspend User

async function suspendUser(userId: string, reason: string) {
  await db
    .update(users)
    .set({
      status: 'suspended',
      suspendedAt: new Date(),
      suspendedReason: reason
    })
    .where(eq(users.id, userId))
}

Analytics

Dashboard Metrics

export default defineEventHandler(async (event) => {
  const [
    totalUsers,
    activeUsers,
    totalRevenue,
    newSignups
  ] = await Promise.all([
    db.select({ count: count() }).from(users),
    db.select({ count: count() })
      .from(users)
      .where(gte(users.lastActiveAt, subDays(new Date(), 30))),
    db.select({ sum: sum(subscriptions.amount) }).from(subscriptions),
    db.select({ count: count() })
      .from(users)
      .where(gte(users.createdAt, subDays(new Date(), 7)))
  ])
  
  return {
    totalUsers: totalUsers[0].count,
    activeUsers: activeUsers[0].count,
    totalRevenue: totalRevenue[0].sum,
    newSignups: newSignups[0].count
  }
})

Activity Logs

Log Events

async function logActivity(event: {
  userId: string
  action: string
  resource: string
  metadata?: any
}) {
  await db.insert(activityLogs).values({
    userId: event.userId,
    action: event.action,
    resource: event.resource,
    metadata: event.metadata,
    createdAt: new Date()
  })
}

View Logs

export default defineEventHandler(async (event) => {
  const logs = await db
    .select()
    .from(activityLogs)
    .orderBy(desc(activityLogs.createdAt))
    .limit(100)
  
  return logs
})

System Settings

// GET /api/admin/settings
export default defineEventHandler(async () => {
  const settings = await db.select().from(systemSettings)
  return Object.fromEntries(
    settings.map(s => [s.key, s.value])
  )
})

// PATCH /api/admin/settings
export default defineEventHandler(async (event) => {
  const data = await readBody(event)
  
  for (const [key, value] of Object.entries(data)) {
    await db
      .insert(systemSettings)
      .values({ key, value })
      .onConflictDoUpdate({
        target: systemSettings.key,
        set: { value, updatedAt: new Date() }
      })
  }
  
  return { success: true }
})

Billing Overview

export default defineEventHandler(async () => {
  const [
    activeSubscriptions,
    monthlyRecurringRevenue,
    churnRate,
    averageRevenuePerUser
  ] = await calculateBillingMetrics()
  
  return {
    activeSubscriptions,
    mrr: monthlyRecurringRevenue,
    churnRate,
    arpu: averageRevenuePerUser
  }
})

Export Data

// Export users as CSV
export default defineEventHandler(async (event) => {
  const users = await db.select().from(users)
  
  const csv = [
    'ID,Email,Name,Created At,Status',
    ...users.map(u => 
      `${u.id},${u.email},${u.name},${u.createdAt},${u.status}`
    )
  ].join('\n')
  
  setHeader(event, 'Content-Type', 'text/csv')
  setHeader(event, 'Content-Disposition', 'attachment; filename=users.csv')
  
  return csv
})

Best Practices

  1. Implement audit logging
  2. Use proper authorization
  3. Rate limit admin actions
  4. Add confirmation for destructive actions
  5. Monitor admin activity
  6. Implement 2FA for admins
  7. Regular security audits

Next Steps