300 lines
13 KiB
PHP
300 lines
13 KiB
PHP
<?php include 'header.php'; ?>
|
|
<?php include 'hero.php'; ?>
|
|
|
|
<div class="container">
|
|
<form action="index.php" method="get" id="filter-form">
|
|
<!-- Hidden search field to persist search query -->
|
|
<input type="hidden" name="search" value="<?= isset($_GET['search']) ? htmlspecialchars($_GET['search']) : '' ?>">
|
|
|
|
<h2 class="page-title">Explore Cuisines</h2>
|
|
<div class="cuisine-carousel">
|
|
<?php
|
|
$cuisine_stmt = db()->query("SELECT * FROM cuisines ORDER BY name");
|
|
$all_cuisines = $cuisine_stmt->fetchAll(PDO::FETCH_ASSOC);
|
|
$selected_cuisines = isset($_GET['cuisines']) && is_array($_GET['cuisines']) ? $_GET['cuisines'] : [];
|
|
|
|
foreach ($all_cuisines as $cuisine): ?>
|
|
<div class="cuisine-card">
|
|
<input type="checkbox" name="cuisines[]" value="<?= $cuisine['id'] ?>" id="cuisine-<?= $cuisine['id'] ?>" <?= in_array($cuisine['id'], $selected_cuisines) ? 'checked' : '' ?> onchange="this.form.submit()">
|
|
<label for="cuisine-<?= $cuisine['id'] ?>">
|
|
<?= htmlspecialchars($cuisine['name']) ?>
|
|
</label>
|
|
</div>
|
|
<?php endforeach; ?>
|
|
</div>
|
|
|
|
<div class="filter-bar-new">
|
|
<div class="form-group">
|
|
<label for="min_rating">Rating</label>
|
|
<select name="min_rating" id="min_rating" class="form-control" onchange="this.form.submit()">
|
|
<option value="">Any</option>
|
|
<option value="4" <?= isset($_GET['min_rating']) && $_GET['min_rating'] == 4 ? 'selected' : '' ?>>4+ stars</option>
|
|
<option value="3" <?= isset($_GET['min_rating']) && $_GET['min_rating'] == 3 ? 'selected' : '' ?>>3+ stars</option>
|
|
<option value="2" <?= isset($_GET['min_rating']) && $_GET['min_rating'] == 2 ? 'selected' : '' ?>>2+ stars</option>
|
|
<option value="1" <?= isset($_GET['min_rating']) && $_GET['min_rating'] == 1 ? 'selected' : '' ?>>1+ star</option>
|
|
</select>
|
|
</div>
|
|
<div class="form-check">
|
|
<input class="form-check-input" type="checkbox" name="open_now" value="1" id="open-now" <?= isset($_GET['open_now']) ? 'checked' : '' ?> onchange="this.form.submit()">
|
|
<label class="form-check-label" for="open-now">
|
|
Open Now
|
|
</label>
|
|
</div>
|
|
<a href="index.php" class="btn btn-secondary">Clear Filters</a>
|
|
</div>
|
|
</form>
|
|
|
|
<h2 class="page-title mt-4">All Restaurants</h2>
|
|
<section class="restaurant-list">
|
|
<div class="restaurant-grid" id="restaurant-grid">
|
|
<?php
|
|
// Base query
|
|
$sql = "SELECT DISTINCT r.id, r.name, r.image_url, r.opening_time, r.closing_time, r.days_open, AVG(rt.rating) as average_rating, COUNT(rt.id) as rating_count
|
|
FROM restaurants r
|
|
LEFT JOIN ratings rt ON r.id = rt.restaurant_id";
|
|
$params = [];
|
|
|
|
// Join with restaurant_cuisines if filtering by cuisine
|
|
if (!empty($selected_cuisines)) {
|
|
$sql .= " JOIN restaurant_cuisines rc ON r.id = rc.restaurant_id";
|
|
}
|
|
|
|
$where_clauses = [];
|
|
|
|
// Append search condition
|
|
if (!empty($_GET['search'])) {
|
|
$where_clauses[] = "r.name LIKE ?";
|
|
$params[] = '%' . $_GET['search'] . '%';
|
|
}
|
|
|
|
// Append cuisine filter
|
|
if (!empty($selected_cuisines)) {
|
|
$placeholders = implode(',', array_fill(0, count($selected_cuisines), '?'));
|
|
$where_clauses[] = "rc.cuisine_id IN ($placeholders)";
|
|
$params = array_merge($params, $selected_cuisines);
|
|
}
|
|
|
|
// Append "Open Now" filter
|
|
if (isset($_GET['open_now'])) {
|
|
$current_time = date('H:i:s');
|
|
$current_day = date('D'); // Mon, Tue, etc.
|
|
$where_clauses[] = "r.opening_time <= ? AND r.closing_time >= ? AND r.days_open LIKE ?";
|
|
$params[] = $current_time;
|
|
$params[] = $current_time;
|
|
$params[] = '%' . $current_day . '%';
|
|
}
|
|
|
|
|
|
if (!empty($where_clauses)) {
|
|
$sql .= " WHERE " . implode(' AND ', $where_clauses);
|
|
}
|
|
|
|
$sql .= " GROUP BY r.id, r.name, r.image_url, r.opening_time, r.closing_time, r.days_open";
|
|
|
|
// Add rating filter (HAVING clause)
|
|
$selected_min_rating = isset($_GET['min_rating']) && is_numeric($_GET['min_rating']) ? (int)$_GET['min_rating'] : 0;
|
|
if ($selected_min_rating > 0) {
|
|
$sql .= " HAVING AVG(rt.rating) >= ?";
|
|
$params[] = $selected_min_rating;
|
|
}
|
|
|
|
$sql .= " ORDER BY r.name";
|
|
|
|
$stmt = db()->prepare($sql);
|
|
$stmt->execute($params);
|
|
$restaurants = $stmt->fetchAll();
|
|
|
|
if (empty($restaurants)) {
|
|
echo '<p>No restaurants found matching your criteria.</p>';
|
|
} else {
|
|
foreach ($restaurants as $restaurant) {
|
|
// Get cuisines for this restaurant
|
|
$cuisine_sql = "SELECT c.name FROM cuisines c JOIN restaurant_cuisines rc ON c.id = rc.cuisine_id WHERE rc.restaurant_id = ?";
|
|
$cuisine_stmt = db()->prepare($cuisine_sql);
|
|
$cuisine_stmt->execute([$restaurant['id']]);
|
|
$restaurant_cuisines_list = $cuisine_stmt->fetchAll(PDO::FETCH_COLUMN);
|
|
|
|
echo '<a href="menu.php?restaurant_id=' . htmlspecialchars($restaurant['id']) . '" class="restaurant-card">';
|
|
echo '<img src="' . htmlspecialchars($restaurant['image_url'] ? $restaurant['image_url'] : 'assets/images/hero.jpg') . '" alt="' . htmlspecialchars($restaurant['name']) . '">';
|
|
echo '<div class="restaurant-card-content">';
|
|
echo '<h3>' . htmlspecialchars($restaurant['name']) . '</h3>';
|
|
echo '<p>' . htmlspecialchars(implode(', ', $restaurant_cuisines_list)) . '</p>';
|
|
echo '<div class="restaurant-info">';
|
|
if ($restaurant['rating_count'] > 0) {
|
|
echo '<div class="rating-display">';
|
|
echo '<span class="star">★</span>';
|
|
echo '<span>' . htmlspecialchars(number_format($restaurant['average_rating'], 1)) . '</span>';
|
|
echo '</div>';
|
|
} else {
|
|
echo '<div class="rating-display"><span class="rating-count">No ratings yet</span></div>';
|
|
}
|
|
echo '</div>';
|
|
echo '</div>';
|
|
echo '</a>';
|
|
}
|
|
}
|
|
?>
|
|
</div>
|
|
</section>
|
|
</div>
|
|
</main>
|
|
|
|
|
|
<div id="map-modal" class="modal">
|
|
<div class="modal-content">
|
|
<span class="close-button">×</span>
|
|
<h2>Pin Your Location</h2>
|
|
<div id="map" style="height: 400px;"></div>
|
|
<p id="map-message"></p>
|
|
<button id="confirm-location-button">Confirm Location</button>
|
|
<button id="cancel-location-button">Cancel</button>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
const pinLocationButton = document.getElementById('pin-location');
|
|
const myLocationButton = document.getElementById('my-location');
|
|
const locationActions = document.querySelector('.location-actions');
|
|
const addressDisplay = document.getElementById('address-display');
|
|
|
|
const mapModal = document.getElementById('map-modal');
|
|
const closeModalButton = mapModal.querySelector('.close-button');
|
|
const confirmLocationButton = document.getElementById('confirm-location-button');
|
|
const cancelLocationButton = document.getElementById('cancel-location-button');
|
|
const mapMessage = document.getElementById('map-message');
|
|
|
|
let map;
|
|
let marker;
|
|
|
|
const majuroBounds = {
|
|
minLat: 7.05,
|
|
maxLat: 7.15,
|
|
minLng: 171.17,
|
|
maxLng: 171.39
|
|
};
|
|
|
|
function isWithinMajuro(lat, lng) {
|
|
return lat >= majuroBounds.minLat && lat <= majuroBounds.maxLat &&
|
|
lng >= majuroBounds.minLng && lng <= majuroBounds.maxLng;
|
|
}
|
|
|
|
function openMapModal(lat, lng) {
|
|
mapModal.style.display = 'block';
|
|
if (!map) {
|
|
map = L.map('map').setView([7.09, 171.28], 12);
|
|
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
|
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
|
|
}).addTo(map);
|
|
}
|
|
map.setView([lat, lng], 14);
|
|
if (marker) {
|
|
marker.setLatLng([lat, lng]);
|
|
} else {
|
|
marker = L.marker([lat, lng], { draggable: true }).addTo(map);
|
|
}
|
|
mapMessage.textContent = '';
|
|
}
|
|
|
|
function closeMapModal() {
|
|
mapModal.style.display = 'none';
|
|
}
|
|
|
|
pinLocationButton.addEventListener('click', function() {
|
|
openMapModal(7.09, 171.28);
|
|
});
|
|
|
|
myLocationButton.addEventListener('click', function() {
|
|
if (navigator.geolocation) {
|
|
navigator.geolocation.getCurrentPosition(function(position) {
|
|
const lat = position.coords.latitude;
|
|
const lng = position.coords.longitude;
|
|
if (isWithinMajuro(lat, lng)) {
|
|
saveLocation(lat, lng);
|
|
} else {
|
|
alert('Sorry, we do not offer services for your current location.');
|
|
}
|
|
}, function() {
|
|
alert('Could not get your location.');
|
|
});
|
|
} else {
|
|
alert('Geolocation is not supported by your browser.');
|
|
}
|
|
});
|
|
|
|
closeModalButton.addEventListener('click', closeMapModal);
|
|
cancelLocationButton.addEventListener('click', closeMapModal);
|
|
|
|
confirmLocationButton.addEventListener('click', function() {
|
|
const latlng = marker.getLatLng();
|
|
if (isWithinMajuro(latlng.lat, latlng.lng)) {
|
|
saveLocation(latlng.lat, latlng.lng);
|
|
} else {
|
|
mapMessage.textContent = 'Sorry, we do not offer services for the location you pinned. Please select a location within Majuro (Rita-Laura).';
|
|
mapMessage.style.color = 'red';
|
|
}
|
|
});
|
|
|
|
function saveLocation(lat, lng) {
|
|
fetch('api/save_location.php', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json'
|
|
},
|
|
body: JSON.stringify({ lat: lat, lng: lng })
|
|
})
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
if (data.success) {
|
|
updateLocationUI(lat, lng);
|
|
closeMapModal();
|
|
} else {
|
|
alert(data.message || 'Could not save location.');
|
|
}
|
|
});
|
|
}
|
|
|
|
function updateLocationUI(lat, lng) {
|
|
locationActions.innerHTML = `
|
|
<div class="pinned-location">
|
|
<span>Pinned: ${lat.toFixed(4)}, ${lng.toFixed(4)}</span>
|
|
<button id="change-location">Change</button>
|
|
</div>
|
|
`;
|
|
addressDisplay.textContent = `Delivery to: ${lat.toFixed(4)}, ${lng.toFixed(4)}`;
|
|
document.getElementById('change-location').addEventListener('click', function() {
|
|
locationActions.innerHTML = `
|
|
<button class="location-button" id="pin-location">Pin a Location</button>
|
|
<button class="location-button" id="my-location">My Location</button>
|
|
`;
|
|
// Re-add event listeners
|
|
document.getElementById('pin-location').addEventListener('click', function() { openMapModal(7.09, 171.28); });
|
|
document.getElementById('my-location').addEventListener('click', function() {
|
|
if (navigator.geolocation) {
|
|
navigator.geolocation.getCurrentPosition(function(position) {
|
|
const lat = position.coords.latitude;
|
|
const lng = position.coords.longitude;
|
|
if (isWithinMajuro(lat, lng)) {
|
|
saveLocation(lat, lng);
|
|
} else {
|
|
alert('Sorry, we do not offer services for your current location.');
|
|
}
|
|
}, function() {
|
|
alert('Could not get your location.');
|
|
});
|
|
} else {
|
|
alert('Geolocation is not supported by your browser.');
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
// On page load, check if location is in session
|
|
<?php if (isset($_SESSION['delivery_location'])):
|
|
updateLocationUI(<?php echo $_SESSION['delivery_location']['lat']; ?>, <?php echo $_SESSION['delivery_location']['lng']; ?>);
|
|
<?php endif; ?>
|
|
});
|
|
</script>
|
|
|
|
<?php include 'footer.php'; ?>
|