post bug fix
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
"use client";
|
||||
import { deleteNews, getAllNews } from "@/pages/news/lib/api";
|
||||
import { deleteNews, getAllNews, updateNews } from "@/pages/news/lib/api";
|
||||
import { Badge } from "@/shared/ui/badge";
|
||||
import { Button } from "@/shared/ui/button";
|
||||
import { Card } from "@/shared/ui/card";
|
||||
@@ -10,12 +10,15 @@ import {
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
} from "@/shared/ui/dialog";
|
||||
import { Switch } from "@/shared/ui/switch";
|
||||
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
||||
import clsx from "clsx";
|
||||
import {
|
||||
ChevronLeft,
|
||||
ChevronRight,
|
||||
Edit,
|
||||
Eye,
|
||||
EyeOff,
|
||||
FolderOpen,
|
||||
Loader2,
|
||||
PlusCircle,
|
||||
@@ -41,11 +44,33 @@ const News = () => {
|
||||
queryFn: () => getAllNews({ page: currentPage, page_size: 10 }),
|
||||
});
|
||||
|
||||
const { mutate, isPending } = useMutation({
|
||||
const { mutate: deleteMutate, isPending } = useMutation({
|
||||
mutationFn: (id: number) => deleteNews(id),
|
||||
onSuccess: () => {
|
||||
setDeleteId(null);
|
||||
queryClient.refetchQueries({ queryKey: ["all_news"] });
|
||||
toast.success(t("Yangilik o'chirildi"), {
|
||||
richColors: true,
|
||||
position: "top-center",
|
||||
});
|
||||
},
|
||||
onError: () => {
|
||||
toast.error(t("Xatolik yuz berdi"), {
|
||||
richColors: true,
|
||||
position: "top-center",
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
const { mutate: togglePublicMutate } = useMutation({
|
||||
mutationFn: ({ id, body }: { id: number; body: FormData }) =>
|
||||
updateNews({ body, id }),
|
||||
onSuccess: () => {
|
||||
queryClient.refetchQueries({ queryKey: ["all_news"] });
|
||||
toast.success(t("Status o'zgartirildi"), {
|
||||
richColors: true,
|
||||
position: "top-center",
|
||||
});
|
||||
},
|
||||
onError: () => {
|
||||
toast.error(t("Xatolik yuz berdi"), {
|
||||
@@ -57,10 +82,21 @@ const News = () => {
|
||||
|
||||
const confirmDelete = () => {
|
||||
if (deleteId) {
|
||||
mutate(deleteId);
|
||||
deleteMutate(deleteId);
|
||||
}
|
||||
};
|
||||
|
||||
const handleTogglePublic = (id: number, currentStatus: boolean) => {
|
||||
const formData = new FormData();
|
||||
console.log(currentStatus);
|
||||
|
||||
formData.append("is_public", String(currentStatus));
|
||||
togglePublicMutate({
|
||||
id,
|
||||
body: formData,
|
||||
});
|
||||
};
|
||||
|
||||
if (isLoading) {
|
||||
return (
|
||||
<div className="min-h-screen bg-gray-900 w-full text-white flex justify-center items-center">
|
||||
@@ -135,10 +171,10 @@ const News = () => {
|
||||
allNews?.data.data.results.map((item) => (
|
||||
<Card
|
||||
key={item.id}
|
||||
className="overflow-hidden bg-neutral-900 hover:bg-neutral-800 transition-all duration-300 border border-neutral-800 hover:border-neutral-700 group"
|
||||
className="overflow-hidden p-0 bg-neutral-900 hover:bg-neutral-800 transition-all duration-300 border border-neutral-800 hover:border-neutral-700 group flex flex-col"
|
||||
>
|
||||
{/* Image */}
|
||||
<div className="relative h-48 overflow-hidden">
|
||||
<div className="relative h-64 overflow-hidden">
|
||||
<img
|
||||
src={item.image}
|
||||
alt={item.title}
|
||||
@@ -158,7 +194,7 @@ const News = () => {
|
||||
</div>
|
||||
|
||||
{/* Content */}
|
||||
<div className="p-4 space-y-3">
|
||||
<div className="p-4 space-y-3 flex-1 flex flex-col">
|
||||
{/* Title */}
|
||||
<h2 className="text-xl font-bold line-clamp-2 group-hover:text-blue-400 transition-colors">
|
||||
{item.title}
|
||||
@@ -169,21 +205,47 @@ const News = () => {
|
||||
{item.text}
|
||||
</p>
|
||||
|
||||
{/* Date */}
|
||||
<div className="flex items-center gap-2 text-xs text-gray-500">
|
||||
<span>{item.is_public}</span>
|
||||
</div>
|
||||
|
||||
{/* Slug */}
|
||||
<div className="pt-2 border-t border-neutral-800">
|
||||
{item.tag?.map((e) => (
|
||||
<code className="text-xs text-gray-500 bg-neutral-800 px-2 py-1 rounded">
|
||||
/{e.name}
|
||||
</code>
|
||||
))}
|
||||
{item.tag && item.tag.length > 0 && (
|
||||
<div className="pt-2 border-t border-neutral-800 flex flex-wrap gap-2">
|
||||
{item.tag.map((e, idx) => (
|
||||
<code
|
||||
key={idx}
|
||||
className="text-xs text-gray-500 bg-neutral-800 px-2 py-1 rounded"
|
||||
>
|
||||
/{e.name}
|
||||
</code>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Spacer to push content to bottom */}
|
||||
<div className="flex-1"></div>
|
||||
|
||||
{/* Public/Private Toggle */}
|
||||
<div className="pt-3 border-t border-neutral-800">
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex items-center gap-2">
|
||||
{item.is_public ? (
|
||||
<Eye size={16} className="text-green-500" />
|
||||
) : (
|
||||
<EyeOff size={16} className="text-gray-500" />
|
||||
)}
|
||||
<span className="text-sm text-gray-400">
|
||||
{t("Оmmaviy")}
|
||||
</span>
|
||||
</div>
|
||||
<Switch
|
||||
checked={item.is_public}
|
||||
onCheckedChange={() =>
|
||||
handleTogglePublic(item.id, !item.is_public)
|
||||
}
|
||||
className="data-[state=checked]:bg-green-600"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Actions */}
|
||||
{/* Actions - at the very bottom */}
|
||||
<div className="flex justify-end gap-2 pt-3">
|
||||
<Button
|
||||
onClick={() => navigate(`/news/edit/${item.id}`)}
|
||||
@@ -240,7 +302,8 @@ const News = () => {
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
||||
<div className="flex justify-end gap-2">
|
||||
{/* Pagination */}
|
||||
<div className="flex justify-end gap-2 w-[90%] mx-auto mt-8">
|
||||
<button
|
||||
disabled={currentPage === 1}
|
||||
onClick={() => setCurrentPage((p) => Math.max(p - 1, 1))}
|
||||
|
||||
Reference in New Issue
Block a user