gendesign/tradein-mvp/frontend/src/components/trade-in/PlacementHistoryCard.tsx
lekss361 f2f9e5b79b
Some checks failed
Deploy Trade-In / deploy (push) Blocked by required conditions
Deploy Trade-In / build-frontend (push) Has been cancelled
Deploy Trade-In / changes (push) Successful in 6s
Deploy Trade-In / build-backend (push) Has been skipped
feat(tradein-ui): placement history card (#529)
2026-05-24 14:22:16 +00:00

101 lines
3.3 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 { useEstimatePlacementHistory } from "@/lib/trade-in-api";
import type { PlacementHistoryItem } from "@/types/trade-in";
type Props = { estimateId: string };
const fmtPrice = (n: number | null): string =>
n == null ? "—" : `${(n / 1_000_000).toFixed(2)} М`;
const fmtDate = (d: string | null): string => {
if (!d) return "—";
try {
return new Date(d).toLocaleDateString("ru-RU");
} catch {
return d;
}
};
function lotLabel(it: PlacementHistoryItem): string {
if (it.title) return it.title;
const rooms = it.rooms != null ? `${it.rooms}к` : "?к";
const area = it.area_m2 != null ? `${it.area_m2} м²` : "? м²";
const floor =
it.floor != null && it.total_floors != null
? `, эт. ${it.floor}/${it.total_floors}`
: "";
return `${rooms}, ${area}${floor}`;
}
export function PlacementHistoryCard({ estimateId }: Props) {
const { data: items, isPending, isError } = useEstimatePlacementHistory(estimateId);
if (isPending || isError) return null;
if (!items || items.length === 0) return null;
const visible = items.slice(0, 20);
return (
<article className="card" style={{ marginTop: 16 }}>
<header className="card-head">
<h3 style={{ margin: 0, fontSize: 15 }}>История продаж в этом доме</h3>
<small style={{ color: "var(--muted, #6b7280)" }}>
{items.length} лот{items.length === 1 ? "" : "ов"}
</small>
</header>
<div style={{ padding: "8px 16px 16px" }}>
<table
style={{ width: "100%", fontSize: 13, borderCollapse: "collapse" }}
>
<thead>
<tr
style={{
borderBottom: "1px solid var(--border, #e5e7eb)",
textAlign: "left",
}}
>
<th style={{ padding: "6px 8px" }}>Лот</th>
<th style={{ padding: "6px 8px" }}>Цена нач. посл.</th>
<th style={{ padding: "6px 8px" }}>Дата</th>
<th style={{ padding: "6px 8px" }}>Экспозиция</th>
</tr>
</thead>
<tbody>
{visible.map((it) => (
<tr
key={it.id}
style={{
borderBottom: "1px solid var(--border-soft, #f3f4f6)",
}}
>
<td style={{ padding: "6px 8px" }}>{lotLabel(it)}</td>
<td style={{ padding: "6px 8px", whiteSpace: "nowrap" }}>
{fmtPrice(it.start_price)} {" "}
<strong>{fmtPrice(it.last_price)}</strong>
</td>
<td style={{ padding: "6px 8px", whiteSpace: "nowrap" }}>
{fmtDate(it.last_price_date ?? it.start_price_date)}
</td>
<td style={{ padding: "6px 8px" }}>
{it.exposure_days ?? "—"} дн.
</td>
</tr>
))}
</tbody>
</table>
{items.length > 20 && (
<small
style={{
color: "var(--muted, #6b7280)",
display: "block",
marginTop: 8,
}}
>
показано 20 из {items.length}
</small>
)}
</div>
</article>
);
}