initial commit
This commit is contained in:
163
app/api/admin/users/route.ts
Normal file
163
app/api/admin/users/route.ts
Normal file
@@ -0,0 +1,163 @@
|
||||
import { NextRequest, NextResponse } from 'next/server'
|
||||
import { withAdminAuth } from '@/lib/admin-middleware'
|
||||
import { connectDB } from '@/lib/mongodb'
|
||||
import { User } from '@/models/user'
|
||||
import { z } from 'zod'
|
||||
|
||||
const UserUpdateSchema = z.object({
|
||||
name: z.string().min(1).optional(),
|
||||
email: z.string().email().optional(),
|
||||
role: z.enum(['user', 'admin']).optional(),
|
||||
isVerified: z.boolean().optional(),
|
||||
balance: z.number().min(0).optional(),
|
||||
})
|
||||
|
||||
const UserCreateSchema = z.object({
|
||||
name: z.string().min(1),
|
||||
email: z.string().email(),
|
||||
password: z.string().min(6),
|
||||
role: z.enum(['user', 'admin']).default('user'),
|
||||
isVerified: z.boolean().default(false),
|
||||
balance: z.number().min(0).default(0),
|
||||
})
|
||||
|
||||
export async function GET(request: NextRequest) {
|
||||
return withAdminAuth(request, async (req, admin) => {
|
||||
try {
|
||||
await connectDB()
|
||||
|
||||
const { searchParams } = new URL(request.url)
|
||||
const page = parseInt(searchParams.get('page') || '1')
|
||||
const limit = parseInt(searchParams.get('limit') || '20')
|
||||
const search = searchParams.get('search') || ''
|
||||
const role = searchParams.get('role') || ''
|
||||
const verified = searchParams.get('verified') || ''
|
||||
|
||||
const skip = (page - 1) * limit
|
||||
|
||||
// Build filter query
|
||||
const filter: any = {}
|
||||
|
||||
if (search) {
|
||||
filter.$or = [
|
||||
{ name: { $regex: search, $options: 'i' } },
|
||||
{ email: { $regex: search, $options: 'i' } },
|
||||
{ siliconId: { $regex: search, $options: 'i' } },
|
||||
]
|
||||
}
|
||||
|
||||
if (role && role !== 'all') {
|
||||
filter.role = role
|
||||
}
|
||||
|
||||
if (verified && verified !== 'all') {
|
||||
filter.isVerified = verified === 'true'
|
||||
}
|
||||
|
||||
const [users, totalUsers] = await Promise.all([
|
||||
User.find(filter)
|
||||
.select('-password -refreshToken')
|
||||
.sort({ createdAt: -1 })
|
||||
.skip(skip)
|
||||
.limit(limit),
|
||||
User.countDocuments(filter),
|
||||
])
|
||||
|
||||
const totalPages = Math.ceil(totalUsers / limit)
|
||||
|
||||
return NextResponse.json({
|
||||
users,
|
||||
pagination: {
|
||||
currentPage: page,
|
||||
totalPages,
|
||||
totalUsers,
|
||||
hasNext: page < totalPages,
|
||||
hasPrev: page > 1,
|
||||
},
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('Admin users fetch error:', error)
|
||||
return NextResponse.json({ error: 'Failed to fetch users' }, { status: 500 })
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export async function POST(request: NextRequest) {
|
||||
return withAdminAuth(request, async (req, admin) => {
|
||||
try {
|
||||
await connectDB()
|
||||
|
||||
const body = await request.json()
|
||||
const { action, userId, data } = body
|
||||
|
||||
if (action === 'update') {
|
||||
const validatedData = UserUpdateSchema.parse(data)
|
||||
|
||||
const user = await User.findByIdAndUpdate(userId, validatedData, {
|
||||
new: true,
|
||||
runValidators: true,
|
||||
}).select('-password -refreshToken')
|
||||
|
||||
if (!user) {
|
||||
return NextResponse.json({ error: 'User not found' }, { status: 404 })
|
||||
}
|
||||
|
||||
return NextResponse.json({ user })
|
||||
}
|
||||
|
||||
if (action === 'create') {
|
||||
const validatedData = UserCreateSchema.parse(data)
|
||||
|
||||
// Check if user already exists
|
||||
const existingUser = await User.findOne({ email: validatedData.email })
|
||||
if (existingUser) {
|
||||
return NextResponse.json(
|
||||
{ error: 'User with this email already exists' },
|
||||
{ status: 400 }
|
||||
)
|
||||
}
|
||||
|
||||
// Generate unique Silicon ID
|
||||
const generateSiliconId = () => {
|
||||
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
|
||||
let result = 'SP'
|
||||
for (let i = 0; i < 8; i++) {
|
||||
result += chars.charAt(Math.floor(Math.random() * chars.length))
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
let siliconId = generateSiliconId()
|
||||
while (await User.findOne({ siliconId })) {
|
||||
siliconId = generateSiliconId()
|
||||
}
|
||||
|
||||
const user = new User({
|
||||
...validatedData,
|
||||
siliconId,
|
||||
provider: 'local',
|
||||
})
|
||||
|
||||
await user.save()
|
||||
|
||||
const userResponse = await User.findById(user._id).select('-password -refreshToken')
|
||||
return NextResponse.json({ user: userResponse })
|
||||
}
|
||||
|
||||
if (action === 'delete') {
|
||||
const user = await User.findByIdAndDelete(userId)
|
||||
|
||||
if (!user) {
|
||||
return NextResponse.json({ error: 'User not found' }, { status: 404 })
|
||||
}
|
||||
|
||||
return NextResponse.json({ message: 'User deleted successfully' })
|
||||
}
|
||||
|
||||
return NextResponse.json({ error: 'Invalid action' }, { status: 400 })
|
||||
} catch (error) {
|
||||
console.error('Admin user action error:', error)
|
||||
return NextResponse.json({ error: 'Failed to perform user action' }, { status: 500 })
|
||||
}
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user