feat: add admin panel, Openinary media integration and standardized footer backlink
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
import { prisma } from '@/lib/db';
|
||||
import { getSession } from '@/lib/auth';
|
||||
import { redirect } from 'next/navigation';
|
||||
import { Trash2, CheckCircle } from 'lucide-react';
|
||||
import { deleteContact, markContactAsRead } from '../actions';
|
||||
import { revalidatePath } from 'next/cache';
|
||||
|
||||
export default async function ContactAdminPage() {
|
||||
const session = await getSession();
|
||||
if (!session) redirect('/admin/login');
|
||||
|
||||
const messages = await prisma.contactMessage.findMany({
|
||||
orderBy: { createdAt: 'desc' }
|
||||
});
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h1 className="text-3xl font-bold mb-8">İletişim Mesajları</h1>
|
||||
<div className="bg-white dark:bg-slate-900 rounded-2xl shadow-sm border border-slate-200 dark:border-slate-800 overflow-hidden">
|
||||
<div className="overflow-x-auto">
|
||||
<table className="w-full text-left border-collapse">
|
||||
<thead>
|
||||
<tr className="bg-slate-50 dark:bg-slate-800/50 border-b border-slate-200 dark:border-slate-800">
|
||||
<th className="p-4 font-semibold text-sm text-slate-600 dark:text-slate-300">Tarih</th>
|
||||
<th className="p-4 font-semibold text-sm text-slate-600 dark:text-slate-300">Gönderen</th>
|
||||
<th className="p-4 font-semibold text-sm text-slate-600 dark:text-slate-300">E-posta</th>
|
||||
<th className="p-4 font-semibold text-sm text-slate-600 dark:text-slate-300">Konu</th>
|
||||
<th className="p-4 font-semibold text-sm text-slate-600 dark:text-slate-300">Mesaj</th>
|
||||
<th className="p-4 font-semibold text-sm text-slate-600 dark:text-slate-300">Durum</th>
|
||||
<th className="p-4 font-semibold text-sm text-slate-600 dark:text-slate-300">İşlem</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{messages.map(msg => (
|
||||
<tr key={msg.id} className="border-b border-slate-200 dark:border-slate-800 hover:bg-slate-50 dark:hover:bg-slate-800/50">
|
||||
<td className="p-4 text-sm">{msg.createdAt.toLocaleDateString('tr-TR')}</td>
|
||||
<td className="p-4 text-sm font-medium">{msg.name}</td>
|
||||
<td className="p-4 text-sm text-slate-500 dark:text-slate-400">{msg.email}</td>
|
||||
<td className="p-4 text-sm">{msg.subject || '-'}</td>
|
||||
<td className="p-4 text-sm max-w-xs truncate" title={msg.message}>{msg.message}</td>
|
||||
<td className="p-4 text-sm">
|
||||
{msg.isRead ? (
|
||||
<span className="inline-flex items-center px-2 py-1 rounded-full text-xs font-medium bg-green-100 text-green-800 dark:bg-green-900/30 dark:text-green-400">
|
||||
Okundu
|
||||
</span>
|
||||
) : (
|
||||
<span className="inline-flex items-center px-2 py-1 rounded-full text-xs font-medium bg-amber-100 text-amber-800 dark:bg-amber-900/30 dark:text-amber-400">
|
||||
Yeni
|
||||
</span>
|
||||
)}
|
||||
</td>
|
||||
<td className="p-4 text-sm">
|
||||
<div className="flex items-center space-x-2">
|
||||
{!msg.isRead && (
|
||||
<form action={async () => {
|
||||
'use server';
|
||||
await markContactAsRead(msg.id);
|
||||
revalidatePath('/admin/contact');
|
||||
}}>
|
||||
<button type="submit" className="text-blue-600 hover:text-blue-800 dark:text-blue-400 dark:hover:text-blue-300" title="Okundu İşaretle">
|
||||
<CheckCircle className="w-5 h-5" />
|
||||
</button>
|
||||
</form>
|
||||
)}
|
||||
<form action={async () => {
|
||||
'use server';
|
||||
await deleteContact(msg.id);
|
||||
revalidatePath('/admin/contact');
|
||||
}}>
|
||||
<button type="submit" className="text-red-600 hover:text-red-800 dark:text-red-400 dark:hover:text-red-300" title="Sil">
|
||||
<Trash2 className="w-5 h-5" />
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
{messages.length === 0 && (
|
||||
<tr>
|
||||
<td colSpan={7} className="p-8 text-center text-slate-500">Hiç mesaj bulunamadı.</td>
|
||||
</tr>
|
||||
)}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user