feat: add table components and admin article list with skeleton loading
Some checks failed
Build and Test / run-test (20.x) (push) Failing after 1m30s

This commit is contained in:
2026-04-13 20:51:20 -03:00
parent 79e6fae0f9
commit c938974d2b
14 changed files with 1054 additions and 34 deletions

View File

@@ -0,0 +1,84 @@
'use client';
import { deleteArticle } from '@/lib/feature/article/article.external';
import {
AlertDialog,
AlertDialogAction,
AlertDialogCancel,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogTitle,
AlertDialogTrigger,
} from '@/ui/components/shadcn/alert-dialog';
import { Button } from '@/ui/components/shadcn/button';
import { Trash2Icon } from 'lucide-react';
import { useTransition } from 'react';
import { toast } from 'sonner';
interface DeleteArticleButtonProps {
articleId: string;
articleTitle: string;
}
export const DeleteArticleButton = ({
articleId,
articleTitle,
}: DeleteArticleButtonProps) => {
const [isPending, startTransition] = useTransition();
const handleDelete = () => {
startTransition(async () => {
const result = await deleteArticle(articleId);
if (!result.ok) {
toast.error('Failed to delete article', {
description: result.error.message,
position: 'bottom-right',
});
return;
}
toast.success('Article deleted', {
description: `"${articleTitle}" has been removed.`,
position: 'bottom-right',
});
});
};
return (
<AlertDialog>
<AlertDialogTrigger asChild>
<Button variant='destructive' size='sm' disabled={isPending}>
<Trash2Icon className='size-4' />
Delete
</Button>
</AlertDialogTrigger>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle>Delete article?</AlertDialogTitle>
<AlertDialogDescription>
This will permanently delete &ldquo;{articleTitle}
&rdquo;. This action cannot be undone.
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel asChild>
<Button variant='outline' size='sm'>
Cancel
</Button>
</AlertDialogCancel>
<AlertDialogAction asChild>
<Button
variant='destructive'
size='sm'
disabled={isPending}
onClick={handleDelete}
>
{isPending ? 'Deleting…' : 'Delete'}
</Button>
</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
);
};