38980-vm/app-9w9pd00g5j41/TIMELINE_MAP_SYNC_IMPROVEMENTS.md
2026-03-04 18:25:09 +00:00

12 KiB
Raw Permalink Blame History

Timeline ↔ Map Senkronizasyonu - Tüm İyileştirmeler

Yapılan Değişiklikler

1. activeDayId Harita Filtreleme (KRİTİK)

Problem: activeDayId state var ama harita tüm günleri gösteriyordu

Çözüm:

// Gün bazlı marker filtreleme
const filteredMarkers = activeDayId 
  ? mapMarkers.filter(m => m.dayId === activeDayId)
  : mapMarkers;

// GoogleMap'e filtrelenmiş marker'lar gönderiliyor
<GoogleMap 
  markers={filteredMarkers}  // ✅ Artık sadece aktif günün marker'ları
  activeDayId={activeDayId}
  ...
/>

Sonuç:

  • Bir gün açıldığında haritada SADECE o günün marker'ları gösteriliyor
  • Polyline sadece o günün sırasına göre çiziliyor
  • activeDayId === null ise tüm günler gösteriliyor

2. Marker Numaralandırma Düzeltildi (UX İYİLEŞTİRMESİ)

Problem: Marker label globalIndex (1-2-3-4-5...) kullanıyordu, Gün 2'de "7" yazması kafa karıştırıcıydı

Çözüm:

// Gün renkleri tanımlandı
const getDayColor = (dayIndex: number) => {
  const colors = [
    { fill: '#f97316', stroke: '#ea580c' }, // Turuncu (Gün 1)
    { fill: '#3b82f6', stroke: '#2563eb' }, // Mavi (Gün 2)
    { fill: '#10b981', stroke: '#059669' }, // Yeşil (Gün 3)
    { fill: '#8b5cf6', stroke: '#7c3aed' }, // Mor (Gün 4)
    { fill: '#ec4899', stroke: '#db2777' }, // Pembe (Gün 5)
    { fill: '#f59e0b', stroke: '#d97706' }, // Sarı (Gün 6)
    { fill: '#06b6d4', stroke: '#0891b2' }, // Cyan (Gün 7)
  ];
  return colors[dayIndex % colors.length];
};

// Marker oluşturma - gün içi sıra + gün rengi
const mapMarkers = trip?.days?.flatMap((day: any, dayIndex: number) => {
  return day.places?.map((place: any, placeIndex: number) => {
    const dayColor = getDayColor(dayIndex);
    
    return {
      id: place.id,
      position: place.position,
      label: `${placeIndex + 1}`, // ✅ Gün içi sıra (1, 2, 3...)
      title: place.name,
      dayId: day.id,
      dayIndex: dayIndex,
      color: dayColor, // ✅ Gün rengi
    };
  }) || [];
}) || [];

GoogleMap Component Güncellendi:

// Marker rengi - gün rengini kullan
const markerColor = markerData.color || { fill: '#f97316', stroke: '#ea580c' };

const marker = new google.maps.Marker({
  icon: {
    path: google.maps.SymbolPath.CIRCLE,
    scale: isActive ? 24 : 20,
    fillColor: isActive ? markerColor.stroke : markerColor.fill, // ✅ Gün rengi
    fillOpacity: 1,
    strokeColor: 'white',
    strokeWeight: isActive ? 4 : 3,
  },
  ...
});

Sonuç:

  • Marker label = gün içi sıra (1, 2, 3...)
  • Gün 1 → Turuncu marker (1, 2, 3)
  • Gün 2 → Mavi marker (1, 2)
  • Gün 3 → Yeşil marker (1, 2, 3)
  • Her gün farklı renkle ayırt ediliyor

3. Map → Timeline Hover ve Odak Davranışı

3.1 Marker Hover Davranışı

Çözüm:

const handleMarkerHover = useCallback((placeId: string | null, dayId?: string) => {
  setHoveredPlaceId(placeId);
  
  // Marker hover olduğunda activeDayId'yi ayarla
  if (placeId && dayId) {
    setActiveDayId(dayId);
  }
}, []);

GoogleMap Component:

// Hover handler'da dayId gönder
marker.addListener('mouseover', () => {
  if (onMarkerHover) {
    onMarkerHover(markerData.id, markerData.dayId); // ✅ dayId eklendi
  }
});

Sonuç:

  • Marker hover olduğunda activeDayId = marker.dayId
  • İlgili AccordionItem otomatik açılıyor
  • Timeline kartı highlight/glow alıyor (mevcut CSS ile)

3.2 Marker Click Davranışı

Mevcut Kod (Zaten Çalışıyor):

const handleMarkerClick = useCallback((placeId: string) => {
  setSelectedPlaceId(placeId);
  
  // Scroll to place in timeline
  const placeElement = placeRefs.current.get(placeId);
  if (placeElement) {
    placeElement.scrollIntoView({ 
      behavior: 'smooth', 
      block: 'center' 
    });
  }
}, []);

Sonuç:

  • Marker click → Timeline kartına scrollIntoView
  • Kart selected state alıyor

4. Timeline Açılış Davranışı (ZİHİNSEL YÜK AZALTMA)

Problem: Tüm günler açıktı, timeline çok uzundu

Çözüm:

<Accordion 
  type="single"           // ✅ Sadece 1 gün açık olabilir
  collapsible             // ✅ Açık günü kapatabilme
  defaultValue={trip.days[0]?.id}  // ✅ Varsayılan: 1. gün açık
  value={activeDayId || undefined}
  onValueChange={(value) => setActiveDayId(value || null)}
  className="space-y-4"
>

AccordionTrigger Güncellendi:

// onClick kaldırıldı - Accordion kendi yönetiyor
<AccordionTrigger 
  className="px-4 py-3 hover:no-underline [&[data-state=open]]:bg-muted/50"
>

Sonuç:

  • Accordion type="single" → Sadece 1 gün açık
  • Default: Sadece 1. gün açık
  • Bir gün açıldığında diğerleri otomatik kapanıyor
  • Timeline daha temiz ve yönetilebilir

5. "Yer Ekle" Dialog Gün Bağlamını Gösteriyor

Problem: Kullanıcı hangi gün için eklediğini görmüyordu

Çözüm:

<DialogHeader>
  <DialogTitle>
    Gün {day.dayNumber} - {day.dayName} için yer ekle
  </DialogTitle>
  <DialogDescription>
    Görmek istediğiniz bir yeri arayın ve seyahat programınıza ekleyin.
  </DialogDescription>
</DialogHeader>

Sonuç:

  • Dialog başlığı: "Gün 2 - Pazartesi için yer ekle"
  • Kullanıcı hangi güne eklediğini açıkça görüyor

6. Contextual Lead Banner Akıllı Tetikleme

Problem: Qualifying activity varsa banner çıkıyordu, yeterli değildi

Çözüm:

// AKILLI TETİKLEME KOŞULLARI
const totalDays = trip.days.length;
const totalPlaces = trip.days.reduce((sum: number, day: any) => 
  sum + (day.places?.length || 0), 0
);

// Nitelikli aktivite kategorileri
const qualifyingCategories = ['hot-air-balloon', 'atv', 'horse-riding', 'tour', 'guide'];

const hasQualifyingActivity = trip.days.some((day: any) => 
  day.places?.some((place: any) => 
    qualifyingCategories.includes(place.type?.toLowerCase())
  )
);

// Banner SADECE şu koşullarda gösterilir:
const shouldShowBanner = 
  totalDays >= 2 &&           // ✅ En az 2 gün
  totalPlaces >= 3 &&         // ✅ Toplam en az 3 yer
  hasQualifyingActivity &&    // ✅ En az 1 qualifying activity
  !bannerDismissed;

setShowContextualBanner(shouldShowBanner);

Sonuç:

  • Banner SADECE şu koşullarda çıkıyor:
    • En az 2 gün
    • Toplam en az 3 yer
    • En az 1 qualifying activity
  • Aksi halde banner gösterilmiyor
  • Daha hedefli ve anlamlı tetikleme

7. Harita Arama Inputu Kaldırıldı

Problem: Sağ üstteki "Yerleri yakınlaştır" inputu fake feature'dı

Çözüm: Seçenek A (ÖNERİLEN) - Tamamen kaldırıldı

// ÖNCE:
<div className="absolute top-4 left-4 right-4 z-10">
  <div className="bg-white dark:bg-background rounded-full shadow-lg p-2 flex items-center gap-2">
    <Search className="h-4 w-4 text-muted-foreground ml-2" />
    <Input 
      placeholder="Yerleri yakınlaştır" 
      className="border-none shadow-none focus-visible:ring-0 h-8"
    />
  </div>
</div>

// SONRA:
// ❌ Kaldırıldı - Fake feature olmaması için

Sonuç:

  • Fake feature kaldırıldı
  • Harita daha temiz görünüyor
  • Kullanıcı kafası karışmıyor

Teknik Detaylar

Değiştirilen Dosyalar

  1. src/pages/TripPlanner.tsx (ANA SAYFA)

    • activeDayId filtreleme mantığı
    • Marker renklendirme sistemi
    • Accordion type="single" yapıldı
    • Dialog başlığı güncellendi
    • Banner akıllı tetikleme
    • Harita arama inputu kaldırıldı
  2. src/components/ui/GoogleMap.tsx (HARİTA KOMPONENTİ)

    • MapMarker interface'ine color ve dayIndex eklendi
    • GoogleMapProps'a onMarkerHover dayId parametresi eklendi
    • Marker renklendirme uygulandı
    • Hover handler'da dayId gönderimi

TypeScript Tip Güncellemeleri

// MapMarker interface
interface MapMarker {
  id: string;
  position: { lat: number; lng: number };
  label: string;
  title: string;
  dayId?: string;
  dayIndex?: number;        // ✅ YENİ
  color?: { fill: string; stroke: string }; // ✅ YENİ
}

// GoogleMapProps
interface GoogleMapProps {
  ...
  onMarkerHover?: (placeId: string | null, dayId?: string) => void; // ✅ dayId eklendi
  ...
}

Lint Durumu

Tüm dosyalar lint kontrolünden geçti (112 dosya)


Test Senaryoları

Test 1: activeDayId Filtreleme

  1. Timeline'da bir günü aç
  2. Haritada SADECE o günün marker'ları görünmeli
  3. Polyline sadece o günün yerlerini bağlamalı
  4. Günü kapat (tüm günleri kapat)
  5. Haritada tüm günlerin marker'ları görünmeli

Test 2: Marker Numaralandırma

  1. Gün 1'i aç → Turuncu marker'lar (1, 2, 3...)
  2. Gün 2'yi aç → Mavi marker'lar (1, 2, 3...)
  3. Gün 3'ü aç → Yeşil marker'lar (1, 2, 3...)
  4. Her günün marker'ları kendi içinde 1'den başlamalı
  5. Her gün farklı renkle ayırt edilmeli

Test 3: Marker Hover → Timeline

  1. Haritada bir marker'ın üzerine gel
  2. İlgili gün otomatik açılmalı
  3. Timeline kartı highlight almalı
  4. Marker'dan ayrıl → highlight kaybolmalı

Test 4: Marker Click → Timeline Scroll

  1. Haritada bir marker'a tıkla
  2. Timeline o karta scroll yapmalı
  3. Kart selected state almalı (ring-2 ring-primary/20)
  4. Info window açılmalı

Test 5: Accordion Single Mode

  1. Sayfa yüklendiğinde sadece Gün 1 açık olmalı
  2. Gün 2'yi aç → Gün 1 otomatik kapanmalı
  3. Gün 3'ü aç → Gün 2 otomatik kapanmalı
  4. ık günü tekrar tıkla → Kapanmalı (collapsible)

Test 6: "Yer Ekle" Dialog Bağlamı

  1. Gün 2'nin "Yer Ekle" butonuna tıkla
  2. Dialog başlığı: "Gün 2 - Pazartesi için yer ekle" olmalı
  3. Yer ekle → Gün 2'ye eklenmeli

Test 7: Akıllı Banner Tetikleme

Senaryo A: Banner GÖSTERİLMELİ

  • 2 gün
  • 5 yer
  • 1 hot-air-balloon aktivitesi
  • Sonuç: Banner gösterilir

Senaryo B: Banner GÖSTERİLMEMELİ

  • 1 gün
  • 5 yer
  • 1 hot-air-balloon aktivitesi
  • Sonuç: Banner gösterilmez

Senaryo C: Banner GÖSTERİLMEMELİ

  • 2 gün
  • 2 yer
  • 1 hot-air-balloon aktivitesi
  • Sonuç: Banner gösterilmez

Senaryo D: Banner GÖSTERİLMEMELİ

  • 2 gün
  • 5 yer
  • 0 qualifying aktivite
  • Sonuç: Banner gösterilmez

Test 8: Harita Arama Inputu

  1. Haritaya bak
  2. Sağ üstte arama inputu OLMAMALI
  3. Harita temiz görünmeli

Kullanıcı Deneyimi İyileştirmeleri

Önceki Durum

  • Tüm günler açık → Timeline çok uzun
  • Marker numaraları global → Kafa karıştırıcı (Gün 2'de "7" yazıyor)
  • Harita tüm günleri gösteriyor → Karmaşık
  • Marker hover → Timeline'da hiçbir şey olmuyor
  • "Yer Ekle" → Hangi güne eklediğim belli değil
  • Banner her zaman çıkıyor → Rahatsız edici
  • Fake arama inputu → Kullanıcı kafası karışıyor

Yeni Durum

  • Sadece 1 gün açık → Timeline temiz ve yönetilebilir
  • Marker numaraları gün içi sıra → Net ve anlaşılır (1, 2, 3...)
  • Harita sadece aktif günü gösteriyor → Odaklanmış
  • Marker hover → İlgili gün açılıyor, kart highlight alıyor
  • "Yer Ekle" → "Gün 2 - Pazartesi için yer ekle" → Bağlam net
  • Banner akıllı tetikleniyor → Sadece anlamlı durumlarda
  • Fake feature kaldırıldı → Temiz ve dürüst UX

Performans İyileştirmeleri

  1. Marker Filtreleme: activeDayId varsa sadece o günün marker'ları render ediliyor
  2. Accordion Single Mode: Aynı anda sadece 1 gün açık → DOM daha hafif
  3. useCallback Kullanımı: Handler fonksiyonları memoize edildi
  4. Gereksiz Render Önleme: activeDayId değiştiğinde sadece ilgili componentler re-render

Sonuç

Tüm 7 iyileştirme başarıyla uygulandı:

1. activeDayId haritayı gerçekten filtreliyor
2. Marker numaralandırma düzeltildi (gün içi sıra + gün rengi)
3. Map → Timeline hover ve odak davranışı çalışıyor
4. Timeline accordion single mode (sadece 1 gün açık)
5. "Yer Ekle" dialog gün bağlamını gösteriyor
6. Contextual lead banner akıllı tetikleniyor
7. Harita arama inputu kaldırıldı

Kullanıcı deneyimi önemli ölçüde iyileştirildi! 🎉