Files
gulermak_metro/components/MetroLine.tsx
Şahan Hasret 08c426f97b Ana Sayfa Fix
2025-11-18 15:19:50 +03:00

244 lines
12 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) => {
if (index === currentStationIndex) {
return 'w-16 h-16 bg-[#F59E0B] border-4 border-white shadow-2xl scale-110';
}
if (station.status === 'completed' || index < currentStationIndex) {
return 'w-14 h-14 bg-green-500 border-4 border-white shadow-lg';
}
if (station.status === 'in-progress') {
return 'w-14 h-14 bg-blue-500 border-4 border-white shadow-lg';
}
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) => {
if (index === currentStationIndex) {
return 'text-[#F59E0B] font-bold';
}
if (station.status === 'completed' || index < currentStationIndex) {
return 'text-green-600 font-bold';
}
if (station.status === 'in-progress') {
return 'text-blue-600 font-bold';
}
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) => (
<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>
</>
) : station.status === 'completed' || index < currentStationIndex ? (
<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>
) : station.status === 'in-progress' ? (
<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>
) : (
<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' :
station.status === 'completed' || index < currentStationIndex ? 'text-green-600' :
station.status === 'in-progress' ? 'text-blue-600' : 'text-gray-400'
}`}>
{index === currentStationIndex ? '🚇 Metro Burada' :
station.status === 'completed' || index < currentStationIndex ? '✓ Tamamlandı' :
station.status === 'in-progress' ? '🔄 Devam Ediyor' :
'◯ Planlı'}
</span>
</div>
))}
</div>
</div>
{/* Metro Hat - Mobil (Dikey Liste) */}
<div className="md:hidden space-y-3">
{stations.map((station, index) => (
<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]' :
station.status === 'completed' || index < currentStationIndex ? 'bg-green-50 border border-green-200' :
station.status === 'in-progress' ? '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]' :
station.status === 'completed' || index < currentStationIndex ? 'w-10 h-10 bg-green-500' :
station.status === 'in-progress' ? '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>
) : station.status === 'completed' || index < currentStationIndex ? (
<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>
) : station.status === 'in-progress' ? (
<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]' :
station.status === 'completed' || index < currentStationIndex ? 'text-green-700' :
station.status === 'in-progress' ? 'text-blue-700' :
'text-gray-600'
}`}>
{station.name}
</h4>
<p className={`text-xs ${
index === currentStationIndex ? 'text-[#F59E0B]' :
station.status === 'completed' || index < currentStationIndex ? 'text-green-600' :
station.status === 'in-progress' ? 'text-blue-600' :
'text-gray-500'
}`}>
{index === currentStationIndex ? '🚇 Metro Burada' :
station.status === 'completed' || index < currentStationIndex ? '✓ Tamamlandı' :
station.status === 'in-progress' ? '🔄 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>
);
}