post bug fix

This commit is contained in:
Samandar Turgunboyev
2025-11-04 18:10:37 +05:00
parent c6c01a4607
commit 2d96eab3d7
10 changed files with 325 additions and 192 deletions

View File

@@ -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))}