| <!DOCTYPE html> |
| <html lang="pt-BR"> |
| <head> |
| <meta charset="UTF-8"> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| <title>Gelie Web - Sistema de Pedidos</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> |
| @keyframes pulse { |
| 0% { transform: scale(1); } |
| 50% { transform: scale(1.05); } |
| 100% { transform: scale(1); } |
| } |
| |
| .pulse { |
| animation: pulse 1.5s infinite; |
| } |
| |
| .order-card { |
| transition: all 0.3s ease; |
| } |
| |
| .order-card:hover { |
| transform: translateY(-5px); |
| box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.1); |
| } |
| |
| .tv-screen { |
| background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%); |
| } |
| </style> |
| </head> |
| <body class="bg-gray-50"> |
| |
| <div id="adminPanel" class="min-h-screen"> |
| <header class="bg-blue-600 text-white shadow-lg"> |
| <div class="container mx-auto px-4 py-6"> |
| <div class="flex justify-between items-center"> |
| <div class="flex items-center space-x-2"> |
| <i class="fas fa-ice-cream text-3xl"></i> |
| <h1 class="text-2xl font-bold">Gelie Web</h1> |
| </div> |
| <button onclick="toggleTVView()" class="bg-white text-blue-600 px-4 py-2 rounded-lg font-semibold hover:bg-blue-50 transition"> |
| <i class="fas fa-tv mr-2"></i>Visualizar TV |
| </button> |
| </div> |
| </div> |
| </header> |
|
|
| <main class="container mx-auto px-4 py-8"> |
| <div class="grid grid-cols-1 md:grid-cols-3 gap-6 mb-8"> |
| <div class="bg-white p-6 rounded-xl shadow-md"> |
| <h3 class="text-lg font-semibold text-gray-700 mb-2">Pedidos Feitos</h3> |
| <p class="text-3xl font-bold text-blue-600" id="madeCount">0</p> |
| </div> |
| <div class="bg-white p-6 rounded-xl shadow-md"> |
| <h3 class="text-lg font-semibold text-gray-700 mb-2">Em Preparação</h3> |
| <p class="text-3xl font-bold text-yellow-500" id="preparingCount">0</p> |
| </div> |
| <div class="bg-white p-6 rounded-xl shadow-md"> |
| <h3 class="text-lg font-semibold text-gray-700 mb-2">Finalizados</h3> |
| <p class="text-3xl font-bold text-green-500" id="finishedCount">0</p> |
| </div> |
| </div> |
|
|
| <div class="bg-white rounded-xl shadow-md overflow-hidden mb-8"> |
| <div class="p-6"> |
| <h2 class="text-xl font-bold text-gray-800 mb-4">Novo Pedido</h2> |
| <form id="orderForm" class="grid grid-cols-1 md:grid-cols-2 gap-6"> |
| <div> |
| <label class="block text-gray-700 mb-2" for="icecreamType">Tipo de Sorvete</label> |
| <select id="icecreamType" class="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500" required> |
| <option value="" disabled selected>Selecione um tipo</option> |
| <option value="Casquinha">Casquinha</option> |
| <option value="Cascão">Cascão</option> |
| <option value="Copo">Copo</option> |
| <option value="Milkshake">Milkshake</option> |
| <option value="Sundae">Sundae</option> |
| </select> |
| </div> |
| <div> |
| <label class="block text-gray-700 mb-2" for="flavor">Sabor</label> |
| <select id="flavor" class="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500" required> |
| <option value="" disabled selected>Selecione um sabor</option> |
| <option value="Chocolate">Chocolate</option> |
| <option value="Morango">Morango</option> |
| <option value="Baunilha">Baunilha</option> |
| <option value="Flocos">Flocos</option> |
| <option value="Napolitano">Napolitano</option> |
| </select> |
| </div> |
| <div> |
| <label class="block text-gray-700 mb-2" for="quantity">Quantidade</label> |
| <input type="number" id="quantity" min="1" value="1" class="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500" required> |
| </div> |
| <div> |
| <label class="block text-gray-700 mb-2" for="price">Valor (R$)</label> |
| <input type="number" id="price" min="0" step="0.01" class="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500" required> |
| </div> |
| <div class="md:col-span-2"> |
| <button type="submit" class="w-full bg-blue-600 text-white py-3 px-4 rounded-lg font-semibold hover:bg-blue-700 transition"> |
| <i class="fas fa-plus-circle mr-2"></i>Adicionar Pedido |
| </button> |
| </div> |
| </form> |
| </div> |
| </div> |
|
|
| <div class="bg-white rounded-xl shadow-md overflow-hidden"> |
| <div class="p-6"> |
| <h2 class="text-xl font-bold text-gray-800 mb-4">Pedidos Ativos</h2> |
| <div class="overflow-x-auto"> |
| <table class="min-w-full divide-y divide-gray-200"> |
| <thead class="bg-gray-50"> |
| <tr> |
| <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Código</th> |
| <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Tipo</th> |
| <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Sabor</th> |
| <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Quantidade</th> |
| <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Valor</th> |
| <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Status</th> |
| <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Ações</th> |
| </tr> |
| </thead> |
| <tbody id="ordersTableBody" class="bg-white divide-y divide-gray-200"> |
| |
| </tbody> |
| </table> |
| </div> |
| </div> |
| </div> |
| </main> |
| </div> |
|
|
| |
| <div id="tvView" class="hidden min-h-screen tv-screen"> |
| <div class="container mx-auto px-4 py-8"> |
| <div class="flex justify-center mb-12"> |
| <div class="flex items-center space-x-4"> |
| <i class="fas fa-ice-cream text-5xl text-blue-600"></i> |
| <h1 class="text-5xl font-bold text-gray-800">Gelie Web</h1> |
| </div> |
| </div> |
| |
| <div class="grid grid-cols-1 md:grid-cols-3 gap-8"> |
| |
| <div class="bg-white p-6 rounded-xl shadow-lg"> |
| <div class="flex items-center justify-between mb-6"> |
| <h2 class="text-2xl font-bold text-blue-600">Pedido Feito</h2> |
| <div class="bg-blue-100 text-blue-800 px-3 py-1 rounded-full text-sm font-semibold" id="madeCountTV">0</div> |
| </div> |
| <div id="madeOrders" class="space-y-4"> |
| |
| </div> |
| </div> |
| |
| |
| <div class="bg-white p-6 rounded-xl shadow-lg"> |
| <div class="flex items-center justify-between mb-6"> |
| <h2 class="text-2xl font-bold text-yellow-600">Em Preparação</h2> |
| <div class="bg-yellow-100 text-yellow-800 px-3 py-1 rounded-full text-sm font-semibold" id="preparingCountTV">0</div> |
| </div> |
| <div id="preparingOrders" class="space-y-4"> |
| |
| </div> |
| </div> |
| |
| |
| <div class="bg-white p-6 rounded-xl shadow-lg"> |
| <div class="flex items-center justify-between mb-6"> |
| <h2 class="text-2xl font-bold text-green-600">Finalizado</h2> |
| <div class="bg-green-100 text-green-800 px-3 py-1 rounded-full text-sm font-semibold" id="finishedCountTV">0</div> |
| </div> |
| <div id="finishedOrders" class="space-y-4"> |
| |
| </div> |
| </div> |
| </div> |
| |
| <div class="mt-12 text-center"> |
| <button onclick="toggleTVView()" class="bg-blue-600 text-white px-6 py-3 rounded-lg font-semibold hover:bg-blue-700 transition"> |
| <i class="fas fa-arrow-left mr-2"></i>Voltar ao Painel |
| </button> |
| </div> |
| </div> |
| </div> |
|
|
| <script> |
| |
| let orders = []; |
| let orderCounter = 1000; |
| |
| |
| const adminPanel = document.getElementById('adminPanel'); |
| const tvView = document.getElementById('tvView'); |
| const orderForm = document.getElementById('orderForm'); |
| const ordersTableBody = document.getElementById('ordersTableBody'); |
| |
| |
| const madeCount = document.getElementById('madeCount'); |
| const preparingCount = document.getElementById('preparingCount'); |
| const finishedCount = document.getElementById('finishedCount'); |
| |
| |
| const madeCountTV = document.getElementById('madeCountTV'); |
| const preparingCountTV = document.getElementById('preparingCountTV'); |
| const finishedCountTV = document.getElementById('finishedCountTV'); |
| |
| |
| const madeOrders = document.getElementById('madeOrders'); |
| const preparingOrders = document.getElementById('preparingOrders'); |
| const finishedOrders = document.getElementById('finishedOrders'); |
| |
| |
| function toggleTVView() { |
| adminPanel.classList.toggle('hidden'); |
| tvView.classList.toggle('hidden'); |
| updateTVView(); |
| } |
| |
| |
| function generateOrderCode() { |
| orderCounter++; |
| return 'GEL' + orderCounter.toString().padStart(4, '0'); |
| } |
| |
| |
| function addOrder(type, flavor, quantity, price) { |
| const order = { |
| code: generateOrderCode(), |
| type: type, |
| flavor: flavor, |
| quantity: quantity, |
| price: price.toFixed(2), |
| status: 'made', |
| timestamp: new Date().getTime() |
| }; |
| |
| orders.push(order); |
| updateOrdersTable(); |
| updateCounts(); |
| |
| |
| orderForm.reset(); |
| } |
| |
| |
| function updateOrderStatus(code, newStatus) { |
| const orderIndex = orders.findIndex(order => order.code === code); |
| if (orderIndex !== -1) { |
| orders[orderIndex].status = newStatus; |
| orders[orderIndex].timestamp = new Date().getTime(); |
| updateOrdersTable(); |
| updateCounts(); |
| updateTVView(); |
| } |
| } |
| |
| |
| function deleteOrder(code) { |
| orders = orders.filter(order => order.code !== code); |
| updateOrdersTable(); |
| updateCounts(); |
| updateTVView(); |
| } |
| |
| |
| function updateOrdersTable() { |
| ordersTableBody.innerHTML = ''; |
| |
| |
| const sortedOrders = [...orders].sort((a, b) => b.timestamp - a.timestamp); |
| |
| sortedOrders.forEach(order => { |
| const row = document.createElement('tr'); |
| |
| |
| let statusClass, statusText; |
| switch(order.status) { |
| case 'made': |
| statusClass = 'bg-blue-100 text-blue-800'; |
| statusText = 'Pedido Feito'; |
| break; |
| case 'preparing': |
| statusClass = 'bg-yellow-100 text-yellow-800'; |
| statusText = 'Em Preparação'; |
| break; |
| case 'finished': |
| statusClass = 'bg-green-100 text-green-800'; |
| statusText = 'Finalizado'; |
| break; |
| } |
| |
| row.innerHTML = ` |
| <td class="px-6 py-4 whitespace-nowrap font-medium text-gray-900">${order.code}</td> |
| <td class="px-6 py-4 whitespace-nowrap">${order.type}</td> |
| <td class="px-6 py-4 whitespace-nowrap">${order.flavor}</td> |
| <td class="px-6 py-4 whitespace-nowrap">${order.quantity}</td> |
| <td class="px-6 py-4 whitespace-nowrap">R$ ${order.price}</td> |
| <td class="px-6 py-4 whitespace-nowrap"> |
| <span class="px-2 py-1 rounded-full text-xs font-semibold ${statusClass}">${statusText}</span> |
| </td> |
| <td class="px-6 py-4 whitespace-nowrap space-x-2"> |
| ${order.status !== 'made' ? '' : `<button onclick="updateOrderStatus('${order.code}', 'preparing')" class="text-yellow-600 hover:text-yellow-800"> |
| <i class="fas fa-utensils"></i> |
| </button>`} |
| ${order.status !== 'preparing' ? '' : `<button onclick="updateOrderStatus('${order.code}', 'finished')" class="text-green-600 hover:text-green-800"> |
| <i class="fas fa-check-circle"></i> |
| </button>`} |
| <button onclick="deleteOrder('${order.code}')" class="text-red-600 hover:text-red-800"> |
| <i class="fas fa-trash-alt"></i> |
| </button> |
| </td> |
| `; |
| |
| ordersTableBody.appendChild(row); |
| }); |
| } |
| |
| |
| function updateCounts() { |
| const madeOrdersCount = orders.filter(order => order.status === 'made').length; |
| const preparingOrdersCount = orders.filter(order => order.status === 'preparing').length; |
| const finishedOrdersCount = orders.filter(order => order.status === 'finished').length; |
| |
| madeCount.textContent = madeOrdersCount; |
| preparingCount.textContent = preparingOrdersCount; |
| finishedCount.textContent = finishedOrdersCount; |
| |
| madeCountTV.textContent = madeOrdersCount; |
| preparingCountTV.textContent = preparingOrdersCount; |
| finishedCountTV.textContent = finishedOrdersCount; |
| } |
| |
| |
| function updateTVView() { |
| madeOrders.innerHTML = ''; |
| preparingOrders.innerHTML = ''; |
| finishedOrders.innerHTML = ''; |
| |
| |
| const sortedOrders = [...orders].sort((a, b) => a.timestamp - b.timestamp); |
| |
| sortedOrders.forEach(order => { |
| const orderCard = document.createElement('div'); |
| orderCard.className = 'order-card bg-white p-4 rounded-lg shadow-md border-l-4'; |
| |
| |
| let borderColor; |
| switch(order.status) { |
| case 'made': |
| borderColor = 'border-blue-500'; |
| break; |
| case 'preparing': |
| borderColor = 'border-yellow-500 pulse'; |
| break; |
| case 'finished': |
| borderColor = 'border-green-500'; |
| break; |
| } |
| |
| orderCard.classList.add(borderColor); |
| |
| orderCard.innerHTML = ` |
| <div class="flex justify-between items-start mb-2"> |
| <h3 class="text-xl font-bold text-gray-800">${order.code}</h3> |
| <span class="text-lg font-semibold">R$ ${order.price}</span> |
| </div> |
| <div class="mb-1"> |
| <span class="font-medium">${order.type}</span> - ${order.flavor} |
| </div> |
| <div class="text-gray-600"> |
| Quantidade: ${order.quantity} |
| </div> |
| `; |
| |
| |
| switch(order.status) { |
| case 'made': |
| madeOrders.appendChild(orderCard); |
| break; |
| case 'preparing': |
| preparingOrders.appendChild(orderCard); |
| break; |
| case 'finished': |
| finishedOrders.appendChild(orderCard); |
| break; |
| } |
| }); |
| } |
| |
| |
| orderForm.addEventListener('submit', function(e) { |
| e.preventDefault(); |
| |
| const type = document.getElementById('icecreamType').value; |
| const flavor = document.getElementById('flavor').value; |
| const quantity = parseInt(document.getElementById('quantity').value); |
| const price = parseFloat(document.getElementById('price').value); |
| |
| addOrder(type, flavor, quantity, price); |
| }); |
| |
| |
| function initializeSampleData() { |
| addOrder('Casquinha', 'Chocolate', 1, 5.00); |
| addOrder('Cascão', 'Morango', 2, 12.00); |
| addOrder('Copo', 'Napolitano', 1, 8.00); |
| |
| |
| setTimeout(() => { |
| updateOrderStatus('GEL1000', 'preparing'); |
| updateOrderStatus('GEL1001', 'preparing'); |
| }, 1000); |
| |
| setTimeout(() => { |
| updateOrderStatus('GEL1000', 'finished'); |
| }, 3000); |
| } |
| |
| |
| initializeSampleData(); |
| </script> |
| <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=mdarlen/ufopa" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> |
| </html> |