Önceki hata: ThemeTab her iki setter'ı da çağırıyordu (setSelectedTheme +
setSelectedTweakcnTheme). Bunlar wrapper'a bağlıydı, her wrapper kendi
saveThemePrefsAction'ını çağırıyordu. İkinci çağrı colorTheme:'' yazarak
birincinin kaydını siliyordu.
Düzeltme:
- ThemeTab'a RAW React state setter'ları iletildi (wrapper değil)
- ThemeTab'ın cross-clear mantığı olduğu gibi kaldı
- Appwrite kaydı useEffect'e taşındı: React 18 olay yöneticisindeki
tüm state güncellemelerini batch'ledikten SONRA tek seferde tetiklenir
→ selectedTheme ve selectedTweakcnTheme doğru nihai değerleriyle kaydedilir
- saveThemePrefsAction: account.updatePrefs ile mevcut prefs'i merge eder
- Dashboard layout'ta account.getPrefs ile prefs server-side yüklenir
- PrefsInitializer: mount'ta dark/light, renk teması, radius, sidebar
config'ini Appwrite'dan gelen initialPrefs ile uygular
- ThemeCustomizer: renk teması / tweakcn / radius / sidebar değişikliği
anında Appwrite'a kaydedilir; dark/light toggle useEffect ile izlenir
- Sayfa yenileme ve farklı cihazda giriş sonrasında ayarlar korunur
- Install maplibre-gl; use OpenFreeMap tiles (no API key)
- PropertyMapPickerInner: address search via Nominatim, draggable
marker, click-to-place, geolocation, clear button
- PropertyMapPicker/View: dynamic next/dynamic wrappers (ssr: false)
- PropertyMapViewInner: read-only marker view with navigation control
- PropertyFormSheet: hidden mapLat/mapLng inputs, picker renders only
when sheet is open, resets on property change
- Property detail page: Konum section with PropertyMapView + Google Maps link
- Sunum page: Google Maps deep link on PropertyCard when coordinates exist
- Server actions: property/customer/search/presentation/activity/investor CRUD
- Matching engine: matchPropertyToSearches + syncMatchesForSearch on search save
- UI: form sheets + table clients for all modules
- Public /sunum/[token] page (no auth) with property card grid + expiry check
- All pages force-dynamic for auth guard compatibility