feat: admin user creation, Vite migration, dialog fix, pl24 integration
- Add POST /admin/users endpoint with password hashing and role support - Add user creation dialog to admin users page - Migrate web from Next.js to Vite + TanStack Router - Fix Dialog component positioning for Tailwind CSS v4 - Add @source directive for @sase/ui package scanning - Add pl24 integration parsers and vehicle decode flow - Backup old Next.js app to apps/web-nj Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { Controller, Get, Param, Query } from "@nestjs/common";
|
||||
import { Body, Controller, Get, Param, Post, Query } from "@nestjs/common";
|
||||
import { AdminService } from "./admin.service";
|
||||
import { Roles } from "../common/decorators/roles.decorator";
|
||||
|
||||
@@ -7,6 +7,13 @@ import { Roles } from "../common/decorators/roles.decorator";
|
||||
export class AdminController {
|
||||
constructor(private adminService: AdminService) {}
|
||||
|
||||
@Post("users")
|
||||
async createUser(
|
||||
@Body() body: { name: string; email: string; password: string; role?: string },
|
||||
) {
|
||||
return this.adminService.createUser(body);
|
||||
}
|
||||
|
||||
@Get("dashboard")
|
||||
async getDashboardStats() {
|
||||
return this.adminService.getDashboardStats();
|
||||
|
||||
@@ -1,14 +1,22 @@
|
||||
import { Inject, Injectable, Logger, NotFoundException } from "@nestjs/common";
|
||||
import {
|
||||
ConflictException,
|
||||
Inject,
|
||||
Injectable,
|
||||
Logger,
|
||||
NotFoundException,
|
||||
} from "@nestjs/common";
|
||||
import { and, count, desc, eq, gte, ilike, inArray, or, sql } from "drizzle-orm";
|
||||
import { DATABASE, Database } from "../database/database.provider";
|
||||
import {
|
||||
users,
|
||||
accounts,
|
||||
userSubscriptions,
|
||||
payments,
|
||||
queryLogs,
|
||||
brands,
|
||||
referrals,
|
||||
} from "../database/schema/core";
|
||||
import { hashPassword } from "better-auth/crypto";
|
||||
|
||||
@Injectable()
|
||||
export class AdminService {
|
||||
@@ -16,6 +24,54 @@ export class AdminService {
|
||||
|
||||
constructor(@Inject(DATABASE) private db: Database) {}
|
||||
|
||||
async createUser(data: {
|
||||
name: string;
|
||||
email: string;
|
||||
password: string;
|
||||
role?: string;
|
||||
}) {
|
||||
// Check if email already exists
|
||||
const [existing] = await this.db
|
||||
.select({ id: users.id })
|
||||
.from(users)
|
||||
.where(eq(users.email, data.email))
|
||||
.limit(1);
|
||||
|
||||
if (existing) {
|
||||
throw new ConflictException("Bu e-posta adresi zaten kullaniliyor");
|
||||
}
|
||||
|
||||
const hashedPassword = await hashPassword(data.password);
|
||||
|
||||
// Insert user
|
||||
const [newUser] = await this.db
|
||||
.insert(users)
|
||||
.values({
|
||||
name: data.name,
|
||||
email: data.email,
|
||||
emailVerified: true,
|
||||
role: data.role || "user",
|
||||
})
|
||||
.returning({
|
||||
id: users.id,
|
||||
name: users.name,
|
||||
email: users.email,
|
||||
role: users.role,
|
||||
createdAt: users.createdAt,
|
||||
});
|
||||
|
||||
// Insert credential account for better-auth compatibility
|
||||
await this.db.insert(accounts).values({
|
||||
id: crypto.randomUUID(),
|
||||
userId: newUser.id,
|
||||
accountId: newUser.id,
|
||||
providerId: "credential",
|
||||
password: hashedPassword,
|
||||
});
|
||||
|
||||
return newUser;
|
||||
}
|
||||
|
||||
async getDashboardStats() {
|
||||
const now = new Date();
|
||||
const thirtyDaysAgo = new Date(now.getTime() - 30 * 24 * 60 * 60 * 1000);
|
||||
|
||||
Reference in New Issue
Block a user