fix: 12 bin ihalelik havuz localStorage kotasını aşıp uygulamayı beyaz ekranla çökertiyordu
This commit is contained in:
+53
-12
@@ -6,11 +6,44 @@ import { getAllUserData, setUserData, getPlan } from '../services/account';
|
||||
|
||||
const AppContext = createContext();
|
||||
|
||||
// İhale önbelleği: tam havuz (10.000+ kayıt) localStorage kotasına sığmaz.
|
||||
const TENDER_CACHE_KEY = 'ihaleist_tenders';
|
||||
const TENDER_CACHE_LIMIT = 300;
|
||||
|
||||
// localStorage her zaman yazılabilir değildir (kota dolu, gizli sekme, site
|
||||
// verisi kapalı). Yazma hatası uygulamayı çökertmemeli.
|
||||
const yerelKaydet = (anahtar, deger) => {
|
||||
try {
|
||||
localStorage.setItem(anahtar, JSON.stringify(deger));
|
||||
return true;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
const yerelOku = (anahtar, varsayilan) => {
|
||||
try {
|
||||
const ham = localStorage.getItem(anahtar);
|
||||
if (!ham) return varsayilan;
|
||||
const v = JSON.parse(ham);
|
||||
return v == null ? varsayilan : v;
|
||||
} catch {
|
||||
return varsayilan;
|
||||
}
|
||||
};
|
||||
|
||||
export const AppProvider = ({ children }) => {
|
||||
const [activeTab, setActiveTab] = useState('list'); // 'list', 'bulten', 'sonuc', 'takvim', 'sozlesme', 'kdv', 'fiyat', 'kanban', 'smart_filter_builder'
|
||||
const [tenders, setTenders] = useState(() => {
|
||||
const saved = localStorage.getItem('ihaleist_tenders');
|
||||
return saved ? JSON.parse(saved) : [];
|
||||
// Sadece ilk boyama için küçük bir önbellek; asıl kaynak sunucudur.
|
||||
// Bozuk/eski kayıt uygulamayı çökertmemeli.
|
||||
try {
|
||||
const saved = localStorage.getItem(TENDER_CACHE_KEY);
|
||||
const parsed = saved ? JSON.parse(saved) : null;
|
||||
return Array.isArray(parsed) ? parsed : [];
|
||||
} catch {
|
||||
try { localStorage.removeItem(TENDER_CACHE_KEY); } catch { /* yok say */ }
|
||||
return [];
|
||||
}
|
||||
});
|
||||
|
||||
const [liveStats, setLiveStats] = useState({ toplamIhale: 0, bugunEklenen: 0, arsiv: 0 });
|
||||
@@ -23,8 +56,8 @@ export const AppProvider = ({ children }) => {
|
||||
const [quickFilter, setQuickFilter] = useState('all');
|
||||
|
||||
const [savedFilters, setSavedFilters] = useState(() => {
|
||||
const saved = localStorage.getItem('ihaleist_saved_filters');
|
||||
return saved ? JSON.parse(saved) : [];
|
||||
const v = yerelOku('ihaleist_saved_filters', []);
|
||||
return Array.isArray(v) ? v : [];
|
||||
});
|
||||
|
||||
const [isLiveMode, setIsLiveMode] = useState(true);
|
||||
@@ -142,7 +175,7 @@ export const AppProvider = ({ children }) => {
|
||||
try { return JSON.parse(localStorage.getItem('ihaleist_rakip_izleme') || '[]'); } catch { return []; }
|
||||
});
|
||||
useEffect(() => {
|
||||
localStorage.setItem('ihaleist_rakip_izleme', JSON.stringify(competitorWatchlist));
|
||||
yerelKaydet('ihaleist_rakip_izleme', competitorWatchlist);
|
||||
if (veriSenkron) sunucuyaYaz('rakip_izleme', competitorWatchlist);
|
||||
}, [competitorWatchlist, veriSenkron]);
|
||||
|
||||
@@ -151,7 +184,7 @@ export const AppProvider = ({ children }) => {
|
||||
try { return JSON.parse(localStorage.getItem('ihaleist_favori_kurumlar') || '[]'); } catch { return []; }
|
||||
});
|
||||
useEffect(() => {
|
||||
localStorage.setItem('ihaleist_favori_kurumlar', JSON.stringify(favoriteKurumlar));
|
||||
yerelKaydet('ihaleist_favori_kurumlar', favoriteKurumlar);
|
||||
if (veriSenkron) sunucuyaYaz('favori_kurumlar', favoriteKurumlar);
|
||||
}, [favoriteKurumlar, veriSenkron]);
|
||||
const toggleFavoriteKurum = (kurum) => {
|
||||
@@ -171,7 +204,7 @@ export const AppProvider = ({ children }) => {
|
||||
];
|
||||
});
|
||||
useEffect(() => {
|
||||
localStorage.setItem('ihaleist_ekip', JSON.stringify(teamMembers));
|
||||
yerelKaydet('ihaleist_ekip', teamMembers);
|
||||
if (veriSenkron) sunucuyaYaz('ekip', teamMembers);
|
||||
}, [teamMembers, veriSenkron]);
|
||||
const addTeamMember = (m) => setTeamMembers((prev) => [...prev, { id: 'tm-' + Date.now(), ...m }]);
|
||||
@@ -182,7 +215,7 @@ export const AppProvider = ({ children }) => {
|
||||
try { return JSON.parse(localStorage.getItem('ihaleist_belgeler') || '[]'); } catch { return []; }
|
||||
});
|
||||
useEffect(() => {
|
||||
localStorage.setItem('ihaleist_belgeler', JSON.stringify(vaultDocuments));
|
||||
yerelKaydet('ihaleist_belgeler', vaultDocuments);
|
||||
}, [vaultDocuments]);
|
||||
|
||||
const [reminderSettings, setReminderSettings] = useState(() => {
|
||||
@@ -198,7 +231,7 @@ export const AppProvider = ({ children }) => {
|
||||
} catch { return def; }
|
||||
});
|
||||
useEffect(() => {
|
||||
localStorage.setItem('ihaleist_reminder', JSON.stringify(reminderSettings));
|
||||
yerelKaydet('ihaleist_reminder', reminderSettings);
|
||||
if (veriSenkron) sunucuyaYaz('reminder', reminderSettings);
|
||||
}, [reminderSettings, veriSenkron]);
|
||||
|
||||
@@ -266,7 +299,7 @@ export const AppProvider = ({ children }) => {
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
localStorage.setItem('ihaleist_ai_model_config', JSON.stringify(aiModelConfig));
|
||||
yerelKaydet('ihaleist_ai_model_config', aiModelConfig);
|
||||
}, [aiModelConfig]);
|
||||
|
||||
const getModelById = (id) => AI_MODEL_CATALOG.find(m => m.id === id);
|
||||
@@ -353,12 +386,20 @@ export const AppProvider = ({ children }) => {
|
||||
const markNotificationsRead = () => setNotifications((prev) => prev.map((n) => ({ ...n, read: true })));
|
||||
|
||||
// Persist state to localstorage
|
||||
// Havuz on binlerce kayda çıkabiliyor; tamamı localStorage kotasını (≈5 MB)
|
||||
// aşar ve yakalanmazsa uygulama beyaz ekranla çöker. Bu yüzden yalnızca ilk
|
||||
// boyamaya yetecek kadarını, hataya dayanıklı biçimde saklıyoruz.
|
||||
useEffect(() => {
|
||||
localStorage.setItem('ihaleist_tenders', JSON.stringify(tenders));
|
||||
try {
|
||||
localStorage.setItem(TENDER_CACHE_KEY, JSON.stringify(tenders.slice(0, TENDER_CACHE_LIMIT)));
|
||||
} catch {
|
||||
// Kota dolduysa önbelleği bırak — veri zaten sunucudan geliyor.
|
||||
try { localStorage.removeItem(TENDER_CACHE_KEY); } catch { /* yok say */ }
|
||||
}
|
||||
}, [tenders]);
|
||||
|
||||
useEffect(() => {
|
||||
localStorage.setItem('ihaleist_saved_filters', JSON.stringify(savedFilters));
|
||||
yerelKaydet('ihaleist_saved_filters', savedFilters);
|
||||
if (veriSenkron) sunucuyaYaz('saved_filters', savedFilters);
|
||||
}, [savedFilters, veriSenkron]);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user