Allow retrying item extraction from stored tender documents
This commit is contained in:
@@ -26,13 +26,25 @@ export const TenderDocuments = ({ tender }) => {
|
||||
const ikn = String(tender?.ikn || '').replace(/[\s\u00a0]+/g, '') || undefined;
|
||||
const [belgeler, setBelgeler] = useState([]);
|
||||
const [yukleniyor, setYukleniyor] = useState(false);
|
||||
const [listeHata, setListeHata] = useState(null);
|
||||
const [listeBekliyor, setListeBekliyor] = useState(false);
|
||||
const listeIstegi = useRef(0);
|
||||
const dosyaRef = useRef(null);
|
||||
|
||||
const belgeleriYukle = useCallback(() => {
|
||||
const belgeleriYukle = useCallback(async () => {
|
||||
if (!ikn) return;
|
||||
listTenderDocuments(ikn).then(setBelgeler).catch(() => {});
|
||||
const request = ++listeIstegi.current;
|
||||
setListeBekliyor(true); setListeHata(null);
|
||||
try {
|
||||
const rows = await listTenderDocuments(ikn);
|
||||
if (request === listeIstegi.current) setBelgeler(rows);
|
||||
} catch (e) {
|
||||
if (request === listeIstegi.current) setListeHata(e.message);
|
||||
} finally {
|
||||
if (request === listeIstegi.current) setListeBekliyor(false);
|
||||
}
|
||||
}, [ikn]);
|
||||
useEffect(() => { belgeleriYukle(); }, [belgeleriYukle]);
|
||||
useEffect(() => { setBelgeler([]); belgeleriYukle(); return () => { listeIstegi.current++; }; }, [belgeleriYukle]);
|
||||
|
||||
// EKAP dokümanı kullanıcının tarayıcısına iniyor; indirdiği dosyayı buraya
|
||||
// yükleyince ihaleye bağlanır ve metni AI analizine verilebilir.
|
||||
@@ -96,6 +108,17 @@ export const TenderDocuments = ({ tender }) => {
|
||||
return text;
|
||||
};
|
||||
|
||||
const kalemleriYenidenCikar = async (b) => {
|
||||
setBusy('kalem'); setError(null); setBilgi(null);
|
||||
try {
|
||||
const metin = await belgeMetni(b);
|
||||
const { kalemCikar } = await import('../services/kalem');
|
||||
const result = await kalemCikar({ ikn, metin, dosya:b.ad, documentId:b.id });
|
||||
setBilgi({ isleme: `${b.ad}: ${result.sayi || 0} kalem çıkarıldı.` });
|
||||
} catch (e) { setError(`Kalem çıkarımı tamamlanamadı: ${e.message}. Dosya kaydı korunmuştur.`); }
|
||||
finally { await belgeleriYukle(); setBusy(null); }
|
||||
};
|
||||
|
||||
// Yüklenen PDF'i AI'ya ver
|
||||
const belgeyiAnalizEt = async (b, mod) => {
|
||||
setBusy('belge'); setError(null);
|
||||
@@ -294,12 +317,7 @@ export const TenderDocuments = ({ tender }) => {
|
||||
</p>
|
||||
)}
|
||||
|
||||
{error && (
|
||||
<div className="bg-red-50 border border-red-200 rounded-lg p-2.5 flex gap-2">
|
||||
<AlertTriangle className="w-3.5 h-3.5 text-red-600 shrink-0 mt-0.5" />
|
||||
<p className="text-[11px] text-red-800 leading-relaxed">{error}</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
|
||||
</>
|
||||
)}
|
||||
@@ -334,15 +352,27 @@ export const TenderDocuments = ({ tender }) => {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{error && (
|
||||
<div className="bg-red-50 border border-red-200 rounded-lg p-2.5 flex gap-2">
|
||||
<AlertTriangle className="w-3.5 h-3.5 text-red-600 shrink-0 mt-0.5" />
|
||||
<p className="text-[11px] text-red-800 leading-relaxed">{error}</p>
|
||||
</div>
|
||||
)}
|
||||
{bilgi?.isleme && <p role="status" className="text-xs text-slate-700">{bilgi.isleme}</p>}
|
||||
{listeBekliyor && <p role="status" className="text-xs text-slate-500">Belge listesi yükleniyor…</p>}
|
||||
{listeHata && <div role="alert" className="text-xs text-red-700">
|
||||
Belge listesi alınamadı: {listeHata}
|
||||
<button onClick={belgeleriYukle} className="ml-2 underline">Listeyi yeniden yükle</button>
|
||||
</div>}
|
||||
{belgeler.length > 0 && (
|
||||
<div className="space-y-1.5">
|
||||
<p className="text-[11px] font-bold text-slate-700 flex items-center gap-1.5">
|
||||
<Paperclip className="w-3.5 h-3.5 text-slate-400" /> Bu ihaleye yüklenen belgeler ({belgeler.length})
|
||||
</p>
|
||||
{belgeler.map((b) => (
|
||||
<div key={b.id} className="flex items-center gap-2 bg-white border border-slate-200 rounded-lg px-2.5 py-2">
|
||||
<div key={b.id} className="flex flex-wrap items-center gap-2 bg-white border border-slate-200 rounded-lg px-2.5 py-2">
|
||||
<FileText className="w-3.5 h-3.5 text-slate-400 shrink-0" />
|
||||
<span className="text-xs text-slate-800 truncate flex-1" title={b.ad}>{b.ad}</span><span className="block text-[10px] text-slate-500">{documentProcessingLabel(b.isleme)}</span>
|
||||
<div className="flex-1 min-w-32"><span className="block text-xs text-slate-800 break-all">{b.ad}</span><span className="block text-[10px] text-slate-500">{documentProcessingLabel(b.isleme)}</span></div>
|
||||
<span className="text-[10px] text-slate-400 whitespace-nowrap">
|
||||
{(b.boyut / 1024).toLocaleString('tr-TR', { maximumFractionDigits: 0 })} KB
|
||||
</span>
|
||||
@@ -361,7 +391,14 @@ export const TenderDocuments = ({ tender }) => {
|
||||
>
|
||||
Derin
|
||||
</button>
|
||||
<button onClick={() => belgeSil(b.id)} className="text-slate-300 hover:text-red-600" aria-label="Sil">
|
||||
{b.tur === 'ihale' && okunabilirMi(b.ad) && (
|
||||
<button onClick={() => kalemleriYenidenCikar(b)} disabled={busy !== null || yukleniyor || !b.erisilebilir}
|
||||
aria-label={`${b.ad} için kalem çıkarımını yeniden dene`}
|
||||
className="text-[10px] font-bold text-blue-700 disabled:opacity-40">
|
||||
{busy === 'kalem' ? 'İşleniyor…' : 'Kalemleri yeniden çıkar'}
|
||||
</button>
|
||||
)}
|
||||
<button disabled={busy !== null || yukleniyor} onClick={() => belgeSil(b.id)} className="text-slate-300 hover:text-red-600" aria-label="Sil">
|
||||
<Trash2 className="w-3.5 h-3.5" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user