Files
moybeach-main/app/admin/hero/page.tsx
T
2026-07-10 09:30:48 +03:00

93 lines
4.5 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 { Image as ImageIcon, Video, Upload } from 'lucide-react';
import { updateHeroMedia } from '../actions';
import { revalidatePath } from 'next/cache';
import { uploadImage } from '@/lib/openinary';
export default async function HeroAdminPage() {
const session = await getSession();
if (!session) redirect('/admin/login');
const heroMediaList = await prisma.heroMedia.findMany();
const currentHero = heroMediaList.length > 0 ? heroMediaList[0] : null;
return (
<div>
<div className="flex justify-between items-center mb-8">
<h1 className="text-3xl font-bold">Hero (Ana Ekran) Yönetimi</h1>
</div>
<div className="grid grid-cols-1 lg:grid-cols-2 gap-8">
{/* Yükleme Formu */}
<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">Yeni Medya Yükle</h2>
<form action={async (formData: FormData) => {
'use server';
const file = formData.get('media') as File;
if (file && file.size > 0) {
const url = await uploadImage(file);
// Cloudinary returns video format URLs or we can infer from file type
const type = file.type.startsWith('video/') ? 'video' : 'image';
await updateHeroMedia(url, type);
revalidatePath('/admin/hero');
}
}} className="space-y-4">
<div>
<label className="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-1">
Resim veya Video Seçin (Maksimum 50MB)
</label>
<input
type="file"
name="media"
accept="image/*,video/*"
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 file:mr-4 file:py-2 file:px-4 file:rounded-full file:border-0 file:text-sm file:font-semibold file:bg-blue-50 file:text-blue-700 hover:file:bg-blue-100"
/>
<p className="mt-2 text-xs text-slate-500">
Yeni bir dosya yüklediğinizde, mevcut olan otomatik olarak silinir ve yerini alır. Sadece bir adet Hero medyası bulunabilir.
</p>
</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">
<Upload className="w-5 h-5" />
<span>Yükle ve Güncelle</span>
</button>
</form>
</div>
{/* Mevcut Medya */}
<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">Aktif Medya</h2>
{currentHero ? (
<div className="rounded-xl overflow-hidden border border-slate-200 dark:border-slate-700 bg-slate-50 dark:bg-slate-800">
<div className="aspect-[16/9] w-full overflow-hidden bg-slate-200 dark:bg-slate-700 relative">
{currentHero.type === 'video' ? (
<video
src={currentHero.url}
controls
className="w-full h-full object-cover"
/>
) : (
// eslint-disable-next-line @next/next/no-img-element
<img src={currentHero.url} alt="Hero" className="w-full h-full object-cover" />
)}
<div className="absolute top-2 right-2 bg-black/70 backdrop-blur-md text-white text-xs px-2 py-1 rounded flex items-center space-x-1">
{currentHero.type === 'video' ? <Video className="w-3 h-3" /> : <ImageIcon className="w-3 h-3" />}
<span>{currentHero.type === 'video' ? 'Video' : 'Görsel'}</span>
</div>
</div>
</div>
) : (
<div className="py-12 text-center text-slate-500 bg-slate-50 dark:bg-slate-800 rounded-xl border border-dashed border-slate-300 dark:border-slate-700">
Henüz medya yüklenmemiş. Varsayılan resim gösteriliyor.
</div>
)}
</div>
</div>
</div>
);
}