"use client"; import { useState } from "react"; import { useRouter, useSearchParams } from "next/navigation"; import type { AggregatedEstimate, TradeInEstimateInput, } from "@/types/trade-in"; import { useEstimateMutation, useEstimate } from "@/lib/trade-in-api"; import { EstimateForm } from "@/components/trade-in/EstimateForm"; import { EstimateResult } from "@/components/trade-in/EstimateResult"; import { EstimateProgress } from "@/components/trade-in/EstimateProgress"; // ── URL persistence helpers ──────────────────────────────────────────────────── function useEstimateId() { // SSR guard: searchParams is only available in client if (typeof window === "undefined") return null; const params = new URLSearchParams(window.location.search); return params.get("id"); } // ── Page ────────────────────────────────────────────────────────────────────── export default function TradeInPage() { const router = useRouter(); // Result from mutation (fresh) or from URL (restored) const [freshResult, setFreshResult] = useState<{ estimate: AggregatedEstimate; input: TradeInEstimateInput; } | null>(null); const urlEstimateId = useEstimateId(); // Fetch from URL if no fresh result yet const restoredEstimate = useEstimate( freshResult === null ? urlEstimateId : null, ); const mutation = useEstimateMutation(); function handleSubmit(input: TradeInEstimateInput) { mutation.mutate(input, { onSuccess: (estimate) => { setFreshResult({ estimate, input }); // Persist estimate_id in URL for shareable link router.replace(`/trade-in?id=${estimate.estimate_id}`, { scroll: false, }); }, }); } const apiError = mutation.error?.message ?? null; // Determine what to render on the right side const resultData: { estimate: AggregatedEstimate; input: TradeInEstimateInput; } | null = freshResult ?? (restoredEstimate.data ? { estimate: restoredEstimate.data, // When restoring from URL we don't have the original input — synthesise a minimal one input: { address: restoredEstimate.data.analogs[0]?.address ?? "—", area_m2: 0, rooms: 0, floor: 0, total_floors: 0, }, } : null); return (
{/* Page header */}

Trade-In Estimator

Оценка рыночной стоимости квартиры по аналогам и сделкам ЕКБ

{/* Two-column layout */}
{/* Left — sticky form */}
{/* Right — result area */}
{resultData ? ( ) : restoredEstimate.isLoading ? ( ) : ( )}
{/* Responsive: stack on mobile */}
); } function EmptyState() { return (
🏠
Введите параметры квартиры
Оценка появится здесь после нажатия «Оценить»
); }