"use client"; import { createFaq, deleteFaq, getAllFaq, getAllFaqCategory, getOneFaq, updateFaq, } from "@/pages/faq/lib/api"; import { Button } from "@/shared/ui/button"; import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle, } from "@/shared/ui/dialog"; import { Form, FormControl, FormField, FormItem, FormMessage, } from "@/shared/ui/form"; import { InfiniteScrollSelect } from "@/shared/ui/infiniteScrollSelect"; import { Input } from "@/shared/ui/input"; import { Label } from "@/shared/ui/label"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "@/shared/ui/table"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/shared/ui/tabs"; import { Textarea } from "@/shared/ui/textarea"; import { zodResolver } from "@hookform/resolvers/zod"; import { useInfiniteQuery, useMutation, useQuery, useQueryClient, } from "@tanstack/react-query"; import { ChevronLeft, ChevronRight, Loader2, Pencil, PlusCircle, Trash2, } from "lucide-react"; import { useEffect, useRef, useState } from "react"; import { useForm } from "react-hook-form"; import { useTranslation } from "react-i18next"; import { toast } from "sonner"; import z from "zod"; const faqForm = z.object({ categories: z.string().min(1, { message: "Majburiy maydon" }), title: z.string().min(1, { message: "Majburiy maydon" }), title_ru: z.string().min(1, { message: "Majburiy maydon" }), answer: z.string().min(1, { message: "Majburiy maydon" }), answer_ru: z.string().min(1, { message: "Majburiy maydon" }), }); const Faq = () => { const [activeTab, setActiveTab] = useState(""); const [currentPage, setCurrentPage] = useState(1); const { t } = useTranslation(); const [openModal, setOpenModal] = useState(false); const [editFaq, setEditFaq] = useState(null); const queryClient = useQueryClient(); const scrollRef = useRef(null); const loaderRef = useRef(null); // Infinite scroll uchun useInfiniteQuery const { data: categoryData, fetchNextPage, hasNextPage, isFetchingNextPage, } = useInfiniteQuery({ queryKey: ["all_faqcategory"], queryFn: ({ pageParam = 1 }) => { return getAllFaqCategory({ page: pageParam, page_size: 10 }); }, getNextPageParam: (lastPage) => { const data = lastPage.data.data; if (data.current_page < data.total_pages) { return data.current_page + 1; } return undefined; }, initialPageParam: 1, }); useEffect(() => { setCurrentPage(1); }, [activeTab]); const category = categoryData?.pages.flatMap((page) => page.data.data.results) ?? []; const { data: faq } = useQuery({ queryKey: ["all_faq", activeTab, currentPage], queryFn: () => { return getAllFaq({ page: currentPage, page_size: 10, category: Number(activeTab), }); }, select(data) { return data.data.data; }, enabled: !!activeTab, }); const { data: detailFaq } = useQuery({ queryKey: ["detail_faq", editFaq], queryFn: () => { return getOneFaq(editFaq!); }, select(data) { return data.data.data; }, enabled: !!editFaq, }); const { mutate: create, isPending } = useMutation({ mutationFn: (body: { title: string; title_ru: string; text: string; text_ru: string; category: number; }) => createFaq(body), onSuccess: () => { queryClient.refetchQueries({ queryKey: ["all_faq"] }); setOpenModal(false); toast.success(t("Muvaffaqiyatli qo'shildi"), { position: "top-center" }); }, onError: () => { toast.error(t("Xatolik yuz berdi"), { position: "top-center", richColors: true, }); }, }); const { mutate: edit, isPending: editPending } = useMutation({ mutationFn: ({ body, id, }: { id: number; body: { title: string; title_ru: string; text: string; text_ru: string; category?: number; }; }) => updateFaq({ body, id }), onSuccess: () => { queryClient.refetchQueries({ queryKey: ["all_faq"] }); setOpenModal(false); toast.success(t("Tahrirlandi"), { position: "top-center" }); }, onError: () => { toast.error(t("Xatolik yuz berdi"), { position: "top-center", richColors: true, }); }, }); const { mutate: deleteFaqs, isPending: deletePending } = useMutation({ mutationFn: ({ id }: { id: number }) => deleteFaq({ id }), onSuccess: () => { queryClient.refetchQueries({ queryKey: ["all_faq"] }); setDeleteId(null); toast.success(t("O'chirildi"), { position: "top-center" }); }, onError: () => { toast.error(t("Xatolik yuz berdi"), { position: "top-center", richColors: true, }); }, }); useEffect(() => { if (category.length > 0 && !activeTab) { setActiveTab(String(category[0].id)); } }, [category, activeTab]); // Intersection Observer for lazy loading useEffect(() => { if (!scrollRef.current || !loaderRef.current) return; const observer = new IntersectionObserver( (entries) => { if (entries[0].isIntersecting && hasNextPage && !isFetchingNextPage) { fetchNextPage(); } }, { root: scrollRef.current, threshold: 0.1 }, ); if (loaderRef.current) { observer.observe(loaderRef.current); } return () => observer.disconnect(); }, [hasNextPage, isFetchingNextPage, fetchNextPage]); const [deleteId, setDeleteId] = useState(null); const form = useForm>({ resolver: zodResolver(faqForm), defaultValues: { answer: "", answer_ru: "", categories: "", title: "", title_ru: "", }, }); useEffect(() => { if (detailFaq) { form.setValue("title", detailFaq.title_uz); form.setValue("title_ru", detailFaq.title_ru); form.setValue("answer", detailFaq.text_uz); form.setValue("answer_ru", detailFaq.text_ru); form.setValue("categories", activeTab); } }, [detailFaq, form]); function onSubmit(value: z.infer) { if (editFaq === null) { create({ category: Number(value.categories), text: value.answer, text_ru: value.answer_ru, title: value.title, title_ru: value.title_ru, }); } else if (editFaq) { edit({ body: { text: value.answer, text_ru: value.answer_ru, title: value.title, title_ru: value.title_ru, }, id: editFaq, }); } } const handleEdit = (faq: number) => { setOpenModal(true); setEditFaq(faq); }; const handleDelete = () => { if (deleteId) { deleteFaqs({ id: deleteId }); } }; useEffect(() => { if (!openModal) { form.reset(); setEditFaq(null); } }, [openModal, form]); return (
{/* Header */}

{t("FAQ (Savol va javoblar)")}

{/* Tabs */}
{category.map((cat) => ( {cat.name} ))} {hasNextPage && (
{isFetchingNextPage ? ( ) : ( )}
)}
{/* Tabs content */} {category.map((cat) => ( {faq && faq?.results.length > 0 ? (
# {t("Savol")} {t("Javob")} {t("Amallar")} {faq.results.map((faq, index) => ( {index + 1} {faq.title} {faq.text.length > 80 ? faq.text.slice(0, 80) + "..." : faq.text} ))}
) : (

{t("Bu bo'limda savollar yo'q")}

)}
))}
{[...Array(faq?.total_pages)].map((_, i) => ( ))}
{editFaq ? t("FAQni tahrirlash") : t("Yangi FAQ qo'shish")}
( ({ key: cat.id, value: String(cat.id), label: cat.name, })} /> )} /> ( )} /> ( )} /> (