Distinguish shared item inventory from tender rows and load errors

This commit is contained in:
2026-09-06 10:15:53 +03:00
parent 0fd46c4867
commit 91451b1134
6 changed files with 77 additions and 16 deletions
+21 -10
View File
@@ -9,19 +9,23 @@ import { kalemleriGetir } from '../services/kalem';
* sunucu otomatik indiremiyor. Bir kullanıcı ihale dokümanını yüklediğinde
* kalemler ayrıştırılıp havuza yazılıyor ve bu liste herkese görünür oluyor.
*/
export const TeklifCetveliKalemleri = ({ ikn }) => {
export const TeklifCetveliKalemleri = ({ikn, knownItemCount = 0}) => <SharedItems key={ikn || 'unknown'} ikn={ikn} knownItemCount={knownItemCount} />;
const SharedItems = ({ikn, knownItemCount}) => {
const [durum, setDurum] = useState({ yukleniyor: true, kalemler: [], kaynak: null });
const [suzgec, setSuzgec] = useState('');
const [retry, setRetry] = useState(0);
useEffect(() => {
if (!ikn) { setDurum({ yukleniyor: false, kalemler: [], kaynak: null }); return; }
let iptal = false;
setDurum((d) => ({ ...d, yukleniyor: true }));
kalemleriGetir(ikn)
const controller = new AbortController();
setDurum({yukleniyor:true,kalemler:[],kaynak:null});
kalemleriGetir(ikn, {signal:controller.signal})
.then((d) => { if (!iptal) setDurum({ yukleniyor: false, kalemler: d.kalemler || [], kaynak: d.kaynak }); })
.catch(() => { if (!iptal) setDurum({ yukleniyor: false, kalemler: [], kaynak: null }); });
return () => { iptal = true; };
}, [ikn]);
.catch(error => { if (!iptal) setDurum({ yukleniyor:false, kalemler:[], kaynak:null, hata:error.message }); });
return () => { iptal = true; controller.abort(); };
}, [ikn, retry]);
if (durum.yukleniyor) {
return (
@@ -31,6 +35,11 @@ export const TeklifCetveliKalemleri = ({ ikn }) => {
);
}
if (durum.hata) return <div role="alert" className="rounded-xl border border-amber-200 bg-amber-50 p-3 text-xs text-amber-900">
<p>Ortak doküman kalemleri yüklenemedi. {durum.hata}</p>
<button type="button" onClick={() => setRetry(n => n + 1)} className="mt-2 underline font-semibold">Kalemleri yeniden yükle</button>
</div>;
if (!durum.kalemler.length) {
return (
<div className="bg-slate-50 border border-slate-200 rounded-xl p-4">
@@ -38,9 +47,11 @@ export const TeklifCetveliKalemleri = ({ ikn }) => {
<Package className="w-4 h-4 text-indigo-600" /> Teklif Cetveli Kalemleri
</h3>
<p className="text-xs text-slate-600 leading-relaxed mt-1.5">
Bu ihalenin kalem listesi henüz havuzda yok. Kalemler EKAP'ın API'sinde yayımlanmıyor;
yalnızca ihale dokümanının içinde bulunuyor. Aşağıdan dokümanı yüklerseniz kalemler
otomatik çıkarılır ve bu ihale <strong>tüm kullanıcılarda</strong> kalemleriyle listelenir.
{knownItemCount > 0
? `İhale kaydında aşağıda gösterilen ${knownItemCount} kalem var. Ortak doküman havuzunda ayrıca çıkarılmış bir cetvel bulunamadı; mevcut kalemleri resmi dokümanla karşılaştırın.`
: 'Ortak doküman havuzunda bu ihale için kalem bulunamadı. Resmi ihale dokümanını yükleyerek kalemleri çıkarmayı deneyebilirsiniz.'}
{' '}İhale dokümanından ortak havuza aktarılan kalemler diğer kullanıcılara da görünür.
</p>
</div>
);
@@ -56,7 +67,7 @@ export const TeklifCetveliKalemleri = ({ ikn }) => {
<div className="flex items-center justify-between gap-3 flex-wrap">
<h3 className="font-bold text-sm text-slate-900 flex items-center gap-2">
<Package className="w-4 h-4 text-indigo-600" />
Teklif Cetveli Kalemleri ({durum.kalemler.length})
Ortak Doküman Kalemleri ({durum.kalemler.length})
</h3>
<label className="relative">
<Search className="w-3.5 h-3.5 text-slate-400 absolute left-2.5 top-1/2 -translate-y-1/2" />
+1 -1
View File
@@ -288,7 +288,7 @@ export const TenderDetailModal = () => {
)}
{/* Ortak havuzdan teklif cetveli kalemleri */}
<TeklifCetveliKalemleri ikn={tender.ikn} />
<TeklifCetveliKalemleri ikn={tender.ikn} knownItemCount={tender.items?.length || 0} />
{/* Material Table */}
{tender.items?.length > 0 && (