Files
moybeach-main/app/admin/users/page.tsx
T

186 lines
8.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { prisma } from '@/lib/db';
import { getSession } from '@/lib/auth';
import { redirect } from 'next/navigation';
import { UserPlus, Trash2, KeyRound, ShieldCheck } from 'lucide-react';
import { createUser, deleteUser, changePassword } from './actions';
export default async function UsersAdminPage() {
const session = await getSession();
if (!session) redirect('/admin/login');
const users = await prisma.user.findMany({
orderBy: { createdAt: 'asc' },
});
return (
<div>
<h1 className="text-3xl font-bold mb-8">Kullanıcı Yönetimi</h1>
<div className="grid grid-cols-1 lg:grid-cols-2 gap-8">
{/* Sol: Kullanıcı listesi */}
<div className="space-y-6">
{/* Yeni kullanıcı ekle */}
<div className="bg-white dark:bg-slate-900 rounded-2xl shadow-sm border border-slate-200 dark:border-slate-800 p-6">
<h2 className="text-xl font-bold mb-6 flex items-center gap-2">
<UserPlus className="w-5 h-5 text-blue-500" />
Yeni Kullanıcı Ekle
</h2>
<form action={createUser} className="space-y-4">
<div>
<label className="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-1">
Kullanıcı Adı
</label>
<input
type="text"
name="username"
required
placeholder="kullanici_adi"
className="w-full px-4 py-2.5 rounded-lg border border-slate-200 dark:border-slate-700 bg-white dark:bg-slate-800 text-slate-900 dark:text-white focus:outline-none focus:ring-2 focus:ring-blue-500"
/>
</div>
<div>
<label className="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-1">
Şifre
</label>
<input
type="password"
name="password"
required
placeholder="••••••••"
minLength={6}
className="w-full px-4 py-2.5 rounded-lg border border-slate-200 dark:border-slate-700 bg-white dark:bg-slate-800 text-slate-900 dark:text-white focus:outline-none focus:ring-2 focus:ring-blue-500"
/>
</div>
<div>
<label className="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-1">
Şifre Tekrar
</label>
<input
type="password"
name="confirmPassword"
required
placeholder="••••••••"
minLength={6}
className="w-full px-4 py-2.5 rounded-lg border border-slate-200 dark:border-slate-700 bg-white dark:bg-slate-800 text-slate-900 dark:text-white focus:outline-none focus:ring-2 focus:ring-blue-500"
/>
</div>
<button
type="submit"
className="w-full px-4 py-2.5 bg-blue-600 hover:bg-blue-700 text-white font-semibold rounded-lg transition-colors"
>
Kullanıcı Ekle
</button>
</form>
</div>
{/* Mevcut kullanıcılar */}
<div className="bg-white dark:bg-slate-900 rounded-2xl shadow-sm border border-slate-200 dark:border-slate-800 p-6">
<h2 className="text-xl font-bold mb-6 flex items-center gap-2">
<ShieldCheck className="w-5 h-5 text-green-500" />
Mevcut Kullanıcılar ({users.length})
</h2>
<div className="space-y-3">
{users.map((user: any) => (
<div
key={user.id}
className="flex items-center justify-between p-4 rounded-lg border border-slate-100 dark:border-slate-800 bg-slate-50 dark:bg-slate-800/50"
>
<div>
<p className="font-semibold text-slate-800 dark:text-white">{user.username}</p>
<p className="text-xs text-slate-500 dark:text-slate-400 mt-0.5">
{new Date(user.createdAt).toLocaleDateString('tr-TR', {
day: 'numeric',
month: 'long',
year: 'numeric',
})}
</p>
</div>
{users.length > 1 && (
<form action={deleteUser}>
<input type="hidden" name="id" value={user.id} />
<button
type="submit"
title="Kullanıcıyı Sil"
className="p-2 text-red-400 hover:text-red-600 hover:bg-red-50 dark:hover:bg-red-900/20 rounded-lg transition-colors"
onClick={(e) => {
if (!confirm(`"${user.username}" kullanıcısı silinsin mi?`)) {
e.preventDefault();
}
}}
>
<Trash2 className="w-4 h-4" />
</button>
</form>
)}
</div>
))}
{users.length === 0 && (
<p className="text-slate-500 text-sm text-center py-4">Kullanıcı bulunamadı.</p>
)}
</div>
</div>
</div>
{/* Sağ: Şifre değiştir */}
<div className="bg-white dark:bg-slate-900 rounded-2xl shadow-sm border border-slate-200 dark:border-slate-800 p-6 h-fit">
<h2 className="text-xl font-bold mb-6 flex items-center gap-2">
<KeyRound className="w-5 h-5 text-amber-500" />
Şifre Değiştir
</h2>
<form action={changePassword} className="space-y-4">
<div>
<label className="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-1">
Kullanıcı
</label>
<select
name="userId"
required
className="w-full px-4 py-2.5 rounded-lg border border-slate-200 dark:border-slate-700 bg-white dark:bg-slate-800 text-slate-900 dark:text-white focus:outline-none focus:ring-2 focus:ring-blue-500"
>
<option value="">Kullanıcı seçin</option>
{users.map((user: any) => (
<option key={user.id} value={user.id}>
{user.username}
</option>
))}
</select>
</div>
<div>
<label className="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-1">
Yeni Şifre
</label>
<input
type="password"
name="newPassword"
required
placeholder="••••••••"
minLength={6}
className="w-full px-4 py-2.5 rounded-lg border border-slate-200 dark:border-slate-700 bg-white dark:bg-slate-800 text-slate-900 dark:text-white focus:outline-none focus:ring-2 focus:ring-blue-500"
/>
</div>
<div>
<label className="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-1">
Yeni Şifre Tekrar
</label>
<input
type="password"
name="confirmPassword"
required
placeholder="••••••••"
minLength={6}
className="w-full px-4 py-2.5 rounded-lg border border-slate-200 dark:border-slate-700 bg-white dark:bg-slate-800 text-slate-900 dark:text-white focus:outline-none focus:ring-2 focus:ring-blue-500"
/>
</div>
<button
type="submit"
className="w-full px-4 py-2.5 bg-amber-500 hover:bg-amber-600 text-white font-semibold rounded-lg transition-colors"
>
Şifreyi Güncelle
</button>
</form>
</div>
</div>
</div>
);
}