"use client"; import { useState } from "react"; import type { ParcelAnalysisCompetitor } from "@/types/site-finder"; type StatusFilter = "all" | "building" | "ready"; interface Props { competitors: ParcelAnalysisCompetitor[]; districtName: string | null | undefined; onRowClick?: (competitor: ParcelAnalysisCompetitor) => void; } const CLASS_COLORS: Record = { Комфорт: "#1d4ed8", "Комфорт+": "#2563eb", Бизнес: "#7c3aed", Эконом: "#6b7280", Премиум: "#b45309", }; function StatusBadge({ status }: { status: string | null | undefined }) { if (status === "Строящиеся") { return ( Строящиеся ); } if (status === "Сданные") { return ( Сданные ); } return ( ); } export function CompetitorTable({ competitors, districtName, onRowClick, }: Props) { const [filter, setFilter] = useState("all"); const buildingCount = competitors.filter( (c) => c.site_status === "Строящиеся", ).length; const readyCount = competitors.filter( (c) => c.site_status === "Сданные", ).length; const filtered = competitors.filter((c) => { if (filter === "building") return c.site_status === "Строящиеся"; if (filter === "ready") return c.site_status === "Сданные"; return true; }); const top20 = filtered.slice(0, 20); const tabBase = { padding: "4px 12px", borderRadius: 6, fontSize: 12, fontWeight: 500, cursor: "pointer", border: "1px solid transparent", background: "transparent", color: "#6b7280", transition: "all 0.15s", } as const; const tabActive = { ...tabBase, background: "#fff", border: "1px solid #d1d5db", color: "#111827", fontWeight: 600, } as const; return (
{/* Header */}
Конкуренты ({competitors.length}) {districtName && ( ЖК в районе «{districtName}» подсвечены )}
{/* Filter tabs */}
{top20.length === 0 ? (
{filtered.length === 0 && competitors.length > 0 ? "Нет конкурентов по выбранному фильтру" : "Конкурентов не найдено"}
) : (
{[ "ЖК", "Девелопер", "Класс", "Статус", "Квартир", "Район", "Расст., м", ].map((h, idx) => ( ))} {top20.map((c, i) => { const sameDistrict = districtName && c.district_name === districtName; const rowBg = sameDistrict ? "#eff6ff" : i % 2 ? "#fafbfc" : "#fff"; return ( onRowClick?.(c)} style={{ background: rowBg, borderBottom: "1px solid #f3f4f6", cursor: onRowClick ? "pointer" : "default", }} onMouseEnter={(e) => { if (onRowClick) { ( e.currentTarget as HTMLTableRowElement ).style.background = "#e0e7ff"; } }} onMouseLeave={(e) => { ( e.currentTarget as HTMLTableRowElement ).style.background = rowBg; }} > ); })}
{h}
{c.comm_name ?? `ЖК #${c.obj_id}`} {c.dev_name ?? "—"} {c.obj_class ? ( {c.obj_class} ) : ( )} {c.flat_count != null ? c.flat_count.toLocaleString("ru-RU") : "—"} {c.district_name ?? "—"} {Math.round(c.distance_m).toLocaleString("ru-RU")}
)} {filtered.length > 20 && (
Показано 20 из {filtered.length} ближайших ЖК
)}
); }