fix: show cents in price analysis display
This commit is contained in:
@@ -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.
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
Reference in New Issue
Block a user