api ulandi

This commit is contained in:
Samandar Turgunboyev
2025-10-29 18:41:59 +05:00
parent a9e99f9755
commit 2d0285dafc
64 changed files with 6319 additions and 2352 deletions

View File

@@ -1,5 +1,5 @@
"use client";
import { getAllNews } from "@/pages/news/lib/api";
import { deleteNews, getAllNews } from "@/pages/news/lib/api";
import { Badge } from "@/shared/ui/badge";
import { Button } from "@/shared/ui/button";
import { Card } from "@/shared/ui/card";
@@ -10,27 +10,56 @@ import {
DialogHeader,
DialogTitle,
} from "@/shared/ui/dialog";
import { useQuery } from "@tanstack/react-query";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import clsx from "clsx";
import { Edit, FolderOpen, PlusCircle, Trash2 } from "lucide-react";
import {
ChevronLeft,
ChevronRight,
Edit,
FolderOpen,
Loader2,
PlusCircle,
Trash2,
} from "lucide-react";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { useNavigate } from "react-router-dom";
import { toast } from "sonner";
const News = () => {
const [currentPage, setCurrentPage] = useState(1);
const { t } = useTranslation();
const [deleteId, setDeleteId] = useState<number | null>(null);
const queryClient = useQueryClient();
const navigate = useNavigate();
const {
data: allNews,
isLoading,
isError,
} = useQuery({
queryKey: ["all_news"],
queryFn: () => getAllNews({ page: 1, page_size: 2 }),
queryKey: ["all_news", currentPage],
queryFn: () => getAllNews({ page: currentPage, page_size: 10 }),
});
const confirmDelete = () => {};
const { mutate, isPending } = useMutation({
mutationFn: (id: number) => deleteNews(id),
onSuccess: () => {
setDeleteId(null);
queryClient.refetchQueries({ queryKey: ["all_news"] });
},
onError: () => {
toast.error(t("Xatolik yuz berdi"), {
richColors: true,
position: "top-center",
});
},
});
const confirmDelete = () => {
if (deleteId) {
mutate(deleteId);
}
};
if (isLoading) {
return (
@@ -157,7 +186,7 @@ const News = () => {
{/* Actions */}
<div className="flex justify-end gap-2 pt-3">
<Button
onClick={() => navigate(`/news/add`)}
onClick={() => navigate(`/news/edit/${item.id}`)}
size="sm"
variant="outline"
className="hover:bg-neutral-700 hover:text-blue-400"
@@ -201,11 +230,51 @@ const News = () => {
</Button>
<Button variant="destructive" onClick={confirmDelete}>
<Trash2 className="w-4 h-4 mr-2" />
{t("O'chirish")}
{isPending ? (
<Loader2 className="animate-spin" />
) : (
t("O'chirish")
)}
</Button>
</DialogFooter>
</DialogContent>
</Dialog>
<div className="flex justify-end gap-2">
<button
disabled={currentPage === 1}
onClick={() => setCurrentPage((p) => Math.max(p - 1, 1))}
className="p-2 rounded-lg border border-slate-600 text-slate-300 hover:bg-slate-700/50 disabled:opacity-50 disabled:cursor-not-allowed transition-all hover:border-slate-500"
>
<ChevronLeft className="w-5 h-5" />
</button>
{[...Array(allNews?.data.data.total_pages)].map((_, i) => (
<button
key={i}
onClick={() => setCurrentPage(i + 1)}
className={`px-4 py-2 rounded-lg border transition-all font-medium ${
currentPage === i + 1
? "bg-gradient-to-r from-blue-600 to-cyan-600 border-blue-500 text-white shadow-lg shadow-cyan-500/50"
: "border-slate-600 text-slate-300 hover:bg-slate-700/50 hover:border-slate-500"
}`}
>
{i + 1}
</button>
))}
<button
disabled={currentPage === allNews?.data.data.total_pages}
onClick={() =>
setCurrentPage((p) =>
Math.min(p + 1, allNews ? allNews?.data.data.total_pages : 0),
)
}
className="p-2 rounded-lg border border-slate-600 text-slate-300 hover:bg-slate-700/50 disabled:opacity-50 disabled:cursor-not-allowed transition-all hover:border-slate-500"
>
<ChevronRight className="w-5 h-5" />
</button>
</div>
</div>
);
};