117 lines
3.6 KiB
TypeScript
117 lines
3.6 KiB
TypeScript
"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>
|
||
);
|
||
}
|