first commit
This commit is contained in:
@@ -11,25 +11,17 @@ export default function CategorySection({ category, lang, currency }: Props) {
|
||||
const l = lang as 'tr' | 'en'
|
||||
|
||||
return (
|
||||
<section id={category.id} className="category-section category-reveal px-4 pt-9 pb-1">
|
||||
<section id={category.id} className="category-section category-reveal px-4 pt-12 pb-2">
|
||||
{/* Category header */}
|
||||
<div className="mb-4">
|
||||
<div className="flex items-center gap-3 mb-2">
|
||||
{/* Emoji badge with gradient ring */}
|
||||
<div className="mb-6">
|
||||
<div className="flex items-center gap-3 mb-3">
|
||||
{/* Subtle minimal Emoji badge */}
|
||||
<div className="relative flex-shrink-0">
|
||||
{/* Outer glow ring */}
|
||||
<div
|
||||
className="absolute inset-0 rounded-2xl blur-sm opacity-60"
|
||||
className="w-12 h-12 rounded-full flex items-center justify-center text-2xl shadow-sm"
|
||||
style={{
|
||||
background: 'linear-gradient(135deg, #4AAFA8, #5C8A5C)',
|
||||
transform: 'scale(1.15)',
|
||||
}}
|
||||
/>
|
||||
<div
|
||||
className="relative w-11 h-11 rounded-2xl flex items-center justify-center text-xl"
|
||||
style={{
|
||||
background: 'linear-gradient(135deg, rgba(74,175,168,0.18), rgba(92,138,92,0.12))',
|
||||
border: '1px solid rgba(74,175,168,0.30)',
|
||||
background: '#FDFCF8',
|
||||
border: '1px solid rgba(212,200,176,0.40)',
|
||||
}}
|
||||
>
|
||||
{category.emoji}
|
||||
@@ -37,75 +29,43 @@ export default function CategorySection({ category, lang, currency }: Props) {
|
||||
</div>
|
||||
|
||||
{/* Title */}
|
||||
<div className="flex-1 min-w-0">
|
||||
<div className="flex-1 min-w-0 flex items-center gap-2">
|
||||
<h2
|
||||
className="font-display font-semibold italic text-coffee leading-tight"
|
||||
style={{ fontSize: '1.2rem' }}
|
||||
className="font-display font-semibold text-coffee uppercase tracking-wide leading-tight"
|
||||
style={{ fontSize: '1.25rem' }}
|
||||
>
|
||||
{category.label[l]}
|
||||
</h2>
|
||||
{/* Item count badge */}
|
||||
<span
|
||||
className="font-body text-[0.65rem] font-semibold tracking-widest text-muted mt-0.5"
|
||||
>
|
||||
({category.items.length})
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{/* Item count badge */}
|
||||
<span
|
||||
className="flex-shrink-0 font-body text-[0.6rem] font-semibold tracking-widest uppercase rounded-full px-2.5 py-0.5"
|
||||
style={{
|
||||
color: '#8A7265',
|
||||
background: 'rgba(61,43,31,0.07)',
|
||||
border: '1px solid rgba(61,43,31,0.10)',
|
||||
}}
|
||||
>
|
||||
{category.items.length}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{/* Decorative divider */}
|
||||
<div className="flex items-center gap-2 ml-1">
|
||||
<div className="w-1.5 h-1.5 rounded-full bg-teal opacity-70" />
|
||||
<div
|
||||
className="flex-1 h-px"
|
||||
style={{
|
||||
background:
|
||||
'linear-gradient(90deg, rgba(74,175,168,0.40) 0%, rgba(212,200,176,0.40) 60%, transparent 100%)',
|
||||
}}
|
||||
/>
|
||||
<div className="w-1 h-1 rounded-full bg-gold opacity-50" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Items card */}
|
||||
<div
|
||||
className="rounded-2xl overflow-hidden"
|
||||
style={{
|
||||
background: 'rgba(253,250,245,0.72)',
|
||||
border: '1px solid rgba(212,200,176,0.60)',
|
||||
backdropFilter: 'blur(8px)',
|
||||
WebkitBackdropFilter: 'blur(8px)',
|
||||
boxShadow:
|
||||
'0 2px 16px rgba(61,43,31,0.06), 0 1px 3px rgba(61,43,31,0.04)',
|
||||
}}
|
||||
>
|
||||
{/* Thin top gradient line */}
|
||||
{/* Minimalist divider */}
|
||||
<div
|
||||
className="h-px w-full"
|
||||
className="w-full h-px"
|
||||
style={{
|
||||
background:
|
||||
'linear-gradient(90deg, transparent, rgba(74,175,168,0.35), transparent)',
|
||||
background: 'linear-gradient(90deg, rgba(61,43,31,0.15) 0%, transparent 100%)',
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="px-4 pb-1 pt-0.5">
|
||||
{category.items.map((item, i) => (
|
||||
<MenuItemRow
|
||||
key={item.id}
|
||||
item={item}
|
||||
lang={lang}
|
||||
currency={currency}
|
||||
index={i}
|
||||
isLast={i === category.items.length - 1}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
{/* Items list (no background card) */}
|
||||
<div className="flex flex-col gap-1">
|
||||
{category.items.map((item, i) => (
|
||||
<MenuItemRow
|
||||
key={item.id}
|
||||
item={item}
|
||||
lang={lang}
|
||||
currency={currency}
|
||||
index={i}
|
||||
isLast={i === category.items.length - 1}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
|
||||
+34
-26
@@ -13,48 +13,56 @@ export default function MenuItemRow({ item, lang, currency, index, isLast }: Pro
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`menu-item-row flex items-center gap-3.5 py-3.5 rounded-xl px-2 -mx-2 ${
|
||||
!isLast ? 'border-b border-dashed border-beige' : ''
|
||||
className={`menu-item-row flex items-start gap-4 py-4 rounded-xl px-2 -mx-2 transition-colors ${
|
||||
!isLast ? 'border-b border-[rgba(61,43,31,0.06)]' : ''
|
||||
}`}
|
||||
style={{ '--item-index': index } as React.CSSProperties}
|
||||
>
|
||||
{/* Emoji circle with gradient */}
|
||||
{/* Image or Emoji circle */}
|
||||
<div
|
||||
className="w-11 h-11 rounded-xl flex items-center justify-center flex-shrink-0 text-[1.2rem]"
|
||||
className="w-16 h-16 rounded-full flex items-center justify-center flex-shrink-0 text-3xl overflow-hidden shadow-sm mt-0.5"
|
||||
style={{
|
||||
background:
|
||||
'linear-gradient(135deg, #F0E8D8 0%, #E8DCC8 100%)',
|
||||
border: '1px solid rgba(212,200,176,0.80)',
|
||||
boxShadow: 'inset 0 1px 2px rgba(255,255,255,0.8)',
|
||||
background: '#FDFCF8',
|
||||
border: '1px solid rgba(212,200,176,0.30)',
|
||||
}}
|
||||
>
|
||||
{item.emoji || '✨'}
|
||||
{item.image ? (
|
||||
<img src={item.image} alt={item.name[l]} className="w-full h-full object-cover" />
|
||||
) : (
|
||||
item.emoji || '✨'
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Text */}
|
||||
<div className="flex-1 min-w-0">
|
||||
<p
|
||||
className="font-display text-coffee font-semibold leading-snug"
|
||||
style={{ fontSize: '0.9rem' }}
|
||||
>
|
||||
{item.name[l]}
|
||||
</p>
|
||||
{/* Text Content */}
|
||||
<div className="flex-1 min-w-0 pt-0.5">
|
||||
<div className="flex justify-between items-start gap-2">
|
||||
<h3
|
||||
className="font-display text-coffee font-semibold leading-tight mb-1"
|
||||
style={{ fontSize: '1.05rem' }}
|
||||
>
|
||||
{item.name[l]}
|
||||
</h3>
|
||||
|
||||
{/* Price */}
|
||||
{item.price !== undefined && (
|
||||
<span
|
||||
className="flex-shrink-0 font-medium text-coffee mt-0.5"
|
||||
style={{ fontSize: '1rem' }}
|
||||
>
|
||||
{item.price} {currency}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{item.description && (
|
||||
<p
|
||||
className="font-body text-muted leading-relaxed mt-0.5 line-clamp-2"
|
||||
style={{ fontSize: '0.72rem' }}
|
||||
className="font-body text-muted leading-relaxed line-clamp-2"
|
||||
style={{ fontSize: '0.85rem' }}
|
||||
>
|
||||
{item.description[l]}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Price pill */}
|
||||
{item.price !== undefined && (
|
||||
<span className="price-pill flex-shrink-0">
|
||||
{currency}{item.price}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,356 @@
|
||||
'use client'
|
||||
|
||||
import { useState, useTransition, useEffect } from 'react'
|
||||
import type { Category, MenuItem } from '@/data/menu'
|
||||
import { saveEntireMenu } from '@/app/actions/menu'
|
||||
import { uploadImage } from '@/app/actions/upload'
|
||||
|
||||
export default function AdminDashboard({ initialCategories }: { initialCategories: Category[] }) {
|
||||
const [categories, setCategories] = useState<Category[]>(initialCategories)
|
||||
const [isPending, startTransition] = useTransition()
|
||||
const [isSaved, setIsSaved] = useState(false)
|
||||
const [selectedCatId, setSelectedCatId] = useState<string | null>(initialCategories[0]?.id || null)
|
||||
|
||||
// Auto-select first category if selected one is deleted
|
||||
useEffect(() => {
|
||||
if (selectedCatId && !categories.find(c => c.id === selectedCatId) && categories.length > 0) {
|
||||
setSelectedCatId(categories[0].id)
|
||||
}
|
||||
}, [categories, selectedCatId])
|
||||
|
||||
const handleSave = () => {
|
||||
startTransition(async () => {
|
||||
await saveEntireMenu(categories)
|
||||
setIsSaved(true)
|
||||
setTimeout(() => setIsSaved(false), 3000)
|
||||
})
|
||||
}
|
||||
|
||||
const handleImageUpload = async (catId: string, itemId: string, e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const file = e.target.files?.[0]
|
||||
if (!file) return
|
||||
const formData = new FormData()
|
||||
formData.append('file', file)
|
||||
try {
|
||||
const res = await uploadImage(formData)
|
||||
if (res?.url) {
|
||||
updateItem(catId, itemId, 'image', res.url)
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(err)
|
||||
alert("Resim yüklenemedi.")
|
||||
}
|
||||
}
|
||||
|
||||
// --- Item CRUD ---
|
||||
const updateItem = (catId: string, itemId: string, field: string, value: any, lang?: 'tr' | 'en') => {
|
||||
setCategories(cats => cats.map(cat => {
|
||||
if (cat.id !== catId) return cat
|
||||
return {
|
||||
...cat,
|
||||
items: cat.items.map(item => {
|
||||
if (item.id !== itemId) return item
|
||||
if (lang) {
|
||||
return { ...item, [field]: { ...(item as any)[field], [lang]: value } }
|
||||
}
|
||||
return { ...item, [field]: value }
|
||||
})
|
||||
}
|
||||
}))
|
||||
}
|
||||
|
||||
const addItem = (catId: string) => {
|
||||
const newItem: MenuItem = {
|
||||
id: `item-${Date.now()}`,
|
||||
name: { tr: 'Yeni Ürün', en: 'New Item' },
|
||||
description: { tr: '', en: '' },
|
||||
price: 0,
|
||||
highlight: false,
|
||||
}
|
||||
setCategories(cats => cats.map(cat => {
|
||||
if (cat.id !== catId) return cat
|
||||
return { ...cat, items: [...cat.items, newItem] }
|
||||
}))
|
||||
}
|
||||
|
||||
const deleteItem = (catId: string, itemId: string) => {
|
||||
if (!confirm('Bu ürünü silmek istediğinize emin misiniz?')) return
|
||||
setCategories(cats => cats.map(cat => {
|
||||
if (cat.id !== catId) return cat
|
||||
return { ...cat, items: cat.items.filter(item => item.id !== itemId) }
|
||||
}))
|
||||
}
|
||||
|
||||
const moveItem = (catId: string, itemIndex: number, direction: 'up' | 'down') => {
|
||||
setCategories(cats => cats.map(cat => {
|
||||
if (cat.id !== catId) return cat
|
||||
const newItems = [...cat.items]
|
||||
if (direction === 'up' && itemIndex > 0) {
|
||||
[newItems[itemIndex - 1], newItems[itemIndex]] = [newItems[itemIndex], newItems[itemIndex - 1]]
|
||||
} else if (direction === 'down' && itemIndex < newItems.length - 1) {
|
||||
[newItems[itemIndex + 1], newItems[itemIndex]] = [newItems[itemIndex], newItems[itemIndex + 1]]
|
||||
}
|
||||
return { ...cat, items: newItems }
|
||||
}))
|
||||
}
|
||||
|
||||
// --- Category CRUD ---
|
||||
const updateCategory = (catId: string, field: string, value: any, lang?: 'tr' | 'en') => {
|
||||
setCategories(cats => cats.map(cat => {
|
||||
if (cat.id !== catId) return cat
|
||||
if (lang && field === 'label') {
|
||||
return { ...cat, label: { ...cat.label, [lang]: value } }
|
||||
}
|
||||
return { ...cat, [field]: value }
|
||||
}))
|
||||
}
|
||||
|
||||
const addCategory = () => {
|
||||
const newCategory: Category = {
|
||||
id: `cat-${Date.now()}`,
|
||||
emoji: '🍽️',
|
||||
label: { tr: 'Yeni Kategori', en: 'New Category' },
|
||||
items: [],
|
||||
}
|
||||
setCategories(cats => [...cats, newCategory])
|
||||
setSelectedCatId(newCategory.id)
|
||||
}
|
||||
|
||||
const deleteCategory = (catId: string) => {
|
||||
if (!confirm('Bu kategoriyi ve içindeki tüm ürünleri silmek istediğinize emin misiniz?')) return
|
||||
setCategories(cats => cats.filter(cat => cat.id !== catId))
|
||||
}
|
||||
|
||||
const moveCategory = (catIndex: number, direction: 'up' | 'down') => {
|
||||
setCategories(cats => {
|
||||
const newCats = [...cats]
|
||||
if (direction === 'up' && catIndex > 0) {
|
||||
[newCats[catIndex - 1], newCats[catIndex]] = [newCats[catIndex], newCats[catIndex - 1]]
|
||||
} else if (direction === 'down' && catIndex < newCats.length - 1) {
|
||||
[newCats[catIndex + 1], newCats[catIndex]] = [newCats[catIndex], newCats[catIndex + 1]]
|
||||
}
|
||||
return newCats
|
||||
})
|
||||
}
|
||||
|
||||
const selectedCategory = categories.find(c => c.id === selectedCatId)
|
||||
|
||||
return (
|
||||
<div className="flex flex-col h-screen max-h-screen bg-gray-50 pb-8">
|
||||
{/* Top Bar */}
|
||||
<div className="flex justify-between items-center bg-white p-4 shadow-sm z-10 border-b shrink-0">
|
||||
<h2 className="text-xl font-bold text-coffee" style={{ color: '#3D2B1F' }}>Menü Yönetimi</h2>
|
||||
<div className="flex items-center gap-3">
|
||||
<button
|
||||
onClick={handleSave}
|
||||
disabled={isPending}
|
||||
className="px-6 py-2 rounded-lg text-white font-medium shadow-sm transition-all"
|
||||
style={{ backgroundColor: '#4AAFA8', opacity: isPending ? 0.7 : 1 }}
|
||||
>
|
||||
{isPending ? 'Kaydediliyor...' : isSaved ? '✓ Kaydedildi' : 'Değişiklikleri Kaydet'}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-1 overflow-hidden">
|
||||
{/* Left Sidebar (Categories) */}
|
||||
<div className="w-1/3 md:w-1/4 bg-white border-r border-gray-200 flex flex-col">
|
||||
<div className="p-4 border-b">
|
||||
<button
|
||||
onClick={addCategory}
|
||||
className="w-full py-2 rounded-lg text-emerald-700 bg-emerald-50 border border-emerald-200 font-medium hover:bg-emerald-100 transition-colors text-sm"
|
||||
>
|
||||
+ Yeni Kategori Ekle
|
||||
</button>
|
||||
</div>
|
||||
<div className="flex-1 overflow-y-auto p-2 space-y-1">
|
||||
{categories.map((cat, catIndex) => (
|
||||
<div
|
||||
key={cat.id}
|
||||
className={`flex items-center justify-between p-2 rounded-lg cursor-pointer transition-colors group ${
|
||||
selectedCatId === cat.id ? 'bg-emerald-50 border-emerald-200 border' : 'hover:bg-gray-100 border border-transparent'
|
||||
}`}
|
||||
onClick={() => setSelectedCatId(cat.id)}
|
||||
>
|
||||
<div className="flex items-center gap-2 truncate">
|
||||
<span className="text-xl">{cat.emoji}</span>
|
||||
<span className={`text-sm font-medium truncate ${selectedCatId === cat.id ? 'text-emerald-800' : 'text-gray-700'}`}>
|
||||
{cat.label.tr}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{/* Category Actions (visible on hover or when selected) */}
|
||||
<div className={`flex items-center opacity-0 group-hover:opacity-100 ${selectedCatId === cat.id ? 'opacity-100' : ''}`}>
|
||||
<button onClick={(e) => { e.stopPropagation(); moveCategory(catIndex, 'up') }} disabled={catIndex === 0} className="p-1 hover:bg-white rounded text-gray-500 disabled:opacity-30">↑</button>
|
||||
<button onClick={(e) => { e.stopPropagation(); moveCategory(catIndex, 'down') }} disabled={catIndex === categories.length - 1} className="p-1 hover:bg-white rounded text-gray-500 disabled:opacity-30">↓</button>
|
||||
<button onClick={(e) => { e.stopPropagation(); deleteCategory(cat.id) }} className="p-1 hover:bg-red-100 text-red-500 rounded ml-1">Sil</button>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
{categories.length === 0 && (
|
||||
<div className="text-center p-4 text-gray-400 text-sm">Kategori bulunamadı.</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Right Content (Items) */}
|
||||
<div className="flex-1 overflow-y-auto bg-gray-50 p-6">
|
||||
{selectedCategory ? (
|
||||
<div className="max-w-4xl mx-auto space-y-6">
|
||||
{/* Category Edit Header */}
|
||||
<div className="bg-white p-6 rounded-xl shadow-sm border border-gray-200">
|
||||
<h3 className="text-sm font-semibold text-gray-500 uppercase tracking-wider mb-4 border-b pb-2">Kategori Ayarları</h3>
|
||||
<div className="flex flex-col md:flex-row items-center gap-4">
|
||||
<div className="flex flex-col items-center gap-1">
|
||||
<input
|
||||
type="text"
|
||||
value={selectedCategory.emoji}
|
||||
onChange={(e) => updateCategory(selectedCategory.id, 'emoji', e.target.value)}
|
||||
className="w-14 h-14 text-center text-3xl border border-gray-300 rounded-xl bg-gray-50"
|
||||
title="Kategori Emojisi"
|
||||
/>
|
||||
<span className="text-[10px] text-gray-400">Emoji</span>
|
||||
</div>
|
||||
<div className="flex-1 flex flex-col md:flex-row gap-4 w-full">
|
||||
<div className="flex-1">
|
||||
<label className="block text-xs font-medium text-gray-500 mb-1">Türkçe İsim</label>
|
||||
<input
|
||||
type="text"
|
||||
value={selectedCategory.label.tr}
|
||||
onChange={(e) => updateCategory(selectedCategory.id, 'label', e.target.value, 'tr')}
|
||||
className="w-full px-3 py-2 border rounded-md font-bold text-coffee bg-gray-50"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex-1">
|
||||
<label className="block text-xs font-medium text-gray-500 mb-1">İngilizce İsim</label>
|
||||
<input
|
||||
type="text"
|
||||
value={selectedCategory.label.en}
|
||||
onChange={(e) => updateCategory(selectedCategory.id, 'label', e.target.value, 'en')}
|
||||
className="w-full px-3 py-2 border rounded-md text-gray-600 bg-gray-50"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Items List */}
|
||||
<div className="space-y-4">
|
||||
<div className="flex justify-between items-end">
|
||||
<h3 className="text-lg font-bold text-coffee">Ürünler ({selectedCategory.items.length})</h3>
|
||||
</div>
|
||||
|
||||
{selectedCategory.items.map((item, itemIndex) => (
|
||||
<div key={item.id} className="border border-gray-200 p-5 rounded-xl bg-white relative hover:border-gray-300 transition-colors shadow-sm">
|
||||
{/* Item Actions (Top Right) */}
|
||||
<div className="absolute top-3 right-3 flex items-center gap-1">
|
||||
<button onClick={() => moveItem(selectedCategory.id, itemIndex, 'up')} disabled={itemIndex === 0} className="p-1.5 bg-gray-100 rounded disabled:opacity-30 hover:bg-gray-200 text-xs">↑</button>
|
||||
<button onClick={() => moveItem(selectedCategory.id, itemIndex, 'down')} disabled={itemIndex === selectedCategory.items.length - 1} className="p-1.5 bg-gray-100 rounded disabled:opacity-30 hover:bg-gray-200 text-xs">↓</button>
|
||||
<button onClick={() => deleteItem(selectedCategory.id, item.id)} className="p-1.5 bg-red-50 text-red-500 rounded hover:bg-red-100 text-xs ml-1 font-medium">Sil</button>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-6 mt-4">
|
||||
{/* TR Fields */}
|
||||
<div className="space-y-3">
|
||||
<div className="font-semibold text-sm text-gray-700 mb-2 border-b pb-1">Türkçe (TR)</div>
|
||||
<div>
|
||||
<label className="block text-xs font-medium text-gray-500 mb-1">İsim</label>
|
||||
<input
|
||||
type="text"
|
||||
value={item.name.tr}
|
||||
onChange={(e) => updateItem(selectedCategory.id, item.id, 'name', e.target.value, 'tr')}
|
||||
className="w-full text-sm px-3 py-2 border rounded-md bg-gray-50 focus:bg-white"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label className="block text-xs font-medium text-gray-500 mb-1">Açıklama</label>
|
||||
<textarea
|
||||
value={item.description?.tr || ''}
|
||||
onChange={(e) => updateItem(selectedCategory.id, item.id, 'description', e.target.value, 'tr')}
|
||||
className="w-full text-sm px-3 py-2 border rounded-md bg-gray-50 focus:bg-white"
|
||||
rows={2}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* EN Fields */}
|
||||
<div className="space-y-3">
|
||||
<div className="font-semibold text-sm text-gray-700 mb-2 border-b pb-1">İngilizce (EN)</div>
|
||||
<div>
|
||||
<label className="block text-xs font-medium text-gray-500 mb-1">Name</label>
|
||||
<input
|
||||
type="text"
|
||||
value={item.name.en}
|
||||
onChange={(e) => updateItem(selectedCategory.id, item.id, 'name', e.target.value, 'en')}
|
||||
className="w-full text-sm px-3 py-2 border rounded-md bg-gray-50 focus:bg-white"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label className="block text-xs font-medium text-gray-500 mb-1">Description</label>
|
||||
<textarea
|
||||
value={item.description?.en || ''}
|
||||
onChange={(e) => updateItem(selectedCategory.id, item.id, 'description', e.target.value, 'en')}
|
||||
className="w-full text-sm px-3 py-2 border rounded-md bg-gray-50 focus:bg-white"
|
||||
rows={2}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Common Fields */}
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-4 mt-5 pt-4 border-t border-gray-100">
|
||||
<div>
|
||||
<label className="block text-xs font-medium text-gray-500 mb-1">Fiyat (₺)</label>
|
||||
<input
|
||||
type="number"
|
||||
value={item.price || 0}
|
||||
onChange={(e) => updateItem(selectedCategory.id, item.id, 'price', Number(e.target.value))}
|
||||
className="w-full text-sm px-3 py-2 border rounded-md bg-gray-50 focus:bg-white font-mono"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label className="block text-xs font-medium text-gray-500 mb-1">Emoji (Opsiyonel)</label>
|
||||
<input
|
||||
type="text"
|
||||
value={item.emoji || ''}
|
||||
onChange={(e) => updateItem(selectedCategory.id, item.id, 'emoji', e.target.value)}
|
||||
className="w-full text-sm px-3 py-2 border rounded-md bg-gray-50 focus:bg-white text-center text-xl"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label className="block text-xs font-medium text-gray-500 mb-1">Resim Ekle</label>
|
||||
<input
|
||||
type="file"
|
||||
accept="image/*"
|
||||
onChange={(e) => handleImageUpload(selectedCategory.id, item.id, e)}
|
||||
className="w-full text-xs px-2 py-1.5 border rounded-md file:mr-2 file:py-1 file:px-2 file:rounded file:border-0 file:bg-emerald-50 file:text-emerald-700 file:text-xs"
|
||||
/>
|
||||
{item.image && (
|
||||
<div className="mt-2 flex items-center gap-2 bg-gray-50 p-1.5 rounded-md border">
|
||||
<img src={item.image} alt="" className="w-8 h-8 rounded object-cover" />
|
||||
<button onClick={() => updateItem(selectedCategory.id, item.id, 'image', undefined)} className="text-xs text-red-500 hover:underline px-2">Kaldır</button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
|
||||
<button
|
||||
onClick={() => addItem(selectedCategory.id)}
|
||||
className="w-full py-4 rounded-xl border-2 border-dashed border-gray-300 text-gray-500 font-medium hover:border-emerald-300 hover:text-emerald-600 transition-colors bg-white hover:bg-emerald-50 text-sm mt-4 shadow-sm"
|
||||
>
|
||||
+ Kategoriye Yeni Ürün Ekle
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<div className="flex items-center justify-center h-full text-gray-400">
|
||||
Düzenlemek için sol taraftan bir kategori seçin.
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user