taja / index.html
tahatehrani's picture
Update index.html
7b0979f verified
<!DOCTYPE html>
<html lang="fa" dir="rtl">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>اطلاعات ایستگاه</title>
<link rel="stylesheet" href="https://cdn.tailwindcss.com">
<script src="https://cdnjs.cloudflare.com/ajax/libs/cytoscape/3.21.1/cytoscape.min.js"></script>
<style>
@keyframes pulse {
0%, 100% { opacity: 1; }
50% { opacity: 0.5; }
}
.animate-pulse {
animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}
#cy {
width: 100%;
height: 400px;
background-color: #2d3748;
}
@media (max-width: 640px) {
#cy {
height: 300px;
}
}
</style>
</head>
<body class="bg-gray-900 text-white p-4 md:p-6">
<div class="container mx-auto" id="station-info">
<h1 class="text-3xl md:text-4xl font-extrabold mb-4 md:mb-6 text-center">اطلاعات ایستگاه</h1>
<div id="dataInfo" class="text-center text-base md:text-lg text-blue-400 mb-4 md:mb-6 font-bold"></div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6">
<div>
<h2 class="text-2xl md:text-3xl font-semibold mb-3">اطلاعات ایستگاه: {{ station_name }} (ID: {{ station_id }})</h2>
<h3 class="text-xl md:text-2xl font-semibold mb-2">زمان‌بندی اتوبوس‌ها ({{ 'رفت' if direction == '76' else 'برگشت' }}):</h3>
<div class="overflow-x-auto mb-4">
<table class="w-full border-collapse">
<thead>
<tr class="bg-gray-800">
<th class="p-2 md:p-3 text-right text-xs md:text-sm">کد مسیر</th>
<th class="p-2 md:p-3 text-right text-xs md:text-sm">مبدأ</th>
<th class="p-2 md:p-3 text-right text-xs md:text-sm">مقصد</th>
<th class="p-2 md:p-3 text-right text-xs md:text-sm">ترتیب</th>
<th class="p-2 md:p-3 text-right text-xs md:text-sm">نوع مسیر</th>
<th class="p-2 md:p-3 text-right text-xs md:text-sm">زمان رسیدن (دقیقه)</th>
</tr>
</thead>
<tbody>
{% for stop in stops_eta %}
<tr class="border-b border-gray-700 hover:bg-gray-800">
<td class="p-2 md:p-3 text-xs md:text-sm">{{ stop.route_code }}</td>
<td class="p-2 md:p-3 text-xs md:text-sm">{{ stop.origination_name }}</td>
<td class="p-2 md:p-3 text-xs md:text-sm">{{ stop.destination_name }}</td>
<td class="p-2 md:p-3 text-xs md:text-sm">{{ stop.order }}</td>
<td class="p-2 md:p-3 text-xs md:text-sm">{{ stop.route_type }}</td>
<td class="p-2 md:p-3 text-xs md:text-sm">{{ stop.eta }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
<div>
<h3 class="text-xl md:text-2xl font-semibold mb-2">چهار ایستگاه بعدی:</h3>
<div class="overflow-x-auto mb-4">
<table class="w-full border-collapse">
<thead>
<tr class="bg-gray-800">
<th class="p-2 md:p-3 text-right text-xs md:text-sm">کد ایستگاه</th>
<th class="p-2 md:p-3 text-right text-xs md:text-sm">نام ایستگاه</th>
<th class="p-2 md:p-3 text-right text-xs md:text-sm">کد مسیر</th>
<th class="p-2 md:p-3 text-right text-xs md:text-sm">زمان رسیدن (دقیقه)</th>
</tr>
</thead>
<tbody>
{% for next_station in next_stations_eta[:4] %}
<tr class="border-b border-gray-700 hover:bg-gray-800">
<td class="p-2 md:p-3 text-xs md:text-sm">{{ next_station.code }}</td>
<td class="p-2 md:p-3 text-xs md:text-sm">{{ next_station.name }}</td>
<td class="p-2 md:p-3 text-xs md:text-sm">
{% for eta in next_station.eta %}
{{ eta.route_code }}{% if not loop.last %}, {% endif %}
{% endfor %}
</td>
<td class="p-2 md:p-3 text-xs md:text-sm">
{% for eta in next_station.eta %}
{{ eta.eta }}{% if not loop.last %}, {% endif %}
{% endfor %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
<h3 class="text-xl md:text-2xl font-semibold mb-3">نمودار ارتباط ایستگاه‌ها:</h3>
<p class="text-gray-400 mb-4 text-sm md:text-base">این نمودار ارتباط ایستگاه فعلی را با ایستگاه‌های قبلی و بعدی نشان می‌دهد.</p>
<div id="cy" class="mb-6"></div>
<div id="station-details" class="mt-6">
<h3 class="text-xl md:text-2xl font-semibold mb-3">جزئیات ایستگاه‌ها:</h3>
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4">
{% if previous_station %}
<div class="bg-gray-800 p-4 rounded-lg">
<h4 class="text-lg md:text-xl font-semibold mb-2">ایستگاه قبلی</h4>
<p class="text-sm md:text-base"><strong>نام:</strong> {{ previous_station.name }}</p>
<p class="text-sm md:text-base"><strong>کد:</strong> {{ previous_station.code }}</p>
<p class="text-sm md:text-base"><strong>فاصله:</strong> {{ previous_station.distance }} متر</p>
</div>
{% endif %}
<div class="bg-gray-800 p-4 rounded-lg">
<h4 class="text-lg md:text-xl font-semibold mb-2">ایستگاه فعلی</h4>
<p class="text-sm md:text-base"><strong>نام:</strong> {{ station_name }}</p>
<p class="text-sm md:text-base"><strong>کد:</strong> {{ station_id }}</p>
<p class="text-sm md:text-base"><strong>جهت:</strong> {{ 'رفت' if direction == '76' else 'برگشت' }}</p>
</div>
{% for next_station in next_stations_eta[:4] %}
<div class="bg-gray-800 p-4 rounded-lg">
<h4 class="text-lg md:text-xl font-semibold mb-2">ایستگاه بعدی {{ loop.index }}</h4>
<p class="text-sm md:text-base"><strong>نام:</strong> {{ next_station.name }}</p>
<p class="text-sm md:text-base"><strong>کد:</strong> {{ next_station.code }}</p>
<p class="text-sm md:text-base"><strong>فاصله:</strong> {{ next_station.distance }} متر</p>
<p class="text-sm md:text-base"><strong>زمان رسیدن:</strong>
{% for eta in next_station.eta %}
{{ eta.eta }} دقیقه ({{ eta.route_code }}){% if not loop.last %}, {% endif %}
{% endfor %}
</p>
</div>
{% endfor %}
</div>
</div>
<div class="flex justify-between mb-6 mt-6">
{% if previous_station %}
<a href="{{ url_for('station_info', station_id=previous_station['code'], direction=direction) }}" class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded transition duration-300 ease-in-out transform hover:scale-105 text-sm md:text-base">ایستگاه قبلی</a>
{% endif %}
{% if next_station %}
<a href="{{ url_for('station_info', station_id=next_station['code'], direction=direction) }}" class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded transition duration-300 ease-in-out transform hover:scale-105 text-sm md:text-base">ایستگاه بعدی</a>
{% endif %}
</div>
</div>
<script>
(function() {
let cy;
let updateTimer;
let countdownTimer;
const UPDATE_INTERVAL = 60000;
function updateTime() {
const now = new Date();
const receivedAt = now.toLocaleString('fa-IR', { timeZone: 'Asia/Tehran' });
const dataInfoElement = document.getElementById('dataInfo');
dataInfoElement.textContent = 'اطلاعات دریافت شده در: ' + receivedAt;
dataInfoElement.classList.add('animate-pulse');
setTimeout(() => dataInfoElement.classList.remove('animate-pulse'), 1000);
}
function updateCountdown(seconds) {
const countdown = document.getElementById('countdown');
clearInterval(countdownTimer);
countdownTimer = setInterval(function() {
countdown.textContent = `بروزرسانی بعدی در ${seconds} ثانیه`;
seconds--;
if (seconds < 0) {
clearInterval(countdownTimer);
}
}, 1000);
}
function updateContent() {
clearTimeout(updateTimer);
fetch(window.location.href)
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.text();
})
.then(html => {
const parser = new DOMParser();
const doc = parser.parseFromString(html, 'text/html');
const newContent = doc.getElementById('station-info').innerHTML;
const currentContent = document.getElementById('station-info');
const cyDiv = currentContent.querySelector('#cy');
currentContent.innerHTML = newContent;
currentContent.querySelector('#cy').replaceWith(cyDiv);
updateTime();
initializeCytoscape();
})
.catch(error => {
console.error('Error:', error);
updateTime();
})
.finally(() => {
updateCountdown(60);
updateTimer = setTimeout(updateContent, UPDATE_INTERVAL);
});
}
function initializeCytoscape() {
if (cy) {
cy.destroy();
}
const stations = [
{% if previous_station %}
{ id: 'previous', label: '{{ previous_station.name }}' },
{% endif %}
{ id: 'current', label: '{{ station_name }}' },
{% for next_station in next_stations_eta[:4] %}
{ id: '{{ next_station.code }}', label: '{{ next_station.name }}' },
{% endfor %}
];
cy = cytoscape({
container: document.getElementById('cy'),
elements: stations.map((station, index) => ({
data: { id: station.id, label: station.label }
})).concat(stations.slice(1).map((station, index) => ({
data: { id: `e${index}`, source: stations[index].id, target: station.id }
}))),
style: [
{
selector: 'node',
style: {
'background-color': '#4299e1',
'label': 'data(label)',
'color': '#ffffff',
'text-valign': 'center',
'text-halign': 'center',
'text-wrap': 'wrap',
'text-max-width': '80px',
'font-size': '12px',
'width': '80px',
'height': '80px'
}
},
{
selector: 'edge',
style: {
'width': 2,
'line-color': '#63b3ed',
'curve-style': 'straight',
'target-arrow-shape': 'triangle',
'target-arrow-color': '#63b3ed',
'arrow-scale': 1.2
}
},
{
selector: '#current',
style: {
'background-color': '#48bb78',
'width': '100px',
'height': '100px',
'font-size': '14px',
'font-weight': 'bold'
}
},
{
selector: '#previous',
style: {
'background-color': '#ed8936'
}
}
],
layout: {
name: 'grid',
rows: 1
},
userZoomingEnabled: false,
userPanningEnabled: false,
boxSelectionEnabled: false,
autoungrabify: true,
autounselectify: true
});
cy.fit();
}
document.addEventListener('DOMContentLoaded', function() {
updateTime();
updateCountdown(60);
initializeCytoscape();
updateTimer = setTimeout(updateContent, UPDATE_INTERVAL);
});
window.addEventListener('resize', function() {
if (cy) {
cy.fit();
}
});
})();
</script>
</body>
</html>