"use client"; import { useCallback, useEffect, useMemo, useState } from "react"; import Alert from "@mui/material/Alert"; import Box from "@mui/material/Box"; import Card from "@mui/material/Card"; import CardContent from "@mui/material/CardContent"; import Chip from "@mui/material/Chip"; import Divider from "@mui/material/Divider"; import IconButton from "@mui/material/IconButton"; import LinearProgress from "@mui/material/LinearProgress"; import Stack from "@mui/material/Stack"; import Table from "@mui/material/Table"; import TableBody from "@mui/material/TableBody"; import TableCell from "@mui/material/TableCell"; import TableContainer from "@mui/material/TableContainer"; import TableHead from "@mui/material/TableHead"; import TableRow from "@mui/material/TableRow"; import Tooltip from "@mui/material/Tooltip"; import Typography from "@mui/material/Typography"; import FertilizationPlanParserPage from "@views/dashboards/farm/fertilizationPlanParser/FertilizationPlanParserPage"; import RelatedPlanSelector, { type RelatedPlanItem, } from "@views/dashboards/farm/planSelector/RelatedPlanSelector"; import { useFarmHub } from "@/hooks/useFarmHub"; import { fertilizationPlanService, type FertilizationPlanDetail, type FertilizationPlanListItem, } from "@/libs/api/services/fertilizationPlanService"; import { irrigationPlanService } from "@/libs/api/services/irrigationPlanService"; import CustomTextField from "@core/components/mui/TextField"; type FertilizationPlanRow = { id: string; planName: string; finalProduct: string; harvestTime: string; outputTon: number; fertilizerType: string; status: "active" | "draft"; sourceLabel: string; growthStage: string; }; const PAGE_SIZE = 10; const formatDate = (value?: string | null) => { if (!value) return "—"; try { return new Intl.DateTimeFormat("fa-IR", { year: "numeric", month: "2-digit", day: "2-digit", }).format(new Date(value)); } catch { return value; } }; const mapFertilizationPlanRow = ( plan: FertilizationPlanListItem, detail?: FertilizationPlanDetail | null, ): FertilizationPlanRow => ({ id: plan.plan_uuid, planName: plan.title, finalProduct: plan.plant_name || plan.crop_id || "—", harvestTime: formatDate(plan.created_at), outputTon: 0, fertilizerType: detail?.plan_payload?.items?.[0]?.name || plan.source_label || "—", status: plan.is_active ? "active" : "draft", sourceLabel: plan.source_label || "—", growthStage: plan.growth_stage || "—", }); const FertilizationPlanPage = () => { const { getFarmUuid } = useFarmHub(); const [plans, setPlans] = useState([]); const [minOutputTon, setMinOutputTon] = useState("0"); const [selectedPlan, setSelectedPlan] = useState(null); const [detailsOpen, setDetailsOpen] = useState(false); const [loading, setLoading] = useState(false); const [detailsLoading, setDetailsLoading] = useState(false); const [actionLoadingId, setActionLoadingId] = useState(null); const [error, setError] = useState(null); const [relatedPlans, setRelatedPlans] = useState([]); const [selectedRelatedPlanId, setSelectedRelatedPlanId] = useState( null, ); const filteredPlans = useMemo(() => { const minTon = Number(minOutputTon); return plans .filter((plan) => plan.outputTon >= minTon) .sort((firstPlan, secondPlan) => secondPlan.outputTon - firstPlan.outputTon); }, [minOutputTon, plans]); const loadPlans = useCallback(async () => { const farmUuid = getFarmUuid(); if (!farmUuid) { setError("ابتدا مزرعه فعال را انتخاب کنید."); setPlans([]); setSelectedPlan(null); return; } setLoading(true); setError(null); try { const response = await fertilizationPlanService.getPlans(farmUuid, 1, PAGE_SIZE); const mappedPlans = response.data.map((plan) => mapFertilizationPlanRow(plan)); setPlans(mappedPlans); setSelectedPlan((current) => mappedPlans.find((plan) => plan.id === current?.id) ?? mappedPlans[0] ?? null, ); } catch (loadError) { setError( loadError instanceof Error ? loadError.message : "دریافت لیست برنامه‌های کوددهی انجام نشد.", ); setPlans([]); setSelectedPlan(null); } finally { setLoading(false); } }, [getFarmUuid]); useEffect(() => { loadPlans(); }, [loadPlans]); const loadRelatedPlans = useCallback(async () => { const farmUuid = getFarmUuid(); if (!farmUuid) { setRelatedPlans([]); setSelectedRelatedPlanId(null); return; } const response = await irrigationPlanService.getPlans(farmUuid, 1, PAGE_SIZE); const items: RelatedPlanItem[] = response.data.map((plan) => ({ id: plan.plan_uuid, title: plan.title, finalProduct: plan.plant_name || plan.crop_id || "—", harvestTime: formatDate(plan.created_at), outputTon: 0, methodLabel: `منبع: ${plan.source_label || "—"}`, status: plan.is_active ? "active" : "draft", })); setRelatedPlans(items); setSelectedRelatedPlanId(items[0]?.id ?? null); }, [getFarmUuid]); const handleActivate = async (planId: string) => { setActionLoadingId(planId); try { await fertilizationPlanService.updatePlanStatus(planId, true); setPlans((currentPlans) => currentPlans.map((plan) => ({ ...plan, status: plan.id === planId ? "active" : "draft", })), ); setSelectedPlan((currentPlan) => currentPlan && currentPlan.id === planId ? { ...currentPlan, status: "active" } : currentPlan, ); } catch (updateError) { setError( updateError instanceof Error ? updateError.message : "تغییر وضعیت برنامه کوددهی انجام نشد.", ); } finally { setActionLoadingId(null); } }; const handleDelete = async (planId: string) => { setActionLoadingId(planId); try { await fertilizationPlanService.deletePlan(planId); setPlans((currentPlans) => currentPlans.filter((plan) => plan.id !== planId)); if (selectedPlan?.id === planId) { setSelectedPlan(null); } } catch (deleteError) { setError( deleteError instanceof Error ? deleteError.message : "حذف برنامه کوددهی انجام نشد.", ); } finally { setActionLoadingId(null); } }; const handleShowDetails = async (plan: FertilizationPlanRow) => { setSelectedPlan(plan); setDetailsOpen(true); setDetailsLoading(true); try { const detail = await fertilizationPlanService.getPlanDetail(plan.id); setSelectedPlan(mapFertilizationPlanRow(detail, detail)); await loadRelatedPlans(); } catch (detailError) { setError( detailError instanceof Error ? detailError.message : "دریافت جزئیات برنامه کوددهی انجام نشد.", ); setDetailsOpen(false); } finally { setDetailsLoading(false); } }; return ( <> {loading ? : null} {error ? {error} : null} لیست برنامه‌های کوددهی لیست برنامه‌های کوددهی ثبت‌شده برای مزرعه فعال setMinOutputTon(event.target.value)} label="فیلتر تن خروجی محصول" sx={{ minWidth: { xs: "100%", md: 260 } }} SelectProps={{ native: true }} > نام برنامه محصول نهایی تاریخ ایجاد مرحله رشد نوع کود / منبع وضعیت عملیات {filteredPlans.map((plan) => ( {plan.planName} {plan.finalProduct} {plan.harvestTime} {plan.growthStage} {plan.fertilizerType} handleActivate(plan.id)} disabled={plan.status === "active" || actionLoadingId === plan.id} > handleShowDetails(plan)} > handleDelete(plan.id)} disabled={actionLoadingId === plan.id} > ))} {filteredPlans.length === 0 ? ( برنامه‌ای با این فیلتر پیدا نشد. ) : null}
جزئیات برنامه انتخاب‌شده {selectedPlan ? ( ) : ( برای دیدن جزئیات، یکی از برنامه‌های کوددهی را انتخاب کنید. )}
{detailsLoading ? : null} {selectedPlan ? ( setDetailsOpen(false)} title="جزییات برنامه کوددهی" description="برای تکمیل اجرای این برنامه کوددهی، یکی از برنامه‌های آبیاری مرتبط را انتخاب کنید." currentPlanName={selectedPlan.planName} currentPlanStatus={selectedPlan.status === "active" ? "برنامه فعال" : "آماده برای فعال‌سازی"} currentPlanOutput={`منبع: ${selectedPlan.sourceLabel}`} summaryItems={[ { label: "محصول نهایی", value: selectedPlan.finalProduct }, { label: "تاریخ ایجاد", value: selectedPlan.harvestTime }, { label: "جزئیات", value: selectedPlan.fertilizerType }, ]} relatedTitle="برنامه‌های آبیاری پیشنهادی" relatedDescription="از بین برنامه‌های زیر، مناسب‌ترین برنامه آبیاری را برای این برنامه کوددهی انتخاب کنید." relatedPlans={relatedPlans} selectedRelatedPlanId={selectedRelatedPlanId} onSelectRelatedPlan={(planId) => setSelectedRelatedPlanId(planId)} onConfirm={() => setDetailsOpen(false)} /> ) : null} ); }; export default FertilizationPlanPage;