Files
Beyhan Oğur 2a5b661443 first commit
2026-04-26 21:46:42 +03:00

133 lines
5.0 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"use client"
import { ColumnDef } from "@tanstack/react-table"
import { Post } from "@/types/post"
import { Button } from "@/components/ui/button"
import { Edit, Trash, RotateCcw } from "lucide-react"
interface PostColumnsProps {
onEdit: (post: Post) => void
onDelete: (id: number) => void
onRestore: (id: number) => void
statusFilter: string
deletedIds: number[]
}
export const getPostColumns = ({ onEdit, onDelete, onRestore, statusFilter, deletedIds }: PostColumnsProps): ColumnDef<Post>[] => [
{
accessorKey: "images",
header: "Görsel",
cell: ({ row }) => {
const rawImages = row.original.images
const apiUrl = process.env.NEXT_PUBLIC_API_URL || "http://localhost:8080"
// Backend tarafında "images" alanı virgülle ayrılmış birden fazla path içerebilir.
// Liste görünümünde ilk path'i küçük görsel için kullanalım.
const firstImage = rawImages
? rawImages
.split(",")
.map(p => p.trim())
.filter(Boolean)[0]
: null
const fullUrl = firstImage
? (firstImage.startsWith("http") ? firstImage : `${apiUrl}${firstImage}`)
: null
return (
<div className="w-16 h-10 bg-gray-100 rounded overflow-hidden flex items-center justify-center">
{fullUrl ? (
// eslint-disable-next-line @next/next/no-img-element
<img src={fullUrl} alt={row.original.title} className="w-full h-full object-cover" />
) : (
<span className="text-xs text-gray-400">Yok</span>
)}
</div>
)
},
},
{
accessorKey: "title",
header: "Başlık",
},
{
accessorKey: "categories",
header: "Kategoriler",
cell: ({ row }) => (
<div className="flex flex-wrap gap-1">
{row.original.categories?.map((cat, index) => (
<span key={cat.id || cat.title || index} className="px-2 py-1 bg-blue-100 text-blue-800 text-xs rounded-full">
{cat.title}
</span>
))}
</div>
),
},
{
accessorKey: "tags",
header: "Etiketler",
cell: ({ row }) => (
<div className="flex flex-wrap gap-1">
{row.original.tags?.map((tag, index) => (
<span key={tag.id || tag.name || index} className="px-2 py-1 bg-gray-100 text-gray-800 text-xs rounded-full">
{tag.name}
</span>
))}
</div>
),
},
{
accessorKey: "updated_at",
header: "Son Güncelleme",
cell: ({ row }) => {
const updatedAt = row.original.updated_at || row.original.UpdatedAt
return updatedAt ? new Date(updatedAt).toLocaleDateString("tr-TR") : "-"
},
},
{
id: "actions",
cell: ({ row }) => {
const id = row.original.id || row.original.ID
const inDeletedList = typeof id === "number" && deletedIds.includes(id)
// "Sadece Silinenler" filtresinde hepsi silinmiş kabul edilir.
// "Tümü (Dahil)" filtresinde ise deletedIds listesine bakılır.
const isDeleted = statusFilter === "only" || inDeletedList
return (
<div className="flex gap-2 justify-end">
{isDeleted ? (
<Button
variant="outline"
size="sm"
onClick={() => onRestore(row.original.id || row.original.ID!)}
className="h-8 w-8 p-0 text-green-600 hover:text-green-700 hover:bg-green-50"
title="Geri Yükle"
>
<RotateCcw className="h-4 w-4" />
</Button>
) : (
<>
<Button
variant="outline"
size="sm"
onClick={() => onEdit(row.original)}
className="h-8 w-8 p-0"
>
<Edit className="h-4 w-4" />
</Button>
<Button
variant="destructive"
size="sm"
onClick={() => onDelete(row.original.id || row.original.ID!)}
className="h-8 w-8 p-0"
>
<Trash className="h-4 w-4" />
</Button>
</>
)}
</div>
)
},
},
]