Files
ihaleist/src/components/PreparationOverview.jsx
T

50 lines
4.9 KiB
React
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import React,{useEffect,useState} from 'react';
import {listDocuments} from '../services/account';
import {preparationSummary} from '../services/preparationSummary';
import {useApp} from '../context/AppContext';
import {getToken} from '../services/auth';
export function PreparationOverview({tenders,now}) {
const {authUser}=useApp();
return <Overview key={`${authUser?.email}:${getToken()}`} tenders={tenders} now={now}/>;
}
function Overview({tenders,now}) {
const {setActiveTenderDetail,userProfile}=useApp();
const [vault,setVault]=useState({loading:true,error:null,documents:[]}),[refresh,setRefresh]=useState(0);
useEffect(()=>{
let cancelled=false;
setVault({loading:true,error:null,documents:[]});
listDocuments().then(data=>{
if (!Array.isArray(data?.belgeler)) throw new Error('Belge listesi biçimi doğrulanamadı.');
if(!cancelled)setVault({loading:false,error:null,documents:data.belgeler});
})
.catch(error=>{if(!cancelled)setVault({loading:false,error:error.message,documents:[]});});
return()=>{cancelled=true;};
},[refresh]);
const open=(tender,target)=>setActiveTenderDetail({...tender,preparationTarget:target});
return <section aria-label="Hazırlık dosyaları özeti" aria-busy={vault.loading} className="bg-white border rounded-xl p-4 space-y-3">
<h2 className="font-bold text-lg">Hazırlık dosyaları · {tenders.length}</h2>
<p className="text-xs text-slate-600">Panodaki ve sorumlu filtresindeki kayıtlı taslaklar gösterilir. Kaydetmediğiniz değişiklikler bu özete girmez. Eksik sayısı başvuru onayı değildir; çıktı sırasında belgeler yeniden kontrol edilir.</p>
<button type="button" className="border rounded px-3 py-2 text-xs" disabled={vault.loading} aria-busy={vault.loading} onClick={()=>setRefresh(n=>n+1)}>Belge durumunu yenile</button>
{vault.loading&&<p role="status" className="text-xs">Belge durumu kontrol ediliyor…</p>}
{vault.error&&<p role="alert" className="text-xs text-red-700">Belge durumu doğrulanamadı: {vault.error}</p>}
{!tenders.length ? <p className="text-sm">İhaleyi takibe alın veya hazırlık görevi açın; dosyası burada görünsün.</p> :
<div><table role="table" className="block md:table w-full text-sm table-fixed"><caption className="sr-only">Hazırlık dosyaları, sorumlular ve sıradaki kontroller</caption>
<thead role="rowgroup" className="sr-only md:not-sr-only md:table-header-group"><tr role="row" className="text-left border-b"><th role="columnheader" scope="col" className="p-2">İhale</th><th role="columnheader" scope="col" className="p-2">Sorumlu</th><th role="columnheader" scope="col" className="p-2">Belge eksikleri</th><th role="columnheader" scope="col" className="p-2">Sıradaki kontrol</th></tr></thead>
<tbody role="rowgroup" className="block md:table-row-group">{tenders.map(tender=>{
const summary=preparationSummary(tender,{...vault,healthPortfolio:userProfile.scrapedCapabilities?.healthPortfolio || []},now);
return <tr role="row" key={tender.id} className="block md:table-row border rounded-lg mb-3 md:mb-0 md:rounded-none md:border-0 md:border-b align-top [overflow-wrap:anywhere]">
<td role="cell" className="block md:table-cell p-2"><span aria-hidden="true" className="block md:hidden text-xs font-bold mb-1">İhale</span><button type="button" onClick={()=>open(tender,'source')} className="text-blue-800 underline text-left">{tender.ikn} · {tender.baslik}</button><p className="text-xs mt-1">{summary.issues.length ? `${summary.issues.length} kontrol eksik` : 'Kayıtlı kontroller tamam; son kontrol gerekli'}</p></td>
<td role="cell" className="block md:table-cell p-2"><span aria-hidden="true" className="block md:hidden text-xs font-bold mb-1">Sorumlu</span>{summary.owner}</td>
<td role="cell" className="block md:table-cell p-2"><span aria-hidden="true" className="block md:hidden text-xs font-bold mb-1">Belge eksikleri</span><details><summary className="cursor-pointer">{summary.documentIssues.length ? `${summary.documentIssues.length} belge kontrolü` : 'Kayıtlı belgelerde eksik bulunmadı'}</summary>
<ul className="space-y-2 mt-2">{summary.documentIssues.map((text,i)=><li key={i}><button type="button" onClick={()=>open(tender,'checks')} className="text-blue-800 underline text-left">{text}</button></li>)}</ul>
</details></td>
<td role="cell" className="block md:table-cell p-2"><span aria-hidden="true" className="block md:hidden text-xs font-bold mb-1">Sıradaki kontrol</span><button type="button" onClick={()=>open(tender,summary.next.target)} className="text-blue-800 underline text-left">{summary.next.text}</button>
<details className="mt-2"><summary className="cursor-pointer text-xs">Tüm eksikleri göster</summary><ul className="space-y-2 mt-2">{summary.issues.map((item,i)=><li key={i}><button type="button" onClick={()=>open(tender,item.target)} className="text-blue-800 underline text-left">{item.text}</button></li>)}</ul></details>
</td>
</tr>;
})}</tbody>
</table></div>}
</section>;
}