This commit is contained in:
Şahan Hasret
2025-10-21 17:44:34 +03:00
parent b57606636b
commit fc5910f440
8 changed files with 650 additions and 94 deletions

14
.github/copilot-instructions.md vendored Normal file
View File

@@ -0,0 +1,14 @@
# Next.js Project Setup Instructions
## Project Information
- Project Type: Next.js Application
- Language: TypeScript
- Framework: Next.js with App Router
- Styling: Tailwind CSS
- Package Manager: npm
## Development Guidelines
- Use TypeScript for type safety
- Follow Next.js best practices
- Use App Router for routing
- Implement responsive design with Tailwind CSS

13
.vscode/tasks.json vendored Normal file
View File

@@ -0,0 +1,13 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "dev",
"type": "shell",
"command": "npm run dev",
"isBackground": true,
"problemMatcher": [],
"group": "build"
}
]
}

View File

@@ -3,6 +3,14 @@
:root {
--background: #ffffff;
--foreground: #171717;
/* Gülermak Metro Renk Paleti */
--vanilla-doe: #d0bea8;
--pale-oyster: #9a8c70;
--pagoda: #117695;
--caraway-brown: #6d573b;
--teal-dark-blue: #0d4b5c;
--black-stallion: #0f1a1a;
}
@theme inline {
@@ -10,6 +18,14 @@
--color-foreground: var(--foreground);
--font-sans: var(--font-geist-sans);
--font-mono: var(--font-geist-mono);
/* Custom Color Palette */
--color-vanilla-doe: var(--vanilla-doe);
--color-pale-oyster: var(--pale-oyster);
--color-pagoda: var(--pagoda);
--color-caraway-brown: var(--caraway-brown);
--color-teal-dark-blue: var(--teal-dark-blue);
--color-black-stallion: var(--black-stallion);
}
@media (prefers-color-scheme: dark) {
@@ -24,3 +40,18 @@ body {
color: var(--foreground);
font-family: Arial, Helvetica, sans-serif;
}
@keyframes fadeIn {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.animate-fadeIn {
animation: fadeIn 0.5s ease-in-out;
}

View File

@@ -1,103 +1,370 @@
import Image from "next/image";
'use client';
import { useState } from 'react';
import Header from "@/components/Header";
import MetroLine from "@/components/MetroLine";
export default function Home() {
return (
<div className="font-sans grid grid-rows-[20px_1fr_20px] items-center justify-items-center min-h-screen p-8 pb-20 gap-16 sm:p-20">
<main className="flex flex-col gap-[32px] row-start-2 items-center sm:items-start">
<Image
className="dark:invert"
src="/next.svg"
alt="Next.js logo"
width={180}
height={38}
priority
/>
<ol className="font-mono list-inside list-decimal text-sm/6 text-center sm:text-left">
<li className="mb-2 tracking-[-.01em]">
Get started by editing{" "}
<code className="bg-black/[.05] dark:bg-white/[.06] font-mono font-semibold px-1 py-0.5 rounded">
app/page.tsx
</code>
.
</li>
<li className="tracking-[-.01em]">
Save and see your changes instantly.
</li>
</ol>
const [showLiveStream, setShowLiveStream] = useState(false);
const [showNews, setShowNews] = useState(false);
const [selectedNews, setSelectedNews] = useState<number | null>(null);
<div className="flex gap-4 items-center flex-col sm:flex-row">
<a
className="rounded-full border border-solid border-transparent transition-colors flex items-center justify-center bg-foreground text-background gap-2 hover:bg-[#383838] dark:hover:bg-[#ccc] font-medium text-sm sm:text-base h-10 sm:h-12 px-4 sm:px-5 sm:w-auto"
href="https://vercel.com/new?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
target="_blank"
rel="noopener noreferrer"
const newsData = [
{
id: 1,
title: "Dikimevi Metro Hattı İnşaatında Yeni Aşama",
date: "20 Ekim 2025",
image: "https://images.unsplash.com/photo-1544620347-c4fd4a3d5957?w=800&h=600&fit=crop",
summary: "A2 Metro Hattı Tuzluçayır istasyonunda kazı çalışmaları tamamlandı. İnşaat ekipleri bir sonraki faza geçiş için hazırlıklara başladı.",
content: "A2 Metro Hattı Tuzluçayır istasyonunda yapılan kazı çalışmaları başarıyla tamamlandı. İnşaat ekipleri, istasyonun temel atma ve beton dökme aşaması için hazırlıklara başladı. Proje yetkililerinin açıklamasına göre, çalışmalar planlanan takvime uygun olarak ilerliyor. İstasyonun 2026 yılı sonunda hizmete girmesi hedefleniyor. Modern teknolojilerle donatılacak istasyonda yolcu konforunu artıracak birçok yenilik bulunacak."
},
{
id: 2,
title: "Metro İstasyonlarında Modern Tasarım",
date: "18 Ekim 2025",
image: "https://images.unsplash.com/photo-1581579438747-1dc8d17bbce4?w=800&h=600&fit=crop",
summary: "Yeni metro istasyonları çağdaş mimari anlayışı ve yolcu konforunu ön planda tutan tasarımlarla hayata geçiriliyor.",
content: "Ankara metro projesi kapsamında inşa edilen istasyonlar, çağdaş mimari anlayışı ile dikkat çekiyor. İstasyonlarda doğal ışık kullanımı maksimize edilirken, enerji verimliliği de göz önünde bulunduruluyor. Geniş peronlar, modern bekleme alanları ve engelli erişimine uygun tasarım, yolcu memnuniyetini artıracak önemli detaylar arasında yer alıyor."
},
{
id: 3,
title: "Çevre Dostu Metro Projesi",
date: "15 Ekim 2025",
image: "https://images.unsplash.com/photo-1531825168889-e600e4998162?w=800&h=600&fit=crop",
summary: "Metro inşaatında kullanılan malzemeler ve yöntemler çevre standartlarına uygun olarak seçiliyor.",
content: "Ankara metro inşaatında çevre dostu malzemeler ve sürdürülebilir inşaat yöntemleri kullanılıyor. Kazı çalışmalarından çıkan topraklar geri dönüştürülüyor, inşaat atıkları ayrıştırılarak değerlendiriliyor. Proje, yeşil bina sertifikası almayı hedefliyor. Ayrıca, metro hatları elektrikli sistemle çalışacağı için karbon emisyonunu azaltacak."
},
{
id: 4,
title: "Metro Hattı 2026'da Hizmete Girecek",
date: "12 Ekim 2025",
image: "https://images.unsplash.com/photo-1568502802862-8dfb70d44c30?w=800&h=600&fit=crop",
summary: "A2 Metro Hattı'nın ilk etabının 2026 yılı sonunda hizmete girmesi planlanıyor.",
content: "Ankara Büyükşehir Belediyesi yetkilileri, A2 Metro Hattı'nın ilk etabının 2026 yılı sonunda hizmete açılacağını duyurdu. 8 istasyondan oluşan hat, günlük 100 bin yolcuya hizmet verecek. Modern trenler, konforlu istasyonlar ve güvenli sistem ile Ankara'nın ulaşım altyapısına önemli bir katkı sağlayacak. İlk etabın ardından hatın genişletilmesi planlanıyor."
}
];
return (
<div className="min-h-screen bg-[#003366]">
<Header />
{/* Hero Video Section */}
<div className="relative w-full h-[calc(100vh-80px)]">
{/* Video Background */}
<div className="absolute inset-0 overflow-hidden">
<video
className="w-full h-full object-cover"
autoPlay
loop
muted
playsInline
>
<Image
className="dark:invert"
src="/vercel.svg"
alt="Vercel logomark"
width={20}
height={20}
/>
Deploy now
<source src="/assets/high-speed-metro-design-template-559897134973592cb13d708cec30ea39_screen.mp4" type="video/mp4" />
Tarayıcınız video etiketini desteklemiyor.
</video>
{/* Dark Overlay */}
<div className="absolute inset-0 bg-linear-to-b from-[#003366]/70 via-[#004B87]/50 to-[#003366]/90"></div>
</div>
{/* Content Overlay */}
<div className="relative z-10 h-full flex items-center">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 w-full">
<div className="max-w-3xl">
<h1 className="text-4xl sm:text-5xl lg:text-6xl font-bold text-white mb-6 leading-tight">
Ankara Metro Altyapı Projelerinde Öncü Çözümler
</h1>
<p className="text-lg sm:text-xl text-[#F8F9FA] mb-8 leading-relaxed">
Ankara Büyükşehir Belediyesi ile birlikte, modern teknoloji ve mühendislik uzmanlığımızla başkentin ulaşım ını inşa ediyor, geleceğin metro sistemlerini bugünden hayata geçiriyoruz.
</p>
{/* Action Buttons */}
<div className="flex flex-col sm:flex-row gap-4">
<button className="px-8 py-4 bg-[#00B4D8] text-white font-semibold rounded-lg hover:bg-[#48CAE4] transition-all duration-300 shadow-lg shadow-[#00B4D8]/30 flex items-center justify-center space-x-2">
<span>Detayları Gör</span>
<svg className="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5l7 7-7 7" />
</svg>
</button>
<button className="px-8 py-4 bg-transparent border-2 border-white text-white font-semibold rounded-lg hover:bg-white hover:text-[#004B87] transition-all duration-300">
Tüm Duyuruları Gör
</button>
</div>
{/* Pagination Dots */}
<div className="flex space-x-3 mt-12">
<button className="w-3 h-3 rounded-full bg-white"></button>
<button className="w-3 h-3 rounded-full bg-white/30 hover:bg-white/50 transition-colors"></button>
<button className="w-3 h-3 rounded-full bg-white/30 hover:bg-white/50 transition-colors"></button>
<button className="w-3 h-3 rounded-full bg-white/30 hover:bg-white/50 transition-colors"></button>
</div>
</div>
</div>
</div>
{/* Alt Menü Kartları - Slide üzerine bindiriyor (yarısı üstte) */}
<div className="absolute bottom-0 left-0 right-0 xz-20 translate-y-1/2">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-6 gap-4">
{/* Canlı Yayın */}
<button
onClick={() => setShowLiveStream(!showLiveStream)}
className="bg-white rounded-xl p-6 shadow-lg hover:shadow-xl transition-all duration-300 hover:-translate-y-1 flex flex-col items-center text-center group"
>
<div className="w-12 h-12 mb-3 text-[#004B87] group-hover:text-[#00B4D8] transition-colors">
<svg fill="currentColor" viewBox="0 0 24 24">
<path d="M17 10.5V7c0-.55-.45-1-1-1H4c-.55 0-1 .45-1 1v10c0 .55.45 1 1 1h12c.55 0 1-.45 1-1v-3.5l4 4v-11l-4 4zM14 13h-3v3H9v-3H6v-2h3V8h2v3h3v2z"/>
</svg>
</div>
<span className="text-[#004B87] font-semibold text-sm">Canlı Yayın</span>
</button>
{/* Haberler */}
<button
onClick={() => setShowNews(!showNews)}
className="bg-white rounded-xl p-6 shadow-lg hover:shadow-xl transition-all duration-300 hover:-translate-y-1 flex flex-col items-center text-center group"
>
<div className="w-12 h-12 mb-3 text-[#004B87] group-hover:text-[#00B4D8] transition-colors">
<svg fill="currentColor" viewBox="0 0 24 24">
<path d="M19 5v14H5V5h14m0-2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-4.86 8.86l-3 3.87L9 13.14 6 17h12l-3.86-5.14z"/>
</svg>
</div>
<span className="text-[#004B87] font-semibold text-sm">Haberler</span>
</button>
{/* Belgeler */}
<a href="/belgeler" className="bg-white rounded-xl p-6 shadow-lg hover:shadow-xl transition-all duration-300 hover:-translate-y-1 flex flex-col items-center text-center group">
<div className="w-12 h-12 mb-3 text-[#004B87] group-hover:text-[#00B4D8] transition-colors">
<svg fill="currentColor" viewBox="0 0 24 24">
<path d="M14 2H6c-1.1 0-1.99.9-1.99 2L4 20c0 1.1.89 2 1.99 2H18c1.1 0 2-.9 2-2V8l-6-6zm2 16H8v-2h8v2zm0-4H8v-2h8v2zm-3-5V3.5L18.5 9H13z"/>
</svg>
</div>
<span className="text-[#004B87] font-semibold text-sm">Belgeler</span>
</a>
<a
className="rounded-full border border-solid border-black/[.08] dark:border-white/[.145] transition-colors flex items-center justify-center hover:bg-[#f2f2f2] dark:hover:bg-[#1a1a1a] hover:border-transparent font-medium text-sm sm:text-base h-10 sm:h-12 px-4 sm:px-5 w-full sm:w-auto md:w-[158px]"
href="https://nextjs.org/docs?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
target="_blank"
rel="noopener noreferrer"
>
Read our docs
{/* Basında Biz */}
<a href="/basinda-biz" className="bg-white rounded-xl p-6 shadow-lg hover:shadow-xl transition-all duration-300 hover:-translate-y-1 flex flex-col items-center text-center group">
<div className="w-12 h-12 mb-3 text-[#004B87] group-hover:text-[#00B4D8] transition-colors">
<svg fill="currentColor" viewBox="0 0 24 24">
<path d="M20 2H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h14l4 4V4c0-1.1-.9-2-2-2zm-2 12H6v-2h12v2zm0-3H6V9h12v2zm0-3H6V6h12v2z"/>
</svg>
</div>
<span className="text-[#004B87] font-semibold text-sm">Basında Biz</span>
</a>
{/* Dilek-Şikayet */}
<a href="/dilek-sikayet" className="bg-white rounded-xl p-6 shadow-lg hover:shadow-xl transition-all duration-300 hover:-translate-y-1 flex flex-col items-center text-center group">
<div className="w-12 h-12 mb-3 text-[#004B87] group-hover:text-[#00B4D8] transition-colors">
<svg fill="currentColor" viewBox="0 0 24 24">
<path d="M20 2H4c-1.1 0-1.99.9-1.99 2L2 22l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-7 9h-2V5h2v6zm0 4h-2v-2h2v2z"/>
</svg>
</div>
<span className="text-[#004B87] font-semibold text-sm">Dilek-Şikayet</span>
</a>
{/* E-İletişim */}
<a href="/e-iletisim" className="bg-white rounded-xl p-6 shadow-lg hover:shadow-xl transition-all duration-300 hover:-translate-y-1 flex flex-col items-center text-center group">
<div className="w-12 h-12 mb-3 text-[#004B87] group-hover:text-[#00B4D8] transition-colors">
<svg fill="currentColor" viewBox="0 0 24 24">
<path d="M20 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 4l-8 5-8-5V6l8 5 8-5v2z"/>
</svg>
</div>
<span className="text-[#004B87] font-semibold text-sm">E-İletişim</span>
</a>
</div>
</div>
</div>
</div>
{/* Canlı Yayın Video Bölümü */}
{showLiveStream && (
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 pt-32 pb-8">
<div className="bg-white rounded-2xl shadow-2xl p-6 lg:p-8">
<div className="flex items-center justify-between mb-6">
<div className="flex items-center space-x-3">
<div className="w-3 h-3 bg-red-500 rounded-full animate-pulse"></div>
<h2 className="text-2xl font-bold text-[#004B87]">Canlı Yayın</h2>
</div>
<button
onClick={() => setShowLiveStream(false)}
className="text-gray-500 hover:text-red-500 transition-colors"
>
<svg className="w-6 h-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
</svg>
</button>
</div>
{/* YouTube Video Embed */}
<div className="relative w-full" style={{paddingBottom: '56.25%'}}>
<iframe
className="absolute top-0 left-0 w-full h-full rounded-lg"
src="https://www.youtube.com/embed/b9q88QDEcKg?autoplay=1"
title="Canlı Yayın"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowFullScreen
></iframe>
</div>
<p className="mt-4 text-gray-600 text-sm">
A2 Metro Hattı İnşaat Çalışmaları - Canlı Yayın
</p>
</div>
</div>
)}
{/* Haberler Bölümü */}
{showNews && (
<div className={`max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 ${showLiveStream ? 'pt-8' : 'pt-32'} pb-8`}>
<div className="bg-white rounded-2xl shadow-2xl p-6 lg:p-8">
<div className="flex items-center justify-between mb-6">
<div className="flex items-center space-x-3">
<div className="w-10 h-10 bg-[#004B87] rounded-lg flex items-center justify-center">
<svg className="w-6 h-6 text-white" fill="currentColor" viewBox="0 0 24 24">
<path d="M19 5v14H5V5h14m0-2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-4.86 8.86l-3 3.87L9 13.14 6 17h12l-3.86-5.14z"/>
</svg>
</div>
<h2 className="text-2xl font-bold text-[#004B87]">Son Haberler</h2>
</div>
<button
onClick={() => setShowNews(false)}
className="text-gray-500 hover:text-red-500 transition-colors"
>
<svg className="w-6 h-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
</svg>
</button>
</div>
{/* Haberler Grid veya Detay */}
{selectedNews === null ? (
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
{newsData.map((news) => (
<div key={news.id} className="bg-gray-50 rounded-xl overflow-hidden hover:shadow-lg transition-all duration-300 hover:-translate-y-1">
{/* Haber Görseli */}
<div className="h-48 overflow-hidden">
<img
src={news.image}
alt={news.title}
className="w-full h-full object-cover hover:scale-110 transition-transform duration-500"
/>
</div>
{/* Haber İçeriği */}
<div className="p-5">
<div className="flex items-center space-x-2 text-sm text-gray-500 mb-2">
<svg className="w-4 h-4" fill="currentColor" viewBox="0 0 24 24">
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm.5-13H11v6l5.25 3.15.75-1.23-4.5-2.67z"/>
</svg>
<span>{news.date}</span>
</div>
<h3 className="text-lg font-bold text-[#004B87] mb-2 line-clamp-2">
{news.title}
</h3>
<p className="text-gray-600 text-sm line-clamp-3 mb-4">
{news.summary}
</p>
<button
onClick={() => setSelectedNews(news.id)}
className="text-[#00B4D8] hover:text-[#004B87] font-semibold text-sm flex items-center space-x-1 transition-colors"
>
<span>Devamını Oku</span>
<svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5l7 7-7 7" />
</svg>
</button>
</div>
</div>
))}
</div>
) : (
/* Haber Detayı */
<div className="animate-fadeIn">
{newsData.filter(n => n.id === selectedNews).map((news) => (
<div key={news.id}>
{/* Geri Butonu */}
<button
onClick={() => setSelectedNews(null)}
className="flex items-center space-x-2 text-[#00B4D8] hover:text-[#004B87] font-semibold mb-6 transition-colors"
>
<svg className="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 19l-7-7 7-7" />
</svg>
<span>Haberlere Dön</span>
</button>
{/* Detay İçerik */}
<div className="bg-white rounded-xl overflow-hidden">
{/* Büyük Görsel */}
<div className="h-96 overflow-hidden">
<img
src={news.image}
alt={news.title}
className="w-full h-full object-cover"
/>
</div>
{/* Detay Metni */}
<div className="p-8">
<div className="flex items-center space-x-2 text-sm text-gray-500 mb-4">
<svg className="w-4 h-4" fill="currentColor" viewBox="0 0 24 24">
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm.5-13H11v6l5.25 3.15.75-1.23-4.5-2.67z"/>
</svg>
<span>{news.date}</span>
</div>
<h1 className="text-3xl font-bold text-[#004B87] mb-6">
{news.title}
</h1>
<div className="prose max-w-none">
<p className="text-gray-700 text-lg leading-relaxed mb-4">
{news.content}
</p>
</div>
{/* Alt Bilgi */}
<div className="mt-8 pt-6 border-t border-gray-200">
<div className="flex items-center justify-between">
<div className="flex items-center space-x-4">
<span className="text-sm text-gray-500">Paylaş:</span>
<button className="text-[#00B4D8] hover:text-[#004B87] transition-colors">
<svg className="w-5 h-5" fill="currentColor" viewBox="0 0 24 24">
<path d="M18 16.08c-.76 0-1.44.3-1.96.77L8.91 12.7c.05-.23.09-.46.09-.7s-.04-.47-.09-.7l7.05-4.11c.54.5 1.25.81 2.04.81 1.66 0 3-1.34 3-3s-1.34-3-3-3-3 1.34-3 3c0 .24.04.47.09.7L8.04 9.81C7.5 9.31 6.79 9 6 9c-1.66 0-3 1.34-3 3s1.34 3 3 3c.79 0 1.5-.31 2.04-.81l7.12 4.16c-.05.21-.08.43-.08.65 0 1.61 1.31 2.92 2.92 2.92 1.61 0 2.92-1.31 2.92-2.92s-1.31-2.92-2.92-2.92z"/>
</svg>
</button>
</div>
<button
onClick={() => setSelectedNews(null)}
className="px-6 py-2 bg-[#00B4D8] text-white rounded-lg hover:bg-[#004B87] transition-colors"
>
Kapat
</button>
</div>
</div>
</div>
</div>
</div>
))}
</div>
)}
</div>
</div>
)}
{/* Ana İçerik - Kartlar için üstten boşluk */}
<main className={`max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 ${showLiveStream || showNews ? 'pt-8' : 'pt-32'} pb-12`}>
<div className="text-center mb-16">
<h2 className="text-3xl font-bold text-white mb-4">
Metro Hat Durumları
</h2>
<p className="text-lg text-[#F8F9FA] max-w-2xl mx-auto">
Ankara Metro hatları ve durak bilgileri. Metro treni şu anda hangi durakta görebilirsiniz.
</p>
</div>
{/* Metro İnşaat Projesi - Animasyonlu */}
<MetroLine />
</main>
<footer className="row-start-3 flex gap-[24px] flex-wrap items-center justify-center">
<a
className="flex items-center gap-2 hover:underline hover:underline-offset-4"
href="https://nextjs.org/learn?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
target="_blank"
rel="noopener noreferrer"
>
<Image
aria-hidden
src="/file.svg"
alt="File icon"
width={16}
height={16}
/>
Learn
</a>
<a
className="flex items-center gap-2 hover:underline hover:underline-offset-4"
href="https://vercel.com/templates?framework=next.js&utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
target="_blank"
rel="noopener noreferrer"
>
<Image
aria-hidden
src="/window.svg"
alt="Window icon"
width={16}
height={16}
/>
Examples
</a>
<a
className="flex items-center gap-2 hover:underline hover:underline-offset-4"
href="https://nextjs.org?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
target="_blank"
rel="noopener noreferrer"
>
<Image
aria-hidden
src="/globe.svg"
alt="Globe icon"
width={16}
height={16}
/>
Go to nextjs.org
</a>
</footer>
</div>
);
}

57
components/Header.tsx Normal file
View File

@@ -0,0 +1,57 @@
import Link from 'next/link';
export default function Header() {
return (
<header className="w-full bg-linear-to-r from-[#003366] via-[#004B87] to-[#003366] border-b border-[#00B4D8]/40 shadow-lg">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="flex justify-between items-center h-20">
{/* Logo - Sol taraf */}
<div className="shrink-0">
<Link href="/" className="flex items-center space-x-3">
<div className="text-[#00B4D8]">
<svg className="w-12 h-12" viewBox="0 0 50 50" fill="currentColor">
<path d="M25 5L5 15v20l20 10 20-10V15L25 5zm0 3.5L42 18v14l-17 8.5L8 32V18l17-9.5z"/>
<path d="M25 15l-10 5v10l10 5 10-5V20l-10-5zm0 3l7 3.5v7L25 32l-7-3.5v-7l7-3.5z"/>
</svg>
</div>
<div className="flex flex-col">
<span className="text-[#48CAE4] text-sm font-semibold uppercase tracking-wider">Ankara</span>
<span className="text-white text-xl font-bold">Büyükşehir Belediyesi</span>
</div>
</Link>
</div>
{/* Sağ taraf - Dil, Hava Durumu, Arama ve Menü */}
<div className="flex items-center space-x-4">
{/* Dil seçimi */}
<button className="text-white text-sm font-semibold hover:text-[#48CAE4] transition-colors">
TR
</button>
{/* Hava durumu */}
<div className="flex items-center space-x-2 text-white">
<svg className="w-6 h-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M3 15a4 4 0 004 4h9a5 5 0 10-.1-9.999 5.002 5.002 0 10-9.78 2.096A4.001 4.001 0 003 15z" />
</svg>
<span className="text-sm font-medium">10°C</span>
</div>
{/* Arama butonu */}
<button className="p-2 rounded-full border-2 border-white text-white hover:bg-[#00B4D8] hover:border-[#00B4D8] transition-colors">
<svg className="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
</svg>
</button>
{/* Menü butonu */}
<button className="p-3 rounded-lg bg-[#00B4D8] text-white hover:bg-[#48CAE4] transition-colors shadow-lg">
<svg className="w-6 h-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 6h16M4 12h16M4 18h16" />
</svg>
</button>
</div>
</div>
</div>
</header>
);
}

149
components/MetroLine.tsx Normal file
View File

@@ -0,0 +1,149 @@
'use client';
import { useState, useEffect } from 'react';
export default function MetroLine() {
const [currentStation, setCurrentStation] = useState(0);
// Metro başlangıçtan Tuzluçayır'a (index 2) kadar ilerler ve durur
useEffect(() => {
const interval = setInterval(() => {
setCurrentStation((prev) => {
if (prev < 2) return prev + 1; // Sadece 2'ye kadar ilerle
return 2; // Tuzluçayır'da dur
});
}, 3000); // Her 3 saniyede bir ilerle
return () => clearInterval(interval);
}, []);
const stations = [
{ name: 'ABİDİN PAŞA', status: 'completed' },
{ name: 'AŞIK VEYSEL', status: 'completed' },
{ name: 'TUZLUÇAYIR', status: 'construction' },
{ name: 'GENERAL ZEKİ DOĞAN', status: 'planned' },
{ name: 'FAHRİ KORUTÜRK', status: 'planned' },
{ name: 'CENGİZHAN', status: 'planned' },
{ name: 'AKŞEMSETTİN', status: 'planned' },
{ name: 'NATOYOLU', status: 'planned' },
];
const getStationStyle = (index: number, status: string) => {
if (index === currentStation) {
return 'w-16 h-16 bg-[#F59E0B] border-4 border-white shadow-2xl scale-110';
}
if (status === 'completed') {
return 'w-14 h-14 bg-green-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, status: string) => {
if (index === currentStation) {
return 'text-[#F59E0B] font-bold';
}
if (status === 'completed') {
return 'text-green-600 font-bold';
}
return 'text-gray-500 font-semibold';
};
// Her durak arası mesafe için progress hesaplama
const totalStations = stations.length;
const progressPercentage = (currentStation / (totalStations - 1)) * 100;
return (
<div className="bg-white rounded-2xl shadow-2xl p-8 lg:p-12">
{/* Proje Başlığı */}
<div className="flex items-center justify-between mb-8">
<div className="flex items-center space-x-4">
<div className="w-12 h-12 rounded-full bg-[#F59E0B] flex items-center justify-center">
<svg className="w-6 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-2xl font-bold text-[#004B87]">A2 Metro Hattı İnşaatı</h3>
<p className="text-[#6B7280]">Abidin Paşa - Natoyolu</p>
</div>
</div>
<div className="text-right">
<p className="text-sm text-[#6B7280]">İnşaat Durumu</p>
<p className="text-2xl font-bold text-[#F59E0B]">{Math.round(progressPercentage)}%</p>
</div>
</div>
{/* Metro Hat ve İnşaat Çizgisi */}
<div className="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 */}
<div className="grid grid-cols-2 md:grid-cols-4 lg:grid-cols-8 gap-6 relative">
{stations.map((station, index) => (
<div key={index} 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.status)}`}>
{index === currentStation ? (
<>
{/* 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' ? (
<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>
) : (
<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.status)}`}>
{station.name}
</span>
<span className={`text-xs transition-all duration-300 ${
index === currentStation ? 'text-[#F59E0B] font-semibold' :
station.status === 'completed' ? 'text-green-600' : 'text-gray-400'
}`}>
{index === currentStation ? '🚇 Metro Burada' :
station.status === 'completed' ? '✓ Tamamlandı' :
'◯ Planlı'}
</span>
</div>
))}
</div>
</div>
{/* Alt Bilgi */}
<div className="mt-8 pt-6 border-t border-gray-200">
<div className="flex flex-wrap gap-6 justify-center text-sm">
<div className="flex items-center space-x-2">
<div className="w-5 h-5 rounded-full bg-green-500 border-2 border-white flex items-center justify-center">
<svg className="w-3 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-5 h-5 rounded-full bg-[#F59E0B] border-2 border-white"></div>
<span className="text-[#6B7280]">İnşaat Halinde (Metro Burada)</span>
</div>
<div className="flex items-center space-x-2">
<div className="w-5 h-5 rounded-full bg-gray-300 border-2 border-dashed border-gray-400"></div>
<span className="text-[#6B7280]">Planlanan</span>
</div>
</div>
</div>
</div>
);
}

25
styles/colors.ts Normal file
View File

@@ -0,0 +1,25 @@
// Ankara Büyükşehir Belediyesi - Gülermak Metro Renk Paleti
export const colors = {
// Ankara Belediyesi Ana Renkleri
ankaraBlue: '#004B87', // Ankara Blue - Ana koyu mavi (logodan)
ankaraDark: '#003366', // Ankara Dark - Daha koyu ton
ankaraLight: '#0066B3', // Ankara Light - Açık mavi ton
// Vurgu renkleri
ankaraCyan: '#00B4D8', // Ankara Cyan - Açık mavi vurgu (logodan)
turkishSky: '#48CAE4', // Turkish Sky - Gökyüzü mavisi
// Yardımcı renkler
warmWhite: '#F8F9FA', // Warm White - Yumuşak beyaz
coolGray: '#6C757D', // Cool Gray - Gri tonlar
lightGray: '#E9ECEF', // Light Gray - Açık gri
// Nötr tonlar
white: '#FFFFFF',
darkNavy: '#001F3F', // Dark Navy - En koyu ton
// Accent (vurgu için)
starWhite: '#FFFFFF', // Star White - Yıldızlar için
} as const;
export type ColorKey = keyof typeof colors;