Files
employee_votes/templates/index.html
2025-09-17 15:20:01 +08:00

289 lines
11 KiB
HTML

<!DOCTYPE html>
<html lang="zh-TW">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>公司內部訂餐系統</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet">
<style>
body {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}
.navbar-brand {
font-weight: bold;
font-size: 1.5rem;
}
.card {
border: none;
border-radius: 15px;
box-shadow: 0 8px 20px rgba(0,0,0,0.1);
transition: transform 0.3s ease;
}
.card:hover {
transform: translateY(-5px);
}
.card-img-top {
height: 200px;
object-fit: cover;
border-top-left-radius: 15px;
border-top-right-radius: 15px;
}
.category-header {
background: rgba(255,255,255,0.95);
border-radius: 10px;
padding: 15px;
margin-bottom: 20px;
box-shadow: 0 4px 15px rgba(0,0,0,0.1);
}
.price {
color: #28a745;
font-weight: bold;
font-size: 1.2rem;
}
.btn-order {
background: linear-gradient(45deg, #ff6b6b, #ee5a24);
border: none;
border-radius: 25px;
padding: 10px 25px;
font-weight: bold;
transition: all 0.3s ease;
}
.btn-order:hover {
transform: scale(1.05);
box-shadow: 0 5px 15px rgba(255,107,107,0.4);
}
.hero-section {
background: rgba(255,255,255,0.95);
border-radius: 20px;
padding: 40px;
margin: 20px 0;
text-align: center;
}
</style>
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<div class="container">
<a class="navbar-brand" href="#">
<i class="fas fa-utensils me-2"></i>
公司內部訂餐系統
</a>
</div>
</nav>
<div class="container py-5">
<div class="hero-section">
<h1 class="display-4 fw-bold text-primary mb-3">
<i class="fas fa-concierge-bell me-2"></i>
今日菜單
</h1>
<p class="lead text-muted">選擇您喜愛的餐點,享受美味時光</p>
</div>
{% if menu_items %}
{% set categories = menu_items|map(attribute='category')|unique|list %}
{% for category in categories %}
<div class="category-header">
<h2 class="h3 mb-0">
<i class="fas fa-folder me-2"></i>
{{ category }}
</h2>
</div>
<div class="row row-cols-1 row-cols-md-2 row-cols-lg-3 g-4 mb-5">
{% for item in menu_items if item.category == category %}
<div class="col">
<div class="card h-100">
<img src="{{ item.image_url }}" class="card-img-top" alt="{{ item.name }}"
onerror="this.src='https://via.placeholder.com/300x200/667eea/ffffff?text=餐點圖片'">
<div class="card-body">
<h5 class="card-title fw-bold">{{ item.name }}</h5>
<p class="card-text text-muted">{{ item.description }}</p>
<div class="d-flex justify-content-between align-items-center">
<span class="price">${{ "%0.2f"|format(item.price) }}</span>
<button class="btn btn-order" onclick="addToCart({{ item.id }}, '{{ item.name }}', {{ item.price }})">
<i class="fas fa-cart-plus me-2"></i>
加入訂單
</button>
</div>
</div>
</div>
</div>
{% endfor %}
</div>
{% endfor %}
{% else %}
<div class="text-center py-5">
<i class="fas fa-utensils fa-5x text-light mb-3"></i>
<h3 class="text-light">暫無菜單資料</h3>
<p class="text-light">請聯繫管理員更新菜單</p>
<a href="/init" class="btn btn-light btn-lg">
<i class="fas fa-sync me-2"></i>
初始化菜單
</a>
</div>
{% endif %}
</div>
<!-- Shopping Cart Modal -->
<div class="modal fade" id="cartModal" tabindex="-1">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header bg-primary text-white">
<h5 class="modal-title">
<i class="fas fa-shopping-cart me-2"></i>
我的訂單
</h5>
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<div id="cartItems">
<p class="text-muted text-center">購物車是空的</p>
</div>
<div class="d-flex justify-content-between align-items-center mt-3">
<h5>總金額: <span id="totalAmount">$0.00</span></h5>
<button class="btn btn-success" onclick="submitOrder()">
<i class="fas fa-paper-plane me-2"></i>
提交訂單
</button>
</div>
</div>
</div>
</div>
</div>
<!-- Floating Cart Button -->
<div class="position-fixed bottom-0 end-0 m-4">
<button class="btn btn-primary btn-lg rounded-pill shadow" data-bs-toggle="modal" data-bs-target="#cartModal">
<i class="fas fa-shopping-cart me-2"></i>
<span class="badge bg-danger" id="cartCount">0</span>
</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
<script>
let cart = [];
function addToCart(id, name, price) {
const existingItem = cart.find(item => item.id === id);
if (existingItem) {
existingItem.quantity += 1;
} else {
cart.push({
id: id,
name: name,
price: price,
quantity: 1
});
}
updateCartDisplay();
// Show success message
showToast('已加入購物車: ' + name);
}
function updateCartDisplay() {
const cartCount = document.getElementById('cartCount');
const cartItems = document.getElementById('cartItems');
const totalAmount = document.getElementById('totalAmount');
// Update cart count
cartCount.textContent = cart.reduce((total, item) => total + item.quantity, 0);
// Update cart items
if (cart.length === 0) {
cartItems.innerHTML = '<p class="text-muted text-center">購物車是空的</p>';
} else {
cartItems.innerHTML = cart.map(item => `
<div class="card mb-2">
<div class="card-body py-2">
<div class="d-flex justify-content-between align-items-center">
<div>
<h6 class="mb-0">${item.name}</h6>
<small class="text-muted">$${item.price.toFixed(2)} x ${item.quantity}</small>
</div>
<div class="d-flex align-items-center">
<span class="fw-bold me-3">$${(item.price * item.quantity).toFixed(2)}</span>
<button class="btn btn-sm btn-outline-danger" onclick="removeFromCart(${item.id})">
<i class="fas fa-trash"></i>
</button>
</div>
</div>
</div>
</div>
`).join('');
}
// Update total amount
const total = cart.reduce((sum, item) => sum + (item.price * item.quantity), 0);
totalAmount.textContent = '$' + total.toFixed(2);
}
function removeFromCart(id) {
cart = cart.filter(item => item.id !== id);
updateCartDisplay();
}
function submitOrder() {
if (cart.length === 0) {
showToast('請先選擇餐點', 'warning');
return;
}
// Here you would typically send the order to the server
const orderData = {
items: cart,
total: cart.reduce((sum, item) => sum + (item.price * item.quantity), 0),
timestamp: new Date().toISOString()
};
console.log('Order submitted:', orderData);
// Show success message
showToast('訂單提交成功!', 'success');
// Clear cart
cart = [];
updateCartDisplay();
// Close modal
bootstrap.Modal.getInstance(document.getElementById('cartModal')).hide();
}
function showToast(message, type = 'success') {
// Create toast element
const toast = document.createElement('div');
toast.className = `position-fixed bottom-0 end-0 m-3 toast align-items-center text-white bg-${type} border-0`;
toast.setAttribute('role', 'alert');
toast.innerHTML = `
<div class="d-flex">
<div class="toast-body">
${message}
</div>
<button type="button" class="btn-close btn-close-white me-2 m-auto" data-bs-dismiss="toast"></button>
</div>
`;
document.body.appendChild(toast);
// Initialize and show toast
const bsToast = new bootstrap.Toast(toast);
bsToast.show();
// Remove toast after it's hidden
toast.addEventListener('hidden.bs.toast', () => {
document.body.removeChild(toast);
});
}
// Initialize cart display
updateCartDisplay();
</script>
</body>
</html>