"use client"; import { useState, useEffect, useCallback, useRef } from "react"; import { useSession } from "next-auth/react"; import { FileText, Loader2, Check, RefreshCw } from "lucide-react"; import { Button } from "@/shared/components/ui/button"; import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, } from "@/shared/components/ui/tooltip"; import { cn } from "@/shared/lib/utils"; import type { EpaySessionStatus } from "./epay-connect"; import { fetchCfHasCompletedForCadastral, placeCfOrder, } from "./cf-api-base"; /* ------------------------------------------------------------------ */ /* Props */ /* ------------------------------------------------------------------ */ type Props = { nrCadastral: string; siruta: string; judetName: string; uatName: string; /** Custom label for the button (e.g. "Actualizeaza" for expired extracts) */ label?: string; /** Custom tooltip text */ tooltipText?: string; }; /* ------------------------------------------------------------------ */ /* Component */ /* ------------------------------------------------------------------ */ export function EpayOrderButton({ nrCadastral, siruta, judetName, uatName, label, tooltipText, }: Props) { // Plan 003, Faza F — flag drives which backend handles the order. const { data: session } = useSession(); const useGisAc = Boolean( (session as { useGisAc?: boolean } | null)?.useGisAc, ); const [ordering, setOrdering] = useState(false); const [ordered, setOrdered] = useState(false); const [error, setError] = useState(""); const [epayStatus, setEpayStatus] = useState({ connected: false, }); const mountedRef = useRef(true); useEffect(() => { return () => { mountedRef.current = false; }; }, []); // Check ePay status and whether an extract exists useEffect(() => { let cancelled = false; const check = async () => { try { // ePay credit/session status is still served by the legacy route // (gis-api does not expose ePay session state — server-side creds // there). Read it regardless of cutover flag. const sRes = await fetch("/api/ancpi/session"); const sData = (await sRes.json()) as EpaySessionStatus; if (!cancelled) setEpayStatus(sData); // Check if a completed/fresh extract already exists for this // cadastral. Routes the call through legacy or gis-ac per flag. const has = await fetchCfHasCompletedForCadastral( useGisAc, nrCadastral, ); if (!cancelled && has) setOrdered(true); } catch { /* silent */ } }; void check(); return () => { cancelled = true; }; }, [nrCadastral, useGisAc]); const handleOrder = useCallback(async () => { setOrdering(true); setError(""); const result = await placeCfOrder(useGisAc, { nrCadastral, siruta, judetName, uatName, }); if (mountedRef.current) { if (result.ok) { setOrdered(true); } else { setError(result.error ?? "Eroare comanda"); } setOrdering(false); } }, [nrCadastral, siruta, judetName, uatName, useGisAc]); const disabled = !epayStatus.connected || (epayStatus.credits != null && epayStatus.credits < 1) || ordering; const isRenew = !!label; // "Actualizeaza" mode for expired extracts const Icon = isRenew ? RefreshCw : FileText; const resolveTooltip = (): string => { if (error) return error; if (ordering) return "Se comanda..."; if (ordered) return "Extras CF valid"; if (!epayStatus.connected) return "ePay neconectat"; if (epayStatus.credits != null && epayStatus.credits < 1) return "Credite insuficiente"; return tooltipText ?? "Comanda extras CF (1 credit)"; }; if (ordered) { return ( Extras CF comandat cu succes ); } if (label) { // Render as a compact text button with label (for "Actualizeaza" etc.) return ( {resolveTooltip()} ); } // Default: icon-only button return ( {resolveTooltip()} ); }