Site Yönetimi,Kullanıcı Girişi,Karanlık mod özellikleri db bağlantıları.

This commit is contained in:
2026-01-08 23:56:28 +03:00
parent 6e02336827
commit ddf28e1892
40 changed files with 2545 additions and 96 deletions

View File

@@ -0,0 +1,33 @@
import { createClient } from "@/lib/supabase-server"
import { ProductForm } from "@/components/dashboard/product-form"
import { notFound } from "next/navigation"
interface ProductEditPageProps {
params: {
productId: string
}
}
export default async function ProductEditPage({ params }: ProductEditPageProps) {
const supabase = createClient()
const { data: product } = await supabase
.from("products")
.select("*")
.eq("id", params.productId)
.single()
if (!product) {
notFound()
}
return (
<div className="flex-1 space-y-4 p-8 pt-6">
<div className="flex items-center justify-between">
<h2 className="text-3xl font-bold tracking-tight">Ürün Düzenle</h2>
</div>
<div className="max-w-2xl">
<ProductForm initialData={product} />
</div>
</div>
)
}

View File

@@ -0,0 +1,51 @@
"use server"
import { createClient } from "@/lib/supabase-server"
import { revalidatePath } from "next/cache"
export async function createProduct(data: any) {
const supabase = createClient()
// Validate data manually or use Zod schema here again securely
// For simplicity, we assume data is coming from the strongly typed Client Form
// In production, ALWAYS validate server-side strictly.
try {
const { error } = await supabase.from("products").insert({
name: data.name,
category: data.category,
description: data.description,
price: data.price,
image_url: data.image_url,
})
if (error) throw error
revalidatePath("/dashboard/products")
return { success: true }
} catch (error: any) {
return { success: false, error: error.message }
}
}
export async function updateProduct(id: number, data: any) {
const supabase = createClient()
try {
const { error } = await supabase.from("products").update({
name: data.name,
category: data.category,
description: data.description,
price: data.price,
image_url: data.image_url,
}).eq("id", id)
if (error) throw error
revalidatePath("/dashboard/products")
revalidatePath(`/dashboard/products/${id}`)
return { success: true }
} catch (error: any) {
return { success: false, error: error.message }
}
}

View File

@@ -0,0 +1,14 @@
import { ProductForm } from "@/components/dashboard/product-form"
export default function NewProductPage() {
return (
<div className="flex-1 space-y-4 p-8 pt-6">
<div className="flex items-center justify-between">
<h2 className="text-3xl font-bold tracking-tight">Yeni Ürün Ekle</h2>
</div>
<div className="max-w-2xl">
<ProductForm />
</div>
</div>
)
}

View File

@@ -0,0 +1,75 @@
import { createClient } from "@/lib/supabase-server"
import { Button } from "@/components/ui/button"
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "@/components/ui/table"
import { Plus } from "lucide-react"
import Link from "next/link"
import { Badge } from "@/components/ui/badge"
export default async function ProductsPage() {
const supabase = createClient()
const { data: products } = await supabase
.from("products")
.select("*")
.order("created_at", { ascending: false })
return (
<div className="flex-1 space-y-4 p-8 pt-6">
<div className="flex items-center justify-between">
<h2 className="text-3xl font-bold tracking-tight">Ürünler</h2>
<div className="flex items-center space-x-2">
<Link href="/dashboard/products/new">
<Button>
<Plus className="mr-2 h-4 w-4" /> Yeni Ekle
</Button>
</Link>
</div>
</div>
<div className="border rounded-md">
<Table>
<TableHeader>
<TableRow>
<TableHead>Ad</TableHead>
<TableHead>Kategori</TableHead>
<TableHead>Fiyat</TableHead>
<TableHead className="text-right">İşlemler</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{products?.length === 0 ? (
<TableRow>
<TableCell colSpan={4} className="h-24 text-center">
Henüz ürün eklenmemiş.
</TableCell>
</TableRow>
) : (
products?.map((product) => (
<TableRow key={product.id}>
<TableCell className="font-medium">{product.name}</TableCell>
<TableCell>
<Badge variant="secondary" className="capitalize">
{product.category}
</Badge>
</TableCell>
<TableCell>{product.price}</TableCell>
<TableCell className="text-right">
<Link href={`/dashboard/products/${product.id}`}>
<Button variant="ghost" size="sm">Düzenle</Button>
</Link>
</TableCell>
</TableRow>
))
)}
</TableBody>
</Table>
</div>
</div>
)
}