From 6f04e39bf33829f02a08c3973ed085db977029cd Mon Sep 17 00:00:00 2001 From: AyrisAI Date: Fri, 15 May 2026 19:12:42 +0300 Subject: [PATCH] feat: add admin user management (create, password change) --- app/admin/actions.ts | 41 ++++++++++++++++ app/admin/components/UserForm.tsx | 78 +++++++++++++++++++++++++++++++ app/admin/layout.tsx | 4 ++ app/admin/users/UserManager.tsx | 75 +++++++++++++++++++++++++++++ app/admin/users/page.tsx | 13 ++++++ 5 files changed, 211 insertions(+) create mode 100644 app/admin/components/UserForm.tsx create mode 100644 app/admin/users/UserManager.tsx create mode 100644 app/admin/users/page.tsx diff --git a/app/admin/actions.ts b/app/admin/actions.ts index 72688a8..812c77b 100644 --- a/app/admin/actions.ts +++ b/app/admin/actions.ts @@ -33,6 +33,47 @@ export async function signout() { redirect('/login'); } +/* ────── User Actions ────── */ + +export async function createAdmin(formData: FormData) { + const username = formData.get('username') as string; + const password = formData.get('password') as string; + + const hashedPassword = await bcrypt.hash(password, 10); + + await prisma.user.create({ + data: { + username, + password: hashedPassword, + }, + }); + + revalidatePath('/admin/users'); +} + +export async function updateAdminPassword(id: string, formData: FormData) { + const password = formData.get('password') as string; + const hashedPassword = await bcrypt.hash(password, 10); + + await prisma.user.update({ + where: { id }, + data: { + password: hashedPassword, + }, + }); + + revalidatePath('/admin/users'); +} + +export async function deleteAdmin(id: string) { + const session = await encrypt({ expires: new Date(0) }); // placeholder check + // Don't allow deleting self if we had current user id here, + // but for now simple delete + await prisma.user.delete({ where: { id } }); + + revalidatePath('/admin/users'); +} + export async function createCategory(formData: FormData) { const title = formData.get('title') as string; const externalId = formData.get('externalId') as string; diff --git a/app/admin/components/UserForm.tsx b/app/admin/components/UserForm.tsx new file mode 100644 index 0000000..259ac25 --- /dev/null +++ b/app/admin/components/UserForm.tsx @@ -0,0 +1,78 @@ +'use client'; + +import React, { useState } from 'react'; +import { createAdmin, updateAdminPassword } from '../actions'; + +interface UserFormProps { + initialData?: any; + onClose: () => void; +} + +export default function UserForm({ initialData, onClose }: UserFormProps) { + const [loading, setLoading] = useState(false); + + async function handleSubmit(formData: FormData) { + setLoading(true); + if (initialData) { + await updateAdminPassword(initialData.id, formData); + } else { + await createAdmin(formData); + } + setLoading(false); + onClose(); + } + + return ( +
+
+
+

{initialData ? 'Şifre Değiştir' : 'Yeni Admin Ekle'}

+ +
+
+ {!initialData && ( +
+ + +
+ )} + {initialData && ( +
+ + +
+ )} +
+ + +
+
+ + +
+
+
+
+ ); +} diff --git a/app/admin/layout.tsx b/app/admin/layout.tsx index d6b47b2..5974086 100644 --- a/app/admin/layout.tsx +++ b/app/admin/layout.tsx @@ -33,6 +33,10 @@ export default async function AdminLayout({ Ürünler + + + Kullanıcılar +
diff --git a/app/admin/users/UserManager.tsx b/app/admin/users/UserManager.tsx new file mode 100644 index 0000000..5f9dab6 --- /dev/null +++ b/app/admin/users/UserManager.tsx @@ -0,0 +1,75 @@ +'use client'; + +import React, { useState } from 'react'; +import UserForm from '../components/UserForm'; +import DeleteButton from '../components/DeleteButton'; +import { deleteAdmin } from '../actions'; + +interface UserManagerProps { + users: any[]; +} + +export default function UserManager({ users }: UserManagerProps) { + const [showForm, setShowForm] = useState(false); + const [editingUser, setEditingUser] = useState(null); + + const handleEdit = (user: any) => { + setEditingUser(user); + setShowForm(true); + }; + + const handleClose = () => { + setShowForm(false); + setEditingUser(null); + }; + + return ( +
+
+
+

Kullanıcılar

+

Yönetici hesaplarını yönetin

+
+ +
+ +
+ + + + + + + + + + {users.map((user) => ( + + + + + + ))} + +
Kullanıcı AdıOluşturulmaİşlemler
{user.username} + {new Date(user.createdAt).toLocaleDateString('tr-TR')} + + + {users.length > 1 && ( + { await deleteAdmin(user.id); }} /> + )} +
+
+ + {showForm && ( + + )} +
+ ); +} diff --git a/app/admin/users/page.tsx b/app/admin/users/page.tsx new file mode 100644 index 0000000..5f41e77 --- /dev/null +++ b/app/admin/users/page.tsx @@ -0,0 +1,13 @@ +import React from 'react'; +import { prisma } from '@/app/lib/prisma'; +import UserManager from './UserManager'; + +export const dynamic = 'force-dynamic'; + +export default async function AdminUsersPage() { + const users = await prisma.user.findMany({ + orderBy: { createdAt: 'desc' } + }); + + return ; +}