|
<!DOCTYPE html> |
|
<html lang="pt-BR"> |
|
<head> |
|
<meta charset="UTF-8"> |
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
|
<title>FoodExpress - Delivery Moderno</title> |
|
<script src="https://cdn.tailwindcss.com"></script> |
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> |
|
<style> |
|
.restaurant-card:hover { |
|
transform: translateY(-5px); |
|
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.1); |
|
} |
|
.food-card:hover { |
|
transform: scale(1.03); |
|
} |
|
.category-btn.active { |
|
background-color: #f59e0b; |
|
color: white; |
|
} |
|
.cart-item-enter { |
|
animation: slideIn 0.3s forwards; |
|
} |
|
input[type="radio"]:checked + label { |
|
font-weight: bold; |
|
color: #059669; |
|
} |
|
@keyframes slideIn { |
|
from { transform: translateX(100%); opacity: 0; } |
|
to { transform: translateX(0); opacity: 1; } |
|
} |
|
</style> |
|
</head> |
|
<body class="bg-gray-50 font-sans"> |
|
|
|
<header class="bg-white shadow-sm sticky top-0 z-10"> |
|
<div class="container mx-auto px-4 py-3 flex items-center justify-between"> |
|
<div class="flex items-center space-x-2"> |
|
<i class="fas fa-utensils text-orange-500 text-2xl"></i> |
|
<h1 class="text-xl font-bold text-gray-800">FoodExpress</h1> |
|
</div> |
|
|
|
<div class="relative w-1/3 hidden md:block"> |
|
<input type="text" placeholder="Buscar restaurantes ou comidas..." |
|
class="w-full py-2 px-4 rounded-full border border-gray-300 focus:outline-none focus:ring-2 focus:ring-orange-500 focus:border-transparent"> |
|
<i class="fas fa-search absolute right-3 top-2.5 text-gray-400"></i> |
|
</div> |
|
|
|
<div class="flex items-center space-x-4"> |
|
<button id="cart-btn" class="relative"> |
|
<i class="fas fa-shopping-cart text-gray-700 text-xl"></i> |
|
<span id="cart-count" class="absolute -top-2 -right-2 bg-orange-500 text-white text-xs rounded-full h-5 w-5 flex items-center justify-center">0</span> |
|
</button> |
|
<button class="hidden md:block bg-orange-500 text-white px-4 py-2 rounded-full font-medium hover:bg-orange-600 transition">Entrar</button> |
|
<button class="md:hidden"> |
|
<i class="fas fa-bars text-gray-700 text-xl"></i> |
|
</button> |
|
</div> |
|
</div> |
|
|
|
|
|
<div class="md:hidden px-4 pb-3"> |
|
<div class="relative"> |
|
<input type="text" placeholder="Buscar..." |
|
class="w-full py-2 px-4 rounded-full border border-gray-300 focus:outline-none focus:ring-2 focus:ring-orange-500 focus:border-transparent"> |
|
<i class="fas fa-search absolute right-3 top-2.5 text-gray-400"></i> |
|
</div> |
|
</div> |
|
</header> |
|
|
|
|
|
<main class="container mx-auto px-4 py-6"> |
|
|
|
<section class="bg-gradient-to-r from-orange-400 to-orange-600 rounded-2xl p-6 mb-8 text-white"> |
|
<div class="max-w-md"> |
|
<h2 class="text-3xl font-bold mb-2">Peça seu delivery agora!</h2> |
|
<p class="mb-4">Comida rápida, fresca e deliciosa direto na sua porta.</p> |
|
<button class="bg-white text-orange-600 px-6 py-2 rounded-full font-bold hover:bg-gray-100 transition">Pedir Agora</button> |
|
</div> |
|
</section> |
|
|
|
|
|
<section class="mb-8"> |
|
<h2 class="text-xl font-bold mb-4 text-gray-800">Categorias</h2> |
|
<div class="flex space-x-3 overflow-x-auto pb-2"> |
|
<button class="category-btn active px-4 py-2 rounded-full bg-gray-100 font-medium whitespace-nowrap">Todos</button> |
|
<button class="category-btn px-4 py-2 rounded-full bg-gray-100 font-medium whitespace-nowrap">Pizza</button> |
|
<button class="category-btn px-4 py-2 rounded-full bg-gray-100 font-medium whitespace-nowrap">Hambúrguer</button> |
|
<button class="category-btn px-4 py-2 rounded-full bg-gray-100 font-medium whitespace-nowrap">Japonesa</button> |
|
<button class="category-btn px-4 py-2 rounded-full bg-gray-100 font-medium whitespace-nowrap">Brasileira</button> |
|
<button class="category-btn px-4 py-2 rounded-full bg-gray-100 font-medium whitespace-nowrap">Saudável</button> |
|
<button class="category-btn px-4 py-2 rounded-full bg-gray-100 font-medium whitespace-nowrap">Sobremesas</button> |
|
</div> |
|
</section> |
|
|
|
|
|
<section class="mb-8"> |
|
<div class="flex justify-between items-center mb-4"> |
|
<h2 class="text-xl font-bold text-gray-800">Restaurantes populares</h2> |
|
<a href="#" class="text-orange-500 font-medium">Ver todos</a> |
|
</div> |
|
|
|
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6"> |
|
|
|
<div class="restaurant-card bg-white rounded-xl overflow-hidden shadow-md transition cursor-pointer"> |
|
<div class="relative"> |
|
<img src="https://images.unsplash.com/photo-1555396273-367ea4eb4db5?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1074&q=80" |
|
alt="Restaurante" class="w-full h-48 object-cover"> |
|
<div class="absolute top-2 left-2 bg-white px-2 py-1 rounded-full text-xs font-bold flex items-center"> |
|
<i class="fas fa-star text-yellow-400 mr-1"></i> |
|
<span>4.8</span> |
|
</div> |
|
</div> |
|
<div class="p-4"> |
|
<h3 class="font-bold text-lg mb-1">Pizzaria Napoli</h3> |
|
<div class="flex items-center text-gray-600 text-sm mb-2"> |
|
<i class="fas fa-clock mr-1"></i> |
|
<span>30-40 min</span> |
|
<span class="mx-2">•</span> |
|
<i class="fas fa-bicycle mr-1"></i> |
|
<span>R$ 5,00</span> |
|
</div> |
|
<p class="text-gray-500 text-sm">Pizza • Italiana • Massa fina</p> |
|
</div> |
|
</div> |
|
|
|
|
|
<div class="restaurant-card bg-white rounded-xl overflow-hidden shadow-md transition cursor-pointer"> |
|
<div class="relative"> |
|
<img src="https://images.unsplash.com/photo-1572802419224-296b0aeee0d9?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1015&q=80" |
|
alt="Restaurante" class="w-full h-48 object-cover"> |
|
<div class="absolute top-2 left-2 bg-white px-2 py-1 rounded-full text-xs font-bold flex items-center"> |
|
<i class="fas fa-star text-yellow-400 mr-1"></i> |
|
<span>4.6</span> |
|
</div> |
|
</div> |
|
<div class="p-4"> |
|
<h3 class="font-bold text-lg mb-1">Burger Master</h3> |
|
<div class="flex items-center text-gray-600 text-sm mb-2"> |
|
<i class="fas fa-clock mr-1"></i> |
|
<span>20-30 min</span> |
|
<span class="mx-2">•</span> |
|
<i class="fas fa-bicycle mr-1"></i> |
|
<span>R$ 4,50</span> |
|
</div> |
|
<p class="text-gray-500 text-sm">Hambúrguer • Americana • Artesanal</p> |
|
</div> |
|
</div> |
|
|
|
|
|
<div class="restaurant-card bg-white rounded-xl overflow-hidden shadow-md transition cursor-pointer"> |
|
<div class="relative"> |
|
<img src="https://images.unsplash.com/photo-1580828343064-fde4fc206bc6?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1171&q=80" |
|
alt="Restaurante" class="w-full h-48 object-cover"> |
|
<div class="absolute top-2 left-2 bg-white px-2 py-1 rounded-full text-xs font-bold flex items-center"> |
|
<i class="fas fa-star text-yellow-400 mr-1"></i> |
|
<span>4.9</span> |
|
</div> |
|
</div> |
|
<div class="p-4"> |
|
<h3 class="font-bold text-lg mb-1">Sushi Palace</h3> |
|
<div class="flex items-center text-gray-600 text-sm mb-2"> |
|
<i class="fas fa-clock mr-1"></i> |
|
<span>40-50 min</span> |
|
<span class="mx-2">•</span> |
|
<i class="fas fa-bicycle mr-1"></i> |
|
<span>R$ 6,00</span> |
|
</div> |
|
<p class="text-gray-500 text-sm">Japonesa • Sushi • Frutos do mar</p> |
|
</div> |
|
</div> |
|
</div> |
|
</section> |
|
|
|
|
|
<section> |
|
<div class="flex justify-between items-center mb-4"> |
|
<h2 class="text-xl font-bold text-gray-800">Pratos populares</h2> |
|
<a href="#" class="text-orange-500 font-medium">Ver todos</a> |
|
</div> |
|
|
|
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4"> |
|
|
|
<div class="food-card bg-white rounded-lg overflow-hidden shadow-md p-4 transition cursor-pointer"> |
|
<div class="relative mb-3"> |
|
<img src="https://images.unsplash.com/photo-1565299624946-b28f40a0ae38?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1081&q=80" |
|
alt="Pizza" class="w-full h-40 object-cover rounded-lg"> |
|
</div> |
|
<div> |
|
<h3 class="font-bold mb-1">Pizza Margherita</h3> |
|
<p class="text-gray-600 text-sm mb-2">Molho de tomate, mussarela, manjericão</p> |
|
<div class="flex justify-between items-center"> |
|
<span class="font-bold text-orange-500">R$ 39,90</span> |
|
<button class="add-to-cart bg-orange-500 text-white px-3 py-1 rounded-full text-sm hover:bg-orange-600 transition" data-id="1" data-name="Pizza Margherita" data-price="39.90"> |
|
<i class="fas fa-plus"></i> |
|
</button> |
|
</div> |
|
</div> |
|
</div> |
|
|
|
|
|
<div class="food-card bg-white rounded-lg overflow-hidden shadow-md p-4 transition cursor-pointer"> |
|
<div class="relative mb-3"> |
|
<img src="https://images.unsplash.com/photo-1568901346375-23c9450c58cd?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=999&q=80" |
|
alt="Hambúrguer" class="w-full h-40 object-cover rounded-lg"> |
|
</div> |
|
<div> |
|
<h3 class="font-bold mb-1">Cheeseburger</h3> |
|
<p class="text-gray-600 text-sm mb-2">Pão brioche, carne 180g, queijo cheddar</p> |
|
<div class="flex justify-between items-center"> |
|
<span class="font-bold text-orange-500">R$ 24,90</span> |
|
<button class="add-to-cart bg-orange-500 text-white px-3 py-1 rounded-full text-sm hover:bg-orange-600 transition" data-id="2" data-name="Cheeseburger" data-price="24.90"> |
|
<i class="fas fa-plus"></i> |
|
</button> |
|
</div> |
|
</div> |
|
</div> |
|
|
|
|
|
<div class="food-card bg-white rounded-lg overflow-hidden shadow-md p-4 transition cursor-pointer"> |
|
<div class="relative mb-3"> |
|
<img src="https://images.unsplash.com/photo-1579871494447-9811cf80d66c?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1170&q=80" |
|
alt="Sushi" class="w-full h-40 object-cover rounded-lg"> |
|
</div> |
|
<div> |
|
<h3 class="font-bold mb-1">Combo Sushi</h3> |
|
<p class="text-gray-600 text-sm mb-2">10 peças variadas, wasabi e gengibre</p> |
|
<div class="flex justify-between items-center"> |
|
<span class="font-bold text-orange-500">R$ 49,90</span> |
|
<button class="add-to-cart bg-orange-500 text-white px-3 py-1 rounded-full text-sm hover:bg-orange-600 transition" data-id="3" data-name="Combo Sushi" data-price="49.90"> |
|
<i class="fas fa-plus"></i> |
|
</button> |
|
</div> |
|
</div> |
|
</div> |
|
|
|
|
|
<div class="food-card bg-white rounded-lg overflow-hidden shadow-md p-4 transition cursor-pointer"> |
|
<div class="relative mb-3"> |
|
<img src="https://images.unsplash.com/photo-1512621776951-a57141f2eefd?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1170&q=80" |
|
alt="Salada" class="w-full h-40 object-cover rounded-lg"> |
|
</div> |
|
<div> |
|
<h3 class="font-bold mb-1">Salada Caesar</h3> |
|
<p class="text-gray-600 text-sm mb-2">Alface, croutons, parmesão, molho caesar</p> |
|
<div class="flex justify-between items-center"> |
|
<span class="font-bold text-orange-500">R$ 19,90</span> |
|
<button class="add-to-cart bg-orange-500 text-white px-3 py-1 rounded-full text-sm hover:bg-orange-600 transition" data-id="4" data-name="Salada Caesar" data-price="19.90"> |
|
<i class="fas fa-plus"></i> |
|
</button> |
|
</div> |
|
</div> |
|
</div> |
|
</div> |
|
</section> |
|
</main> |
|
|
|
|
|
<div id="cart-sidebar" class="fixed top-0 right-0 h-full w-full md:w-96 bg-white shadow-lg transform translate-x-full transition-transform z-20 overflow-y-auto"> |
|
<div class="p-4 border-b border-gray-200 flex justify-between items-center"> |
|
<h2 class="text-xl font-bold">Seu Carrinho</h2> |
|
<button id="close-cart" class="text-gray-500 hover:text-gray-700"> |
|
<i class="fas fa-times text-xl"></i> |
|
</button> |
|
</div> |
|
|
|
<div id="cart-items" class="p-4 space-y-4"> |
|
|
|
<div class="text-center py-10 text-gray-500"> |
|
<i class="fas fa-shopping-cart text-4xl mb-3"></i> |
|
<p>Seu carrinho está vazio</p> |
|
</div> |
|
</div> |
|
|
|
<div class="p-4 border-t border-gray-200 sticky bottom-0 bg-white"> |
|
<div class="mb-4"> |
|
<h3 class="font-bold mb-2">Forma de Pagamento</h3> |
|
<div class="space-y-2"> |
|
<div class="flex items-center"> |
|
<input type="radio" id="pix" name="payment" value="pix" checked class="mr-2"> |
|
<label for="pix" class="flex items-center"> |
|
<i class="fas fa-qrcode text-green-600 mr-1"></i> |
|
Pix |
|
</label> |
|
</div> |
|
<div class="flex items-center"> |
|
<input type="radio" id="dinheiro" name="payment" value="dinheiro" class="mr-2"> |
|
<label for="dinheiro" class="flex items-center"> |
|
<i class="fas fa-money-bill-wave text-green-600 mr-1"></i> |
|
Dinheiro |
|
</label> |
|
</div> |
|
<div class="flex items-center"> |
|
<input type="radio" id="cartao" name="payment" value="cartao" class="mr-2"> |
|
<label for="cartao" class="flex items-center"> |
|
<i class="fas fa-credit-card text-green-600 mr-1"></i> |
|
Cartão |
|
</label> |
|
</div> |
|
</div> |
|
</div> |
|
|
|
<div class="flex justify-between mb-4"> |
|
<span class="font-bold">Total:</span> |
|
<span id="cart-total" class="font-bold text-orange-500">R$ 0,00</span> |
|
</div> |
|
<button class="w-full bg-orange-500 text-white py-3 rounded-lg font-bold hover:bg-orange-600 transition"> |
|
Finalizar Pedido |
|
</button> |
|
</div> |
|
</div> |
|
|
|
|
|
<div id="orders-section" class="fixed bottom-4 right-4 z-30 hidden md:block"> |
|
<button id="orders-btn" class="bg-orange-500 text-white p-3 rounded-full shadow-lg hover:bg-orange-600 transition"> |
|
<i class="fas fa-clipboard-list text-xl"></i> |
|
<span id="orders-count" class="absolute -top-1 -right-1 bg-red-500 text-white text-xs rounded-full h-5 w-5 flex items-center justify-center">0</span> |
|
</button> |
|
</div> |
|
|
|
|
|
<div id="orders-panel" class="fixed bottom-20 right-4 w-full sm:w-80 bg-white rounded-lg shadow-xl z-20 transform translate-y-full transition-transform"> |
|
<div class="p-4 border-b border-gray-200"> |
|
<h3 class="font-bold">Seus Pedidos</h3> |
|
</div> |
|
<div id="orders-list" class="p-4 max-h-96 overflow-y-auto"> |
|
|
|
<p class="text-gray-500 text-center py-4">Nenhum pedido em andamento</p> |
|
</div> |
|
</div> |
|
|
|
|
|
<div id="overlay" class="fixed inset-0 bg-black bg-opacity-50 z-10 hidden"></div> |
|
|
|
|
|
<footer class="bg-gray-100 py-6 mt-12"> |
|
<div class="container mx-auto px-4"> |
|
<div class="flex flex-col md:flex-row justify-between items-center"> |
|
<div class="flex items-center space-x-2 mb-4 md:mb-0"> |
|
<i class="fas fa-utensils text-orange-500 text-2xl"></i> |
|
<h2 class="text-xl font-bold text-gray-800">FoodExpress</h2> |
|
</div> |
|
|
|
<div class="flex space-x-6"> |
|
<a href="#" class="text-gray-600 hover:text-orange-500"><i class="fab fa-facebook-f"></i></a> |
|
<a href="#" class="text-gray-600 hover:text-orange-500"><i class="fab fa-instagram"></i></a> |
|
<a href="#" class="text-gray-600 hover:text-orange-500"><i class="fab fa-twitter"></i></a> |
|
<a href="#" id="admin-link" class="text-gray-600 hover:text-orange-500 flex flex-col items-center" title="Área Admin"> |
|
<i class="fas fa-user-shield"></i> |
|
<span class="text-xs mt-1">Admin</span> |
|
</a> |
|
</div> |
|
</div> |
|
|
|
<div class="border-t border-gray-200 mt-6 pt-6 text-center text-gray-500 text-sm"> |
|
<p>© 2023 FoodExpress. Todos os direitos reservados.</p> |
|
</div> |
|
</div> |
|
</footer> |
|
|
|
<script> |
|
|
|
let orders = JSON.parse(localStorage.getItem('orders')) || []; |
|
const ordersSection = document.getElementById('orders-section'); |
|
const ordersBtn = document.getElementById('orders-btn'); |
|
const ordersPanel = document.getElementById('orders-panel'); |
|
const ordersList = document.getElementById('orders-list'); |
|
const ordersCount = document.getElementById('orders-count'); |
|
|
|
|
|
updateOrders(); |
|
|
|
|
|
let cart = []; |
|
const cartBtn = document.getElementById('cart-btn'); |
|
const cartSidebar = document.getElementById('cart-sidebar'); |
|
const closeCartBtn = document.getElementById('close-cart'); |
|
const overlay = document.getElementById('overlay'); |
|
const cartItemsContainer = document.getElementById('cart-items'); |
|
const cartTotalElement = document.getElementById('cart-total'); |
|
const cartCountElement = document.getElementById('cart-count'); |
|
const addToCartButtons = document.querySelectorAll('.add-to-cart'); |
|
const categoryButtons = document.querySelectorAll('.category-btn'); |
|
|
|
|
|
cartBtn.addEventListener('click', () => { |
|
cartSidebar.classList.remove('translate-x-full'); |
|
overlay.classList.remove('hidden'); |
|
}); |
|
|
|
closeCartBtn.addEventListener('click', () => { |
|
cartSidebar.classList.add('translate-x-full'); |
|
overlay.classList.add('hidden'); |
|
}); |
|
|
|
overlay.addEventListener('click', () => { |
|
cartSidebar.classList.add('translate-x-full'); |
|
adminLogin.classList.add('hidden'); |
|
overlay.classList.add('hidden'); |
|
}); |
|
|
|
|
|
addToCartButtons.forEach(button => { |
|
button.addEventListener('click', () => { |
|
const id = button.getAttribute('data-id'); |
|
const name = button.getAttribute('data-name'); |
|
const price = parseFloat(button.getAttribute('data-price')); |
|
|
|
|
|
const existingItem = cart.find(item => item.id === id); |
|
|
|
if (existingItem) { |
|
existingItem.quantity += 1; |
|
} else { |
|
cart.push({ |
|
id, |
|
name, |
|
price, |
|
quantity: 1 |
|
}); |
|
} |
|
|
|
updateCart(); |
|
|
|
|
|
if (cart.length === 1) { |
|
cartSidebar.classList.remove('translate-x-full'); |
|
overlay.classList.remove('hidden'); |
|
} |
|
|
|
|
|
button.innerHTML = '<i class="fas fa-check"></i>'; |
|
setTimeout(() => { |
|
button.innerHTML = '<i class="fas fa-plus"></i>'; |
|
}, 1000); |
|
}); |
|
}); |
|
|
|
|
|
function updateCart() { |
|
|
|
const totalItems = cart.reduce((sum, item) => sum + item.quantity, 0); |
|
cartCountElement.textContent = totalItems; |
|
|
|
|
|
if (cart.length === 0) { |
|
cartItemsContainer.innerHTML = ` |
|
<div class="text-center py-10 text-gray-500"> |
|
<i class="fas fa-shopping-cart text-4xl mb-3"></i> |
|
<p>Seu carrinho está vazio</p> |
|
</div> |
|
`; |
|
} else { |
|
cartItemsContainer.innerHTML = cart.map(item => ` |
|
<div class="cart-item-enter bg-gray-50 rounded-lg p-3 flex justify-between items-center"> |
|
<div> |
|
<h3 class="font-medium">${item.name}</h3> |
|
<p class="text-sm text-gray-600">R$ ${item.price.toFixed(2)}</p> |
|
</div> |
|
<div class="flex items-center space-x-2"> |
|
<button class="decrease-quantity text-orange-500 w-6 h-6 rounded-full border border-orange-500 flex items-center justify-center" data-id="${item.id}"> |
|
<i class="fas fa-minus text-xs"></i> |
|
</button> |
|
<span class="quantity">${item.quantity}</span> |
|
<button class="increase-quantity text-orange-500 w-6 h-6 rounded-full border border-orange-500 flex items-center justify-center" data-id="${item.id}"> |
|
<i class="fas fa-plus text-xs"></i> |
|
</button> |
|
<button class="remove-item text-red-500 ml-2" data-id="${item.id}"> |
|
<i class="fas fa-trash"></i> |
|
</button> |
|
</div> |
|
</div> |
|
`).join(''); |
|
|
|
|
|
document.querySelectorAll('.decrease-quantity').forEach(button => { |
|
button.addEventListener('click', (e) => { |
|
const id = e.target.closest('button').getAttribute('data-id'); |
|
const item = cart.find(item => item.id === id); |
|
|
|
if (item.quantity > 1) { |
|
item.quantity -= 1; |
|
} else { |
|
cart = cart.filter(item => item.id !== id); |
|
} |
|
|
|
updateCart(); |
|
}); |
|
}); |
|
|
|
document.querySelectorAll('.increase-quantity').forEach(button => { |
|
button.addEventListener('click', (e) => { |
|
const id = e.target.closest('button').getAttribute('data-id'); |
|
const item = cart.find(item => item.id === id); |
|
item.quantity += 1; |
|
updateCart(); |
|
}); |
|
}); |
|
|
|
document.querySelectorAll('.remove-item').forEach(button => { |
|
button.addEventListener('click', (e) => { |
|
const id = e.target.closest('button').getAttribute('data-id'); |
|
cart = cart.filter(item => item.id !== id); |
|
updateCart(); |
|
}); |
|
}); |
|
} |
|
|
|
|
|
const total = cart.reduce((sum, item) => sum + (item.price * item.quantity), 0); |
|
cartTotalElement.textContent = `R$ ${total.toFixed(2)}`; |
|
} |
|
|
|
|
|
document.querySelector('#cart-sidebar button:last-child').addEventListener('click', () => { |
|
if (cart.length === 0) return; |
|
|
|
const paymentMethod = document.querySelector('input[name="payment"]:checked').value; |
|
const order = { |
|
id: Date.now(), |
|
items: [...cart], |
|
total: cart.reduce((sum, item) => sum + (item.price * item.quantity), 0), |
|
paymentMethod, |
|
status: 'preparando', |
|
date: new Date().toLocaleString('pt-BR', { |
|
day: '2-digit', |
|
month: '2-digit', |
|
year: 'numeric', |
|
hour: '2-digit', |
|
minute: '2-digit' |
|
}) |
|
}; |
|
|
|
orders.push(order); |
|
localStorage.setItem('orders', JSON.stringify(orders)); |
|
cart = []; |
|
updateCart(); |
|
updateOrders(); |
|
|
|
|
|
alert(`Pedido #${order.id} realizado com sucesso! Status: ${order.status}`); |
|
|
|
|
|
cartSidebar.classList.add('translate-x-full'); |
|
overlay.classList.add('hidden'); |
|
|
|
|
|
ordersSection.classList.remove('hidden'); |
|
updateOrders(); |
|
|
|
|
|
ordersPanel.classList.remove('translate-y-full'); |
|
}); |
|
|
|
|
|
function updateOrders() { |
|
orders = JSON.parse(localStorage.getItem('orders')) || []; |
|
ordersCount.textContent = orders.length; |
|
ordersSection.classList.toggle('hidden', orders.length === 0); |
|
|
|
if (orders.length === 0) { |
|
ordersList.innerHTML = '<p class="text-gray-500 text-center py-4">Nenhum pedido em andamento</p>'; |
|
} else { |
|
ordersList.innerHTML = orders.map(order => ` |
|
<div class="mb-4 p-3 border border-gray-200 rounded-lg text-sm sm:text-base"> |
|
<div class="flex justify-between items-center mb-2"> |
|
<span class="font-bold">Pedido #${order.id}</span> |
|
<span class="text-sm ${getStatusColor(order.status)}">${order.status}</span> |
|
</div> |
|
<div class="text-sm text-gray-600 mb-1"> |
|
${order.items.map(item => ` |
|
<div class="flex justify-between py-1"> |
|
<span>${item.quantity}x ${item.name}</span> |
|
<span>R$ ${(item.price * item.quantity).toFixed(2)}</span> |
|
</div> |
|
`).join('')} |
|
</div> |
|
<div class="border-t border-gray-200 pt-2 mt-2"> |
|
<div class="flex justify-between font-medium"> |
|
<span>Total:</span> |
|
<span>R$ ${order.total.toFixed(2)}</span> |
|
</div> |
|
<div class="flex justify-between text-xs text-gray-500 mt-1"> |
|
<span>${order.paymentMethod === 'pix' ? 'Pix' : order.paymentMethod === 'dinheiro' ? 'Dinheiro' : 'Cartão'}</span> |
|
<span>${order.date}</span> |
|
</div> |
|
</div> |
|
</div> |
|
`).join(''); |
|
} |
|
} |
|
|
|
function getStatusColor(status) { |
|
switch(status) { |
|
case 'preparando': return 'text-orange-500'; |
|
case 'a caminho': return 'text-blue-500'; |
|
case 'entregue': return 'text-green-500'; |
|
default: return 'text-gray-500'; |
|
} |
|
} |
|
|
|
|
|
ordersBtn.addEventListener('click', () => { |
|
ordersPanel.classList.toggle('translate-y-full'); |
|
}); |
|
|
|
|
|
|
|
function showNewOrder(order) { |
|
const orderElement = document.createElement('div'); |
|
orderElement.className = 'mb-4 p-3 border border-gray-200 rounded-lg text-sm sm:text-base'; |
|
orderElement.innerHTML = ` |
|
<div class="flex justify-between items-center mb-2"> |
|
<span class="font-bold">Pedido #${order.id}</span> |
|
<span class="text-sm ${getStatusColor(order.status)}">${order.status}</span> |
|
</div> |
|
<div class="text-sm text-gray-600 mb-1"> |
|
${order.items.map(item => ` |
|
<div class="flex justify-between py-1"> |
|
<span>${item.quantity}x ${item.name}</span> |
|
<span>R$ ${(item.price * item.quantity).toFixed(2)}</span> |
|
</div> |
|
`).join('')} |
|
</div> |
|
<div class="border-t border-gray-200 pt-2 mt-2"> |
|
<div class="flex justify-between font-medium"> |
|
<span>Total:</span> |
|
<span>R$ ${order.total.toFixed(2)}</span> |
|
</div> |
|
<div class="flex justify-between text-xs text-gray-500 mt-1"> |
|
<span>${order.paymentMethod === 'pix' ? 'Pix' : order.paymentMethod === 'dinheiro' ? 'Dinheiro' : 'Cartão'}</span> |
|
<span>${order.date}</span> |
|
</div> |
|
</div> |
|
`; |
|
|
|
if (ordersList.firstChild && ordersList.firstChild.classList.contains('text-gray-500')) { |
|
ordersList.innerHTML = ''; |
|
} |
|
ordersList.insertBefore(orderElement, ordersList.firstChild); |
|
} |
|
|
|
setInterval(() => { |
|
if (orders.length > 0) { |
|
const randomOrderIndex = Math.floor(Math.random() * orders.length); |
|
const order = orders[randomOrderIndex]; |
|
|
|
if (order.status === 'preparando') { |
|
order.status = 'a caminho'; |
|
} else if (order.status === 'a caminho') { |
|
order.status = 'entregue'; |
|
} |
|
|
|
localStorage.setItem('orders', JSON.stringify(orders)); |
|
updateOrders(); |
|
} |
|
}, 30000); |
|
|
|
|
|
categoryButtons.forEach(button => { |
|
button.addEventListener('click', () => { |
|
categoryButtons.forEach(btn => btn.classList.remove('active')); |
|
button.classList.add('active'); |
|
|
|
}); |
|
}); |
|
|
|
|
|
const adminLogin = document.getElementById('admin-login'); |
|
const adminDashboard = document.getElementById('admin-dashboard'); |
|
const loginForm = document.getElementById('login-form'); |
|
const logoutBtn = document.getElementById('logout-btn'); |
|
const adminOrdersList = document.getElementById('admin-orders-list'); |
|
const adminLink = document.getElementById('admin-link'); |
|
const closeAdminLogin = document.getElementById('close-admin-login'); |
|
|
|
|
|
adminLink.addEventListener('click', (e) => { |
|
e.preventDefault(); |
|
adminLogin.classList.remove('hidden'); |
|
overlay.classList.remove('hidden'); |
|
}); |
|
|
|
|
|
adminLink.addEventListener('click', (e) => { |
|
e.preventDefault(); |
|
adminLogin.classList.remove('hidden'); |
|
}); |
|
|
|
|
|
closeAdminLogin.addEventListener('click', () => { |
|
adminLogin.classList.add('hidden'); |
|
}); |
|
|
|
|
|
const ADMIN_CREDENTIALS = { |
|
username: 'admin', |
|
password: 'admin123' |
|
}; |
|
|
|
|
|
document.querySelector('a[href="/admin"]').addEventListener('click', (e) => { |
|
e.preventDefault(); |
|
adminLogin.classList.remove('hidden'); |
|
}); |
|
|
|
|
|
loginForm.addEventListener('submit', (e) => { |
|
e.preventDefault(); |
|
const username = e.target[0].value; |
|
const password = e.target[1].value; |
|
|
|
if (username === ADMIN_CREDENTIALS.username && password === ADMIN_CREDENTIALS.password) { |
|
adminLogin.classList.add('hidden'); |
|
adminDashboard.classList.remove('hidden'); |
|
loadAdminOrders(); |
|
} else { |
|
alert('Credenciais inválidas'); |
|
} |
|
}); |
|
|
|
|
|
logoutBtn.addEventListener('click', () => { |
|
adminDashboard.classList.add('hidden'); |
|
loginForm.reset(); |
|
}); |
|
|
|
|
|
function loadAdminOrders() { |
|
const orders = JSON.parse(localStorage.getItem('orders')) || []; |
|
|
|
if (orders.length === 0) { |
|
adminOrdersList.innerHTML = '<tr><td colspan="7" class="py-4 text-center text-gray-500">Nenhum pedido encontrado</td></tr>'; |
|
return; |
|
} |
|
|
|
adminOrdersList.innerHTML = orders.map(order => ` |
|
<tr class="border-b hover:bg-gray-50"> |
|
<td class="py-3 px-4">#${order.id}</td> |
|
<td class="py-3 px-4"> |
|
${order.items.map(item => `${item.quantity}x ${item.name}`).join('<br>')} |
|
</td> |
|
<td class="py-3 px-4">R$ ${order.total.toFixed(2)}</td> |
|
<td class="py-3 px-4"> |
|
${order.paymentMethod === 'pix' ? 'Pix' : |
|
order.paymentMethod === 'dinheiro' ? 'Dinheiro' : 'Cartão'} |
|
</td> |
|
<td class="py-3 px-4">${order.date}</td> |
|
<td class="py-3 px-4"> |
|
<span class="px-2 py-1 rounded-full text-xs ${getStatusColor(order.status)}"> |
|
${order.status} |
|
</span> |
|
</td> |
|
<td class="py-3 px-4"> |
|
<select class="status-select border rounded px-2 py-1 text-sm" data-id="${order.id}"> |
|
<option value="preparando" ${order.status === 'preparando' ? 'selected' : ''}>Preparando</option> |
|
<option value="a caminho" ${order.status === 'a caminho' ? 'selected' : ''}>A caminho</option> |
|
<option value="entregue" ${order.status === 'entregue' ? 'selected' : ''}>Entregue</option> |
|
</select> |
|
</td> |
|
</tr> |
|
`).join(''); |
|
|
|
|
|
document.querySelectorAll('.status-select').forEach(select => { |
|
select.addEventListener('change', (e) => { |
|
const orderId = e.target.getAttribute('data-id'); |
|
const newStatus = e.target.value; |
|
|
|
const orders = JSON.parse(localStorage.getItem('orders')) || []; |
|
const orderIndex = orders.findIndex(o => o.id == orderId); |
|
|
|
if (orderIndex !== -1) { |
|
orders[orderIndex].status = newStatus; |
|
localStorage.setItem('orders', JSON.stringify(orders)); |
|
|
|
|
|
updateOrders(); |
|
} |
|
}); |
|
}); |
|
} |
|
</script> |
|
|
|
<div id="admin-login" class="fixed inset-0 bg-gray-900 bg-opacity-50 z-50 flex items-center justify-center hidden"> |
|
<div class="bg-white rounded-lg p-6 w-full max-w-md shadow-xl"> |
|
<div class="flex justify-between items-center mb-4"> |
|
<div> |
|
<h2 class="text-2xl font-bold text-gray-800">Admin Login</h2> |
|
<p class="text-sm text-gray-600">Use: admin / admin123</p> |
|
</div> |
|
<button id="close-admin-login" class="text-gray-500 hover:text-gray-700"> |
|
<i class="fas fa-times"></i> |
|
</button> |
|
</div> |
|
<form id="login-form"> |
|
<div class="mb-4"> |
|
<label class="block text-gray-700 mb-2">Username</label> |
|
<input type="text" class="w-full px-3 py-2 border rounded-lg" required> |
|
</div> |
|
<div class="mb-6"> |
|
<label class="block text-gray-700 mb-2">Password</label> |
|
<input type="password" class="w-full px-3 py-2 border rounded-lg" required> |
|
</div> |
|
<button type="submit" class="w-full bg-orange-500 text-white py-2 rounded-lg hover:bg-orange-600"> |
|
Login |
|
</button> |
|
</form> |
|
</div> |
|
</div> |
|
|
|
|
|
<div id="admin-dashboard" class="fixed inset-0 bg-gray-100 z-50 hidden overflow-y-auto"> |
|
<div class="container mx-auto px-4 py-8"> |
|
<div class="flex justify-between items-center mb-8"> |
|
<div> |
|
<h1 class="text-2xl font-bold">Painel Administrativo</h1> |
|
<p class="text-sm text-gray-600">Gerencie os pedidos dos clientes</p> |
|
</div> |
|
<button id="logout-btn" class="text-orange-500 hover:text-orange-700"> |
|
<i class="fas fa-sign-out-alt mr-1"></i> Logout |
|
</button> |
|
</div> |
|
|
|
<div class="bg-white rounded-lg shadow-md p-6 mb-8"> |
|
<h2 class="text-xl font-bold mb-4">Pedidos</h2> |
|
<div class="overflow-x-auto"> |
|
<table class="min-w-full bg-white"> |
|
<thead> |
|
<tr class="border-b"> |
|
<th class="py-3 px-4 text-left">ID</th> |
|
<th class="py-3 px-4 text-left">Itens</th> |
|
<th class="py-3 px-4 text-left">Total</th> |
|
<th class="py-3 px-4 text-left">Pagamento</th> |
|
<th class="py-3 px-4 text-left">Data</th> |
|
<th class="py-3 px-4 text-left">Status</th> |
|
<th class="py-3 px-4 text-left">Ações</th> |
|
</tr> |
|
</thead> |
|
<tbody id="admin-orders-list"> |
|
|
|
</tbody> |
|
</table> |
|
</div> |
|
</div> |
|
</div> |
|
</div> |
|
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=Lengel/entregaja" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> |
|
</html> |