main
Some checks failed
UI Deploy (Next-Auth Support) 🎨 / build-and-deploy (push) Has been cancelled

This commit is contained in:
Harun CAN
2026-03-14 14:01:11 +03:00
parent eca4b8c652
commit eba6ea9b8d
11 changed files with 1243 additions and 287 deletions

View File

@@ -1,7 +1,7 @@
"use client";
import { Box, Table, Badge, HStack, IconButton } from "@chakra-ui/react";
import { useState, useEffect } from "react";
import { Box, Table, Badge, HStack, IconButton, Button } from "@chakra-ui/react";
import { useState, useEffect, useCallback } from "react";
import { useSession } from "next-auth/react";
import { LuEye, LuPencil, LuTrash2, LuRefreshCw } from "react-icons/lu";
import { toaster } from "@/components/ui/feedback/toaster";
@@ -9,9 +9,8 @@ import { ContentPreviewDialog } from "./ContentPreviewDialog";
const getStatusColor = (status: string) => {
switch (status) {
switch (status?.toLowerCase()) {
case "published": return "green";
case "draft": return "gray";
case "scheduled": return "blue";
@@ -27,30 +26,49 @@ export function ContentTable() {
const [contentList, setContentList] = useState<any[]>([]);
const [isLoading, setIsLoading] = useState(false);
useEffect(() => {
const fetchContent = async () => {
if (!session?.accessToken) return;
setIsLoading(true);
try {
const res = await fetch('/api/backend/content', {
headers: {
'Authorization': `Bearer ${session.accessToken}`
}
});
if (res.ok) {
const data = await res.json();
setContentList(Array.isArray(data) ? data : []);
const fetchContent = useCallback(async () => {
if (!session?.accessToken) return;
setIsLoading(true);
try {
const res = await fetch('/api/backend/content', {
headers: {
'Authorization': `Bearer ${session.accessToken}`
}
} catch (error) {
console.error("Failed to fetch content:", error);
} finally {
setIsLoading(false);
});
if (res.ok) {
const data = await res.json();
setContentList(Array.isArray(data) ? data : []);
}
};
fetchContent();
} catch (error) {
console.error("Failed to fetch content:", error);
} finally {
setIsLoading(false);
}
}, [session]);
useEffect(() => {
fetchContent();
}, [fetchContent]);
const handleDelete = async (item: any) => {
if (!session?.accessToken) return;
try {
const res = await fetch(`/api/backend/content/${item.id}`, {
method: 'DELETE',
headers: {
'Authorization': `Bearer ${session.accessToken}`
}
});
if (res.ok) {
toaster.create({ title: "Deleted", description: `"${item.title || 'Content'}" removed.`, type: "success" });
fetchContent();
} else {
toaster.create({ title: "Delete failed", type: "error" });
}
} catch {
toaster.create({ title: "Delete failed", type: "error" });
}
};
const handleAction = (action: string, item: any) => {
if (action === 'View') {
@@ -58,16 +76,30 @@ export function ContentTable() {
setIsPreviewOpen(true);
return;
}
toaster.create({
title: `${action} Action`,
description: `You clicked ${action} for ${item.title}`,
type: "info",
});
if (action === 'Edit') {
// Open the preview in edit mode
setSelectedItem(item);
setIsPreviewOpen(true);
return;
}
if (action === 'Delete') {
handleDelete(item);
return;
}
};
return (
<>
<HStack justify="flex-end" mb={3}>
<Button
size="sm"
variant="outline"
onClick={fetchContent}
loading={isLoading}
>
<LuRefreshCw /> Refresh
</Button>
</HStack>
<Box borderWidth="1px" borderRadius="lg" overflow="hidden" bg="bg.panel">
<Table.Root striped>
<Table.Header>
@@ -97,7 +129,9 @@ export function ContentTable() {
</Table.Row>
) : contentList.map((item) => (
<Table.Row key={item.id}>
<Table.Cell fontWeight="medium">{item.title}</Table.Cell>
<Table.Cell fontWeight="medium">
{item.title || item.body?.substring(0, 60) + '...' || 'Untitled'}
</Table.Cell>
<Table.Cell>{item.type || item.platform}</Table.Cell>
<Table.Cell>
<Badge colorPalette={getStatusColor(item.status)} variant="solid">
@@ -145,6 +179,7 @@ export function ContentTable() {
item={selectedItem}
open={isPreviewOpen}
onOpenChange={(e) => setIsPreviewOpen(e.open)}
onContentUpdated={fetchContent}
/>
</>
);