gendesign/tradein-mvp/frontend/src/components/trade-in/HouseInfoCard.tsx
lekss361 72d2b97ee0
All checks were successful
Deploy Trade-In / deploy (push) Successful in 21s
Deploy Trade-In / changes (push) Successful in 4s
Deploy Trade-In / build-backend (push) Has been skipped
Deploy Trade-In / build-frontend (push) Successful in 1m21s
feat(tradein): Stage 4b — IMV benchmark badge + house info card on estimate result (#461)
2026-05-23 13:28:23 +00:00

117 lines
3.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"use client";
import type { HouseInfoForEstimate } from "@/types/trade-in";
interface Props {
houses: HouseInfoForEstimate[] | undefined;
isLoading: boolean;
}
function formatHouseType(t: string | null): string {
switch (t) {
case "monolith":
case "monolithic":
return "монолит";
case "panel":
return "панель";
case "brick":
return "кирпич";
case "monolith_brick":
return "монолит-кирпич";
case "block":
return "блочный";
case "wood":
return "дерево";
default:
return t ?? "—";
}
}
export function HouseInfoCard({ houses, isLoading }: Props) {
if (isLoading) {
return (
<div className="house-info-card house-info-card--loading">
<h3>Дом и инфраструктура</h3>
<p>Загрузка</p>
</div>
);
}
if (!houses || houses.length === 0) {
return null;
}
// Show ближайший дом (первый в массиве — sorted by distance)
const h = houses[0];
const features: Array<{ label: string; value: string }> = [];
if (h.year_built != null)
features.push({ label: "Год постройки", value: String(h.year_built) });
if (h.total_floors != null)
features.push({ label: "Этажей", value: String(h.total_floors) });
if (h.house_type)
features.push({ label: "Тип дома", value: formatHouseType(h.house_type) });
if (h.passenger_elevators != null)
features.push({
label: "Пассажирский лифт",
value: String(h.passenger_elevators),
});
if (h.cargo_elevators != null)
features.push({
label: "Грузовой лифт",
value: String(h.cargo_elevators),
});
if (h.has_concierge != null)
features.push({ label: "Консьерж", value: h.has_concierge ? "да" : "нет" });
if (h.closed_yard != null)
features.push({
label: "Закрытая территория",
value: h.closed_yard ? "да" : "нет",
});
if (h.has_playground != null)
features.push({
label: "Детская площадка",
value: h.has_playground ? "да" : "нет",
});
if (h.parking_type)
features.push({ label: "Парковка", value: h.parking_type });
if (h.developer_name)
features.push({ label: "Застройщик", value: h.developer_name });
return (
<section className="house-info-card" aria-label="Информация о доме">
<header className="house-info-card__head">
<h3 className="house-info-card__title">Дом</h3>
{h.short_address && (
<p className="house-info-card__addr">{h.short_address}</p>
)}
</header>
{h.rating != null && (
<div className="house-info-card__rating">
<strong>{h.rating.toFixed(1)}</strong>
<span className="house-info-card__rating-label">
{h.reviews_count != null
? `${h.reviews_count} отзывов`
: "рейтинг"}
</span>
</div>
)}
{features.length > 0 && (
<dl className="house-info-card__features">
{features.map((f) => (
<div key={f.label} className="house-info-card__feature">
<dt>{f.label}</dt>
<dd>{f.value}</dd>
</div>
))}
</dl>
)}
{houses.length > 1 && (
<footer className="house-info-card__more">
+ {houses.length - 1}{" "}
{houses.length - 1 === 1 ? "соседний дом" : "соседних домов"}
</footer>
)}
</section>
);
}