<?php
include 'includes/db.php';
include 'includes/header.php';
// Fetch branches from DB
$branches_result = $conn->query("SELECT * FROM branches WHERE lat IS NOT NULL AND lng IS NOT NULL");
$branches_data = [];
while($row = $branches_result->fetch_assoc()) {
$branches_data[] = $row;
}
?>
<style>
#map {
height: 600px;
border-radius: 15px;
border: 2px solid var(--border-color);
}
.branch-list .list-group-item {
background-color: rgba(0,0,0,0.2);
border: 1px solid var(--border-color);
color: white;
cursor: pointer;
transition: all 0.3s ease;
}
.branch-list .list-group-item:hover, .branch-list .list-group-item.active {
background-color: var(--primary-color);
border-color: var(--primary-color);
}
</style>
<main class="container my-5 pt-5">
<div class="text-center mb-5">
<h2 data-aos="fade-in">فروعنا</h2>
<p data-aos="fade-in" data-aos-delay="100" class="text-muted">ابحث عن الفرع الأقرب إليك أو تصفح قائمتنا.</p>
<button id="find-nearest" class="btn btn-danger"><i class="fas fa-location-arrow me-2"></i>البحث عن أقرب فرع</button>
</div>
<div class="row g-4">
<!-- Map -->
<div class="col-lg-8" data-aos="fade-left">
<div id="map"></div>
</div>
<!-- Branch List -->
<div class="col-lg-4" data-aos="fade-right">
<div class="glass-card p-3" style="max-height: 600px; overflow-y: auto;">
<h4>قائمة الفروع</h4>
<div id="branch-list" class="list-group branch-list mt-3">
<?php if (count($branches_data) > 0): ?>
<?php foreach ($branches_data as $branch): ?>
<div class="list-group-item" data-lat="<?= $branch['lat'] ?>" data-lng="<?= $branch['lng'] ?>" data-branch-id="<?= $branch['id'] ?>">
<div class="d-flex w-100 justify-content-between">
<h5 class="mb-1"><?= htmlspecialchars($branch['name']) ?></h5>
</div>
<p class="mb-1"><?= htmlspecialchars($branch['address']) ?></p>
<small class="d-block mb-2"><i class="fas fa-phone me-2"></i><?= htmlspecialchars($branch['phone']) ?></small>
<!-- Action Buttons -->
<div class="d-flex gap-2 mt-2">
<button class="btn btn-primary btn-sm book-visit-btn" data-branch-id="<?= $branch['id'] ?>" data-branch-name="<?= htmlspecialchars($branch['name']) ?>">
<i class="fas fa-calendar-plus me-1"></i>حجز زيارة
</button>
<button class="btn btn-success btn-sm directions-btn" data-lat="<?= $branch['lat'] ?>" data-lng="<?= $branch['lng'] ?>" data-branch-name="<?= htmlspecialchars($branch['name']) ?>">
<i class="fas fa-directions me-1"></i>الاتجاهات
</button>
</div>
</div>
<?php endforeach; ?>
<?php else: ?>
<p class="text-center">لم يتم إضافة فروع بعد.</p>
<?php endif; ?>
</div>
</div>
</div>
</div>
</main>
<?php include 'includes/footer.php'; ?>
<script>
// 1. Initialize Map
const map = L.map('map').setView([30.0444, 31.2357], 12); // Default to Cairo
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map);
// 2. Get branch data from PHP
const branches = <?= json_encode($branches_data) ?>;
const markers = [];
// 3. Add markers to map
branches.forEach(branch => {
const marker = L.marker([branch.lat, branch.lng]).addTo(map)
.bindPopup(`<b>${branch.name}</b><br>${branch.address}`);
markers.push({ id: branch.id, marker: marker });
});
// 4. Handle clicks on branch list
document.querySelectorAll('.branch-list .list-group-item').forEach(item => {
item.addEventListener('click', function() {
const lat = this.getAttribute('data-lat');
const lng = this.getAttribute('data-lng');
map.flyTo([lat, lng], 15);
// Highlight active item
document.querySelectorAll('.branch-list .list-group-item').forEach(i => i.classList.remove('active'));
this.classList.add('active');
});
});
// 5. Geolocation
document.getElementById('find-nearest').addEventListener('click', function() {
navigator.geolocation.getCurrentPosition(findNearestBranch, handleLocationError);
});
function findNearestBranch(position) {
const userLat = position.coords.latitude;
const userLng = position.coords.longitude;
// Add a marker for user's location
L.marker([userLat, userLng], { icon: L.icon({ iconUrl: 'https://raw.githubusercontent.com/pointhi/leaflet-color-markers/master/img/marker-icon-2x-blue.png', shadowUrl: 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.7/images/marker-shadow.png', iconSize: [25, 41], iconAnchor: [12, 41], popupAnchor: [1, -34], shadowSize: [41, 41] }) }).addTo(map)
.bindPopup('موقعك الحالي').openPopup();
let nearestBranch = null;
let minDistance = Infinity;
branches.forEach(branch => {
const distance = getDistance(userLat, userLng, branch.lat, branch.lng);
if (distance < minDistance) {
minDistance = distance;
nearestBranch = branch;
}
});
if (nearestBranch) {
map.flyTo([nearestBranch.lat, nearestBranch.lng], 14);
// Find and trigger click on the nearest branch in the list
const nearestItem = document.querySelector(`.branch-list .list-group-item[data-lat='${nearestBranch.lat}']`);
if(nearestItem) nearestItem.click();
Swal.fire({
title: 'أقرب فرع لك',
text: `فرع "${nearestBranch.name}" هو الأقرب إليك.`,
icon: 'info',
confirmButtonText: 'حسناً',
background: '#333',
color: '#fff'
});
}
}
function handleLocationError(error) {
let errorMessage = 'لا يمكن الوصول إلى موقعك. يرجى التأكد من تفعيل خدمات الموقع في متصفحك.';
// Check if the error is due to an insecure connection
if (window.isSecureContext === false) {
errorMessage = 'ميزة تحديد الموقع تتطلب اتصالاً آمناً (HTTPS). قد لا تعمل هذه الميزة على الخوادم المحلية (HTTP).';
} else if (error.code === error.PERMISSION_DENIED) {
errorMessage = 'لقد رفضت الإذن بالوصول إلى موقعك. يرجى تفعيل الإذن من إعدادات المتصفح.';
}
Swal.fire('خطأ في تحديد الموقع', errorMessage, 'error');
}
// Haversine formula to calculate distance
function getDistance(lat1, lon1, lat2, lon2) {
const R = 6371; // Radius of the earth in km
const dLat = deg2rad(lat2 - lat1);
const dLon = deg2rad(lon2 - lon1);
const a =
Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) *
Math.sin(dLon / 2) * Math.sin(dLon / 2);
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
return R * c; // Distance in km
}
function deg2rad(deg) {
return deg * (Math.PI / 180);
}
// Handle book visit buttons
document.addEventListener('click', function(e) {
if (e.target.closest('.book-visit-btn')) {
const btn = e.target.closest('.book-visit-btn');
const branchId = btn.getAttribute('data-branch-id');
const branchName = btn.getAttribute('data-branch-name');
// Redirect to visit booking page with branch pre-selected
window.location.href = `visit.php?branch_id=${branchId}&branch_name=${encodeURIComponent(branchName)}`;
}
});
// Handle directions buttons
document.addEventListener('click', function(e) {
if (e.target.closest('.directions-btn')) {
const btn = e.target.closest('.directions-btn');
const lat = btn.getAttribute('data-lat');
const lng = btn.getAttribute('data-lng');
const branchName = btn.getAttribute('data-branch-name');
// Check if user wants to use current location
if (navigator.geolocation) {
Swal.fire({
title: 'الحصول على الاتجاهات',
text: `هل تريد الحصول على الاتجاهات إلى ${branchName}؟`,
icon: 'question',
showCancelButton: true,
confirmButtonText: 'نعم، احصل على الاتجاهات',
cancelButtonText: 'إلغاء',
background: '#333',
color: '#fff'
}).then((result) => {
if (result.isConfirmed) {
navigator.geolocation.getCurrentPosition(
function(position) {
const userLat = position.coords.latitude;
const userLng = position.coords.longitude;
// Open Google Maps with directions
const googleMapsUrl = `https://www.google.com/maps/dir/${userLat},${userLng}/${lat},${lng}`;
window.open(googleMapsUrl, '_blank');
},
function() {
// If geolocation fails, just open the branch location
const googleMapsUrl = `https://www.google.com/maps/search/?api=1&query=${lat},${lng}`;
window.open(googleMapsUrl, '_blank');
}
);
}
});
} else {
// If geolocation is not supported, just open the branch location
const googleMapsUrl = `https://www.google.com/maps/search/?api=1&query=${lat},${lng}`;
window.open(googleMapsUrl, '_blank');
}
}
});
// Prevent event bubbling for buttons inside list items
document.addEventListener('click', function(e) {
if (e.target.closest('.book-visit-btn') || e.target.closest('.directions-btn')) {
e.stopPropagation();
}
});
</script>