Site içerik yönetimi

This commit is contained in:
2026-01-25 02:03:27 +03:00
parent 0fe49b5c96
commit 6992891ae3
9 changed files with 154 additions and 248 deletions

View File

@@ -1,32 +1,56 @@
"use client"
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"
import { SiteSettingsForm, SettingsFormValues } from "@/components/dashboard/site-settings-form"
import { SmsSettingsForm } from "@/components/dashboard/sms-settings-form"
import { AppearanceForm } from "@/components/dashboard/appearance-form"
import { UsersTable } from "@/components/dashboard/users-table"
import { ContentForm } from "@/components/dashboard/content-form"
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
import { Button } from "@/components/ui/button"
import { SiteContent } from "@/types/cms"
interface SettingsTabsProps {
siteSettings: Partial<SettingsFormValues> | null
smsSettings: {
username: string
header: string
} | null
users: any[]
contents: SiteContent[]
}
export function SettingsTabs({ siteSettings, smsSettings }: SettingsTabsProps) {
export function SettingsTabs({ smsSettings, users, contents }: SettingsTabsProps) {
return (
<Tabs defaultValue="general" className="space-y-4">
<TabsList>
<TabsTrigger value="general">Genel</TabsTrigger>
<Tabs defaultValue="content" className="space-y-4">
<TabsList className="grid w-full grid-cols-2 md:grid-cols-5 h-auto">
<TabsTrigger value="content">İçerik Yönetimi</TabsTrigger>
<TabsTrigger value="users">Kullanıcılar</TabsTrigger>
<TabsTrigger value="sms">SMS / Bildirimler</TabsTrigger>
<TabsTrigger value="appearance">Görünüm</TabsTrigger>
<TabsTrigger value="security">Güvenlik</TabsTrigger>
</TabsList>
<TabsContent value="general" className="space-y-4">
<SiteSettingsForm initialData={siteSettings} />
<TabsContent value="content" className="space-y-4">
<div className="space-y-4">
<div>
<h3 className="text-lg font-medium">Site İçerik Yönetimi</h3>
<p className="text-sm text-muted-foreground">
Site genel ayarları, iletişim bilgileri ve logolar.
</p>
</div>
<ContentForm initialContent={contents} />
</div>
</TabsContent>
<TabsContent value="users" className="space-y-4">
<div className="space-y-4">
<div>
<h3 className="text-lg font-medium">Kullanıcı Yönetimi</h3>
<p className="text-sm text-muted-foreground">
Sistemdeki kayıtlı kullanıcıları ve rollerini yönetin.
</p>
</div>
<UsersTable users={users} />
</div>
</TabsContent>
<TabsContent value="sms" className="space-y-4">

View File

@@ -3,7 +3,7 @@
import Link from "next/link"
import { usePathname } from "next/navigation"
import { cn } from "@/lib/utils"
import { LayoutDashboard, Package, ShoppingCart, Users, Settings, Globe, Tags, FileText } from "lucide-react"
import { LayoutDashboard, Package, ShoppingCart, Settings, Globe, Tags } from "lucide-react"
const sidebarItems = [
{
@@ -26,16 +26,6 @@ const sidebarItems = [
href: "/dashboard/categories",
icon: Tags,
},
{
title: "Kullanıcılar",
href: "/dashboard/users",
icon: Users,
},
{
title: "İçerik Yönetimi",
href: "/dashboard/cms/content",
icon: FileText,
},
{
title: "Ayarlar",
href: "/dashboard/settings",

View File

@@ -1,163 +0,0 @@
"use client"
import { useState } from "react"
import { useRouter } from "next/navigation"
import { useForm } from "react-hook-form"
import { zodResolver } from "@hookform/resolvers/zod"
import * as z from "zod"
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Textarea } from "@/components/ui/textarea"
import {
Form,
FormControl,
FormDescription,
FormField,
FormItem,
FormLabel,
FormMessage,
} from "@/components/ui/form"
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
import { toast } from "sonner"
import { Loader2 } from "lucide-react"
import { updateSiteSettings } from "@/app/(dashboard)/dashboard/settings/actions"
const settingsSchema = z.object({
site_title: z.string().min(2, "Site başlığı en az 2 karakter olmalıdır."),
site_description: z.string(),
contact_email: z.literal("").or(z.string().email("Geçerli bir e-posta adresi giriniz.")),
contact_phone: z.string(),
currency: z.string(),
})
export type SettingsFormValues = z.infer<typeof settingsSchema>
interface SiteSettingsFormProps {
initialData: Partial<SettingsFormValues> | null
}
export function SiteSettingsForm({ initialData }: SiteSettingsFormProps) {
const router = useRouter()
const [loading, setLoading] = useState(false)
const form = useForm<SettingsFormValues>({
resolver: zodResolver(settingsSchema),
defaultValues: {
site_title: initialData?.site_title || "ParaKasa",
site_description: initialData?.site_description || "",
contact_email: initialData?.contact_email || "",
contact_phone: initialData?.contact_phone || "",
currency: initialData?.currency || "TRY",
},
})
const onSubmit = async (data: SettingsFormValues) => {
setLoading(true)
try {
const result = await updateSiteSettings(data)
if (result.error) {
toast.error(result.error)
return
}
toast.success("Site ayarları güncellendi.")
router.refresh()
} catch {
toast.error("Bir sorun oluştu.")
} finally {
setLoading(false)
}
}
return (
<Card>
<CardHeader>
<CardTitle>Genel Ayarlar</CardTitle>
<CardDescription>Web sitesinin genel yapılandırma ayarları.</CardDescription>
</CardHeader>
<CardContent>
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-4">
<FormField
control={form.control}
name="site_title"
render={({ field }) => (
<FormItem>
<FormLabel>Site Başlığı</FormLabel>
<FormControl>
<Input placeholder="ParaKasa" {...field} />
</FormControl>
<FormDescription>Tarayıcı sekmesinde görünen ad.</FormDescription>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="site_description"
render={({ field }) => (
<FormItem>
<FormLabel>Site ıklaması</FormLabel>
<FormControl>
<Textarea placeholder="Premium çelik kasalar..." {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<div className="grid grid-cols-2 gap-4">
<FormField
control={form.control}
name="contact_email"
render={({ field }) => (
<FormItem>
<FormLabel>İletişim E-posta</FormLabel>
<FormControl>
<Input placeholder="info@parakasa.com" {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="contact_phone"
render={({ field }) => (
<FormItem>
<FormLabel>İletişim Telefon</FormLabel>
<FormControl>
<Input placeholder="+90 555 123 45 67" {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
</div>
<FormField
control={form.control}
name="currency"
render={({ field }) => (
<FormItem>
<FormLabel>Para Birimi</FormLabel>
<FormControl>
<Input placeholder="TRY" {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<Button type="submit" disabled={loading}>
{loading && <Loader2 className="mr-2 h-4 w-4 animate-spin" />}
Ayarları Kaydet
</Button>
</form>
</Form>
</CardContent>
</Card>
)
}

View File

@@ -0,0 +1,69 @@
"use client"
import { Button } from "@/components/ui/button"
import Link from "next/link"
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "@/components/ui/table"
import { Badge } from "@/components/ui/badge"
interface Profile {
id: string
full_name: string
role: string
created_at: string
}
interface UsersTableProps {
users: Profile[]
}
export function UsersTable({ users }: UsersTableProps) {
return (
<div className="space-y-4">
<div className="flex items-center justify-between space-y-2">
<h3 className="text-lg font-medium">Kullanıcı Listesi</h3>
{/*
<Link href="/dashboard/users/new">
<Button size="sm">Yeni Kullanıcı</Button>
</Link>
*/}
</div>
<div className="rounded-md border">
<Table>
<TableHeader>
<TableRow>
<TableHead>Ad Soyad</TableHead>
<TableHead>Rol</TableHead>
<TableHead>Kayıt Tarihi</TableHead>
<TableHead className="text-right">İşlemler</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{users?.map((profile) => (
<TableRow key={profile.id}>
<TableCell className="font-medium">{profile.full_name}</TableCell>
<TableCell>
<Badge variant={profile.role === 'admin' ? 'default' : 'secondary'}>
{profile.role === 'admin' ? 'Yönetici' : 'Kullanıcı'}
</Badge>
</TableCell>
<TableCell>{new Date(profile.created_at).toLocaleDateString('tr-TR')}</TableCell>
<TableCell className="text-right">
<Link href={`/dashboard/users/${profile.id}`}>
<Button variant="ghost" size="sm">Düzenle</Button>
</Link>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</div>
</div>
)
}