fix: show cents in price analysis display

This commit is contained in:
2026-09-06 16:36:14 +03:00
parent 315f3ab59b
commit df64ec6b25
2 changed files with 12 additions and 5 deletions
+5
View File
@@ -1350,6 +1350,11 @@ Taslak türü seçicisine erişilebilir ad eklendi. Üretim derlemesi geçti. Ö
- Fiyat analizi grafiği min/medyan/ortalama/maksimum değerlerini tam iki ondalık istatistikten çiziyor; CSV ve grafik aynı tutarı kullanıyor. Görsel kartların mevcut Türkçe biçimlendirmesi korunuyor. - Fiyat analizi grafiği min/medyan/ortalama/maksimum değerlerini tam iki ondalık istatistikten çiziyor; CSV ve grafik aynı tutarı kullanıyor. Görsel kartların mevcut Türkçe biçimlendirmesi korunuyor.
- 283 test ve build başarılı. Grafik ve CSV’nin gerçek pazar ekranında birlikte kabulü henüz yapılmadı; genel plan açık. - 283 test ve build başarılı. Grafik ve CSV’nin gerçek pazar ekranında birlikte kabulü henüz yapılmadı; genel plan açık.
### 2026-09-06 — Fiyat analizinde kuruş gösterimi
- Fiyat grafiğinin kart, tooltip ve kapsam açıklaması artık iki ondalık basamak gösteriyor. Önceki genel `formatTL` biçimi sıfır ondalık kullandığı için hassas grafik değerleri ekranda yuvarlanıyordu.
- Seçilen birim açıklaması da kapsam metnine eklendi; kategori tutarının hangi birime ait olduğu görünür. 283 test ve build başarılı. Gerçek pazar ekranı kabulü hâlâ yapılmadı; genel plan açık.
### 2026-09-06 — Fiyat analizi CSV kuruş koruması ### 2026-09-06 — Fiyat analizi CSV kuruş koruması
- Fiyat analizi CSV dışa aktarımında min/medyan/ortalama/maksimum değerleri artık yuvarlanıp kuruş kaybetmiyor; iki ondalık basamakla aynı ham istatistikleri taşıyor. - Fiyat analizi CSV dışa aktarımında min/medyan/ortalama/maksimum değerleri artık yuvarlanıp kuruş kaybetmiyor; iki ondalık basamakla aynı ham istatistikleri taşıyor.
+7 -5
View File
@@ -2,9 +2,11 @@ import React, { useState, useMemo, useEffect } from 'react';
import { ResponsiveContainer, BarChart, Bar, XAxis, YAxis, Tooltip, CartesianGrid, Cell } from 'recharts'; import { ResponsiveContainer, BarChart, Bar, XAxis, YAxis, Tooltip, CartesianGrid, Cell } from 'recharts';
import { TrendingUp, Download, Sparkles, Inbox } from 'lucide-react'; import { TrendingUp, Download, Sparkles, Inbox } from 'lucide-react';
import { useApp } from '../../context/AppContext'; import { useApp } from '../../context/AppContext';
import { itemStats, formatTL } from '../../services/analytics'; import { itemStats } from '../../services/analytics';
import confetti from 'canvas-confetti'; import confetti from 'canvas-confetti';
const formatPrice = (n) => n == null || !Number.isFinite(Number(n)) ? '—' : Number(n).toLocaleString('tr-TR', {minimumFractionDigits:2, maximumFractionDigits:2}) + ' ₺';
export const PriceAnalysis = () => { export const PriceAnalysis = () => {
const { tenders } = useApp(); const { tenders } = useApp();
const { items, itemCount, uniqueItems } = useMemo(() => itemStats(tenders), [tenders]); const { items, itemCount, uniqueItems } = useMemo(() => itemStats(tenders), [tenders]);
@@ -102,7 +104,7 @@ export const PriceAnalysis = () => {
}`} }`}
> >
<div className="truncate">📦 {it.ad}</div> <div className="truncate">📦 {it.ad}</div>
<div className={`text-[10px] ${selectedKey === `${it.ad}||${it.birim}` ? 'text-emerald-100' : 'text-slate-400'}`}>{it.count} kayıt · {it.birim} medyan {formatTL(it.median)}</div> <div className={`text-[10px] ${selectedKey === `${it.ad}||${it.birim}` ? 'text-emerald-100' : 'text-slate-400'}`}>{it.count} kayıt · {it.birim} medyan {formatPrice(it.median)}</div>
</button> </button>
))} ))}
</div> </div>
@@ -119,7 +121,7 @@ export const PriceAnalysis = () => {
<CartesianGrid strokeDasharray="3 3" stroke="#f1f5f9" /> <CartesianGrid strokeDasharray="3 3" stroke="#f1f5f9" />
<XAxis dataKey="label" tick={{ fontSize: 12 }} /> <XAxis dataKey="label" tick={{ fontSize: 12 }} />
<YAxis tick={{ fontSize: 11 }} /> <YAxis tick={{ fontSize: 11 }} />
<Tooltip formatter={(v) => formatTL(v)} /> <Tooltip formatter={(v) => formatPrice(v)} />
<Bar dataKey="value" radius={[6, 6, 0, 0]}> <Bar dataKey="value" radius={[6, 6, 0, 0]}>
{chartData.map((d, i) => <Cell key={i} fill={d.renk} />)} {chartData.map((d, i) => <Cell key={i} fill={d.renk} />)}
</Bar> </Bar>
@@ -130,7 +132,7 @@ export const PriceAnalysis = () => {
{chartData.map((d) => ( {chartData.map((d) => (
<div key={d.label} className="bg-slate-50 rounded-lg p-2 border border-slate-100"> <div key={d.label} className="bg-slate-50 rounded-lg p-2 border border-slate-100">
<div className="text-[10px] text-slate-500">{d.label}</div> <div className="text-[10px] text-slate-500">{d.label}</div>
<div className="text-sm font-black" style={{ color: d.renk }}>{formatTL(d.value)}</div> <div className="text-sm font-black" style={{ color: d.renk }}>{formatPrice(d.value)}</div>
</div> </div>
))} ))}
</div> </div>
@@ -141,7 +143,7 @@ export const PriceAnalysis = () => {
<Sparkles className="w-5 h-5 text-amber-400" /> Karşılaştırmanın kapsamı <Sparkles className="w-5 h-5 text-amber-400" /> Karşılaştırmanın kapsamı
</div> </div>
<p className="text-xs text-slate-300 leading-relaxed"> <p className="text-xs text-slate-300 leading-relaxed">
<strong>{selected?.ad}</strong> grubunda {selected?.count} kaydın medyan kategori tutarı {formatTL(selected?.median)}. <strong>{selected?.ad}</strong> grubunda {selected?.count} kaydın {selected?.birim} birimindeki medyan kategori tutarı {formatPrice(selected?.median)}.
Bunlar ürün birim fiyatı değildir. Test adedi, ambalaj birimi, cihaz ve hizmet kapsamı doğrulanmadan Bunlar ürün birim fiyatı değildir. Test adedi, ambalaj birimi, cihaz ve hizmet kapsamı doğrulanmadan
bu tutarlardan teklif fiyatı veya kazanma olasılığı çıkarılamaz. bu tutarlardan teklif fiyatı veya kazanma olasılığı çıkarılamaz.
</p> </p>