hero section added

hero article menagment implemented in admin UI
This commit is contained in:
dimitar committed 2026-02-06 02:14:10 +01:00
1 parent 6d65d5975c
commit add12b2fbf
10 files changed
+604 -217

No files matched your search

@@ -1,6 +1,6 @@
import { useState } from 'react';
import { useLiveBlogs } from '@/queries/live-blogs';
import { useArticles, useDeleteArticle, useArchiveArticle, usePublishArticle } from '@/queries/articles';
import { useArticles, useDeleteArticle, useArchiveArticle, usePublishArticle, useUpdateArticle } from '@/queries/articles';
import { useDeleteLiveBlog, useArchiveLiveBlog, usePublishLiveBlog } from '@/queries/live-blogs';
import { Link } from '@tanstack/react-router';
import { Button } from '@/components/ui/button';
@@ -35,6 +35,7 @@ export function AdminDashboardComponent() {
const archiveLiveBlogMutation = useArchiveLiveBlog();
const publishArticleMutation = usePublishArticle();
const publishLiveBlogMutation = usePublishLiveBlog();
const updateArticleMutation = useUpdateArticle();
const liveBlogs = liveBlogsData?.data || [];
const articles = articlesData?.data || [];
@@ -102,6 +103,20 @@ export function AdminDashboardComponent() {
setItemToDelete(null);
};
const handleSetHero = async (articleId: string, isHero: boolean) => {
setIsProcessing(true);
try {
await updateArticleMutation.mutateAsync({
id: articleId,
dto: { isHero }
});
} catch (error) {
console.error('Failed to update hero status:', error);
} finally {
setIsProcessing(false);
}
};
const getStatusColor = (status: string) => {
switch (status) {
case 'published':
@@ -304,18 +319,23 @@ export function AdminDashboardComponent() {
>
<div className="flex items-start justify-between">
<div className="flex-1">
<div className="flex items-center gap-2 mb-1">
<Link
to="/articles/$id"
params={{ id: article.id }}
className="font-medium hover:text-primary hover:underline"
>
{article.title}
</Link>
<Badge variant="outline" className={getStatusColor(article.status)}>
{getStatusText(article.status)}
</Badge>
</div>
<div className="flex items-center gap-2 mb-1">
<Link
to="/articles/$id"
params={{ id: article.id }}
className="font-medium hover:text-primary hover:underline"
>
{article.title}
</Link>
<Badge variant="outline" className={getStatusColor(article.status)}>
{getStatusText(article.status)}
</Badge>
{article.isHero && (
<Badge variant="default" className="bg-yellow-500 hover:bg-yellow-600">
★ Hero
</Badge>
)}
</div>
<div className="flex items-center gap-4 text-sm text-muted-foreground">
<span>Слаг: {article.slug}</span>
<span>•</span>
@@ -336,43 +356,51 @@ export function AdminDashboardComponent() {
</p>
)}
</div>
<div className="flex gap-2 ml-4">
<Button asChild size="sm" variant="outline">
<Link to="/articles/$id" params={{ id: article.id }}>Уреди</Link>
</Button>
<Button asChild size="sm" variant="ghost">
<Link to="/articles/$id" params={{ id: article.id }} target="_blank">
Преглед
</Link>
</Button>
{showArchived ? (
<Button
size="sm"
variant="outline"
onClick={() => handlePublishClick('article', article.id)}
disabled={isProcessing}
>
Објави
</Button>
) : (
<Button
size="sm"
variant="outline"
onClick={() => handleArchiveClick('article', article.id, article.title)}
disabled={isProcessing}
>
Архивирај
</Button>
)}
<Button
size="sm"
variant="destructive"
onClick={() => handleDeleteClick('article', article.id, article.title)}
disabled={isProcessing}
>
Избриши
</Button>
</div>
<div className="flex gap-2 ml-4">
<Button asChild size="sm" variant="outline">
<Link to="/articles/$id" params={{ id: article.id }}>Уреди</Link>
</Button>
<Button asChild size="sm" variant="ghost">
<Link to="/articles/$id" params={{ id: article.id }} target="_blank">
Преглед
</Link>
</Button>
<Button
size="sm"
variant={article.isHero ? "default" : "outline"}
onClick={() => handleSetHero(article.id, !article.isHero)}
disabled={isProcessing || updateArticleMutation.isPending}
>
{article.isHero ? '★ Hero' : 'Set as Hero'}
</Button>
{showArchived ? (
<Button
size="sm"
variant="outline"
onClick={() => handlePublishClick('article', article.id)}
disabled={isProcessing}
>
Објави
</Button>
) : (
<Button
size="sm"
variant="outline"
onClick={() => handleArchiveClick('article', article.id, article.title)}
disabled={isProcessing}
>
Архивирај
</Button>
)}
<Button
size="sm"
variant="destructive"
onClick={() => handleDeleteClick('article', article.id, article.title)}
disabled={isProcessing}
>
Избриши
</Button>
</div>
</div>
</div>
))}