Historia cen - liczby takze tam, gdzie nie ma jeszcze ogloszen
Deploy Polska Lokalnie / deploy (push) Successful in 21s
Deploy Polska Lokalnie / deploy (push) Successful in 21s
Dzielnica bez wlasnych ogloszen miala na wykresie pelne serie NBP i GUS, ale naglowek i wszystkie cztery rubryki pokazywaly kreski. - brak ogloszen: naglowek i rubryki licza srednia z NBP i GUS w kwartale - podpis mowi wprost, ze to dane transakcyjne dla calego miasta - tytul, cena i zmiana procentowa staja w jednej linii - "Zmiana w okresie" przy jednym zapisie ma podpis "Za krotka historia" Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
+40
-12
@@ -21136,18 +21136,32 @@ function PriceHistoryPage({ user }: { user: AuthUser | null }) {
|
||||
});
|
||||
const nbpPrices = historySlots.map((slot) => historyQuarterValue(history?.nbp ?? [], slot));
|
||||
const gusPrices = historySlots.map((slot) => historyQuarterValue(history?.gus ?? [], slot));
|
||||
const knownPrices = offerPrices
|
||||
const offerKnownPrices = offerPrices
|
||||
.map((price, slotIndex) => ({ price, slotIndex }))
|
||||
.filter((entry): entry is { price: number; slotIndex: number } => entry.price != null);
|
||||
const hasOfferData = knownPrices.length > 0;
|
||||
const hasOfferData = offerKnownPrices.length > 0;
|
||||
const hasNbpData = nbpPrices.some((price) => price != null);
|
||||
const hasGusData = gusPrices.some((price) => price != null);
|
||||
const hasHistoryData = hasOfferData || hasNbpData || hasGusData;
|
||||
// Dzielnica bez ogloszen nie ma wlasnej sredniej, ale wykres pokazuje w niej ceny
|
||||
// transakcyjne dla calego miasta. Liczby nad wykresem i w rubrykach biora wtedy
|
||||
// srednia z tego, co w danym kwartale podaly NBP i GUS - zrodlo jest podpisane,
|
||||
// zeby nikt nie wzial danych miasta za dane dzielnicy.
|
||||
const externalKnownPrices = historySlots
|
||||
.map((_slot, slotIndex) => {
|
||||
const sources = [nbpPrices[slotIndex], gusPrices[slotIndex]].filter((price): price is number => price != null);
|
||||
return sources.length > 0
|
||||
? { price: Math.round(sources.reduce((sum, price) => sum + price, 0) / sources.length), slotIndex }
|
||||
: null;
|
||||
})
|
||||
.filter((entry): entry is { price: number; slotIndex: number } => entry != null);
|
||||
const knownPrices = hasOfferData ? offerKnownPrices : externalKnownPrices;
|
||||
const statsFromOffers = hasOfferData;
|
||||
const firstKnown = knownPrices[0] ?? null;
|
||||
const latestKnown = knownPrices[knownPrices.length - 1] ?? null;
|
||||
const lowestKnown = knownPrices.reduce<{ price: number; slotIndex: number } | null>((lowest, entry) => (!lowest || entry.price < lowest.price ? entry : lowest), null);
|
||||
const highestKnown = knownPrices.reduce<{ price: number; slotIndex: number } | null>((highest, entry) => (!highest || entry.price > highest.price ? entry : highest), null);
|
||||
const averageKnown = hasOfferData ? Math.round(knownPrices.reduce((sum, entry) => sum + entry.price, 0) / knownPrices.length) : null;
|
||||
const averageKnown = knownPrices.length > 0 ? Math.round(knownPrices.reduce((sum, entry) => sum + entry.price, 0) / knownPrices.length) : null;
|
||||
// Zmiana ma sens dopiero przy dwoch roznych przedzialach z danymi.
|
||||
const changePercent = firstKnown && latestKnown && knownPrices.length > 1 && firstKnown.price > 0
|
||||
? ((latestKnown.price - firstKnown.price) / firstKnown.price) * 100
|
||||
@@ -21540,16 +21554,28 @@ function PriceHistoryPage({ user }: { user: AuthUser | null }) {
|
||||
<section className="history-chart-card">
|
||||
<div className="history-chart-head">
|
||||
<div>
|
||||
<h2>Średnia cena za {areaSuffix} w {activeLocationLabel}</h2>
|
||||
<strong>{latestKnown ? formatPricePerArea(latestKnown.price) : '—'}</strong>
|
||||
{changePercent != null && (
|
||||
<p className={changePercent >= 0 ? 'positive' : 'negative'}>
|
||||
{changePercent >= 0 ? '+' : ''}{changePercent.toFixed(1).replace('.', ',')}% <span>(od {historySlots[firstKnown!.slotIndex].sinceLabel})</span>
|
||||
</p>
|
||||
)}
|
||||
<div className="history-chart-title-row">
|
||||
<h2>Średnia cena za {areaSuffix} w {activeLocationLabel}</h2>
|
||||
<strong>{latestKnown ? formatPricePerArea(latestKnown.price) : '—'}</strong>
|
||||
{changePercent != null && firstKnown && (
|
||||
<p className={changePercent >= 0 ? 'positive' : 'negative'}>
|
||||
{changePercent >= 0 ? '+' : ''}{changePercent.toFixed(1).replace('.', ',')}% <span>(od {historySlots[firstKnown.slotIndex].sinceLabel})</span>
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
<small className="history-source-note">
|
||||
Średnie ceny ofertowe z ogłoszeń w serwisie Polska Lokalnie
|
||||
{history?.trackedSince ? `, zapisywane codziennie od ${formatArticleDate(history.trackedSince)}` : ''}.
|
||||
{statsFromOffers || !hasHistoryData ? (
|
||||
<>
|
||||
Średnie ceny ofertowe z ogłoszeń w serwisie Polska Lokalnie
|
||||
{history?.trackedSince ? `, zapisywane codziennie od ${formatArticleDate(history.trackedSince)}` : ''}.
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
Średnia z cen transakcyjnych NBP i GUS dla całego miasta
|
||||
{selectedMarket ? ` ${selectedMarket.city}` : ''} - w tej lokalizacji nie ma jeszcze ogłoszeń
|
||||
w serwisie Polska Lokalnie.
|
||||
</>
|
||||
)}
|
||||
</small>
|
||||
</div>
|
||||
<span className="history-chart-mode">Cena za {areaSuffix}</span>
|
||||
@@ -21630,6 +21656,8 @@ function PriceHistoryPage({ user }: { user: AuthUser | null }) {
|
||||
<span>Zmiana w okresie</span>
|
||||
<strong>{changePercent == null ? '—' : `${changePercent >= 0 ? '+' : ''}${changePercent.toFixed(1).replace('.', ',')}%`}</strong>
|
||||
{changePercent != null && firstKnown && latestKnown && <small>{formatPricePerArea(latestKnown.price - firstKnown.price)}</small>}
|
||||
{/* Jeden przedzial z danymi to jeszcze nie trend - mowimy wprost, czego brakuje. */}
|
||||
{changePercent == null && knownPrices.length > 0 && <small>Za krótka historia</small>}
|
||||
</article>
|
||||
<article><span>Średnia cena</span><strong>{averageKnown != null ? formatPricePerArea(averageKnown) : '—'}</strong></article>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user