131 lines
5.6 KiB
TypeScript
131 lines
5.6 KiB
TypeScript
'use client'
|
||
|
||
import { useState } from "react"
|
||
import { SiteContent } from "@/types/cms"
|
||
import { Button } from "@/components/ui/button"
|
||
import { Input } from "@/components/ui/input"
|
||
import { Label } from "@/components/ui/label"
|
||
import { Textarea } from "@/components/ui/textarea"
|
||
import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/components/ui/card"
|
||
import { ImageUpload } from "@/components/ui/image-upload" // Ensure this exists or adapt
|
||
import { updateSiteContent } from "@/app/(dashboard)/dashboard/cms/content/actions"
|
||
import { toast } from "sonner"
|
||
import { Save, Loader2 } from "lucide-react"
|
||
import { cn } from "@/lib/utils"
|
||
|
||
interface ContentFormProps {
|
||
initialContent: SiteContent[]
|
||
}
|
||
|
||
const SECTIONS = [
|
||
{ id: 'general', label: 'Genel Ayarlar' },
|
||
{ id: 'home', label: 'Anasayfa' },
|
||
{ id: 'contact', label: 'İletişim' },
|
||
{ id: 'seo', label: 'SEO Ayarları' },
|
||
{ id: 'scripts', label: 'Script & Analitik' },
|
||
]
|
||
|
||
export function ContentForm({ initialContent }: ContentFormProps) {
|
||
const [contents, setContents] = useState<SiteContent[]>(initialContent)
|
||
const [loading, setLoading] = useState(false)
|
||
const [activeSection, setActiveSection] = useState('general')
|
||
|
||
const handleChange = (key: string, value: string) => {
|
||
setContents(prev => prev.map(item =>
|
||
item.key === key ? { ...item, value } : item
|
||
))
|
||
}
|
||
|
||
const onSubmit = async () => {
|
||
setLoading(true)
|
||
try {
|
||
const result = await updateSiteContent(contents)
|
||
if (result.success) {
|
||
toast.success("İçerikler başarıyla güncellendi")
|
||
} else {
|
||
toast.error(result.error)
|
||
}
|
||
} catch {
|
||
toast.error("Bir hata oluştu")
|
||
} finally {
|
||
setLoading(false)
|
||
}
|
||
}
|
||
|
||
const filteredContent = contents.filter(item => item.section === activeSection)
|
||
|
||
return (
|
||
<div className="space-y-6">
|
||
{/* Custom Tabs */}
|
||
<div className="flex space-x-1 rounded-lg bg-muted p-1 overflow-x-auto">
|
||
{SECTIONS.map((section) => (
|
||
<button
|
||
key={section.id}
|
||
onClick={() => setActiveSection(section.id)}
|
||
className={cn(
|
||
"flex-1 justify-center whitespace-nowrap rounded-md px-3 py-1.5 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
|
||
activeSection === section.id
|
||
? "bg-background text-foreground shadow-sm"
|
||
: "text-muted-foreground hover:bg-background/50 hover:text-foreground"
|
||
)}
|
||
>
|
||
{section.label}
|
||
</button>
|
||
))}
|
||
</div>
|
||
|
||
<Card>
|
||
<CardHeader>
|
||
<CardTitle>{SECTIONS.find(s => s.id === activeSection)?.label}</CardTitle>
|
||
<CardDescription>
|
||
Bu bölümdeki içerikleri aşağıdan düzenleyebilirsiniz.
|
||
</CardDescription>
|
||
</CardHeader>
|
||
<CardContent className="space-y-6">
|
||
{filteredContent.length === 0 && (
|
||
<p className="text-sm text-muted-foreground">Bu bölümde henüz ayar bulunmuyor.</p>
|
||
)}
|
||
{filteredContent.map((item) => (
|
||
<div key={item.key} className="space-y-2">
|
||
<Label className="capitalize">
|
||
{item.key.replace(/_/g, ' ').replace(activeSection, '').trim() || item.key}
|
||
</Label>
|
||
|
||
{item.type === 'image_url' ? (
|
||
<ImageUpload
|
||
value={item.value}
|
||
onChange={(url) => handleChange(item.key, url)}
|
||
onRemove={() => handleChange(item.key, '')}
|
||
/>
|
||
) : item.type === 'long_text' || item.type === 'html' || item.key.includes('address') ? (
|
||
<Textarea
|
||
value={item.value}
|
||
onChange={(e) => handleChange(item.key, e.target.value)}
|
||
rows={4}
|
||
/>
|
||
) : (
|
||
<Input
|
||
value={item.value}
|
||
onChange={(e) => handleChange(item.key, e.target.value)}
|
||
/>
|
||
)}
|
||
{item.key.includes('map_embed') && (
|
||
<p className="text-xs text-muted-foreground mt-1">
|
||
Google Maps'den alınan <iframe> kodunu buraya yapıştırın.
|
||
</p>
|
||
)}
|
||
</div>
|
||
))}
|
||
</CardContent>
|
||
</Card>
|
||
|
||
<div className="flex justify-end sticky bottom-6 z-10">
|
||
<Button onClick={onSubmit} disabled={loading} size="lg" className="shadow-lg">
|
||
{loading ? <Loader2 className="mr-2 h-4 w-4 animate-spin" /> : <Save className="mr-2 h-4 w-4" />}
|
||
Değişiklikleri Kaydet
|
||
</Button>
|
||
</div>
|
||
</div>
|
||
)
|
||
}
|