Files
gulermak_metro/components/MetroLine.tsx
Şahan Hasret c0b7fb463e Build
2025-11-20 16:50:28 +03:00

282 lines
13 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
'use client';
import { useState, useEffect } from 'react';
import { dataStore } from '@/lib/dataStore';
import type { MetroStation } from '@/data/metroStations';
export default function MetroLine() {
const [stations, setStations] = useState<MetroStation[]>([]);
const [selectedStationId, setSelectedStationId] = useState<number | null>(null);
const [currentStationIndex, setCurrentStationIndex] = useState(0);
useEffect(() => {
// Metro istasyonlarını yükle
const loadedStations = dataStore.getMetroStations();
setStations(loadedStations);
// Admin panelinden seçili istasyonu al
const adminSelectedId = localStorage.getItem('metro_selected_station');
if (adminSelectedId) {
setSelectedStationId(parseInt(adminSelectedId));
// Seçili istasyonun index'ini bul
const selectedIndex = loadedStations.findIndex(s => s.id === parseInt(adminSelectedId));
if (selectedIndex !== -1) {
// Metro animasyonu başlat
let currentIndex = 0;
const interval = setInterval(() => {
if (currentIndex < selectedIndex) {
currentIndex++;
setCurrentStationIndex(currentIndex);
} else {
clearInterval(interval);
}
}, 2000); // Her 2 saniyede bir ilerle
return () => clearInterval(interval);
}
}
}, []);
const getStationStyle = (index: number, station: MetroStation) => {
// Seçili istasyonun index'ini bul
const selectedIndex = selectedStationId
? stations.findIndex(s => s.id === selectedStationId)
: -1;
// Animasyonda şu an bulunulan istasyon (sarı - metro treni burada)
if (index === currentStationIndex) {
return 'w-16 h-16 bg-[#F59E0B] border-4 border-white shadow-2xl scale-110';
}
// Seçili istasyondan ÖNCE olanlar - Tamamlandı (yeşil)
if (selectedIndex !== -1 && index < selectedIndex) {
return 'w-14 h-14 bg-green-500 border-4 border-white shadow-lg';
}
// Seçili istasyon - Şu an inşaat aşamasında (mavi)
if (index === selectedIndex) {
return 'w-14 h-14 bg-blue-500 border-4 border-white shadow-lg';
}
// Seçili istasyondan SONRA olanlar - Planlı (gri)
return 'w-12 h-12 bg-gray-300 border-4 border-dashed border-gray-400 shadow-lg opacity-60';
};
const getTextStyle = (index: number, station: MetroStation) => {
const selectedIndex = selectedStationId
? stations.findIndex(s => s.id === selectedStationId)
: -1;
// Animasyonda şu an bulunulan istasyon
if (index === currentStationIndex) {
return 'text-[#F59E0B] font-bold';
}
// Seçili istasyondan ÖNCE olanlar - Tamamlandı
if (selectedIndex !== -1 && index < selectedIndex) {
return 'text-green-600 font-bold';
}
// Seçili istasyon - İnşaat aşamasında
if (index === selectedIndex) {
return 'text-blue-600 font-bold';
}
// Seçili istasyondan SONRA olanlar - Planlı
return 'text-gray-500 font-semibold';
};
const progressPercentage = stations.length > 0 ? (currentStationIndex / (stations.length - 1)) * 100 : 0;
if (stations.length === 0) {
return <div className="bg-white rounded-2xl shadow-2xl p-8 text-center">Yükleniyor...</div>;
}
return (
<div className="bg-white rounded-2xl shadow-2xl p-4 md:p-8 lg:p-12">
{/* Proje Başlığı */}
<div className="flex flex-col md:flex-row items-start md:items-center justify-between mb-6 md:mb-8 gap-4">
<div className="flex items-center space-x-3 md:space-x-4">
<div className="w-10 h-10 md:w-12 md:h-12 rounded-full bg-[#F59E0B] flex items-center justify-center shrink-0">
<svg className="w-5 h-5 md:w-6 md:h-6 text-white" fill="currentColor" viewBox="0 0 24 24">
<path d="M13 3v6h3l-4 5-4-5h3V3m-1 11v7h-1c-1.1 0-2-.9-2-2v-5h3m10 0v5c0 1.1-.9 2-2 2h-1v-7h3z"/>
</svg>
</div>
<div>
<h3 className="text-lg md:text-2xl font-bold text-[#004B87]">A2 Metro Hattı İnşaatı</h3>
<p className="text-sm md:text-base text-[#6B7280]">Abidin Paşa - Natoyolu</p>
</div>
</div>
<div className="text-left md:text-right">
<p className="text-xs md:text-sm text-[#6B7280]">İnşaat Durumu</p>
<p className="text-xl md:text-2xl font-bold text-[#F59E0B]">{Math.round(progressPercentage)}%</p>
</div>
</div>
{/* Metro Hat ve İnşaat Çizgisi - Desktop */}
<div className="hidden md:block relative mb-4">
{/* Gri arka plan hattı (tüm hat) */}
<div className="absolute top-6 left-0 right-0 h-2 bg-gray-300 rounded-full"></div>
{/* Renkli ilerleme çubuğu - duraklar arası geçişle */}
<div className="absolute top-6 left-0 h-2 bg-linear-to-r from-green-500 via-[#00B4D8] to-[#F59E0B] rounded-full transition-all duration-1000 ease-in-out"
style={{width: `${progressPercentage}%`}}>
</div>
{/* Duraklar Grid - Desktop */}
<div className="grid grid-cols-4 lg:grid-cols-8 gap-6 relative">
{stations.map((station, index) => {
const selectedIndex = selectedStationId
? stations.findIndex(s => s.id === selectedStationId)
: -1;
return (
<div key={station.id} className="flex flex-col items-center">
<div className={`relative z-10 rounded-full flex items-center justify-center mb-3 transition-all duration-500 ${getStationStyle(index, station)}`}>
{index === currentStationIndex ? (
<>
{/* Metro simgesi - animasyonlu */}
<svg className="w-8 h-8 text-white" fill="currentColor" viewBox="0 0 24 24">
<path d="M12 2c-4 0-8 .5-8 4v9.5C4 17.43 5.57 19 7.5 19L6 20.5v.5h2l2-2h4l2 2h2v-.5L16.5 19c1.93 0 3.5-1.57 3.5-3.5V6c0-3.5-4-4-8-4zM7.5 17c-.83 0-1.5-.67-1.5-1.5S6.67 14 7.5 14s1.5.67 1.5 1.5S8.33 17 7.5 17zm3.5-6H6V6h5v5zm5.5 6c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5zm1.5-6h-5V6h5v5z"/>
</svg>
{/* Pulse efekti */}
<div className="absolute inset-0 rounded-full bg-[#F59E0B] animate-ping opacity-30"></div>
</>
) : (selectedIndex !== -1 && index < selectedIndex) ? (
// Tamamlandı - Yeşil check
<svg className="w-6 h-6 text-white" fill="currentColor" viewBox="0 0 24 24">
<path d="M9 16.2L4.8 12l-1.4 1.4L9 19 21 7l-1.4-1.4L9 16.2z"/>
</svg>
) : (index === selectedIndex) ? (
// Seçili istasyon - İnşaat aşamasında
<svg className="w-5 h-5 text-white" fill="currentColor" viewBox="0 0 24 24">
<path d="M12 2c-4 0-8 .5-8 4v9.5C4 17.43 5.57 19 7.5 19L6 20.5v.5h2l2-2h4l2 2h2v-.5L16.5 19c1.93 0 3.5-1.57 3.5-3.5V6c0-3.5-4-4-8-4z"/>
</svg>
) : (
// Planlı - Gri saat
<svg className="w-5 h-5 text-gray-500" fill="currentColor" viewBox="0 0 24 24">
<path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/>
</svg>
)}
</div>
<span className={`text-center text-xs transition-all duration-300 ${getTextStyle(index, station)}`}>
{station.name}
</span>
<span className={`text-xs transition-all duration-300 ${
index === currentStationIndex ? 'text-[#F59E0B] font-semibold' :
(selectedIndex !== -1 && index < selectedIndex) ? 'text-green-600' :
(index === selectedIndex) ? 'text-blue-600' : 'text-gray-400'
}`}>
{index === currentStationIndex ? '🚇 Metro Burada' :
(selectedIndex !== -1 && index < selectedIndex) ? '✓ Tamamlandı' :
(index === selectedIndex) ? '🔄 Devam Ediyor' :
'◯ Planlı'}
</span>
</div>
);
})}
</div>
</div>
{/* Metro Hat - Mobil (Dikey Liste) */}
<div className="md:hidden space-y-3">
{stations.map((station, index) => {
const selectedIndex = selectedStationId
? stations.findIndex(s => s.id === selectedStationId)
: -1;
return (
<div key={station.id} className={`flex items-center space-x-3 p-3 rounded-lg transition-all duration-500 ${
index === currentStationIndex ? 'bg-[#F59E0B]/10 border-2 border-[#F59E0B]' :
(selectedIndex !== -1 && index < selectedIndex) ? 'bg-green-50 border border-green-200' :
(index === selectedIndex) ? 'bg-blue-50 border border-blue-200' :
'bg-gray-50 border border-gray-200'
}`}>
{/* İkon */}
<div className={`rounded-full flex items-center justify-center transition-all duration-500 shrink-0 ${
index === currentStationIndex ? 'w-12 h-12 bg-[#F59E0B]' :
(selectedIndex !== -1 && index < selectedIndex) ? 'w-10 h-10 bg-green-500' :
(index === selectedIndex) ? 'w-10 h-10 bg-blue-500' :
'w-10 h-10 bg-gray-300'
}`}>
{index === currentStationIndex ? (
<svg className="w-6 h-6 text-white" fill="currentColor" viewBox="0 0 24 24">
<path d="M12 2c-4 0-8 .5-8 4v9.5C4 17.43 5.57 19 7.5 19L6 20.5v.5h2l2-2h4l2 2h2v-.5L16.5 19c1.93 0 3.5-1.57 3.5-3.5V6c0-3.5-4-4-8-4zM7.5 17c-.83 0-1.5-.67-1.5-1.5S6.67 14 7.5 14s1.5.67 1.5 1.5S8.33 17 7.5 17zm3.5-6H6V6h5v5zm5.5 6c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5zm1.5-6h-5V6h5v5z"/>
</svg>
) : (selectedIndex !== -1 && index < selectedIndex) ? (
<svg className="w-5 h-5 text-white" fill="currentColor" viewBox="0 0 24 24">
<path d="M9 16.2L4.8 12l-1.4 1.4L9 19 21 7l-1.4-1.4L9 16.2z"/>
</svg>
) : (index === selectedIndex) ? (
<svg className="w-4 h-4 text-white" fill="currentColor" viewBox="0 0 24 24">
<path d="M12 2c-4 0-8 .5-8 4v9.5C4 17.43 5.57 19 7.5 19L6 20.5v.5h2l2-2h4l2 2h2v-.5L16.5 19c1.93 0 3.5-1.57 3.5-3.5V6c0-3.5-4-4-8-4z"/>
</svg>
) : (
<svg className="w-4 h-4 text-gray-500" fill="currentColor" viewBox="0 0 24 24">
<path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/>
</svg>
)}
</div>
{/* Bilgi */}
<div className="flex-1">
<h4 className={`font-bold text-sm ${
index === currentStationIndex ? 'text-[#F59E0B]' :
(selectedIndex !== -1 && index < selectedIndex) ? 'text-green-700' :
(index === selectedIndex) ? 'text-blue-700' :
'text-gray-600'
}`}>
{station.name}
</h4>
<p className={`text-xs ${
index === currentStationIndex ? 'text-[#F59E0B]' :
(selectedIndex !== -1 && index < selectedIndex) ? 'text-green-600' :
(index === selectedIndex) ? 'text-blue-600' :
'text-gray-500'
}`}>
{index === currentStationIndex ? '🚇 Metro Burada' :
(selectedIndex !== -1 && index < selectedIndex) ? '✓ Tamamlandı' :
(index === selectedIndex) ? '🔄 Devam Ediyor' :
'◯ Planlı'}
</p>
</div>
{/* Bağlantı çizgisi (son istasyon hariç) */}
{index < stations.length - 1 && (
<div className={`absolute left-8 w-0.5 h-8 ${
index < currentStationIndex ? 'bg-green-500' :
index === currentStationIndex ? 'bg-[#F59E0B]' :
'bg-gray-300'
}`} style={{ top: '100%', marginLeft: '-1px' }}></div>
)}
</div>
);
})}
</div>
{/* Alt Bilgi */}
<div className="mt-6 md:mt-8 pt-4 md:pt-6 border-t border-gray-200">
<div className="flex flex-col md:flex-row flex-wrap gap-3 md:gap-6 justify-center text-xs md:text-sm">
<div className="flex items-center space-x-2">
<div className="w-4 h-4 md:w-5 md:h-5 rounded-full bg-green-500 border-2 border-white flex items-center justify-center shrink-0">
<svg className="w-2 h-2 md:w-3 md:h-3 text-white" fill="currentColor" viewBox="0 0 24 24">
<path d="M9 16.2L4.8 12l-1.4 1.4L9 19 21 7l-1.4-1.4L9 16.2z"/>
</svg>
</div>
<span className="text-[#6B7280]">Tamamlandı</span>
</div>
<div className="flex items-center space-x-2">
<div className="w-4 h-4 md:w-5 md:h-5 rounded-full bg-[#F59E0B] border-2 border-white shrink-0"></div>
<span className="text-[#6B7280]">İnşaat Halinde (Metro Burada)</span>
</div>
<div className="flex items-center space-x-2">
<div className="w-4 h-4 md:w-5 md:h-5 rounded-full bg-gray-300 border-2 border-dashed border-gray-400 shrink-0"></div>
<span className="text-[#6B7280]">Planlanan</span>
</div>
</div>
</div>
</div>
);
}