diff --git a/server/dt-store.mjs b/server/dt-store.mjs index ef44dde..b08d78a 100644 --- a/server/dt-store.mjs +++ b/server/dt-store.mjs @@ -6,6 +6,7 @@ import fs from 'node:fs'; import path from 'node:path'; import { fileURLToPath } from 'node:url'; +import { titleCaseTr } from './tr-text.mjs'; // node:sqlite bazı Node sürümlerinde deneysel/flag'li. Yoksa DT devre dışı kalır, // ilan.gov.tr canlı verisi yine de çalışır. @@ -66,7 +67,7 @@ function mapDtRow(row) { ikn: row.dtn || '', baslik: row.isin_adi || '', kurum, - sehir: row.ili && !row.ili.startsWith('Plaka') ? row.ili : '', + sehir: row.ili && !row.ili.startsWith('Plaka') ? titleCaseTr(row.ili) : '', bolge: '', tarih: row.dt_tarihi || '', saat: '', diff --git a/server/history-store.mjs b/server/history-store.mjs index 4a71e02..6982511 100644 --- a/server/history-store.mjs +++ b/server/history-store.mjs @@ -8,6 +8,7 @@ import fs from 'node:fs'; import path from 'node:path'; import { fileURLToPath } from 'node:url'; +import { titleCaseTr } from './tr-text.mjs'; let DatabaseSync = null; try { @@ -148,7 +149,7 @@ function rowToTender(r) { ikn: r.ikn, baslik: r.ihale_adi || 'İhale', kurum: r.idare_adi || '—', - sehir: r.il || '', + sehir: titleCaseTr(r.il), tarih: r.ihale_tarihi || '', alimTuru: r.ihale_tipi || 'İhale', sektor: r.ihale_tipi || 'Genel', diff --git a/server/tr-text.mjs b/server/tr-text.mjs new file mode 100644 index 0000000..36c5858 --- /dev/null +++ b/server/tr-text.mjs @@ -0,0 +1,21 @@ +/** + * Türkçe metin yardımcıları. + * Kaynaklar il adını farklı yazıyor (ilan.gov.tr "Ankara", EKAP "ANKARA"); + * tek biçime indirgemezsek il filtresi ve gruplamalar bölünüyor. + */ + +/** "İSTANBUL" → "İstanbul", "şanlıurfa" → "Şanlıurfa" (Türkçe i/ı duyarlı) */ +export function titleCaseTr(s) { + if (!s) return ''; + return String(s) + .trim() + .toLocaleLowerCase('tr-TR') + .split(/(\s+|-)/) + .map((w) => (/^[\s-]*$/.test(w) ? w : w.charAt(0).toLocaleUpperCase('tr-TR') + w.slice(1))) + .join(''); +} + +/** Karşılaştırma için normalize (büyük harf, Türkçe duyarlı) */ +export function normTr(s) { + return String(s || '').trim().toLocaleUpperCase('tr-TR'); +} diff --git a/src/components/TenderList.jsx b/src/components/TenderList.jsx index 17af0ad..e3cc009 100644 --- a/src/components/TenderList.jsx +++ b/src/components/TenderList.jsx @@ -4,6 +4,10 @@ import { TenderCard } from './TenderCard'; import { Download, SlidersHorizontal, Layers, ChevronLeft, ChevronRight } from 'lucide-react'; import confetti from 'canvas-confetti'; +// İl adları kaynaklar arasında farklı yazılabiliyor (Ankara / ANKARA); +// filtre büyük-küçük harf ve Türkçe karakter duyarlılığına takılmasın. +const normTr = (v) => String(v || '').trim().toLocaleUpperCase('tr-TR'); + export const TenderList = () => { const { tenders, @@ -46,7 +50,7 @@ export const TenderList = () => { if (quickFilter === 'iptal' && tender.durum !== 'İptal') return false; // Dropdown Filters - if (selectedCity && tender.sehir !== selectedCity) return false; + if (selectedCity && normTr(tender.sehir) !== normTr(selectedCity)) return false; if (selectedAlimTuru && tender.alimTuru !== selectedAlimTuru) return false; if (selectedSektor && tender.sektor !== selectedSektor) return false; if (selectedKurumTipi && tender.kurumTipi !== selectedKurumTipi) return false;