12 KiB
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
-
✅
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ı
-
✅
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
- Timeline'da bir günü aç
- Haritada SADECE o günün marker'ları görünmeli
- Polyline sadece o günün yerlerini bağlamalı
- Günü kapat (tüm günleri kapat)
- Haritada tüm günlerin marker'ları görünmeli
✅ Test 2: Marker Numaralandırma
- Gün 1'i aç → Turuncu marker'lar (1, 2, 3...)
- Gün 2'yi aç → Mavi marker'lar (1, 2, 3...)
- Gün 3'ü aç → Yeşil marker'lar (1, 2, 3...)
- Her günün marker'ları kendi içinde 1'den başlamalı
- Her gün farklı renkle ayırt edilmeli
✅ Test 3: Marker Hover → Timeline
- Haritada bir marker'ın üzerine gel
- İlgili gün otomatik açılmalı
- Timeline kartı highlight almalı
- Marker'dan ayrıl → highlight kaybolmalı
✅ Test 4: Marker Click → Timeline Scroll
- Haritada bir marker'a tıkla
- Timeline o karta scroll yapmalı
- Kart selected state almalı (ring-2 ring-primary/20)
- Info window açılmalı
✅ Test 5: Accordion Single Mode
- Sayfa yüklendiğinde sadece Gün 1 açık olmalı
- Gün 2'yi aç → Gün 1 otomatik kapanmalı
- Gün 3'ü aç → Gün 2 otomatik kapanmalı
- Açık günü tekrar tıkla → Kapanmalı (collapsible)
✅ Test 6: "Yer Ekle" Dialog Bağlamı
- Gün 2'nin "Yer Ekle" butonuna tıkla
- Dialog başlığı: "Gün 2 - Pazartesi için yer ekle" olmalı
- 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
- Haritaya bak
- Sağ üstte arama inputu OLMAMALI ✅
- 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
- Marker Filtreleme: activeDayId varsa sadece o günün marker'ları render ediliyor
- Accordion Single Mode: Aynı anda sadece 1 gün açık → DOM daha hafif
- useCallback Kullanımı: Handler fonksiyonları memoize edildi
- 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! 🎉