Files
moygroup/app/admin/gallery/page.tsx
T

100 lines
5.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 { Trash2, Plus } from 'lucide-react';
import { addGalleryItem, deleteGalleryItem } from '../actions';
import { revalidatePath } from 'next/cache';
import type { Gallery } from '@prisma/client';
export default async function GalleryAdminPage() {
const session = await getSession();
if (!session) redirect('/admin/login');
const galleryItems = await prisma.gallery.findMany({
orderBy: { createdAt: 'desc' }
});
return (
<div>
<div className="flex justify-between items-center mb-8">
<h1 className="text-3xl font-bold">Galeri Yönetimi</h1>
</div>
<div className="grid grid-cols-1 lg:grid-cols-3 gap-8">
{/* Ekleme Formu */}
<div className="lg:col-span-1">
<div className="bg-white dark:bg-slate-900 rounded-2xl shadow-sm border border-slate-200 dark:border-slate-800 p-6 sticky top-8">
<h2 className="text-xl font-bold mb-6">Yeni Resim Ekle</h2>
<form action={async (formData: FormData) => {
'use server';
const title = formData.get('title') as string;
const category = formData.get('category') as string;
const imageUrl = formData.get('imageUrl') as string;
if (title && category && imageUrl) {
await addGalleryItem({ title, category, imageUrl });
revalidatePath('/admin/gallery');
}
}} className="space-y-4">
<div>
<label className="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-1">Başlık</label>
<input type="text" name="title" required className="w-full px-4 py-2 bg-slate-50 dark:bg-slate-800 border border-slate-200 dark:border-slate-700 rounded-lg 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">Kategori (Örn: Beach, Hotel, Kite Surf)</label>
<input type="text" name="category" required className="w-full px-4 py-2 bg-slate-50 dark:bg-slate-800 border border-slate-200 dark:border-slate-700 rounded-lg 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">Resim URL (Cloudinary vs)</label>
<input type="url" name="imageUrl" required className="w-full px-4 py-2 bg-slate-50 dark:bg-slate-800 border border-slate-200 dark:border-slate-700 rounded-lg outline-none focus:ring-2 focus:ring-blue-500" />
</div>
<button type="submit" className="w-full flex items-center justify-center space-x-2 bg-blue-600 hover:bg-blue-700 text-white py-2.5 rounded-lg transition-colors">
<Plus className="w-5 h-5" />
<span>Ekle</span>
</button>
</form>
</div>
</div>
{/* Listeleme */}
<div className="lg:col-span-2">
<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">Mevcut Resimler ({galleryItems.length})</h2>
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
{galleryItems.map((item: Gallery) => (
<div key={item.id} className="group relative rounded-xl overflow-hidden border border-slate-200 dark:border-slate-700 bg-slate-50 dark:bg-slate-800">
<div className="aspect-video w-full overflow-hidden bg-slate-200 dark:bg-slate-700">
{/* eslint-disable-next-line @next/next/no-img-element */}
<img src={item.imageUrl} alt={item.title} className="w-full h-full object-cover" />
</div>
<div className="p-3">
<h3 className="font-semibold text-slate-800 dark:text-white truncate">{item.title}</h3>
<p className="text-sm text-slate-500 dark:text-slate-400">{item.category}</p>
</div>
<div className="absolute top-2 right-2 opacity-0 group-hover:opacity-100 transition-opacity">
<form action={async () => {
'use server';
await deleteGalleryItem(item.id);
revalidatePath('/admin/gallery');
}}>
<button type="submit" className="p-2 bg-red-600 hover:bg-red-700 text-white rounded-lg shadow-lg transition-colors">
<Trash2 className="w-4 h-4" />
</button>
</form>
</div>
</div>
))}
{galleryItems.length === 0 && (
<div className="col-span-full py-8 text-center text-slate-500">
Galeriye henüz resim eklenmemiş.
</div>
)}
</div>
</div>
</div>
</div>
</div>
);
}