Compare commits
No commits in common. "cbb3c64cd617775249329ea9a9dd8c05d414bcad" and "1a733302c21559cdbf0017f44a0970797e855e4e" have entirely different histories.
cbb3c64cd6
...
1a733302c2
2 changed files with 5 additions and 331 deletions
|
|
@ -5,17 +5,7 @@
|
||||||
// photo_url=null у всех лотов — намеренно, чтобы не тянуть внешние картинки
|
// photo_url=null у всех лотов — намеренно, чтобы не тянуть внешние картинки
|
||||||
// (чистый оффлайн-рендер для lighthouse/axe).
|
// (чистый оффлайн-рендер для lighthouse/axe).
|
||||||
|
|
||||||
import type {
|
import type { AggregatedEstimate, AnalogLot, TradeInEstimateInput } from "@/types/trade-in";
|
||||||
AggregatedEstimate,
|
|
||||||
AnalogLot,
|
|
||||||
HouseAnalyticsResponse,
|
|
||||||
HouseInfoForEstimate,
|
|
||||||
IMVBenchmarkResponse,
|
|
||||||
PlacementHistoryItem,
|
|
||||||
SalesVsListingsResponse,
|
|
||||||
SellTimeSensitivityResponse,
|
|
||||||
TradeInEstimateInput,
|
|
||||||
} from "@/types/trade-in";
|
|
||||||
|
|
||||||
const analogs: AnalogLot[] = [
|
const analogs: AnalogLot[] = [
|
||||||
{
|
{
|
||||||
|
|
@ -197,217 +187,3 @@ export const FIXTURE_INPUT: TradeInEstimateInput = {
|
||||||
repair_state: "good",
|
repair_state: "good",
|
||||||
has_balcony: true,
|
has_balcony: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
// ── IMV Benchmark fixture ─────────────────────────────────────────────────────
|
|
||||||
// available:true обязательно — иначе IMVBenchmark возвращает null.
|
|
||||||
export const FIXTURE_IMV: IMVBenchmarkResponse = {
|
|
||||||
available: true,
|
|
||||||
cache_key: "ekb:preview-house:2k",
|
|
||||||
recommended_price: 10_200_000,
|
|
||||||
lower_price: 9_400_000,
|
|
||||||
higher_price: 11_000_000,
|
|
||||||
market_count: 7,
|
|
||||||
fetched_at: "2026-05-30T12:00:00Z",
|
|
||||||
our_median_price: 9_850_000,
|
|
||||||
diff_pct: -3.4,
|
|
||||||
};
|
|
||||||
|
|
||||||
// ── HouseInfo fixture ─────────────────────────────────────────────────────────
|
|
||||||
// houses.length > 0 обязательно — иначе HouseInfoCard возвращает null.
|
|
||||||
export const FIXTURE_HOUSES: HouseInfoForEstimate[] = [
|
|
||||||
{
|
|
||||||
house_id: 42001,
|
|
||||||
ext_house_id: "ekb-repin-75",
|
|
||||||
address: "Екатеринбург, ул. Репина, 75",
|
|
||||||
short_address: "Репина, 75",
|
|
||||||
lat: 56.84,
|
|
||||||
lon: 60.57,
|
|
||||||
year_built: 2018,
|
|
||||||
total_floors: 11,
|
|
||||||
house_type: "monolith",
|
|
||||||
passenger_elevators: 2,
|
|
||||||
cargo_elevators: 1,
|
|
||||||
has_concierge: false,
|
|
||||||
closed_yard: true,
|
|
||||||
has_playground: true,
|
|
||||||
parking_type: "подземная",
|
|
||||||
developer_name: "Атомстройкомплекс",
|
|
||||||
rating: 4.3,
|
|
||||||
reviews_count: 28,
|
|
||||||
raw_characteristics: [],
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
// ── PlacementHistory fixture ──────────────────────────────────────────────────
|
|
||||||
// items.length > 0 обязательно — иначе PlacementHistoryCard возвращает null.
|
|
||||||
export const FIXTURE_PLACEMENT: PlacementHistoryItem[] = [
|
|
||||||
{
|
|
||||||
id: 1001,
|
|
||||||
source: "avito",
|
|
||||||
house_id: 42001,
|
|
||||||
ext_item_id: "avito-preview-1001",
|
|
||||||
title: "2к, 54 м², 7/16 эт.",
|
|
||||||
rooms: 2,
|
|
||||||
area_m2: 54,
|
|
||||||
floor: 7,
|
|
||||||
total_floors: 16,
|
|
||||||
start_price: 10_200_000,
|
|
||||||
start_price_date: "2025-11-01",
|
|
||||||
last_price: 9_700_000,
|
|
||||||
last_price_date: "2026-03-15",
|
|
||||||
removed_date: "2026-04-10",
|
|
||||||
exposure_days: 160,
|
|
||||||
notes: null,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 1002,
|
|
||||||
source: "cian",
|
|
||||||
house_id: 42001,
|
|
||||||
ext_item_id: "cian-preview-1002",
|
|
||||||
title: "2к, 57 м², 4/10 эт.",
|
|
||||||
rooms: 2,
|
|
||||||
area_m2: 57,
|
|
||||||
floor: 4,
|
|
||||||
total_floors: 10,
|
|
||||||
start_price: 9_800_000,
|
|
||||||
start_price_date: "2025-09-10",
|
|
||||||
last_price: 9_500_000,
|
|
||||||
last_price_date: "2025-12-20",
|
|
||||||
removed_date: "2026-01-05",
|
|
||||||
exposure_days: 117,
|
|
||||||
notes: null,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 1003,
|
|
||||||
source: "avito",
|
|
||||||
house_id: 42001,
|
|
||||||
ext_item_id: "avito-preview-1003",
|
|
||||||
title: "2к, 55 м², 5/11 эт.",
|
|
||||||
rooms: 2,
|
|
||||||
area_m2: 55,
|
|
||||||
floor: 5,
|
|
||||||
total_floors: 11,
|
|
||||||
start_price: 9_500_000,
|
|
||||||
start_price_date: "2025-06-01",
|
|
||||||
last_price: 9_100_000,
|
|
||||||
last_price_date: "2025-08-30",
|
|
||||||
removed_date: "2025-09-05",
|
|
||||||
exposure_days: 96,
|
|
||||||
notes: null,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
// ── HouseAnalytics fixture ────────────────────────────────────────────────────
|
|
||||||
// kpi.total_lots > 0 обязательно — иначе HouseAnalyticsSection возвращает null.
|
|
||||||
// price_history >= 2 точки — для рендера PriceHistoryChart.
|
|
||||||
// recent_sold > 0 — для рендера RecentSoldList.
|
|
||||||
export const FIXTURE_ANALYTICS: HouseAnalyticsResponse = {
|
|
||||||
house_ids: [42001],
|
|
||||||
radius_m: 0,
|
|
||||||
kpi: {
|
|
||||||
total_lots: 38,
|
|
||||||
sold_count: 24,
|
|
||||||
sold_rate_pct: 63.2,
|
|
||||||
median_exposure_days: 112,
|
|
||||||
median_bargain_pct: 4.8,
|
|
||||||
},
|
|
||||||
price_history: [
|
|
||||||
{ year: 2022, source: "avito_imv", median_price_per_m2: 155_000, n_lots: 6, median_price_rub: 8_525_000 },
|
|
||||||
{ year: 2023, source: "avito_imv", median_price_per_m2: 161_000, n_lots: 9, median_price_rub: 8_855_000 },
|
|
||||||
{ year: 2024, source: "avito_imv", median_price_per_m2: 170_000, n_lots: 12, median_price_rub: 9_350_000 },
|
|
||||||
{ year: 2025, source: "avito_imv", median_price_per_m2: 176_000, n_lots: 11, median_price_rub: 9_680_000 },
|
|
||||||
],
|
|
||||||
recent_sold: [
|
|
||||||
{
|
|
||||||
id: 2001,
|
|
||||||
source: "avito_imv",
|
|
||||||
rooms: 2,
|
|
||||||
area_m2: 54,
|
|
||||||
floor: 7,
|
|
||||||
start_price: 10_200_000,
|
|
||||||
last_price: 9_700_000,
|
|
||||||
removed_date: "2026-04-10",
|
|
||||||
exposure_days: 160,
|
|
||||||
discount_pct: 4.9,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 2002,
|
|
||||||
source: "avito_imv",
|
|
||||||
rooms: 2,
|
|
||||||
area_m2: 57,
|
|
||||||
floor: 4,
|
|
||||||
start_price: 9_800_000,
|
|
||||||
last_price: 9_500_000,
|
|
||||||
removed_date: "2026-01-05",
|
|
||||||
exposure_days: 117,
|
|
||||||
discount_pct: 3.1,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
||||||
// ── SellTimeSensitivity fixture ───────────────────────────────────────────────
|
|
||||||
export const FIXTURE_SELLTIME: SellTimeSensitivityResponse = {
|
|
||||||
house_ids: [42001],
|
|
||||||
radius_m: 0,
|
|
||||||
target_median_price_per_m2: 178_000,
|
|
||||||
buckets: [
|
|
||||||
{ price_premium_label: "cheap", price_premium_pct: -5, median_exposure_days: 38, p25_days: 21, p75_days: 55, n_lots: 8 },
|
|
||||||
{ price_premium_label: "median", price_premium_pct: 0, median_exposure_days: 112, p25_days: 60, p75_days: 160, n_lots: 14 },
|
|
||||||
{ price_premium_label: "plus5", price_premium_pct: 5, median_exposure_days: 185, p25_days: 90, p75_days: 240, n_lots: 10 },
|
|
||||||
{ price_premium_label: "plus10", price_premium_pct: 10, median_exposure_days: 270, p25_days: 150, p75_days: 360, n_lots: 6 },
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
||||||
// Секция 12: StreetDealsCard — useSalesVsListings(address, area_m2, rooms).
|
|
||||||
// Guard: street != null И pairs.length > 0 — иначе return null.
|
|
||||||
export const FIXTURE_SALES: SalesVsListingsResponse = {
|
|
||||||
street: "Репина",
|
|
||||||
period_months: 24,
|
|
||||||
window_days: 180,
|
|
||||||
area_tolerance: 0.15,
|
|
||||||
total_deals: 9,
|
|
||||||
deals_with_listings: 5,
|
|
||||||
linkage_rate_pct: 55.6,
|
|
||||||
median_discount_pct: -6.2,
|
|
||||||
data_quality: "house_linked",
|
|
||||||
pairs: [
|
|
||||||
{
|
|
||||||
deal_id: 9001,
|
|
||||||
deal_date: "2026-04-18",
|
|
||||||
deal_price_rub: 8_900_000,
|
|
||||||
deal_price_per_m2: 161_818,
|
|
||||||
deal_area_m2: 55,
|
|
||||||
deal_rooms: 2,
|
|
||||||
deal_floor: 6,
|
|
||||||
deal_address: "Екатеринбург, ул. Репина, 75/2",
|
|
||||||
listing_id: 50001,
|
|
||||||
listing_source: "avito",
|
|
||||||
listing_source_url: "https://www.avito.ru/ekaterinburg/kvartiry/preview-d1",
|
|
||||||
listing_date: "2026-03-20",
|
|
||||||
listing_price_rub: 9_500_000,
|
|
||||||
listing_price_per_m2: 172_727,
|
|
||||||
listing_area_m2: 55,
|
|
||||||
days_listing_to_deal: 29,
|
|
||||||
discount_pct: -6.3,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
deal_id: 9002,
|
|
||||||
deal_date: "2026-02-27",
|
|
||||||
deal_price_rub: 9_100_000,
|
|
||||||
deal_price_per_m2: 159_649,
|
|
||||||
deal_area_m2: 57,
|
|
||||||
deal_rooms: 2,
|
|
||||||
deal_floor: 9,
|
|
||||||
deal_address: "Екатеринбург, ул. Репина, 73",
|
|
||||||
listing_id: 50002,
|
|
||||||
listing_source: "cian",
|
|
||||||
listing_source_url: "https://www.cian.ru/sale/flat/preview-d2",
|
|
||||||
listing_date: "2026-01-30",
|
|
||||||
listing_price_rub: 9_700_000,
|
|
||||||
listing_price_per_m2: 170_175,
|
|
||||||
listing_area_m2: 57,
|
|
||||||
days_listing_to_deal: 28,
|
|
||||||
discount_pct: -6.2,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
|
||||||
|
|
@ -15,25 +15,6 @@
|
||||||
* Локально: echo NEXT_PUBLIC_ENABLE_PREVIEW=1 > .env.local && npm run dev
|
* Локально: echo NEXT_PUBLIC_ENABLE_PREVIEW=1 > .env.local && npm run dev
|
||||||
* → http://localhost:3000/ui-preview/estimate
|
* → http://localhost:3000/ui-preview/estimate
|
||||||
* CI: собрать с флагом, поднять next start, навести axe/lighthouse.
|
* CI: собрать с флагом, поднять next start, навести axe/lighthouse.
|
||||||
*
|
|
||||||
* Секции (1:1 с page.tsx строки 228-276):
|
|
||||||
* 1. SourcesProgress — estimate prop
|
|
||||||
* 2. WhatIfPanel — baseEstimate + baseInput props
|
|
||||||
* 3. HeroSummary — estimate + input props
|
|
||||||
* 4. IMVBenchmark — benchmark prop (FIXTURE_IMV, available:true)
|
|
||||||
* 5. CianValuationCard — data prop
|
|
||||||
* 6. HouseInfoCard — houses prop (FIXTURE_HOUSES, length>0)
|
|
||||||
* 7. PlacementHistoryCard — estimateId; seed queryKey "placement-history"
|
|
||||||
* 8. HouseAnalyticsSection — estimateId; seed "house-analytics" + "sell-time-sensitivity"
|
|
||||||
* 9. PhotoUpload — estimateId (upload-UI; fetch photo может тихо упасть — ок)
|
|
||||||
* 10. ListingsCard — estimate + estimateId; seed "cian-price-changes" пустым
|
|
||||||
* 11. DealsCard — estimate prop
|
|
||||||
* 12. StreetDealsCard — estimate prop
|
|
||||||
* 13. MapCard — estimate prop (analogs имеют lat/lon → пины есть)
|
|
||||||
* 14. DistributionCard — estimate prop
|
|
||||||
* 15. PriceTrendCard — estimate prop
|
|
||||||
* 16. ExposureCard — estimate prop
|
|
||||||
* 17. OfferCard — estimate + brandSlug=null props
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
||||||
|
|
@ -46,35 +27,14 @@ import { DealsCard } from "@/components/trade-in/DealsCard";
|
||||||
import { DistributionCard } from "@/components/trade-in/DistributionCard";
|
import { DistributionCard } from "@/components/trade-in/DistributionCard";
|
||||||
import { ExposureCard } from "@/components/trade-in/ExposureCard";
|
import { ExposureCard } from "@/components/trade-in/ExposureCard";
|
||||||
import { HeroSummary } from "@/components/trade-in/HeroSummary";
|
import { HeroSummary } from "@/components/trade-in/HeroSummary";
|
||||||
import { HouseAnalyticsSection } from "@/components/trade-in/HouseAnalyticsSection";
|
|
||||||
import { HouseInfoCard } from "@/components/trade-in/HouseInfoCard";
|
|
||||||
import { IMVBenchmark } from "@/components/trade-in/IMVBenchmark";
|
|
||||||
import { ListingsCard } from "@/components/trade-in/ListingsCard";
|
|
||||||
import { MapCard } from "@/components/trade-in/MapCard";
|
|
||||||
import { OfferCard } from "@/components/trade-in/OfferCard";
|
|
||||||
import { PhotoUpload } from "@/components/trade-in/PhotoUpload";
|
|
||||||
import { PlacementHistoryCard } from "@/components/trade-in/PlacementHistoryCard";
|
|
||||||
import { PriceTrendCard } from "@/components/trade-in/PriceTrendCard";
|
import { PriceTrendCard } from "@/components/trade-in/PriceTrendCard";
|
||||||
import { SourcesProgress } from "@/components/trade-in/SourcesProgress";
|
|
||||||
import { StreetDealsCard } from "@/components/trade-in/StreetDealsCard";
|
import { StreetDealsCard } from "@/components/trade-in/StreetDealsCard";
|
||||||
import { WhatIfPanel } from "@/components/trade-in/WhatIfPanel";
|
|
||||||
import { ME_QUERY_KEY, type UserScope } from "@/lib/useMe";
|
import { ME_QUERY_KEY, type UserScope } from "@/lib/useMe";
|
||||||
|
|
||||||
import {
|
import { FIXTURE_ESTIMATE, FIXTURE_INPUT } from "./fixture";
|
||||||
FIXTURE_ANALYTICS,
|
|
||||||
FIXTURE_ESTIMATE,
|
|
||||||
FIXTURE_HOUSES,
|
|
||||||
FIXTURE_IMV,
|
|
||||||
FIXTURE_INPUT,
|
|
||||||
FIXTURE_PLACEMENT,
|
|
||||||
FIXTURE_SALES,
|
|
||||||
FIXTURE_SELLTIME,
|
|
||||||
} from "./fixture";
|
|
||||||
|
|
||||||
const ENABLED = process.env.NEXT_PUBLIC_ENABLE_PREVIEW === "1";
|
const ENABLED = process.env.NEXT_PUBLIC_ENABLE_PREVIEW === "1";
|
||||||
|
|
||||||
const PREVIEW_ID = FIXTURE_ESTIMATE.estimate_id;
|
|
||||||
|
|
||||||
// Фейковый authorized-юзер: засеивается в QueryClient → useMe/useBrand резолвятся
|
// Фейковый authorized-юзер: засеивается в QueryClient → useMe/useBrand резолвятся
|
||||||
// оффлайн (никакого /me, /quota, /brand), generic-бренд (brand=null).
|
// оффлайн (никакого /me, /quota, /brand), generic-бренд (brand=null).
|
||||||
const PREVIEW_USER: UserScope = {
|
const PREVIEW_USER: UserScope = {
|
||||||
|
|
@ -92,26 +52,7 @@ function PreviewContent() {
|
||||||
queries: { retry: false, staleTime: Infinity, refetchOnWindowFocus: false },
|
queries: { retry: false, staleTime: Infinity, refetchOnWindowFocus: false },
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
// /me — пропускает RouteGuard без сетевого запроса
|
|
||||||
qc.setQueryData(ME_QUERY_KEY, PREVIEW_USER);
|
qc.setQueryData(ME_QUERY_KEY, PREVIEW_USER);
|
||||||
// Секция 7: PlacementHistoryCard — useEstimatePlacementHistory
|
|
||||||
qc.setQueryData(["trade-in", "estimate", PREVIEW_ID, "placement-history"], FIXTURE_PLACEMENT);
|
|
||||||
// Секция 8: HouseAnalyticsSection — useEstimateHouseAnalytics + useEstimateSellTimeSensitivity
|
|
||||||
qc.setQueryData(["trade-in", "estimate", PREVIEW_ID, "house-analytics"], FIXTURE_ANALYTICS);
|
|
||||||
qc.setQueryData(["trade-in", "estimate", PREVIEW_ID, "sell-time-sensitivity"], FIXTURE_SELLTIME);
|
|
||||||
// Секция 10: ListingsCard — useEstimateCianPriceChanges (пустой = graceful)
|
|
||||||
qc.setQueryData(["trade-in", "estimate", PREVIEW_ID, "cian-price-changes"], []);
|
|
||||||
// Секция 12: StreetDealsCard — useSalesVsListings(address, area_m2, rooms)
|
|
||||||
qc.setQueryData(
|
|
||||||
[
|
|
||||||
"trade-in",
|
|
||||||
"sales-vs-listings",
|
|
||||||
FIXTURE_ESTIMATE.target_address,
|
|
||||||
FIXTURE_ESTIMATE.area_m2,
|
|
||||||
FIXTURE_ESTIMATE.rooms,
|
|
||||||
],
|
|
||||||
FIXTURE_SALES,
|
|
||||||
);
|
|
||||||
return qc;
|
return qc;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -121,61 +62,18 @@ function PreviewContent() {
|
||||||
(flex-column gap, --container ширина). Без них карточки рендерились узко/«мобильно». */}
|
(flex-column gap, --container ширина). Без них карточки рендерились узко/«мобильно». */}
|
||||||
<main className="page">
|
<main className="page">
|
||||||
<section className="result-col">
|
<section className="result-col">
|
||||||
{/* 1. SourcesProgress */}
|
|
||||||
<SourcesProgress estimate={FIXTURE_ESTIMATE} isPending={false} />
|
|
||||||
|
|
||||||
{/* 2. WhatIfPanel */}
|
|
||||||
<WhatIfPanel baseEstimate={FIXTURE_ESTIMATE} baseInput={FIXTURE_INPUT} />
|
|
||||||
|
|
||||||
{/* 3. HeroSummary */}
|
|
||||||
<HeroSummary
|
<HeroSummary
|
||||||
estimate={FIXTURE_ESTIMATE}
|
estimate={FIXTURE_ESTIMATE}
|
||||||
input={FIXTURE_INPUT}
|
input={FIXTURE_INPUT}
|
||||||
onResubmit={() => {}}
|
onResubmit={() => {}}
|
||||||
isResubmitting={false}
|
isResubmitting={false}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{/* 4. IMVBenchmark — передаём пропом напрямую (available:true → не null) */}
|
|
||||||
<IMVBenchmark benchmark={FIXTURE_IMV} isLoading={false} />
|
|
||||||
|
|
||||||
{/* 5. CianValuationCard */}
|
|
||||||
<CianValuationCard data={FIXTURE_ESTIMATE.cian_valuation} />
|
<CianValuationCard data={FIXTURE_ESTIMATE.cian_valuation} />
|
||||||
|
|
||||||
{/* 6. HouseInfoCard — передаём пропом напрямую (length>0 → не null) */}
|
|
||||||
<HouseInfoCard houses={FIXTURE_HOUSES} isLoading={false} />
|
|
||||||
|
|
||||||
{/* 7. PlacementHistoryCard — useEstimatePlacementHistory; queryKey засеян выше */}
|
|
||||||
<PlacementHistoryCard estimateId={PREVIEW_ID} />
|
|
||||||
|
|
||||||
{/* 8. HouseAnalyticsSection — useEstimateHouseAnalytics; queryKeys засеяны выше */}
|
|
||||||
<HouseAnalyticsSection estimateId={PREVIEW_ID} />
|
|
||||||
|
|
||||||
{/* 9. PhotoUpload — рендерит upload-UI; fetch фото может тихо упасть — ок */}
|
|
||||||
<PhotoUpload estimateId={PREVIEW_ID} />
|
|
||||||
|
|
||||||
{/* 10. ListingsCard — cian-price-changes засеян пустым массивом */}
|
|
||||||
<ListingsCard estimate={FIXTURE_ESTIMATE} estimateId={PREVIEW_ID} />
|
|
||||||
|
|
||||||
{/* 11. DealsCard */}
|
|
||||||
<DealsCard estimate={FIXTURE_ESTIMATE} />
|
|
||||||
|
|
||||||
{/* 12. StreetDealsCard */}
|
|
||||||
<StreetDealsCard estimate={FIXTURE_ESTIMATE} />
|
|
||||||
|
|
||||||
{/* 13. MapCard — analogs имеют lat/lon → пины есть; Leaflet CDN → тайлы из сети (ок) */}
|
|
||||||
<MapCard estimate={FIXTURE_ESTIMATE} />
|
|
||||||
|
|
||||||
{/* 14. DistributionCard */}
|
|
||||||
<DistributionCard estimate={FIXTURE_ESTIMATE} />
|
<DistributionCard estimate={FIXTURE_ESTIMATE} />
|
||||||
|
<DealsCard estimate={FIXTURE_ESTIMATE} />
|
||||||
{/* 15. PriceTrendCard */}
|
<StreetDealsCard estimate={FIXTURE_ESTIMATE} />
|
||||||
<PriceTrendCard estimate={FIXTURE_ESTIMATE} />
|
|
||||||
|
|
||||||
{/* 16. ExposureCard */}
|
|
||||||
<ExposureCard estimate={FIXTURE_ESTIMATE} />
|
<ExposureCard estimate={FIXTURE_ESTIMATE} />
|
||||||
|
<PriceTrendCard estimate={FIXTURE_ESTIMATE} />
|
||||||
{/* 17. OfferCard */}
|
|
||||||
<OfferCard estimate={FIXTURE_ESTIMATE} brandSlug={null} />
|
|
||||||
</section>
|
</section>
|
||||||
</main>
|
</main>
|
||||||
</QueryClientProvider>
|
</QueryClientProvider>
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue