"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, 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; }; tag: [ { id: number; name: string; name_ru: string; name_uz: string; }, ]; post_images: [ { 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 form = useForm({ resolver: zodResolver(newsPostForm), defaultValues: { desc: "", desc_ru: "", is_public: "yes", sections: [{ image: undefined as any, text: "", text_ru: "" }], post_tags: [""], }, }); useEffect(() => { if (detail && !hasReset.current) { // 🧠 xavfsiz map qilish const mappedSections = detail.post_images?.map((img) => ({ image: img.image, text: img.text_uz, text_ru: img.text_ru, })) ?? []; const mappedTags = detail.tag?.map((t) => t.name_uz) ?? []; form.reset({ desc: detail.text_uz || "", desc_ru: detail.text_ru || "", is_public: detail.is_public ? "yes" : "no", post_tags: mappedTags.length > 0 ? mappedTags : [""], sections: mappedSections.length > 0 ? mappedSections : [{ image: "", text: "", text_ru: "" }], }); hasReset.current = true; } }, [detail, form]); const { fields, append, remove } = useFieldArray({ control: form.control, name: "sections", }); const { watch, setValue } = form; const postTags = watch("post_tags"); const addTag = () => setValue("post_tags", [...postTags, ""]); const removeTag = (i: number) => setValue( "post_tags", postTags.filter((_, idx) => idx !== i), ); const { mutate: added } = 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 } = useMutation({ mutationFn: ({ body, id }: { id: number; body: FormData }) => updateNews({ id: 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 handleImageChange = ( e: React.ChangeEvent, index: number, ) => { const file = e.target.files?.[0]; if (file) form.setValue(`sections.${index}.image`, file); }; const onSubmit = (values: NewsPostFormType) => { const formData = new FormData(); formData.append("title", stepOneData.title); formData.append("title_ru", stepOneData.title_ru); formData.append("text", stepOneData.desc); formData.append("text_ru", stepOneData.desc_ru); formData.append("is_public", values.is_public === "no" ? "false" : "true"); formData.append("category", stepOneData.category); if (stepOneData.banner instanceof File) { formData.append("image", stepOneData.banner); } // 🔥 sections values.sections.forEach((section, i) => { if (section.image instanceof File) { formData.append(`post_images[${i}]`, section.image); } formData.append(`post_text[${i}]`, section.text); formData.append(`post_text_ru[${i}]`, section.text_ru); }); values.post_tags.forEach((tag, i) => { formData.append(`post_tags[${i}]`, tag); }); if (id) { update({ body: formData, id: Number(id), }); } else { added(formData); } }; return (
{/* DESC (UZ) */} (