diff --git a/src/modules/geoportal/v2/cf-order-modal.tsx b/src/modules/geoportal/v2/cf-order-modal.tsx index 727760b..7ae3dc6 100644 --- a/src/modules/geoportal/v2/cf-order-modal.tsx +++ b/src/modules/geoportal/v2/cf-order-modal.tsx @@ -25,7 +25,8 @@ import { cn } from "@/shared/lib/utils"; type Phase = | "loading-status" - | "not-connected" + | "connecting" + | "need-credentials" | "no-credits" | "ready" | "placing" @@ -79,6 +80,8 @@ export function CfOrderModal({ const [orderId, setOrderId] = useState(null); const [documentUrl, setDocumentUrl] = useState(null); const [elapsed, setElapsed] = useState(0); + const [username, setUsername] = useState(""); + const [password, setPassword] = useState(""); const startedAtRef = useRef(0); const pollAbortRef = useRef(null); @@ -110,25 +113,69 @@ export function CfOrderModal({ return () => clearInterval(id); }, [phase]); + const evaluateStatus = useCallback((data: SessionStatus) => { + setStatus(data); + if (!data.connected) return "need-connect" as const; + if (data.credits != null && data.credits < 1) { + setPhase("no-credits"); + return "no-credits" as const; + } + setPhase("ready"); + return "ready" as const; + }, []); + + const tryAutoConnect = useCallback( + async (creds?: { username: string; password: string }) => { + setPhase("connecting"); + setError(null); + try { + const res = await fetch("/api/ancpi/session", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify(creds ?? {}), + }); + const data = (await res.json()) as { + success?: boolean; + credits?: number | null; + error?: string; + }; + if (!res.ok || data.error) { + // 400 with empty body = no server-side env creds. Show the + // inline credential form. 401 = bad credentials. + if (creds) { + setError(data.error ?? "Credențiale ePay invalide"); + } + setPhase("need-credentials"); + return; + } + // Re-fetch status to confirm + const sRes = await fetch("/api/ancpi/session", { cache: "no-store" }); + const sData = (await sRes.json()) as SessionStatus; + evaluateStatus(sData); + } catch { + setPhase("need-credentials"); + setError("Nu s-a putut conecta automat. Introdu credențialele manual."); + } + }, + [evaluateStatus], + ); + const loadStatus = useCallback(async () => { try { const res = await fetch("/api/ancpi/session", { cache: "no-store" }); const data = (await res.json()) as SessionStatus; - setStatus(data); - if (!data.connected) { - setPhase("not-connected"); - return; + const result = evaluateStatus(data); + if (result === "need-connect") { + // Session not active yet — silently try the server-side env + // credentials (ANCPI_USERNAME / ANCPI_PASSWORD). Most installs + // have these in Infisical so connection happens transparently. + await tryAutoConnect(); } - if (data.credits != null && data.credits < 1) { - setPhase("no-credits"); - return; - } - setPhase("ready"); } catch { setError("Nu pot verifica sesiunea ePay."); setPhase("error"); } - }, []); + }, [evaluateStatus, tryAutoConnect]); const placeOrder = useCallback(async () => { setPhase("placing"); @@ -228,11 +275,6 @@ export function CfOrderModal({ [cadastralRef], ); - const goToParcelSync = useCallback(() => { - const url = `/parcel-sync?tab=epay&cad=${encodeURIComponent(cadastralRef)}`; - window.open(url, "_blank", "noopener,noreferrer"); - }, [cadastralRef]); - if (!open) return null; return ( @@ -284,29 +326,76 @@ export function CfOrderModal({ )} - {/* Not connected */} - {phase === "not-connected" && ( + {/* Connecting to ePay (auto, env creds) */} + {phase === "connecting" && ( +
+ + Conectare la ePay ANCPI… +
+ )} + + {/* Need credentials — server didn't have them or auto-connect failed */} + {phase === "need-credentials" && (
-
+
-
+

- ePay neconectat + Conectează-te la ePay ANCPI

-

- Conectează-te în secțiunea Parcel Sync → ePay pentru - a putea comanda extrase CF. +

+ {error ?? "Introdu credențialele tale ePay pentru a continua."}

- + + + +

+ Credențialele sunt trimise direct la ANCPI; nu sunt + păstrate la noi după sfârșitul sesiunii. +

+
)} @@ -462,7 +551,10 @@ export function CfOrderModal({ )} - {(phase === "loading-status" || phase === "no-credits") && ( + {(phase === "loading-status" || + phase === "connecting" || + phase === "no-credits" || + phase === "need-credentials") && ( - )} {(phase === "placing" || phase === "processing") && (