TravelAI – Hayalindeki Seyahati Planla
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
:root {
–blue: #1A6EFF;
–blue-dark: #1254CC;
–blue-light: #EEF4FF;
–text: #0D1B2E;
–text-muted: #6B7A90;
–bg: #fff;
–surface: #F5F8FF;
–border: #E2EAF4;
–radius: 16px;
–shadow: 0 4px 24px rgba(26,110,255,0.08);
}
html { scroll-behavior: smooth; }
body {
font-family: ‘Plus Jakarta Sans’, sans-serif;
color: var(–text);
background: var(–bg);
overflow-x: hidden;
}
/* NAV */
nav {
position: fixed; top: 0; left: 0; right: 0; z-index: 100;
background: rgba(255,255,255,0.92);
backdrop-filter: blur(12px);
border-bottom: 1px solid var(–border);
display: flex; align-items: center; justify-content: space-between;
padding: 0 5%;
height: 64px;
transition: box-shadow 0.3s;
}
nav.scrolled { box-shadow: 0 2px 20px rgba(26,110,255,0.1); }
.nav-logo {
display: flex; align-items: center; gap: 8px;
font-weight: 800; font-size: 20px; color: var(–blue);
text-decoration: none;
}
.nav-logo svg { width: 28px; height: 28px; }
.nav-links {
display: flex; gap: 32px; list-style: none;
}
.nav-links a {
text-decoration: none; color: var(–text-muted);
font-size: 14px; font-weight: 500;
transition: color 0.2s;
}
.nav-links a:hover { color: var(–blue); }
/* PLANS PAGE */
#plans-page { display: none; min-height: 100vh; padding: 90px 5% 60px; background: var(–surface); }
#plans-page.active { display: block; }
#plan-detail-page { display: none; min-height: 100vh; padding: 90px 5% 60px; background: var(–surface); }
#plan-detail-page.active { display: block; }
.main-content { display: block; }
.main-content.hidden { display: none; }
.plans-header {
display: flex; align-items: center; justify-content: space-between;
margin-bottom: 32px; flex-wrap: wrap; gap: 16px;
}
.plans-header h1 { font-size: 28px; font-weight: 800; }
.plans-header p { color: var(–text-muted); font-size: 14px; margin-top: 4px; }
.plans-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: 20px;
}
.plan-card {
background: #fff; border-radius: var(–radius);
border: 1px solid var(–border);
padding: 24px; position: relative;
box-shadow: var(–shadow);
transition: all 0.3s;
}
.plan-card:hover { transform: translateY(-3px); box-shadow: 0 12px 32px rgba(26,110,255,0.12); }
.plan-card-header {
display: flex; align-items: flex-start; justify-content: space-between; margin-bottom: 16px;
}
.plan-dest {
font-size: 20px; font-weight: 800; margin-bottom: 2px;
}
.plan-status {
display: inline-block; padding: 4px 12px; border-radius: 50px;
font-size: 11px; font-weight: 700; background: #DCFCE7; color: #16A34A;
}
.plan-meta {
display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-top: 16px;
}
.plan-meta-item label {
font-size: 11px; color: var(–text-muted); font-weight: 600;
text-transform: uppercase; letter-spacing: 0.5px; display: block; margin-bottom: 3px;
}
.plan-meta-item span { font-size: 14px; font-weight: 600; }
.plan-actions {
display: flex; gap: 8px; margin-top: 20px; padding-top: 16px;
border-top: 1px solid var(–border);
}
.plan-act-btn {
flex: 1; padding: 8px; border-radius: 8px; font-size: 13px; font-weight: 600;
cursor: pointer; border: none; font-family: inherit; transition: all 0.2s;
}
.plan-act-btn.view { background: var(–blue-light); color: var(–blue); }
.plan-act-btn.view:hover { background: var(–blue); color: #fff; }
.plan-act-btn.delete { background: #FEF2F2; color: #DC2626; }
.plan-act-btn.delete:hover { background: #DC2626; color: #fff; }
.empty-plans {
text-align: center; padding: 80px 20px; color: var(–text-muted);
}
.empty-plans .empty-icon { font-size: 56px; margin-bottom: 16px; }
.empty-plans h3 { font-size: 20px; font-weight: 700; color: var(–text); margin-bottom: 8px; }
.empty-plans p { font-size: 14px; margin-bottom: 24px; }
.plan-detail-row {
display: flex; align-items: center; gap: 10px;
padding: 12px 0; border-bottom: 1px solid var(–border);
font-size: 14px;
}
.plan-detail-row:last-child { border-bottom: none; }
.plan-detail-row .icon { font-size: 18px; width: 28px; text-align: center; }
.plan-detail-row .dlabel { color: var(–text-muted); font-size: 12px; font-weight: 600; min-width: 90px; }
.plan-detail-row .dval { font-weight: 600; }
.btn {
display: inline-flex; align-items: center; gap: 8px;
padding: 10px 22px; border-radius: 50px;
font-family: inherit; font-weight: 600; font-size: 14px;
cursor: pointer; text-decoration: none; border: none;
transition: all 0.2s;
}
.btn-primary {
background: var(–blue); color: #fff;
}
.btn-primary:hover {
background: var(–blue-dark);
transform: translateY(-1px);
box-shadow: 0 6px 20px rgba(26,110,255,0.35);
}
.btn-outline {
background: transparent; color: var(–blue);
border: 1.5px solid var(–blue);
}
.btn-outline:hover {
background: var(–blue-light);
transform: translateY(-1px);
}
.btn-lg { padding: 14px 32px; font-size: 15px; }
/* HERO */
.hero {
min-height: 100vh;
background: linear-gradient(135deg, rgba(13,27,46,0.80) 0%, rgba(26,58,110,0.68) 50%, rgba(26,110,255,0.50) 100%), url(‘
https://images.unsplash.com/photo-1641128324972-af3212f0f6bd?w=1800&q=85′😉 center center / cover no-repeat;
display: flex; align-items: center;
padding: 100px 5% 60px;
position: relative;
overflow: hidden;
}
.hero::before {
content: ”;
position: absolute; inset: 0;
background: url(“data:image/svg+xml,%3Csvg width=’60’ height=’60’ viewBox=’0 0 60 60′ xmlns=’
http://www.w3.org/2000/svg’%3E%3Cg fill=’none’ fill-rule=’evenodd’%3E%3Cg fill=’%23ffffff’ fill-opacity=’0.03’%3E%3Cpath d=’M36 34v-4h-2v4h-4v2h4v4h2v-4h4v-2h-4zm0-30V0h-2v4h-4v2h4v4h2V6h4V4h-4zM6 34v-4H4v4H0v2h4v4h2v-4h4v-2H6zM6 4V0H4v4H0v2h4v4h2V6h4V4H6z’/%3E%3C/g%3E%3C/g%3E%3C/svg%3E”);
pointer-events: none;
}
.hero-location {
position: absolute; bottom: 20px; right: 24px; z-index: 2;
font-size: 12px; color: rgba(255,255,255,0.5);
font-weight: 500; letter-spacing: 0.3px;
}
/* floating planes */
.plane-float {
position: absolute; color: rgba(255,255,255,0.15);
animation: floatPlane 8s ease-in-out infinite;
}
.plane-float:nth-child(2) { top: 15%; right: 10%; animation-delay: -2s; }
.plane-float:nth-child(3) { top: 60%; right: 25%; animation-delay: -5s; font-size: 12px; }
@keyframes floatPlane {
0%,100% { transform: translateY(0) rotate(-10deg); }
50% { transform: translateY(-20px) rotate(-5deg); }
}
.hero-content { max-width: 560px; position: relative; z-index: 1; }
.hero-badge {
display: inline-flex; align-items: center; gap: 6px;
background: rgba(255,255,255,0.1); border: 1px solid rgba(255,255,255,0.2);
color: #fff; border-radius: 50px; padding: 6px 14px;
font-size: 13px; font-weight: 500; margin-bottom: 24px;
}
.hero-badge span { width: 6px; height: 6px; background: #4ADE80; border-radius: 50%; }
.hero h1 {
font-size: clamp(38px, 5vw, 58px);
font-weight: 800; line-height: 1.15; color: #fff;
margin-bottom: 20px;
}
.hero h1 em { color: #60A5FA; font-style: normal; }
.hero p {
font-size: 16px; color: rgba(255,255,255,0.7);
line-height: 1.7; margin-bottom: 36px; max-width: 440px;
}
.hero-cta { display: flex; gap: 12px; flex-wrap: wrap; }
.hero-image {
position: absolute; right: 0; top: 0; bottom: 0;
width: 48%; overflow: hidden;
}
.hero-image img {
width: 100%; height: 100%; object-fit: cover;
opacity: 0.4;
mask-image: linear-gradient(to right, transparent, black 40%);
}
.hero-stats {
display: flex; gap: 32px; margin-top: 52px;
padding-top: 32px; border-top: 1px solid rgba(255,255,255,0.1);
}
.stat { color: #fff; }
.stat-num { font-size: 28px; font-weight: 800; }
.stat-label { font-size: 13px; color: rgba(255,255,255,0.55); margin-top: 2px; }
/* SECTION COMMON */
section { padding: 80px 5%; }
.section-title {
text-align: center; font-size: clamp(26px, 3vw, 36px);
font-weight: 800; margin-bottom: 12px;
}
.section-line {
width: 48px; height: 4px; background: var(–blue);
border-radius: 2px; margin: 0 auto 48px;
}
.section-subtitle {
text-align: center; color: var(–text-muted);
font-size: 15px; margin-top: -8px; margin-bottom: 48px;
}
/* DESTINATIONS */
#destinasyonlar { background: var(–surface); }
.dest-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
gap: 20px;
}
.dest-card {
border-radius: var(–radius);
overflow: hidden;
background: #fff;
box-shadow: var(–shadow);
cursor: pointer;
transition: transform 0.3s, box-shadow 0.3s;
position: relative;
}
.dest-card:hover {
transform: translateY(-6px);
box-shadow: 0 16px 40px rgba(26,110,255,0.15);
}
.dest-img {
position: relative; overflow: hidden; height: 180px;
}
.dest-img img {
width: 100%; height: 100%; object-fit: cover;
transition: transform 0.4s;
}
.dest-card:hover .dest-img img { transform: scale(1.07); }
.dest-country {
position: absolute; top: 12px; left: 12px;
background: rgba(0,0,0,0.55); backdrop-filter: blur(6px);
color: #fff; border-radius: 50px; padding: 4px 12px;
font-size: 12px; font-weight: 600;
display: flex; align-items: center; gap: 4px;
}
.dest-body { padding: 16px; }
.dest-body h3 { font-size: 17px; font-weight: 700; margin-bottom: 4px; }
.dest-body p { font-size: 13px; color: var(–text-muted); line-height: 1.5; }
.dest-footer {
padding: 0 16px 16px;
display: flex; align-items: center; justify-content: space-between;
}
.dest-price { font-size: 15px; font-weight: 700; color: var(–blue); }
.dest-btn {
background: var(–blue-light); color: var(–blue);
border: none; border-radius: 50px; padding: 6px 14px;
font-size: 12px; font-weight: 600; cursor: pointer;
transition: all 0.2s;
}
.dest-btn:hover { background: var(–blue); color: #fff; }
/* HOW IT WORKS */
#nasil-calisir { background: #fff; }
.steps {
display: flex; gap: 0; justify-content: center;
align-items: flex-start; flex-wrap: wrap; position: relative;
}
.step {
flex: 1; min-width: 200px; max-width: 260px;
text-align: center; position: relative; padding: 0 20px;
}
.step:not(:last-child)::after {
content: ”;
position: absolute; top: 40px; right: -10%;
width: 20%; height: 2px;
background: repeating-linear-gradient(90deg, var(–blue) 0, var(–blue) 6px, transparent 6px, transparent 14px);
}
.step-icon {
width: 80px; height: 80px; border-radius: 50%;
background: var(–blue-light);
display: flex; align-items: center; justify-content: center;
margin: 0 auto 20px; position: relative;
transition: all 0.3s;
}
.step:hover .step-icon {
background: var(–blue);
box-shadow: 0 8px 24px rgba(26,110,255,0.3);
}
.step:hover .step-icon svg { color: #fff; }
.step-icon svg { width: 32px; height: 32px; color: var(–blue); transition: color 0.3s; }
.step-num {
position: absolute; top: -6px; right: -6px;
width: 24px; height: 24px; background: var(–blue);
color: #fff; border-radius: 50%; font-size: 11px; font-weight: 700;
display: flex; align-items: center; justify-content: center;
}
.step h3 { font-size: 17px; font-weight: 700; margin-bottom: 10px; }
.step p { font-size: 14px; color: var(–text-muted); line-height: 1.6; }
/* FEATURES */
#ozellikler { background: var(–surface); }
.features-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: 20px;
}
.feature-card {
background: #fff; border-radius: var(–radius);
padding: 28px; border: 1px solid var(–border);
display: flex; gap: 20px; align-items: flex-start;
transition: all 0.3s; cursor: pointer;
}
.feature-card:hover {
border-color: var(–blue);
box-shadow: 0 8px 32px rgba(26,110,255,0.1);
transform: translateY(-3px);
}
.feature-icon {
width: 52px; height: 52px; border-radius: 14px;
display: flex; align-items: center; justify-content: center;
flex-shrink: 0;
}
.feature-icon.blue { background: #EEF4FF; }
.feature-icon.green { background: #EEFBF0; }
.feature-icon.purple { background: #F3EEFF; }
.feature-icon svg { width: 24px; height: 24px; }
.feature-icon.blue svg { color: #1A6EFF; }
.feature-icon.green svg { color: #16A34A; }
.feature-icon.purple svg { color: #7C3AED; }
.feature-text h3 { font-size: 16px; font-weight: 700; margin-bottom: 6px; }
.feature-text p { font-size: 14px; color: var(–text-muted); line-height: 1.6; }
/* REVIEWS */
#yorumlar { background: #fff; }
.reviews-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: 20px;
}
.review-card {
background: var(–surface); border-radius: var(–radius);
padding: 24px; border: 1px solid var(–border);
transition: all 0.3s;
}
.review-card:hover {
box-shadow: var(–shadow);
transform: translateY(-3px);
}
.reviewer {
display: flex; align-items: center; gap: 12px; margin-bottom: 16px;
}
.avatar {
width: 44px; height: 44px; border-radius: 50%;
background: linear-gradient(135deg, var(–blue), #60A5FA);
display: flex; align-items: center; justify-content: center;
color: #fff; font-weight: 700; font-size: 15px; flex-shrink: 0;
}
.reviewer-info h4 { font-size: 15px; font-weight: 700; }
.stars { color: #F59E0B; font-size: 14px; margin-top: 2px; }
.review-text { font-size: 14px; color: var(–text-muted); line-height: 1.7; font-style: italic; }
/* CTA BANNER */
.cta-banner {
background: linear-gradient(135deg, #0D1B2E, #1A6EFF);
border-radius: 24px;
padding: 56px 48px;
display: flex; align-items: center; justify-content: space-between;
gap: 24px; flex-wrap: wrap;
margin: 0 5% 80px;
}
.cta-banner h2 {
font-size: clamp(26px, 3vw, 36px); font-weight: 800; color: #fff;
max-width: 400px; line-height: 1.2;
}
.cta-banner p {
color: rgba(255,255,255,0.65); font-size: 15px; margin-top: 10px; max-width: 360px;
}
.btn-white {
background: #fff; color: var(–blue);
padding: 14px 32px; font-size: 15px; font-weight: 700;
border-radius: 50px; display: inline-flex; align-items: center; gap: 8px;
text-decoration: none; border: none; cursor: pointer;
transition: all 0.2s; white-space: nowrap;
}
.btn-white:hover {
transform: translateY(-2px);
box-shadow: 0 8px 28px rgba(255,255,255,0.3);
}
/* FOOTER */
footer {
background: var(–text);
color: rgba(255,255,255,0.6);
padding: 40px 5%;
display: flex; align-items: center; justify-content: space-between;
flex-wrap: wrap; gap: 20px;
}
.footer-logo {
font-size: 20px; font-weight: 800; color: #fff;
display: flex; align-items: center; gap: 8px;
}
.footer-links { display: flex; gap: 28px; flex-wrap: wrap; }
.footer-links a {
color: rgba(255,255,255,0.5); font-size: 13px;
text-decoration: none; transition: color 0.2s;
}
.footer-links a:hover { color: #fff; }
.footer-socials { display: flex; gap: 12px; }
.social-btn {
width: 36px; height: 36px; border-radius: 50%;
background: rgba(255,255,255,0.08);
display: flex; align-items: center; justify-content: center;
color: rgba(255,255,255,0.6); cursor: pointer;
transition: all 0.2s; text-decoration: none;
}
.social-btn:hover { background: var(–blue); color: #fff; }
/* MODAL */
.modal-overlay {
display: none; position: fixed; inset: 0; z-index: 200;
background: rgba(0,0,0,0.5); backdrop-filter: blur(4px);
align-items: center; justify-content: center;
}
.modal-overlay.active { display: flex; }
.modal {
background: #fff; border-radius: 24px; padding: 40px;
width: 90%; max-width: 420px; position: relative;
animation: popIn 0.25s ease;
}
@keyframes popIn {
from { transform: scale(0.9); opacity: 0; }
to { transform: scale(1); opacity: 1; }
}
.modal-close {
position: absolute; top: 16px; right: 16px;
background: var(–surface); border: none; border-radius: 50%;
width: 32px; height: 32px; cursor: pointer; font-size: 18px;
display: flex; align-items: center; justify-content: center;
color: var(–text-muted); transition: all 0.2s;
}
.modal-close:hover { background: var(–border); }
.modal h2 { font-size: 22px; font-weight: 800; margin-bottom: 8px; }
.modal p { color: var(–text-muted); font-size: 14px; margin-bottom: 24px; }
.form-group { margin-bottom: 16px; }
.form-group label { display: block; font-size: 13px; font-weight: 600; margin-bottom: 6px; }
.form-group input, .form-group select {
width: 100%; padding: 12px 14px; border-radius: 10px;
border: 1.5px solid var(–border); font-family: inherit; font-size: 14px;
outline: none; transition: border-color 0.2s; color: var(–text);
}
.form-group input:focus, .form-group select:focus { border-color: var(–blue); }
.modal-btn { width: 100%; justify-content: center; padding: 14px; font-size: 15px; border-radius: 12px; }
/* TOAST */
.toast {
position: fixed; bottom: 24px; right: 24px; z-index: 300;
background: #0D1B2E; color: #fff; border-radius: 12px;
padding: 14px 20px; font-size: 14px; font-weight: 500;
display: flex; align-items: center; gap: 10px;
transform: translateY(80px); opacity: 0;
transition: all 0.3s;
box-shadow: 0 8px 32px rgba(0,0,0,0.25);
}
.toast.show { transform: translateY(0); opacity: 1; }
.toast-icon { color: #4ADE80; font-size: 18px; }
/* Scroll reveal */
.reveal { opacity: 0; transform: translateY(30px); transition: all 0.6s ease; }
.reveal.visible { opacity: 1; transform: translateY(0); }
@media (max-width: 768px) {
.hero-image { display: none; }
.hero-stats { gap: 20px; }
.step:not(:last-child)::after { display: none; }
.cta-banner { padding: 36px 28px; text-align: center; justify-content: center; }
nav .nav-links { display: none; }
}
/* Tab buttons */
.dtab {
background: #fff; border: 1.5px solid var(–border);
border-radius: 50px; padding: 8px 18px; font-family: inherit;
font-size: 13px; font-weight: 600; cursor: pointer; color: var(–text-muted);
transition: all 0.2s;
}
.dtab:hover { border-color: var(–blue); color: var(–blue); }
.dtab.active { background: var(–blue); border-color: var(–blue); color: #fff; }
/* Spinner */
.ai-spinner {
width: 48px; height: 48px; border-radius: 50%;
border: 4px solid var(–blue-light);
border-top-color: var(–blue);
animation: spin 0.8s linear infinite;
margin: 0 auto;
}
@keyframes spin { to { transform: rotate(360deg); } }
TravelAI
✈
✈
📍 Kapadokya, Türkiye
Yapay Zeka Destekli Seyahat Planlama
Hayalindeki
Seyahati Planla
TravelAI ile en iyi rotaları, otelleri ve aktiviteleri keşfet. Akıllı önerilerle unutulmaz bir tatil seni bekliyor.
Popüler Destinasyonlar
📍 Fransa
Paris
Romantik bir şehir ve büyüleyici atmosfer.
📍 Japonya
Tokyo
Gelenek ve modernliğin eşsiz birleşimi.
📍 İtalya
Roma
Tarih kokan sokaklarıyla unutulmaz bir deneyim.
📍 ABD
New York
Enerjisi hiç bitmeyen modern metropol.
Nasıl Çalışır?
1
Gideceğin Yeri Seç
Gitmek istediğin şehir veya ülkeyi belirle.
2
Seyahat Planını Oluştur
Akıllı sistemimiz sana en uygun rota, otel ve aktiviteleri hazırlar.
3
Tatiline Başla
Planını kaydet ve unutulmaz bir deneyimin tadını çıkar!
Özellikler
Akıllı Rota Önerisi
Yapay zeka ile en uygun ve optimum rotaları keşfet. Zaman ve para tasarrufu sağla.
Otel Önerileri
Bütçene ve zevkine uygun konaklama seçenekleri bul. En iyi fiyat garantisi.
Aktivite Önerileri
Gideceğin yerdeki gezilecek yerler ve aktiviteleri keşfet. Her yaşa uygun seçenekler.
Kullanıcı Yorumları
“TravelAI sayesinde tatilimizi mükemmel şekilde planladık. Her şey çok kolaydı!”
“Otel ve rota önerileri harikaydı. Zamandan tasarruf ettim, kesinlikle tavsiye ederim.”
“Gitmeden önce tüm aktiviteleri hazır görmek tatili daha keyifli hale getirdi. Harika bir uygulama!”
Yeni bir maceraya
hazır mısın?
TravelAI ile hayalindeki seyahati şimdi planla ve unutulmaz anılar biriktirmeye başla.
✓
İşlem başarılı!
// Navbar scroll
window.addEventListener(‘scroll’, () => {
document.getElementById(‘navbar’).classList.toggle(‘scrolled’, window.scrollY > 20);
});
// Scroll reveal
const revealEls = document.querySelectorAll(‘.reveal’);
const observer = new IntersectionObserver((entries) => {
entries.forEach((e, i) => {
if (e.isIntersecting) setTimeout(() => e.target.classList.add(‘visible’), i * 80);
});
}, { threshold: 0.1 });
revealEls.forEach(el => observer.observe(el));
// Toast
function showToast(msg) {
const t = document.getElementById(‘toast’);
document.getElementById(‘toast-text’).textContent = msg;
t.classList.add(‘show’);
setTimeout(() => t.classList.remove(‘show’), 3500);
}
// Plans storage
let plans = JSON.parse(localStorage.getItem(‘travelai_plans’) || ‘[]’);
function savePlans() { localStorage.setItem(‘travelai_plans’, JSON.stringify(plans)); updateBadge(); }
function updateBadge() {
const b = document.getElementById(‘plans-count-badge’);
b.style.display = plans.length > 0 ? ‘inline’ : ‘none’;
b.textContent = plans.length;
}
updateBadge();
// Page switching
function showMain() {
document.getElementById(‘main-content’).classList.remove(‘hidden’);
document.getElementById(‘plans-page’).classList.remove(‘active’);
document.getElementById(‘plan-detail-page’).classList.remove(‘active’);
}
function showPlans() {
document.getElementById(‘main-content’).classList.add(‘hidden’);
document.getElementById(‘plans-page’).classList.add(‘active’);
document.getElementById(‘plan-detail-page’).classList.remove(‘active’);
renderPlans(); window.scrollTo(0,0);
}
function showPlanDetail(i) {
document.getElementById(‘main-content’).classList.add(‘hidden’);
document.getElementById(‘plans-page’).classList.remove(‘active’);
document.getElementById(‘plan-detail-page’).classList.add(‘active’);
renderPlanDetail(i); window.scrollTo(0,0);
}
// Render plans list
function renderPlans() {
const container = document.getElementById(‘plans-container’);
if (plans.length === 0) {
container.innerHTML = `
🗺️
Henüz bir planın yok
İlk seyahat planını oluşturmak için butona tıkla.
`;
return;
}
container.innerHTML = `
${plans.map((p, i) => `
`).join(”)}
`;
}
function deletePlan(i) {
if (!confirm(‘Bu planı silmek istediğine emin misin?’)) return;
plans.splice(i, 1); savePlans(); renderPlans(); showToast(‘Plan silindi.’);
}
// ─── PLAN DETAIL PAGE ───────────────────────────────────────────
function renderPlanDetail(idx) {
const p = plans[idx];
const page = document.getElementById(‘plan-detail-page’);
page.innerHTML = `
📍 ${p.destination}
${p.date||”}${p.returnDate?’ → ‘+p.returnDate:”} · ${p.people} · ${p.budget} bütçe
${p.itinerary ? renderItineraryHTML(p.itinerary) : ‘
‘}
`;
if (!p.itinerary) generateItinerary(idx);
}
function renderItineraryHTML(data) {
let html = ”;
// Overview card
html += `
🤖 AI Seyahat Özeti
${data.summary}
Toplam Süre
${data.duration}
Tahmini Bütçe
${data.estimatedCost}
En İyi Mevsim
${data.bestSeason}
`;
// Tabs
html += `
`;
// Tab content
html += `
`;
data.days.forEach(day => {
html += `
Gün ${day.day}
${day.title}
`;
day.activities.forEach(a => {
html += `
${a.name}
${a.desc}
${a.tip ? `
💡 ${a.tip}
` : ”}
`;
});
html += `
`;
});
html += `
`;
// Places tab
html += `
`;
data.places.forEach(pl => {
html += `
${pl.icon}
${pl.name}
${pl.category}
${pl.desc}
⏱ ${pl.duration} · ${pl.entryFee}
`;
});
html += `
`;
// Hotels tab
html += `
`;
data.hotels.forEach(h => {
html += `
${h.icon}
${h.name}
${h.stars} ★
${h.budget}
${h.desc}
${h.price} / gece
${h.features.map(f=>`${f}`).join(”)}
`;
});
html += `
`;
// Food tab
html += `
`;
data.restaurants.forEach(r => {
html += `
${r.icon}
${r.name}
${r.cuisine}
${r.desc}
${r.priceRange} · ${r.mustTry}
`;
});
html += `
`;
// Tips tab
html += `
`;
data.tips.forEach(t => {
html += `
`;
});
html += `
`;
return html;
}
function switchTab(name) {
document.querySelectorAll(‘.dtab’).forEach(b => b.classList.remove(‘active’));
document.querySelectorAll(‘.tab-content’).forEach(c => c.style.display = ‘none’);
event.target.classList.add(‘active’);
document.getElementById(‘tab-‘ + name).style.display = ‘block’;
}
// ─── AI ITINERARY GENERATION ────────────────────────────────────
async function generateItinerary(idx) {
const p = plans[idx];
const prompt = `Sen bir uzman seyahat planlayıcısısın. Kullanıcı için ${p.destination} destinasyonuna detaylı bir seyahat planı oluştur.
Bilgiler:
– Destinasyon: ${p.destination}
– Gidiş: ${p.date || ‘belirtilmedi’}
– Dönüş: ${p.returnDate || ‘belirtilmedi’}
– Kişi sayısı: ${p.people}
– Bütçe: ${p.budget}
Yanıtını SADECE aşağıdaki JSON formatında ver, başka hiçbir şey yazma:
{
“summary”: “kısa özet (2 cümle)”,
“duration”: “örn: 5 gün”,
“estimatedCost”: “örn: kişi başı ₺15.000-20.000”,
“bestSeason”: “örn: Nisan-Haziran”,
“days”: [
{
“day”: 1,
“title”: “Günün başlığı”,
“activities”: [
{ “time”: “09:00”, “icon”: “🏛️”, “name”: “Yer adı”, “desc”: “Açıklama”, “tip”: “İpucu veya null” }
]
}
],
“places”: [
{ “icon”: “🗼”, “name”: “Yer”, “category”: “Tarihi / Müze / Doğa vs”, “desc”: “Açıklama”, “duration”: “2-3 saat”, “entryFee”: “Ücretsiz / 15€” }
],
“hotels”: [
{ “icon”: “🏨”, “name”: “Otel adı”, “stars”: 4, “budget”: “Ekonomik/Orta/Lüks”, “desc”: “Açıklama”, “price”: “₺800”, “features”: [“WiFi”,”Kahvaltı”,”Havuz”] }
],
“restaurants”: [
{ “icon”: “🍝”, “name”: “Restoran”, “cuisine”: “Mutfak türü”, “desc”: “Açıklama”, “priceRange”: “💰💰”, “mustTry”: “Denenmesi gereken: yemek adı” }
],
“tips”: [
{ “icon”: “💡”, “title”: “İpucu başlığı”, “desc”: “Detay” }
]
}
Günlük plan için gidilecek destinasyona göre gerçekçi, uygulanabilir bir program yap. En az 3 gün, en fazla 7 gün planla. Günde 4-5 aktivite olsun. En az 5 gezilecek yer, 3 otel, 4 restoran, 5 ipucu ekle. Türkçe yaz.`;
try {
const res = await fetch(‘
https://api.anthropic.com/v1/messages’, {
method: ‘POST’,
headers: { ‘Content-Type’: ‘application/json’ },
body: JSON.stringify({
model: ‘claude-sonnet-4-20250514’,
max_tokens: 4000,
messages: [{ role: ‘user’, content: prompt }]
})
});
const data = await res.json();
let text = data.content.map(c => c.text || ”).join(”);
text = text.replace(/“`json|“`/g, ”).trim();
const itinerary = JSON.parse(text);
plans[idx].itinerary = itinerary;
savePlans();
const area = document.getElementById(‘itinerary-area’);
if (area) area.innerHTML = renderItineraryHTML(itinerary);
renderPlans();
showToast(‘Rota hazır! ✈’);
} catch (err) {
const area = document.getElementById(‘itinerary-area’);
if (area) area.innerHTML = `
⚠️
Plan oluşturulurken bir hata oluştu.
`;
}
}
// Modal
let currentDestForPlan = ”;
const modals = {
login: `
Giriş Yap
Hesabına giriş yaparak seyahat planlarına devam et.
E-posta
Şifre
Hesabın yok mu? Kayıt Ol
`,
register: `
Kayıt Ol
Ücretsiz hesap oluştur ve seyahat planlamaya başla.
Ad Soyad
E-posta
Şifre
`,
plan: `
Seyahat Planla ✈
Hayalindeki tatili birkaç adımda oluştur, AI rotanı hazırlasın!
Nereye gitmek istiyorsun?
Gidiş Tarihi
Dönüş Tarihi
Kaç kişi?1 Kişi2 Kişi3-5 Kişi6+ Kişi
BütçeEkonomikOrtaLüks
`
};
function openModal(type, extra) {
currentDestForPlan = extra || ”;
let body = modals[type] || ”;
if (type === ‘dest’) {
body = `
${extra} 📍
AI senin için ${extra} rotanı hazırlasın!
Gidiş Tarihi
Dönüş Tarihi
Kişi Sayısı1 Kişi2 Kişi3-5 Kişi6+ Kişi
BütçeEkonomikOrtaLüks
`;
}
document.getElementById(‘modal-body’).innerHTML = body;
document.getElementById(‘modal’).classList.add(‘active’);
}
function closeModal() { document.getElementById(‘modal’).classList.remove(‘active’); }
function closeModalOutside(e) { if (e.target.id === ‘modal’) closeModal(); }
function setLoggedIn(email, name) {
const initials = email.slice(0,2).toUpperCase();
document.getElementById(‘avatar-initials’).textContent = initials;
document.getElementById(‘menu-email’).textContent = email;
document.getElementById(‘menu-name’).textContent = name || email.split(‘@’)[0];
document.getElementById(‘btn-giris’).style.display = ‘none’;
document.getElementById(‘btn-avatar’).style.display = ‘block’;
localStorage.setItem(‘travelai_user’, JSON.stringify({ email, name: name || email.split(‘@’)[0] }));
}
function setLoggedOut() {
document.getElementById(‘btn-giris’).style.display = ”;
document.getElementById(‘btn-avatar’).style.display = ‘none’;
localStorage.removeItem(‘travelai_user’);
}
// Restore session
const savedUser = JSON.parse(localStorage.getItem(‘travelai_user’) || ‘null’);
if (savedUser) setLoggedIn(savedUser.email, savedUser.name);
function toggleUserMenu(e) {
e.stopPropagation();
const menu = document.getElementById(‘user-menu’);
menu.style.display = menu.style.display === ‘none’ ? ‘block’ : ‘none’;
}
document.addEventListener(‘click’, () => {
const menu = document.getElementById(‘user-menu’);
if (menu) menu.style.display = ‘none’;
});
function handleLogin() {
const email = document.getElementById(‘login-email’).value.trim();
if (!email) { showToast(‘Lütfen e-posta adresini gir!’); return; }
setLoggedIn(email, ”);
closeModal();
showToast(‘Hoş geldin! 👋’);
}
function handleRegister() {
const name = document.getElementById(‘reg-name’) ? document.getElementById(‘reg-name’).value.trim() : ”;
const email = document.getElementById(‘reg-email’) ? document.getElementById(‘reg-email’).value.trim() : ”;
if (!email) { showToast(‘Lütfen e-posta adresini gir!’); return; }
setLoggedIn(email, name);
closeModal();
showToast(‘Hesabın oluşturuldu! 🎉’);
}
function handleLogout() {
document.getElementById(‘user-menu’).style.display = ‘none’;
setLoggedOut();
showToast(‘Çıkış yapıldı. Görüşürüz! 👋’);
}
function handlePlan() {
const dest = (document.getElementById(‘p-dest’) ? document.getElementById(‘p-dest’).value.trim() : ”) || currentDestForPlan;
if (!dest) { showToast(‘Lütfen bir destinasyon gir!’); return; }
const now = new Date();
const plan = {
destination: dest,
date: document.getElementById(‘p-date’) ? document.getElementById(‘p-date’).value : ”,
returnDate: document.getElementById(‘p-return’) ? document.getElementById(‘p-return’).value : ”,
people: document.getElementById(‘p-people’) ? document.getElementById(‘p-people’).value : ‘1 Kişi’,
budget: document.getElementById(‘p-budget’) ? document.getElementById(‘p-budget’).value : ‘Orta’,
created: now.toLocaleDateString(‘tr-TR’, { day:’2-digit’, month:’long’, year:’numeric’ }),
itinerary: null
};
plans.unshift(plan);
savePlans();
closeModal();
showToast(‘Plan oluşturuluyor, AI rotanı hazırlıyor… ✈’);
setTimeout(() => showPlanDetail(0), 600);
}
document.addEventListener(‘keydown’, e => { if (e.key === ‘Escape’) closeModal(); });