Trade-In Estimator
Оценка рыночной стоимости квартиры по аналогам и сделкам ЕКБ
"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 (
Оценка рыночной стоимости квартиры по аналогам и сделкам ЕКБ
Trade-In Estimator