Compare commits
No commits in common. "2318f0906a9e2839820091484cf659265e724026" and "4a2ed52cb73be293082d1690b51d651ff3ff9636" have entirely different histories.
2318f0906a
...
4a2ed52cb7
3 changed files with 0 additions and 101 deletions
|
|
@ -31,7 +31,6 @@ import { API_BASE_URL } from "@/lib/api";
|
||||||
import { triggerDownload } from "@/lib/download";
|
import { triggerDownload } from "@/lib/download";
|
||||||
import { useParcelForecastQuery } from "@/lib/site-finder-api";
|
import { useParcelForecastQuery } from "@/lib/site-finder-api";
|
||||||
import type { ParcelAnalysis } from "@/types/site-finder";
|
import type { ParcelAnalysis } from "@/types/site-finder";
|
||||||
import { StatusRow } from "@/components/site-finder/ptica/drawers/DrawerPrimitives";
|
|
||||||
import styles from "@/app/site-finder/analysis/[cad]/ptica/ptica.module.css";
|
import styles from "@/app/site-finder/analysis/[cad]/ptica/ptica.module.css";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
|
|
@ -346,19 +345,6 @@ export function PticaReports({ cad, analysis }: Props) {
|
||||||
{error}
|
{error}
|
||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* ── Параметры — что войдёт в сгенерированный отчёт ─────────────── */}
|
|
||||||
<hr className={styles.overlayDivider} />
|
|
||||||
<h3 className={styles.cardTitle}>
|
|
||||||
Параметры <span className={styles.cardTitleSub}>OPTIONS</span>
|
|
||||||
</h3>
|
|
||||||
<StatusRow label="Включить карту и слои" state="Да" tone="ok" />
|
|
||||||
<StatusRow label="Включить финмодель" state="Да" tone="ok" />
|
|
||||||
<StatusRow
|
|
||||||
label="Включить прогноз §22"
|
|
||||||
state={forecastReady ? "Включён" : "Готовится"}
|
|
||||||
tone={forecastReady ? "ok" : "warn"}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* ── Report-section checklist ──────────────────────────────────── */}
|
{/* ── Report-section checklist ──────────────────────────────────── */}
|
||||||
|
|
|
||||||
|
|
@ -1,84 +0,0 @@
|
||||||
/**
|
|
||||||
* FutureSupply — 6.6 «Будущее предложение и конкуренты». Renders
|
|
||||||
* §9.7 forward-looking competitors (report.future_market.future_competitors):
|
|
||||||
* one row per forecast competitor — ЖК / проект · класс · квартир · дистанция ·
|
|
||||||
* темп поглощения. Distinct from the market_now competitors block: these are the
|
|
||||||
* top-N projects ranked by `relevance_weight` at the horizon that will compete
|
|
||||||
* for the same demand.
|
|
||||||
*
|
|
||||||
* The prototype's «Срок сдачи» column has NO backing field in the §22 report, so
|
|
||||||
* it is dropped in favour of the real `velocity_per_month` (темп поглощения) —
|
|
||||||
* every value traces to a real forecast field. Rows are sorted by distance asc
|
|
||||||
* (closest competitors first). Nullable fields render «нет данных», never a
|
|
||||||
* fabricated 0. Empty/absent list → honest empty-state, NOT a hidden section.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import styles from "@/app/site-finder/analysis/[cad]/ptica/ptica.module.css";
|
|
||||||
import type { FutureCompetitor } from "@/types/forecast";
|
|
||||||
import { fmtInt, fmtNum } from "./scenario-helpers";
|
|
||||||
|
|
||||||
interface Props {
|
|
||||||
competitors: FutureCompetitor[] | undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Distance in metres → «445 м» / «1.20 км» (mirrors PticaMapInner.formatMeters). */
|
|
||||||
function formatMeters(m: number): string {
|
|
||||||
if (m >= 1000) return `${(m / 1000).toFixed(2)} км`;
|
|
||||||
return `${Math.round(m)} м`;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function FutureSupply({ competitors }: Props) {
|
|
||||||
const rows = (competitors ?? [])
|
|
||||||
.slice()
|
|
||||||
.sort((a, b) => a.distance_m - b.distance_m);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<div className={styles.sectionLabel}>
|
|
||||||
6.6 · <b>будущее предложение и конкуренты</b>
|
|
||||||
</div>
|
|
||||||
<div className={styles.panel}>
|
|
||||||
{rows.length === 0 ? (
|
|
||||||
<div className={styles.emptyPanel}>
|
|
||||||
Нет данных по конкурирующему предложению
|
|
||||||
</div>
|
|
||||||
) : (
|
|
||||||
<>
|
|
||||||
<table className={styles.dtable}>
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>ЖК / проект</th>
|
|
||||||
<th>Класс</th>
|
|
||||||
<th className={styles.thNum}>Квартир</th>
|
|
||||||
<th className={styles.thNum}>Дистанция</th>
|
|
||||||
<th className={styles.thNum}>Поглощение</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
{rows.map((c) => (
|
|
||||||
<tr key={c.obj_id}>
|
|
||||||
<td>{c.comm_name ?? "нет данных"}</td>
|
|
||||||
<td>{c.obj_class ?? "нет данных"}</td>
|
|
||||||
<td className={styles.tdNum}>
|
|
||||||
{c.flats_total != null
|
|
||||||
? `${fmtInt(c.flats_total)} кв`
|
|
||||||
: "нет данных"}
|
|
||||||
</td>
|
|
||||||
<td className={styles.tdNum}>{formatMeters(c.distance_m)}</td>
|
|
||||||
<td className={styles.tdNum}>
|
|
||||||
{`${fmtNum(c.velocity_per_month, 1)} кв/мес`}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
))}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
<p className={styles.panelHint}>
|
|
||||||
Конкурирующие проекты в горизонте прогноза, отранжированные по
|
|
||||||
близости. Поглощение — темп продаж проекта (квартир в месяц).
|
|
||||||
</p>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
@ -24,7 +24,6 @@ import { ScenarioCompareTable } from "./ScenarioCompareTable";
|
||||||
import { ConfidencePanel } from "./ConfidencePanel";
|
import { ConfidencePanel } from "./ConfidencePanel";
|
||||||
import { RecommendedProduct } from "./RecommendedProduct";
|
import { RecommendedProduct } from "./RecommendedProduct";
|
||||||
import { ScoringTransparency } from "./ScoringTransparency";
|
import { ScoringTransparency } from "./ScoringTransparency";
|
||||||
import { FutureSupply } from "./FutureSupply";
|
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
cad: string;
|
cad: string;
|
||||||
|
|
@ -149,8 +148,6 @@ export function PticaScenarios({ cad, horizon, onHorizonChange }: Props) {
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
{report.scoring && <ScoringTransparency scoring={report.scoring} />}
|
{report.scoring && <ScoringTransparency scoring={report.scoring} />}
|
||||||
|
|
||||||
<FutureSupply competitors={fm.future_competitors} />
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue