feat: modernize admin panel UI and add openinary integration
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
import { useActionState, useState, useRef } from 'react'
|
||||
import { saveSettings } from './actions'
|
||||
import Image from 'next/image'
|
||||
import { Upload, X, Loader2 } from 'lucide-react'
|
||||
import { Upload, X, Loader2, Save } from 'lucide-react'
|
||||
|
||||
export default function SettingsForm({
|
||||
defaultRestaurantName,
|
||||
@@ -49,62 +49,62 @@ export default function SettingsForm({
|
||||
}
|
||||
|
||||
return (
|
||||
<form action={action} className="space-y-6">
|
||||
<form action={action} className="space-y-8">
|
||||
{state?.success && (
|
||||
<div className="bg-green-50 text-green-700 p-3 rounded-lg text-sm">
|
||||
<div className="bg-emerald-50 text-emerald-700 px-4 py-3 rounded-xl text-sm font-medium border border-emerald-100/50">
|
||||
{state.message}
|
||||
</div>
|
||||
)}
|
||||
{state?.error && (
|
||||
<div className="bg-red-50 text-red-700 p-3 rounded-lg text-sm">
|
||||
<div className="bg-red-50 text-red-700 px-4 py-3 rounded-xl text-sm font-medium border border-red-100/50">
|
||||
{state.error}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Logo Upload */}
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-gray-700 mb-2">
|
||||
<label className="block text-sm font-semibold text-slate-700 mb-3">
|
||||
Site Logosu
|
||||
</label>
|
||||
<div className="flex items-start gap-4">
|
||||
<div className="flex flex-col sm:flex-row items-start sm:items-center gap-6">
|
||||
{/* Preview */}
|
||||
<div className="relative w-40 h-20 rounded-xl overflow-hidden border-2 border-gray-200 bg-stone-900 flex items-center justify-center flex-shrink-0">
|
||||
<div className="relative w-48 h-24 rounded-2xl overflow-hidden border border-slate-200 bg-slate-900 shadow-inner flex items-center justify-center flex-shrink-0 group">
|
||||
{logoUrl ? (
|
||||
<>
|
||||
<Image
|
||||
src={logoUrl}
|
||||
alt="Logo önizleme"
|
||||
fill
|
||||
className="object-contain p-2"
|
||||
className="object-contain p-3"
|
||||
/>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => { setLogoUrl(''); if (fileInputRef.current) fileInputRef.current.value = '' }}
|
||||
className="absolute top-1 right-1 bg-red-500 text-white rounded-full p-0.5 hover:bg-red-600 transition-colors"
|
||||
className="absolute top-2 right-2 bg-red-500/90 text-white rounded-full p-1 hover:bg-red-600 transition-colors opacity-0 group-hover:opacity-100 backdrop-blur-sm shadow-sm"
|
||||
>
|
||||
<X size={12} />
|
||||
<X size={14} />
|
||||
</button>
|
||||
</>
|
||||
) : (
|
||||
<span className="text-xs text-gray-400 text-center px-2">Logo yok<br />(varsayılan kullanılır)</span>
|
||||
<span className="text-xs text-slate-400 text-center px-4 font-medium">Logo yok<br />(varsayılan kullanılır)</span>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Upload button */}
|
||||
<div className="flex flex-col gap-2 justify-center h-20">
|
||||
<div className="flex flex-col gap-2.5 justify-center">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => fileInputRef.current?.click()}
|
||||
disabled={uploading}
|
||||
className="flex items-center gap-2 px-4 py-2 border-2 border-dashed border-gray-300 rounded-lg text-sm text-gray-600 hover:border-blue-400 hover:text-blue-600 transition-colors disabled:opacity-50"
|
||||
className="flex items-center gap-2 px-5 py-2.5 border-2 border-dashed border-slate-300 rounded-xl text-sm font-medium text-slate-600 hover:border-blue-400 hover:text-blue-600 transition-colors disabled:opacity-50 hover:bg-blue-50/50"
|
||||
>
|
||||
{uploading
|
||||
? <><Loader2 size={16} className="animate-spin" /> Yükleniyor...</>
|
||||
: <><Upload size={16} /> Logo Yükle</>
|
||||
? <><Loader2 size={18} className="animate-spin" /> Yükleniyor...</>
|
||||
: <><Upload size={18} /> Yeni Logo Seç</>
|
||||
}
|
||||
</button>
|
||||
<p className="text-xs text-gray-500">PNG, SVG, WEBP — Maks. 5MB</p>
|
||||
{uploadError && <p className="text-xs text-red-600">{uploadError}</p>}
|
||||
<p className="text-xs text-slate-400 font-medium ml-1">Önerilen format: Şeffaf arka planlı PNG veya SVG (Maks. 5MB)</p>
|
||||
{uploadError && <p className="text-xs text-red-600 font-medium ml-1">{uploadError}</p>}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -118,39 +118,41 @@ export default function SettingsForm({
|
||||
<input type="hidden" name="logo_url" value={logoUrl} />
|
||||
</div>
|
||||
|
||||
<hr className="border-gray-100" />
|
||||
<hr className="border-slate-100" />
|
||||
|
||||
{/* Restaurant Name */}
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-gray-700 mb-1">
|
||||
Restoran / Mekan Adı
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
name="restaurant_name"
|
||||
defaultValue={defaultRestaurantName}
|
||||
required
|
||||
className="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 outline-none transition-colors"
|
||||
/>
|
||||
</div>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
{/* Restaurant Name */}
|
||||
<div>
|
||||
<label className="block text-sm font-semibold text-slate-700 mb-1.5">
|
||||
Restoran / Mekan Adı
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
name="restaurant_name"
|
||||
defaultValue={defaultRestaurantName}
|
||||
required
|
||||
className="w-full px-4 py-2.5 bg-slate-50 border border-slate-200 rounded-xl focus:ring-2 focus:ring-blue-500/20 focus:border-blue-500 focus:bg-white outline-none text-sm transition-all"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Location */}
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-gray-700 mb-1">
|
||||
Konum Bilgisi
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
name="location"
|
||||
defaultValue={defaultLocation}
|
||||
required
|
||||
className="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 outline-none transition-colors"
|
||||
/>
|
||||
{/* Location */}
|
||||
<div>
|
||||
<label className="block text-sm font-semibold text-slate-700 mb-1.5">
|
||||
Konum Bilgisi
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
name="location"
|
||||
defaultValue={defaultLocation}
|
||||
required
|
||||
className="w-full px-4 py-2.5 bg-slate-50 border border-slate-200 rounded-xl focus:ring-2 focus:ring-blue-500/20 focus:border-blue-500 focus:bg-white outline-none text-sm transition-all"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Google Review Url */}
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-gray-700 mb-1">
|
||||
<label className="block text-sm font-semibold text-slate-700 mb-1.5">
|
||||
Google Yorum Linki
|
||||
</label>
|
||||
<input
|
||||
@@ -158,18 +160,21 @@ export default function SettingsForm({
|
||||
name="google_review_url"
|
||||
defaultValue={defaultGoogleReviewUrl}
|
||||
placeholder="https://g.page/r/..."
|
||||
className="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 outline-none transition-colors"
|
||||
className="w-full px-4 py-2.5 bg-slate-50 border border-slate-200 rounded-xl focus:ring-2 focus:ring-blue-500/20 focus:border-blue-500 focus:bg-white outline-none text-sm transition-all"
|
||||
/>
|
||||
<p className="text-xs text-gray-500 mt-1">Eğer buraya link eklerseniz site açılışında ziyaretçilere yorum yapmaları için popup gösterilir.</p>
|
||||
<p className="text-xs text-slate-500 mt-2 font-medium ml-1">Eğer buraya link eklerseniz, ziyaretçilere her 30 dakikada bir işletmenizi değerlendirmelerini isteyen bir açılır pencere (popup) gösterilir.</p>
|
||||
</div>
|
||||
|
||||
<button
|
||||
type="submit"
|
||||
disabled={isPending || uploading}
|
||||
className="bg-blue-600 hover:bg-blue-700 text-white font-medium py-2 px-6 rounded-lg transition-colors disabled:opacity-70"
|
||||
>
|
||||
{isPending ? 'Kaydediliyor...' : 'Kaydet'}
|
||||
</button>
|
||||
<div className="pt-4 flex justify-end">
|
||||
<button
|
||||
type="submit"
|
||||
disabled={isPending || uploading}
|
||||
className="bg-blue-600 hover:bg-blue-700 text-white font-medium py-2.5 px-8 rounded-xl transition-all shadow-sm hover:shadow hover:-translate-y-0.5 disabled:opacity-70 disabled:hover:translate-y-0 disabled:shadow-none flex items-center gap-2"
|
||||
>
|
||||
<Save size={18} />
|
||||
{isPending ? 'Kaydediliyor...' : 'Değişiklikleri Kaydet'}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user