generated from fahricansecer/boilerplate-fe
main
Some checks failed
UI Deploy (Next-Auth Support) 🎨 / build-and-deploy (push) Has been cancelled
Some checks failed
UI Deploy (Next-Auth Support) 🎨 / build-and-deploy (push) Has been cancelled
This commit is contained in:
@@ -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}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user