Add initial implementation of Schoolkantine project with configuration, order handling, and styling

This commit is contained in:
vista-man
2025-03-07 02:04:48 +01:00
parent 470ba84655
commit 86921596fc
94 changed files with 1349 additions and 0 deletions

View File

@@ -0,0 +1 @@
# Schoolkantine

View File

@@ -0,0 +1,49 @@
body {
font-family: Arial, sans-serif;
text-align: center;
padding: 50px;
background-color: #f9f9f9;
}
h1 {
color: #F56E28;
}
p {
font-size: 1.2em;
margin-top: 20px;
}
button {
margin-top: 30px;
padding: 10px 20px;
background-color: #F56E28;
color: white;
border: none;
cursor: pointer;
font-size: 1.1em;
}
button:hover {
background-color: #F56E28;
}
/* Responsive design */
@media (max-width: 768px) {
body {
padding: 20px;
}
h1 {
font-size: 1.5em;
}
p {
font-size: 1em;
}
button {
font-size: 1em;
padding: 10px 15px;
}
}

View File

@@ -0,0 +1,31 @@
<!DOCTYPE html>
<html lang="nl">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Betaalpagina Mees</title>
<link rel="icon" href="media/favicon.ico" type="image/x-icon">
<link rel="stylesheet" href="betaal.css">
</head>
<script>
window.onload = function() {
const urlParams = new URLSearchParams(window.location.search);
const orderNumber = urlParams.get('order_number');
if (orderNumber) {
document.getElementById("order-number").innerText = `Uw Bestellings nummer = ${orderNumber}`;
} else {
document.getElementById("order-number").innerText = "Uw Bestellings nummer kon niet worden opgehaald.";
}
}
</script>
<body>
<h1>Bedankt voor uw bestelling!</h1>
<p>Uw bestelling is succesvol geplaatst. U kunt dit tabblad nu sluiten.</p>
<button onclick="window.close()">Sluit dit tabblad</button>
<h1 id="order-number">Uw Bestellings nummer = </h1>
</body>
</html>

View File

@@ -0,0 +1,35 @@
<?php
include 'config.php';
// Set header to JSON
header('Content-Type: application/json');
// Get the POST data
$data = json_decode(file_get_contents('php://input'), true);
$order_number = $data['order_number'] ?? '';
if (empty($order_number)) {
echo json_encode(['success' => false, 'message' => 'Order number is required']);
exit;
}
// Delete the order from the database
$sql = "DELETE FROM orders WHERE order_number = ?";
$stmt = $conn->prepare($sql);
if ($stmt === false) {
error_log("Failed to prepare statement: " . $conn->error);
echo json_encode(['success' => false, 'message' => 'Failed to prepare statement']);
exit;
}
$stmt->bind_param("s", $order_number);
if ($stmt->execute()) {
echo json_encode(['success' => true]);
} else {
error_log("Failed to execute statement: " . $stmt->error);
echo json_encode(['success' => false, 'message' => 'Failed to execute statement']);
}
$stmt->close();
$conn->close();
?>

View File

@@ -0,0 +1,14 @@
<?php
$servername = "localhost:3306";
$username = "database";
$password = "13cAv?i52";
$dbname = "schoolkantine";
// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
?>

View File

@@ -0,0 +1,54 @@
<?php
// Disable error output to avoid unwanted characters in the JSON response
ini_set('display_errors', 0);
error_reporting(0);
ob_start(); // Start output buffering
include "config.php";
include "database.inc.php";
// Set header to JSON
header('Content-Type: application/json');
$category = $_GET['category'] ?? '';
if (empty($category)) {
error_log("Category is required");
echo json_encode(['error' => 'Category is required']);
exit;
}
$sql = "SELECT * FROM items WHERE category = ?";
$stmt = $conn->prepare($sql);
if ($stmt === false) {
error_log("Failed to prepare statement: " . $conn->error);
echo json_encode(['error' => 'Failed to prepare statement']);
exit;
}
$stmt->bind_param("s", $category);
$stmt->execute();
$result = $stmt->get_result();
$items = [];
while ($row = $result->fetch_assoc()) {
$items[] = [
'title' => $row['title'],
'imageSrc' => $row['imageSrc'],
'price' => (float)$row['price'], // Ensure price is a number
'description' => $row['description'] // Include description
];
}
if (empty($items)) {
error_log("No items found for category: " . $category);
}
// Clean any buffered output (whitespace, etc.)
ob_clean();
echo json_encode($items);
$stmt->close();
$conn->close();
ob_end_flush();
?>

View File

@@ -0,0 +1,27 @@
<?php
include 'config.php';
// Set header to JSON
header('Content-Type: application/json');
// Fetch orders from the database
$sql = "SELECT order_number, items, total_price, order_time FROM orders ORDER BY order_time DESC";
$result = $conn->query($sql);
if ($result === false) {
error_log("Failed to fetch orders: " . $conn->error);
echo json_encode(['error' => 'Failed to fetch orders']);
exit;
}
$orders = [];
while ($row = $result->fetch_assoc()) {
$row['items'] = json_decode($row['items'], true); // Decode the JSON items
$row['total_price'] = (float)$row['total_price']; // Ensure total_price is a number
$orders[] = $row;
}
echo json_encode($orders);
$conn->close();
?>

View File

@@ -0,0 +1,78 @@
<!DOCTYPE html>
<html lang="nl">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Het hoofdmenu van de Mees</title>
<link rel="stylesheet" href="style.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
<link rel="icon" href="media/favicon.ico" type="image/x-icon">
</head>
<body>
<!-- Logo -->
<img src="media/logo.png" alt="Logo" class="logo">
<!-- Top bar menu -->
<div class="menu-bar">
<div class="menu-item" onclick="showCategory('Broodjes')" data-translate="Broodjes">Broodjes</div>
<div class="menu-item" onclick="showCategory('Koude-Dranken')" data-translate="Koude Dranken">Koude Dranken</div>
<div class="menu-item" onclick="showCategory('Warme-Dranken')" data-translate="Warme Dranken">Warme Dranken</div>
<div class="menu-item" onclick="showCategory('Snacks')" data-translate="Snacks">Snacks</div>
<div class="menu-item" onclick="showCategory('Desserts')" data-translate="Desserts">Desserts</div>
<div class="menu-item" onclick="showCategory('Deals')" data-translate="Deals">Deals</div>
<div class="menu-item" onclick="showCategory('Soepen')" data-translate="Soepen">Soepen</div>
<div class="menu-item" onclick="showCategory('Salades')" data-translate="Salades">Salades</div>
<div class="menu-item" onclick="showCategory('Sausjes')" data-translate="Sausjes">Sausjes</div>
<div class="menu-item" onclick="showCategory('Yoghurt')" data-translate="Yoghurt">Yoghurt</div>
<div class="menu-item" onclick="showCategory('Snoep')" data-translate="Snoep">Snoep</div>
<div class="menu-item" onclick="showCategory('Overige')" data-translate="Overige">Overige</div>
</div>
<!-- Product display area -->
<div id="product-display" class="product-display">
<!-- Products will be inserted dynamically -->
</div>
<!-- Modal for item details -->
<div id="modal" class="modal">
<div class="modal-content">
<span class="close" onclick="closeModal()">&times;</span>
<h2 id="modal-title"></h2>
<img id="modal-image" src="" alt="">
<p id="modal-description"></p>
<p id="modal-price"></p>
<button id="add-to-cart" data-translate="Toevoegen aan winkelmandje">Toevoegen aan winkelmandje</button>
</div>
</div>
<!-- Cart section -->
<div id="cart" class="cart">
<h2 data-translate="Winkelmandje">Winkelmandje</h2>
<ul id="cart-items">
<!-- Cart items will be added here -->
</ul>
<p><span data-translate="Totaal">Totaal</span>: €<span id="total-price">0.00</span></p>
<a href="betalen.html" target="index.html">
<button id="order-button" data-translate="Bestellen">Bestellen</button>
</a>
</div>
<!-- Cart icon -->
<div class="cart-icon">
<i class="fas fa-shopping-cart"></i>
<span id="cart-count" class="cart-count">0</span> <!-- Aantal producten -->
</div>
<!-- Language switcher -->
<div id="language-switcher" class="language-switcher">EN</div>
<script src="script.js"></script>
</body>
</html>

View File

@@ -0,0 +1,3 @@
#676767
#ffffff
#F56E28

Binary file not shown.

After

Width:  |  Height:  |  Size: 892 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 840 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 375 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 369 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 935 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 441 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 719 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 468 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 135 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 812 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 514 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 368 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 328 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 189 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 182 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 526 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 479 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 645 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 644 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 167 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1017 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 431 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 141 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 562 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 657 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 429 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 208 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 208 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 105 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 309 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 279 KiB

View File

@@ -0,0 +1,42 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 24.2.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Laag_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 248 103" style="enable-background:new 0 0 248 103;" xml:space="preserve">
<g>
<g>
<g>
<g>
<g>
<path d="M139,97.5c-0.9,0.4-1.8,0.6-2.8,0.6c-3.1,0-5.1-1.9-5.1-4.9c0-3,2.1-5,5.2-5c1,0,1.8,0.2,2.8,0.6V90
c-0.9-0.5-1.7-0.7-2.7-0.7c-2.4,0-3.9,1.5-3.9,3.8c0,2.4,1.5,3.9,3.9,3.9c1,0,1.8-0.2,2.7-0.7V97.5z"/>
<path d="M146.6,97.6c0.9-2.5,2.1-5.5,3.6-8.9l0.1-0.3h1.5l0.1,0.3c1.2,2.9,2.2,5.6,3.3,8.9l0.1,0.4h-1.5l-0.1-0.2
c-0.3-0.9-0.5-1.6-1-2.9l-0.1-0.2H149l-0.1,0.2c-0.3,0.9-0.8,2.1-1,2.9l-0.1,0.2h-1.4L146.6,97.6z M152.4,93.6l-0.1-0.3
c-0.3-0.8-0.4-1.2-0.6-1.8c-0.2-0.6-0.4-1.1-0.5-1.4l-0.2-0.5l-0.2,0.5l-0.4,1c0,0.1-0.1,0.2-0.3,0.7c-0.1,0.3-0.2,0.6-0.3,0.9
c-0.1,0.4-0.2,0.5-0.3,0.7l-0.1,0.4H152.4z"/>
<path d="M165.6,89.5h-3.3v-1.1h7.8v1.1H167V98h-1.3V89.5z"/>
<path d="M178.1,88.4h5.6v1.1h-4.2v2.9h4.1v1.1h-4.1v3.3h4.3V98h-5.7V88.4z"/>
<path d="M192,88.4l0.2,0c0.7-0.1,1.6-0.1,2.2-0.1c1.2,0,2,0.2,2.7,0.6c0.7,0.5,1.1,1.2,1.1,2.1c0,0.8-0.3,1.6-0.9,2
c-0.3,0.2-0.6,0.4-1.2,0.6l0.2,0.2c0.8,1,1.5,1.9,2.4,3c0.2,0.3,0.6,0.6,0.8,0.9c0.1,0.1,0.2,0.2,0.3,0.3H198
c-0.2-0.2-0.3-0.3-0.5-0.6c-0.5-0.6-0.8-1-1.3-1.6c-0.2-0.2-0.4-0.5-0.7-0.9c-0.3-0.4-0.5-0.6-0.6-0.8l-0.1-0.2
c-0.2,0-0.4,0-0.5,0c-0.1,0-0.4,0-0.6,0h-0.2V98H192V88.4z M193.4,92.8h0.2c0.3,0.1,0.5,0.1,0.7,0.1c0.8,0,1.3-0.1,1.7-0.3
c0.5-0.3,0.8-0.8,0.8-1.5c0-1.2-0.8-1.8-2.3-1.8c-0.3,0-0.6,0-1.1,0.1V92.8z"/>
<path d="M207.3,88.4h1.3V98h-1.3V88.4z"/>
<path d="M217.3,88.4h1.3c0.3,0,0.5,0.1,0.6,0.3l4.2,6.6c0.3,0.4,0.5,0.8,0.8,1.8c-0.1-0.9-0.2-1.3-0.2-1.9v-6.8h1.3V98h-1.3
c-0.3,0-0.5-0.1-0.6-0.3l-4.2-6.7c-0.3-0.4-0.5-0.8-0.8-1.7c0.1,0.9,0.2,1.3,0.2,1.9V98h-1.3V88.4z"/>
<path d="M238.6,93.4h3.3v4.3c-1.1,0.3-2.1,0.4-3,0.4c-1.5,0-2.7-0.4-3.6-1.1c-1.1-0.9-1.7-2.3-1.7-3.8c0-3,2.1-5,5.4-5
c1,0,1.9,0.2,2.9,0.6V90c-0.9-0.5-1.8-0.7-2.8-0.7c-2.5,0-4,1.5-4,3.9c0,1.2,0.4,2.2,1.1,2.8c0.7,0.7,1.6,1,2.9,1
c0.6,0,1.1-0.1,1.6-0.1v-2.3h-2.1V93.4z"/>
</g>
</g>
</g>
<g>
<g>
<path d="M76.1,71.1H60.7V33.7h-5.1v37.4H40.2V33.7H35v37.4H19.6V19.7h25.7v9.3h5.1v-9.3h25.7V71.1z M126.9,71.1H80.7V19.7h46.2
v14H96.1v4.7h20.5v14H96.1v4.7h30.8V71.1z M177.7,71.1h-46.2V19.7h46.2v14h-30.8v4.7h20.5v14h-20.5v4.7h30.8V71.1z M228.4,71.1
h-46.2v-14H213v-4.7h-30.8V19.7h46.2v14h-30.8v4.7h30.8V71.1z"/>
<path d="M14,14.2h220v62.5H14V14.2z M5.9,84.8h236.3V6H5.9V84.8z"/>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 317 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 371 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 161 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 209 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 132 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 105 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 120 KiB

View File

@@ -0,0 +1,52 @@
body {
font-family: Arial, sans-serif;
background-color: #f9f9f9;
padding: 20px;
text-align: center;
}
h1 {
color: #F56E28;
}
.orders-container {
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: 20px;
}
.order {
background-color: white;
border: 2px solid #F56E28;
border-radius: 10px;
padding: 20px;
width: 300px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
text-align: left;
}
.order h2 {
margin-top: 0;
color: #F56E28;
}
.order p {
margin: 5px 0;
}
.order ul {
list-style-type: none;
padding: 0;
}
.order li {
margin: 5px 0;
}
/* Responsive design */
@media (max-width: 768px) {
.order {
width: 100%; /* Full width for smaller screens */
}
}

View File

@@ -0,0 +1,90 @@
<!DOCTYPE html>
<html lang="nl">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Bestellingen Overzicht</title>
<link rel="stylesheet" href="orders.css">
</head>
<body>
<h1>Bestellingen Overzicht</h1>
<div id="orders-container" class="orders-container">
<!-- Orders will be dynamically inserted here -->
</div>
<script>
function fetchOrders() {
fetch('get_orders.php')
.then(response => response.json())
.then(orders => {
const ordersContainer = document.getElementById('orders-container');
ordersContainer.innerHTML = ''; // Clear existing orders
orders.forEach(order => {
const orderElement = document.createElement('div');
orderElement.classList.add('order');
const orderNumber = document.createElement('h2');
orderNumber.innerText = `Order ${order.order_number}`;
orderElement.appendChild(orderNumber);
const orderTime = document.createElement('p');
orderTime.innerText = `Tijd: ${order.order_time}`;
orderElement.appendChild(orderTime);
const itemsList = document.createElement('ul');
order.items.forEach(item => {
const itemElement = document.createElement('li');
itemElement.innerText = `${item.title} - €${item.price.toFixed(2)}`;
itemsList.appendChild(itemElement);
});
orderElement.appendChild(itemsList);
const totalPrice = document.createElement('p');
totalPrice.innerText = `Totaal: €${Number(order.total_price).toFixed(2)}`;
orderElement.appendChild(totalPrice);
const completeCheckbox = document.createElement('input');
completeCheckbox.type = 'checkbox';
completeCheckbox.id = `complete-${order.order_number}`;
completeCheckbox.addEventListener('change', () => completeOrder(order.order_number));
const completeLabel = document.createElement('label');
completeLabel.htmlFor = `complete-${order.order_number}`;
completeLabel.innerText = 'Complete';
orderElement.appendChild(completeCheckbox);
orderElement.appendChild(completeLabel);
ordersContainer.appendChild(orderElement);
});
})
.catch(error => console.error('Error fetching orders:', error));
}
function completeOrder(orderNumber) {
fetch('complete_order.php', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ order_number: orderNumber })
})
.then(response => response.json())
.then(data => {
if (data.success) {
fetchOrders(); // Refresh the orders list
} else {
alert('Failed to complete order');
}
})
.catch(error => console.error('Error completing order:', error));
}
// Fetch orders every 5 seconds
setInterval(fetchOrders, 5000);
fetchOrders(); // Initial fetch
</script>
</body>
</html>

View File

@@ -0,0 +1,48 @@
<?php
include 'config.php';
// Set header to JSON
header('Content-Type: application/json');
// Get the POST data
$data = json_decode(file_get_contents('php://input'), true);
$items = json_encode($data['items'] ?? []);
$total_price = $data['total_price'] ?? 0;
if (empty($items) || empty($total_price)) {
echo json_encode(['success' => false, 'message' => 'Invalid order data']);
exit;
}
// Fetch the last order number
$sql = "SELECT order_number FROM orders ORDER BY id DESC LIMIT 1";
$result = $conn->query($sql);
if ($result === false) {
error_log("Failed to fetch last order number: " . $conn->error);
echo json_encode(['success' => false, 'message' => 'Failed to fetch last order number']);
exit;
}
$last_order_number = $result->fetch_assoc()['order_number'] ?? '#000';
$new_order_number = '#' . str_pad((int)substr($last_order_number, 1) + 1, 3, '0', STR_PAD_LEFT);
$sql = "INSERT INTO orders (order_number, items, total_price) VALUES (?, ?, ?)";
$stmt = $conn->prepare($sql);
if ($stmt === false) {
error_log("Failed to prepare statement: " . $conn->error);
echo json_encode(['success' => false, 'message' => 'Failed to prepare statement']);
exit;
}
$stmt->bind_param("ssd", $new_order_number, $items, $total_price);
if ($stmt->execute()) {
echo json_encode(['success' => true, 'order_number' => $new_order_number]);
} else {
error_log("Failed to execute statement: " . $stmt->error);
echo json_encode(['success' => false, 'message' => 'Failed to execute statement']);
}
$stmt->close();
$conn->close();
?>

View File

@@ -0,0 +1,449 @@
// Function to show products for a selected category
function showCategory(category) {
console.log(`Fetching items for category: ${category}`); // Debugging: log category
const productDisplay = document.getElementById('product-display');
productDisplay.innerHTML = ''; // Clear display before adding new items
fetch(`get_items.php?category=${category}`)
.then(response => {
if (!response.ok) {
console.error('Network response was not ok', response.statusText);
throw new Error('Network response was not ok');
}
return response.json();
})
.then(items => {
if (items.error) {
console.error('Error fetching items:', items.error);
return;
}
if (items.length === 0) {
console.warn(`No items found for category: ${category}`); // Debugging: log no items found
}
console.log('Fetched items:', items); // Debugging: log fetched items
items.forEach(item => {
const productBox = document.createElement('div');
productBox.classList.add('product-box');
productBox.onclick = () => showItemDetails(item);
productBox.innerHTML = `
<img src="${item.imageSrc}" alt="${item.title}">
<h3>${item.title}</h3>
<p>€${item.price.toFixed(2)}</p>
`;
productDisplay.appendChild(productBox);
});
document.querySelector('.menu-bar').classList.add('top'); // Bring menu to top
document.getElementById('cart').classList.add('visible');
document.querySelector('.cart-icon').classList.add('visible');
// Remove logo if present
const logo = document.querySelector('.logo');
if (logo) { logo.remove(); }
})
.catch(error => console.error('Error fetching items:', error));
}
// Functie om de details van een item weer te geven in het modaal
function showItemDetails(item) {
const title = item.title;
const imageSrc = item.imageSrc;
const description = item.description; // Use description from item data
const price = item.price;
// Update de inhoud van het modaal venster
document.getElementById("modal-title").innerText = title;
document.getElementById("modal-image").src = imageSrc;
document.getElementById("modal-description").innerText = description;
document.getElementById("modal-price").innerText = `Prijs: €${price.toFixed(2)}`;
document.getElementById("add-to-cart").onclick = function() {
addToCart({ title, price });
};
document.getElementById('modal').style.display = 'block';
}
// Functie om de beschrijving op te halen afhankelijk van de titel
function getDescription(title) {
// Broodjes beschrijvingen
if (title === "Broodje Gezond") {
return "Op dit broodje zit kaas, veldsla, komkommer, tomaat, ei, ham en/of kip en bufkes saus.";
} else if (title === "Bagel") {
return "Doughnut brood met spek, ei en kaas";
} else if (title === "Broodje Gehakt met Joppiesaus") {
return "Een wit of bruin broodje met Gehakt, Ei, Sla en Joppiesaus .";
} else if (title === "Saucijzenbroodje") {
return "Een knapperig korstje met een warme, kruidige vleesvulling";
} else if (title === "Frikandelbroodje") {
return "Een knapperige korstje met een warme frikandel en curry saus erin";
} else if (title === "Croissant") {
return "Verschilende diverse croisantje beschikbaar bij de counter";
} else if (title === "Chocolade broodje") {
return "Een krokrantig korstje met chocolade erin";
} else if (title === "Broodje kip") {
return "Op het broodje kip zit komkommer, salade, kip en bufkes saus";
} else if (title === "Panini broodje") {
return "Verschillende diverse panini's zijn te vinden op de counter!";
// Koude dranken beschrijving
} else if (title === "Spa Water") {
return "Koude verfrissende water.";
} else if (title === "Milkshake") {
return "Verschillende diverse milkshake (keuze bij de counter maken)";
} else if (title === "Lente Redbull") {
return "De Red Bull Spring Edition Walstro & Pink Grapefruit";
} else if (title === "Redbull") {
return "De orginele Redbull";
// Warme dranken beschrijving
} else if (title === "Chocomel") {
return "Een lekker warme chocolade melk";
} else if (title === "Chocomel met slagroom") {
return "Een lekkere warme chocolade melk met slagroom";
} else if (title === "Koffie") {
return "Een lekker warme koffie";
} else if (title === "Thee") {
return "heerlijke warme thee (keuze bij de kassa)";
// Snacks beschrijving
} else if (title === "Frikandel") {
return "Gemalen gehakt in een staafje";
} else if (title === "Friet") {
return "Een bakje friet";
} else if (title === "Kipcorn") {
return "Een lekkere krokante Kipcorn.";
} else if (title === "Kipnuggets") {
return "Een bakje met 9 kipnuggets.";
} else if (title === "Mexicano") {
return "Een pittige mexicano.";
} else if (title === "Bitterballen") {
return "Een bakje met 9 Bitterballen .";
} else if (title === "Koekjes") {
return "Lekkere knapperige chocolade koekjes!";
} else if (title === "Kroket") {
return "Een lekkere krokante kroket!";
} else if (title === "Kaassoufle") {
return "Een lekkere krokante kaassoufle!";
// Ijsjes beschrijving
} else if (title === "Ijsjes") {
return "Een lekker ijsje met vele smaken, zoals aardbei, vanille, chocolade, mint, bosbes en nog veel meer (alleen in de zomer!).";
} else if (title === "Sorbet") {
return "Lekkeresorbet met saus naar keuze";
} else if (title === "Softijs") {
return "Een melk ijsje";
} else if (title === "Sundea ijs") {
return "Een softijs ijsje in een bakje met een sas naar keuze!";
} else if (title === "Appelflap") {
return "Een lekker korstje met fijn gesneden appels, rozijnen en kaneel erin";
// Deals beschrijing
} else if (title === "Lunch Deal") {
return "Bij deze deal krijg je 1 snack naar keuze, wat frietjes en drinken naar keuze erbij!";
} else if (title === "Gezonde Deal") {
return "Bij deze deal krijg je een keuze naar een broodje en een keuze naar een koude drank!!";
// Soepen beschrijving
} if (title === "Tomatensoep") {
return "Tomatensoep met gehakt balletje";
} if (title === "Kippensoep") {
return "Kippensoep met kip en groenten";
} if (title === "Erwtensoep") {
return "Gemalen erwten met stukjes worst erin";
} if (title === "Groentesoep (met gehaktballetjes)") {
return "Een soep met veel groente erin en gehaktballetjes";
// Salades beschrijving
} if (title === "Caesar Salade") {
return "In een klassieke Ceesar salade zit sla romaine, ui, kipfilet, citroen, mayonaise en olijfolie";
} if (title === "Griekse Salade") {
return "In een Griekse salade zit komkommer, snoeptomatjes, klein beetje rode ui, olijven, feta kaas en croutons";
} if (title === "Krokante Kip Salade") {
return "In de krokante Kip Salade zit kip, sla, klein beetje rode ui, snoeptomaatjes, olijfolie en komkommer";
} if (title === "Aardappel Salade") {
return "In de aardappel salade zit aardappelen, prei, erwten, peper en zout";
// Sauzen beschrijving
} if (title === "Ketchup") {
return "Ketchup";
} if (title === "Mayonaise") {
return "Mayonaise";
} if (title === "Mosterd") {
return "Mosterd";
} if (title === "Sweet Chili") {
return "Sweet Chili";
} if (title === "Curry saus") {
return "Curry saus";
}
// Yoghurt beschrijving
if (title === "Aardbij yoghurt") {
return "Yoghurt met aardbei";
} if (title === "Optimel klein 250ml") {
return "Een klein pakje drink yoghurt";
} if (title === "Optimel groot") {
return "Een groot pakje drink yoghurt";
} if (title === "Melk") {
return "Halfvolle melk in een klein pakje";
} if (title === "Fristi") {
return "Melkdrank met vruchtensmaak";
} if (title === "Koude chocomelk") {
return "Koude chocomelk in een flesje";
} if (title === "Breaker") {
return "Verschillende diverse smaken bij de counter";
} if (title === "Yoghurt beker") {
return "Een klein bakje met yoghurt en musli erbij";
} if (title === "Kwark 150 gram") {
return "Een klein bakje kwark";
}
{
// snoep beschrijing
} if (title === "Haribo starmix") {
return "Een mixzakje met 75g snoepjes. ";
} if (title === "Haribo Kikkers") {
return "Een zakje met 75g kikkertjes.";
} if (title === "Haribo Goudberen") {
return "Een zakje met 75g beertjes";
} if (title === "Haribo Bananen") {
return "Een zakje met 75g banaantjes.";
} if (title === "Haribo Perzikken") {
return "Een zakje met 75g Perzikken.";
} if (title === "Haribo Tropifrutti") {
return "Een mix zakje met 75g Snoepjes.";
} if (title === "Haribo Tangfastics") {
return "Een mixzakje met 75g zure snoepjes.";
} if (title === "Haribo Kersen") {
return "Een zakje met 75g kersjes.";
} if (title === "Haribo Rolletje") {
return "Een rolletje met snoepjes.";
} if (title === "Haribo Pinballs") {
return "Een zakje met 75g balletjes.";
} if (title === "Haribo Happy Cola") {
return "Een zakje met 75g cola snoepjes.";
}
}
{
// overige beschrijing
if (title === "Bestek") {
return "Plastice vorken, messen en lepels ";
} if (title === "Hervul baar bekers") {
return "Bekers die je kunt hervullen en daarna weg kan gooien";
} if (title === "Rietjes") {
return "Plastice rietjes";
}
}
// Functie om een item aan het winkelwagentje toe te voegen
function addToCart(item) {
const cart = JSON.parse(localStorage.getItem('cart')) || [];
cart.push(item); // Add item to the cart array
localStorage.setItem('cart', JSON.stringify(cart));
updateCart();
}
// Functie om het winkelwagentje bij te werken
function updateCart() {
const cart = JSON.parse(localStorage.getItem('cart')) || [];
const cartItemsContainer = document.getElementById("cart-items");
cartItemsContainer.innerHTML = '';
let totalPrice = 0;
cart.forEach((item, index) => {
const cartItemElement = document.createElement('li');
cartItemElement.className = 'cart-item';
cartItemElement.innerHTML = `
<span>${item.title}</span>
<span>€${item.price.toFixed(2)}</span>
<button onclick="removeFromCart(${index})">Verwijderen</button>
`;
cartItemsContainer.appendChild(cartItemElement);
totalPrice += item.price;
});
document.getElementById('total-price').innerText = totalPrice.toFixed(2);
// Show or hide the "Bestellen" button based on the cart's content
const orderButton = document.getElementById('order-button');
if (cart.length > 0) {
orderButton.style.display = 'block';
} else {
orderButton.style.display = 'none';
}
// Update the cart count in the cart icon
document.getElementById('cart-count').innerText = cart.length;
}
// Functie om een item uit het winkelwagentje te verwijderen
function removeFromCart(index) {
const cart = JSON.parse(localStorage.getItem('cart')) || [];
cart.splice(index, 1);
localStorage.setItem('cart', JSON.stringify(cart));
updateCart();
}
// Functie om het modaal venster te sluiten
function closeModal() {
document.getElementById('modal').style.display = 'none';
document.querySelector('.menu-bar').classList.remove('dark'); // Remove dark class from menu-bar
}
// Zorg ervoor dat het modaal venster sluit wanneer er buiten het venster wordt geklikt
window.onclick = function(event) {
if (event.target == document.getElementById('modal')) {
closeModal();
}
}
// Initial call to updateCart to ensure the button is hidden on page load
updateCart();
// Functie om een bestelling te plaatsen
function placeOrder() {
const cart = JSON.parse(localStorage.getItem('cart')) || [];
if (cart.length === 0) {
alert('Uw winkelmandje is leeg.');
return;
}
const totalPrice = cart.reduce((total, item) => total + item.price, 0).toFixed(2);
fetch('place_order.php', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
items: cart,
total_price: totalPrice
})
})
.then(response => response.json())
.then(data => {
if (data.success) {
localStorage.removeItem('cart'); // Clear the cart
updateCart(); // Update the cart display
window.open(`betalen.html?order_number=${encodeURIComponent(data.order_number)}`, '_blank'); // Open the payment page in a new tab with order number
} else {
alert('Er is een fout opgetreden bij het plaatsen van uw bestelling. Probeer het opnieuw.');
}
})
.catch(error => console.error('Error placing order:', error));
}
// Bind the placeOrder function to the order button
document.getElementById('order-button').addEventListener('click', placeOrder);
// Vertalingen voor beide talen (nl en en)
const translations = {
en: {
"Broodjes": "Sandwiches",
"Koude Dranken": "Cold Drinks",
"Warme Dranken": "Hot Drinks",
"Snacks": "Snacks",
"deserts": "Ice Creams",
"Deals": "Deals",
"Soepen": "Soups",
"Salades": "Salads",
"Sausjes": "Sauces",
"Snoep": "Candy",
"Winkelmandje": "Shopping Cart",
"Prijs": "Price",
"Toevoegen aan winkelmandje": "Add to cart",
"Bestellen": "Order",
"Totaal": "Total",
"Overige": "Other",
"Op dit broodje zit kaas, veldsla, komkommer, tomaat, ei, ham en/of kip en bufkes saus.": "This sandwich contains cheese, lamb's lettuce, cucumber, tomato, egg, ham and/or chicken, and bufkes sauce.",
"Doughnut brood met spek, ei en kaas": "Doughnut bread with bacon, egg, and cheese",
"Een wit of bruin broodje met Gehakt, Ei, Sla en Joppiesaus": "A white or brown sandwich with minced meat, egg, lettuce, and Joppiesaus",
"Een knapperig korstje met een warme, kruidige vleesvulling": "A crispy crust with a warm, spicy meat filling",
"Een knapperige korstje met een warme frikandel en curry saus erin": "A crispy crust with a warm frikandel and curry sauce inside",
"Koude verfrissende water.": "Cold refreshing water.",
"Verschillende diverse milkshake (keuze bij de counter maken)": "Various milkshakes (choose at the counter)",
"Een lekker warme chocolade melk": "A delicious hot chocolate milk",
"Een lekkere warme chocolade melk met slagroom": "A delicious hot chocolate milk with whipped cream",
"Een lekker warme koffie": "A delicious hot coffee",
"heerlijke warme thee (keuze bij de kassa)": "Delicious hot tea (choose at the counter)",
"Een frikandel, dat wil je wel!": "A frikandel, you want that!",
"Een klein bakje met friet.": "A small box of fries.",
"Een lekkere krokante Kipcorn.": "A delicious crispy Kipcorn.",
"Een bakje met 9 kipnuggets.": "A box with 9 chicken nuggets.",
"Een pittige mexicano.": "A spicy mexicano.",
"Een bakje met 9 Bitterballen.": "A box with 9 Bitterballen.",
"Een lekker ijsje met vele smaken, zoals aardbei, vanille, chocolade, mint, bosbes en nog veel meer (alleen in de zomer!).": "A delicious ice cream with many flavors, such as strawberry, vanilla, chocolate, mint, blueberry, and many more (only in summer!).",
"Lekkeresorbet met saus naar keuze": "Delicious sorbet with sauce of your choice",
"Bij deze deal krijg je 1 snack naar keuze, wat frietjes en drinken naar keuze erbij!": "With this deal, you get 1 snack of your choice, some fries, and a drink of your choice!",
"Bij deze deal krijg je een keuze naar een broodje en een keuze naar een koude drank!!": "With this deal, you get a choice of a sandwich and a choice of a cold drink!!",
"Soep van de dag! (Allergieën? Meld het bij ons!)": "Soup of the day! (Allergies? Let us know!)",
"Een heerlijke salade met verse groenten en een dressing naar keuze.": "A delicious salad with fresh vegetables and a dressing of your choice.",
"Kies de saus naar je keuze!": "Choose the sauce of your choice!",
},
nl: {
"Sandwiches": "Broodjes",
"Cold Drinks": "Koude Dranken",
"Hot Drinks": "Warme Dranken",
"Snacks": "Snacks",
"Ice Creams": "deserts",
"Deals": "Deals",
"Soups": "Soepen",
"Salads": "Salades",
"Sauces": "Sausjes",
"Candy": "Snoep",
"Shopping Cart": "Winkelmandje",
"Price": "Prijs",
"Add to cart": "Toevoegen aan winkelmandje",
"Order": "Bestellen",
"Total": "Totaal",
"Other": "Overige",
"This sandwich contains cheese, lamb's lettuce, cucumber, tomato, egg, ham and/or chicken, and bufkes sauce.": "Op dit broodje zit kaas, veldsla, komkommer, tomaat, ei, ham en/of kip en bufkes saus.",
"Doughnut bread with bacon, egg, and cheese": "Doughnut brood met spek, ei en kaas",
"A white or brown sandwich with minced meat, egg, lettuce, and Joppiesaus": "Een wit of bruin broodje met Gehakt, Ei, Sla en Joppiesaus",
"A crispy crust with a warm, spicy meat filling": "Een knapperig korstje met een warme, kruidige vleesvulling",
"A crispy crust with a warm frikandel and curry sauce inside": "Een knapperige korstje met een warme frikandel en curry saus erin",
"Cold refreshing water.": "Koude verfrissende water.",
"Various milkshakes (choose at the counter)": "Verschillende diverse milkshake (keuze bij de counter maken)",
"A delicious hot chocolate milk": "Een lekker warme chocolade melk",
"A delicious hot chocolate milk with whipped cream": "Een lekkere warme chocolade melk met slagroom",
"A delicious hot coffee": "Een lekker warme koffie",
"Delicious hot tea (choose at the counter)": "heerlijke warme thee (keuze bij de kassa)",
"A frikandel, you want that!": "Een frikandel, dat wil je wel!",
"A small box of fries.": "Een klein bakje met friet.",
"A delicious crispy Kipcorn.": "Een lekkere krokante Kipcorn.",
"A box with 9 chicken nuggets.": "Een bakje met 9 kipnuggets.",
"A spicy mexicano.": "Een pittige mexicano.",
"A box with 9 Bitterballen.": "Een bakje met 9 Bitterballen.",
"A delicious ice cream with many flavors, such as strawberry, vanilla, chocolate, mint, blueberry, and many more (only in summer!).": "Een lekker ijsje met vele smaken, zoals aardbei, vanille, chocolade, mint, bosbes en nog veel meer (alleen in de zomer!).",
"Delicious sorbet with sauce of your choice": "Lekkeresorbet met saus naar keuze",
"With this deal, you get 1 snack of your choice, some fries, and a drink of your choice!": "Bij deze deal krijg je 1 snack naar keuze, wat frietjes en drinken naar keuze erbij!",
"With this deal, you get a choice of a sandwich and a choice of a cold drink!!": "Bij deze deal krijg je een keuze naar een broodje en een keuze naar een koude drank!!",
"Soup of the day! (Allergies? Let us know!)": "Soep van de dag! (Allergieën? Meld het bij ons!)",
"A delicious salad with fresh vegetables and a dressing of your choice.": "Een heerlijke salade met verse groenten en een dressing naar keuze.",
"Choose the sauce of your choice!": "Kies de saus naar je keuze!",
}
};
// Functie om de taal te wisselen
function switchLanguage(lang) {
// Zoek alle elementen met een data-translate attribuut
document.querySelectorAll("[data-translate]").forEach(element => {
const key = element.getAttribute("data-translate"); // Verkrijg de sleutel uit het data-translate attribuut
element.textContent = translations[lang][key] || key; // Vertaal de tekst of behoud de sleutel als er geen vertaling is
});
}
// Functie om de taal te wisselen wanneer de knop wordt aangeklikt
document.getElementById("language-switcher").addEventListener("click", () => {
const currentLang = document.documentElement.lang; // Huidige taal ophalen
const newLang = currentLang === "nl" ? "en" : "nl"; // Nieuwe taal bepalen
document.documentElement.lang = newLang; // Wijzig de taal van de pagina
switchLanguage(newLang); // Pas de vertalingen toe voor de nieuwe taal
// Verander de tekst op de taalwisselknop
const switcher = document.getElementById("language-switcher");
switcher.textContent = newLang === "nl" ? "EN" : "NL"; // Zet de knop tekst naar de andere taal
});
// Stel de standaardtaal in
document.documentElement.lang = "nl"; // Begin met Nederlands
switchLanguage("nl"); // Pas de vertalingen toe voor Nederlands bij het laden van de pagina

View File

@@ -0,0 +1,376 @@
/* Algemene body */
body {
font-family: Arial, sans-serif;
margin: 0;
display: flex;
flex-direction: column; /* Change to column to accommodate the top bar */
background-color: #ffffff;
}
/* Top bar menu */
.menu-bar {
width: 75%; /* Use 75% of the screen width on the first page */
background-color: #ffffff;
padding: 10px 0;
display: flex;
flex-wrap: wrap; /* Allow wrapping of menu items */
justify-content: center; /* Center the menu items */
align-items: center;
position: absolute; /* Initially position in the middle */
top: 60%;
left: 50%;
transform: translate(-50%, -50%);
transition: all 0.3s ease; /* Add transition for position and background color */
z-index: 1;
}
.menu-bar.top {
width: 100%; /* Use 100% of the screen width when at the top */
position: fixed; /* Fix the top bar to the top */
top: 0;
left: 0;
transform: translate(0, 0);
justify-content: space-around; /* Spread the menu items */
flex-wrap: nowrap; /* Ensure all items are in a single row */
overflow-x: auto; /* Enable horizontal scrolling */
}
.menu-bar.dark {
background-color: #ff8c00; /* Darker background color when modal is open */
}
.menu-item {
background-color: #ff8c00;
padding: 10px 20px;
margin: 5px;
border-radius: 25px;
cursor: pointer;
font-size: 1.2em;
transition: all 0.3s ease;
flex: 1 1 calc(33.333% - 10px); /* Allow 3 items per row with margin */
text-align: center; /* Center text inside the menu item */
}
.menu-bar.top .menu-item {
flex: none; /* Remove flex-grow to fit all items in a single row */
}
.menu-item:hover {
transform: scale(1.05);
}
/* Productweergave in een grid */
.product-display {
width: calc(100% - 20%); /* Adjust width to leave space for the cart */
display: flex;
flex-wrap: wrap;
padding: 20px;
justify-content: space-around;
margin-top: 60px; /* Add margin to ensure it starts below the top bar */
}
.product-box {
width: 200px; /* Keep the width fixed */
margin: 10px;
border-radius: 8px;
overflow: hidden;
text-align: center;
cursor: pointer;
transition: all 0.3s ease, box-shadow 0.3s ease;
border: 2px solid #ff8c00; /* 2px dikke zwarte rand */
padding: 20px; /* Ruimte binnen de container */
}
.product-box:hover {
transform: scale(1.05);
}
.product-box img {
width: 100%;
max-height: 150px;
object-fit: cover;
}
/* Modaal venster */
.modal {
display: none;
position: fixed;
z-index: 1;
left: 0;
top: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
overflow-y: auto; /* Allow scrolling for larger content */
}
.modal-content {
background-color: white;
margin: 7% auto;
padding: 20px;
border-radius: 8px;
width: 80%;
max-width: 600px;
text-align: center;
max-height: 90vh;
overflow-y: auto;
}
.modal img {
width: 100%;
max-width: 300px;
height: auto;
margin: 20px 0;
}
.close {
position: absolute;
top: 110px;
right: 455px;
font-size: 60px;
font-weight: bold;
cursor: pointer;
color: red;
}
#add-to-cart {
background-color: #F56E28;
color: white;
border: none;
padding: 10px 20px;
cursor: pointer;
border-radius: 5px;
margin-top: 20px;
}
#add-to-cart:hover {
background-color: #F56E28;
}
/* Winkelwagen-icoon */
.cart-icon {
display: none; /* Initially hide the cart icon */
position: fixed;
top: 80px; /* Move the cart icon down */
right: 10px; /* Adjust right position to make space for language switcher */
background-color: #ff6600;
color: white;
padding: 10px 15px;
border-radius: 50%;
font-size: 20px;
cursor: pointer;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}
.cart-icon.visible {
display: block; /* Show the cart icon when the 'visible' class is added */
}
.cart-icon:hover {
background-color: #e65c00;
}
.cart-count {
position: absolute;
top: -5px;
right: -5px;
background: red;
color: white;
font-size: 12px;
font-weight: bold;
padding: 3px 6px;
border-radius: 50%;
}
/* Productstijl */
.products {
display: flex;
gap: 20px;
margin: 50px;
}
.product {
border: 1px solid #ddd;
padding: 20px;
text-align: center;
}
.product button {
background-color: #ff6600;
color: white;
border: none;
padding: 10px;
cursor: pointer;
margin-top: 10px;
}
.product button:hover {
background-color: #e65c00;
}
/* Responsive design */
@media (max-width: 768px) {
.menu-bar {
flex-wrap: nowrap; /* Ensure all items are in a single row */
width: 100%; /* Use full width for menu bar */
top: 0; /* Fix the menu bar to the top */
left: 0;
transform: translate(0, 0);
justify-content: flex-start; /* Align items to the start */
overflow-x: auto; /* Enable horizontal scrolling */
padding: 10px; /* Add padding for better spacing */
}
.menu-item {
flex: none; /* Remove flex-grow to fit all items in a single row */
margin: 5px; /* Add margin between items */
font-size: 1em; /* Adjust font size for better readability */
}
.product-display {
width: 100%; /* Use full width for product display */
margin-top: 120px; /* Increase margin to accommodate wrapped menu bar */
padding: 10px; /* Add padding for better spacing */
}
.product-box {
width: calc(50% - 20px); /* Two items per row */
margin: 10px; /* Add margin between items */
}
.cart {
width: 100%; /* Use full width for cart */
top: auto; /* Remove fixed position */
bottom: 0; /* Position at the bottom */
height: auto; /* Adjust height */
max-height: 50vh; /* Set a maximum height for the cart */
overflow-y: auto; /* Enable vertical scrolling if content exceeds max-height */
}
.cart-icon {
top: 20px; /* Adjust position */
right: 20px; /* Adjust position */
}
.language-switcher {
bottom: 20px; /* Position at the bottom */
left: 20px; /* Position at the left */
}
.logo {
width: 80%; /* Adjust width for smaller screens */
max-width: 300px; /* Set a maximum width */
padding: 20px; /* Adjust padding */
margin: 10px auto; /* Adjust margin */
}
}
/* Winkelmandje sectie */
.cart {
display: none; /* Initially hide the cart */
width: 15%; /* Make the cart a bit smaller */
padding: 20px;
background-color: #fff;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
margin-top: 80px; /* Increase margin to ensure it starts below the categories bar */
position: fixed; /* Fix the cart to the right side */
right: 0; /* Align the cart to the right */
top: 60px; /* Ensure it starts below the categories bar */
flex-direction: column; /* Ensure the content is arranged in a column */
overflow-y: auto; /* Enable vertical scrolling if content exceeds max-height */
max-height: 80vh; /* Set a maximum height for the cart */
}
.cart ul {
list-style-type: none;
padding: 0;
margin: 0;
}
.cart li {
padding: 10px 0; /* Space out the items */
border-bottom: 1px solid #ff8c00; /* Change this to the orange color */
}
.cart li {
margin-bottom: 10px;
}
.cart-item button {
background-color: #d32f2f;
color: white;
border: none;
padding: 5px 10px;
cursor: pointer;
border-radius: 5px;
}
.cart-item {
display: flex;
justify-content: space-between;
padding: 10px 0;
border-bottom: 2px solid #ff8c00; /* Change this to the orange color */
}
.cart-item button:hover {
background-color: #b71c1c;
}
#order-button {
background-color: #4CAF50;
color: white;
border: none;
padding: 10px 20px;
cursor: pointer;
border-radius: 5px;
width: 100%;
text-align: center;
margin-top: 20px;
display: none; /* Hide the button by default */
align-self: flex-end; /* Ensure the button is at the bottom */
}
#order-button:hover {
background-color: #45a049;
transform: scale(1.05);
}
.cart.visible {
display: flex; /* Show the cart when the 'visible' class is added */
}
.logo {
width: 100%;
padding: 60px;
max-width: 400px;
margin: 20px auto;
display: block;
transition: opacity 0.3s ease; /* Add transition for smooth hiding */
}
.logo.hidden {
opacity: 0; /* Hide the logo */
visibility: hidden; /* Ensure the logo is not clickable */
}
.language-switcher {
position: fixed;
bottom: 20px; /* Position at the bottom */
left: 20px; /* Position at the left */
background-color: #ff8c00;
color: white;
padding: 10px 20px;
border-radius: 25px;
cursor: pointer;
font-size: 1em;
transition: all 0.3s ease;
z-index: 1100; /* Ensure it is above other elements */
}
.language-switcher:hover {
background-color: #e65c00;
}