"use client"; import { addNews, updateNews } from "@/pages/news/lib/api"; import { useNewsStore } from "@/pages/news/lib/data"; import { newsPostForm, type NewsPostFormType } from "@/pages/news/lib/form"; import { Button } from "@/shared/ui/button"; import { Form, FormControl, FormField, FormItem, FormMessage, } from "@/shared/ui/form"; import { Input } from "@/shared/ui/input"; import { Label } from "@/shared/ui/label"; import { Textarea } from "@/shared/ui/textarea"; import { zodResolver } from "@hookform/resolvers/zod"; import { useMutation, useQueryClient } from "@tanstack/react-query"; import { ImagePlus, Loader2, PlusCircle, Trash2 } from "lucide-react"; import { useEffect, useRef } from "react"; import { useFieldArray, useForm } from "react-hook-form"; import { useTranslation } from "react-i18next"; import { useNavigate } from "react-router-dom"; import { toast } from "sonner"; interface Data { id: number; title: string; title_ru: string; title_uz: string; image: string; text: string; text_ru: string; text_uz: string; is_public: boolean; category: { name: string; name_ru: string; name_uz: string; }; post_tags: Array<{ id: number; name: string; name_ru: string; name_uz: string; }>; post_images: Array<{ id: number; image: string; text: string; text_ru: string; text_uz: string; }>; } const StepTwo = ({ data: detail, id, }: { isEditMode: boolean; id: string; data: Data; }) => { const { t } = useTranslation(); const hasReset = useRef(false); const navigate = useNavigate(); const { stepOneData, resetStepOneData } = useNewsStore(); const queryClient = useQueryClient(); const deletedSections = useRef([]); const form = useForm({ resolver: zodResolver(newsPostForm), defaultValues: { desc: "", desc_ru: "", is_public: "yes", sections: [{ image: undefined as any, text: "", text_ru: "" }], post_tags: [{ name: "", name_ru: "" }], }, }); useEffect(() => { if (detail && !hasReset.current) { const mappedTags = detail.post_tags?.map((t) => ({ name: t.name_uz, name_ru: t.name_ru, })) ?? []; form.reset({ desc: detail.text_uz || "", desc_ru: detail.text_ru || "", is_public: detail.is_public ? "yes" : "no", post_tags: mappedTags.length > 0 ? mappedTags : [{ name: "", name_ru: "" }], sections: detail.post_images?.map((img) => ({ id: img.id, image: img.image, text: img.text_uz, text_ru: img.text_ru, })) ?? [], }); hasReset.current = true; } }, [detail, form]); const handleRemoveSection = (index: number) => { const section = form.getValues(`sections.${index}`); if (section?.id) { deletedSections.current.push(section.id); } // Formdan o'chiramiz removeSection(index); }; const { fields: sectionFields, append: appendSection, remove: removeSection, } = useFieldArray({ control: form.control, name: "sections", }); const { fields: tagFields, append: appendTag, remove: removeTag, } = useFieldArray({ control: form.control, name: "post_tags", }); const handleImageChange = ( e: React.ChangeEvent, index: number, ) => { const file = e.target.files?.[0]; if (file) form.setValue(`sections.${index}.image`, file); }; const { mutate: added, isPending } = useMutation({ mutationFn: (body: FormData) => addNews(body), onSuccess: () => { queryClient.refetchQueries({ queryKey: ["all_news"] }); queryClient.refetchQueries({ queryKey: ["news_detail"] }); navigate("/news"); resetStepOneData(); }, onError: () => { toast.error(t("Xatolik yuz berdi"), { richColors: true, position: "top-center", }); }, }); const { mutate: update, isPending: updatePending } = useMutation({ mutationFn: ({ body, id }: { id: number; body: FormData }) => updateNews({ id, body }), onSuccess: () => { queryClient.refetchQueries({ queryKey: ["news_detail"] }); queryClient.refetchQueries({ queryKey: ["all_news"] }); navigate("/news"); resetStepOneData(); }, onError: () => { toast.error(t("Xatolik yuz berdi"), { richColors: true, position: "top-center", }); }, }); const onSubmit = (values: NewsPostFormType) => { const formData = new FormData(); formData.append("title", stepOneData.title); formData.append("title_ru", stepOneData.title_ru); formData.append("text", values.desc); formData.append("text_ru", values.desc_ru); formData.append("is_public", values.is_public === "no" ? "false" : "true"); formData.append("category", String(stepOneData.category)); if (stepOneData.banner instanceof File) { formData.append("image", stepOneData.banner); } values.sections?.forEach((section, i) => { if (section.id) { formData.append(`updates[${i}]id`, String(section.id)); if (section.text) formData.append(`updates[${i}]text`, section.text); if (section.text_ru) formData.append(`updates[${i}]text_ru`, section.text_ru); if (section.image instanceof File) { formData.append(`updates[${i}]image`, section.image); } } else { if (section.image instanceof File) formData.append(`post_images`, section.image); if (section.text) formData.append(`post_text`, section.text); if (section.text_ru) formData.append(`post_text_ru`, section.text_ru); } }); deletedSections.current.forEach((id) => { formData.append(`delete_list`, String(id)); }); values.post_tags.forEach((tag, i) => { formData.append(`post_tags[${i}]name`, tag.name); formData.append(`post_tags[${i}]name_ru`, tag.name_ru); }); if (id) { update({ body: formData, id: Number(id) }); } else { added(formData); } }; return (
{/* DESC (UZ) */} (