34968-vm/index.php
Flatlogic Bot 7a0a2165fc V12
2025-10-15 14:58:19 +00:00

304 lines
14 KiB
PHP

<?php include 'header.php'; ?>
<main>
<section class="hero">
<div class="hero-content">
<h1>Order from Majuro's best</h1>
<form action="index.php" method="get" class="search-form">
<input type="text" name="search" class="search-bar" placeholder="Search for restaurants..." value="<?= isset($_GET['search']) ? htmlspecialchars($_GET['search']) : '' ?>">
<button type="submit" class="search-button">Search</button>
</form>
<div class="location-actions">
<button class="location-button" id="pin-location">Pin a Location</button>
<button class="location-button" id="my-location">My Location</button>
</div>
</div>
</section>
<div class="container">
<div class="row">
<!-- Filter Sidebar -->
<div class="col-md-3">
<h4>Filter Results</h4>
<form action="index.php" method="get" id="filter-form">
<!-- Hidden search field to persist search query -->
<?php if (isset($_GET['search'])):
<input type="hidden" name="search" value="<?= htmlspecialchars($_GET['search']) ?>">
<?php endif; ?>
<h5>By Cuisine</h5>
<?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="form-check">
<input class="form-check-input" type="checkbox" name="cuisines[]" value="<?= $cuisine['id'] ?>" id="cuisine-<?= $cuisine['id'] ?>" <?= in_array($cuisine['id'], $selected_cuisines) ? 'checked' : '' ?>>
<label class="form-check-label" for="cuisine-<?= $cuisine['id'] ?>">
<?= htmlspecialchars($cuisine['name']) ?>
</label>
</div>
<?php endforeach; ?>
<h5 class="mt-4">By Rating</h5>
<div class="form-group">
<select name="min_rating" class="form-control">
<option value="">Any Rating</option>
<option value="4" <?= isset($_GET['min_rating']) && $_GET['min_rating'] == 4 ? 'selected' : '' ?>>4 stars & up</option>
<option value="3" <?= isset($_GET['min_rating']) && $_GET['min_rating'] == 3 ? 'selected' : '' ?>>3 stars & up</option>
<option value="2" <?= isset($_GET['min_rating']) && $_GET['min_rating'] == 2 ? 'selected' : '' ?>>2 stars & up</option>
<option value="1" <?= isset($_GET['min_rating']) && $_GET['min_rating'] == 1 ? 'selected' : '' ?>>1 star & up</option>
</select>
</div>
<button type="submit" class="btn btn-primary mt-3">Apply Filters</button>
<a href="index.php" class="btn btn-secondary mt-3">Clear Filters</a>
</form>
</div>
<!-- Restaurant Listing -->
<div class="col-md-9">
<h2 class="page-title">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, 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);
}
if (!empty($where_clauses)) {
$sql .= " WHERE " . implode(' AND ', $where_clauses);
}
$sql .= " GROUP BY r.id, r.name, r.image_url";
// 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>';
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 '<span class="rating-count">(' . htmlspecialchars($restaurant['rating_count']) . ' ratings)</span>';
echo '</div>';
} else {
echo '<div class="rating-display"><span class="rating-count">No ratings yet</span></div>';
}
echo '</div>';
echo '</a>';
}
}
?>
</div>
</section>
</div>
</div>
</div>
</main>
<div id="map-modal" class="modal">
<div class="modal-content">
<span class="close-button">&times;</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: '&copy; <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'; ?>