Merge pull request #4 from welton89/dev_home

fixed: timezone de orders alterado para exibição utc -3
This commit is contained in:
Welton Moura
2025-07-02 13:28:09 -03:00
committed by GitHub
30 changed files with 700 additions and 3518 deletions

View File

@@ -6,7 +6,7 @@ from django.shortcuts import render, redirect
from comandas.models import Comanda, ProductComanda from comandas.models import Comanda, ProductComanda
from orders.models import Order from orders.models import Order
from products.models import Product from products.models import Product
from payments.models import Payments from payments.models import Payments, somar
from typePay.models import TypePay from typePay.models import TypePay
from gestaoRaul.decorators import group_required from gestaoRaul.decorators import group_required
from websocket_client.websocketClient import enviar_mensagem from websocket_client.websocketClient import enviar_mensagem
@@ -29,80 +29,6 @@ from asgiref.sync import async_to_sync
# print(f"Erro ao enviar mensagem via websocket: {e}") # print(f"Erro ao enviar mensagem via websocket: {e}")
def somar(consumo:ProductComanda, comanda:Comanda):
parcial = Payments.objects.filter(comanda=comanda)
totalParcial = Decimal(0)
total:Decimal = Decimal(0)
for p in parcial:
totalParcial += p.value
for produto in consumo:
total += Decimal(produto.product.price)
valores = {
'total':total,
'parcial':totalParcial,
'taxa': round(total * Decimal(0.1), 2),
'totalSemTaxa':total - totalParcial,
'totalComTaxa': round((total - totalParcial)+(total * Decimal(0.1)),2)
}
return valores
def listProduct(request, comanda_id):
product = request.GET.get("search-product")
allProducts = Product.objects.filter(name__icontains=product)
products = []
for p in allProducts:
if p.active == True:
products.append(p)
return render(request, "htmx_components/comandas/htmx_list_products.html", {"products": products,'comanda_id':comanda_id})
@group_required(groupName='Garçom')
def addProduct(request, product_id, comanda_id):
config = {
'taxa': False
}
obs = request.GET.get("obs")
product_comanda = ProductComanda(comanda_id=comanda_id, product_id=product_id)
product_comanda.save()
product = Product.objects.get(id=product_id)
comanda = Comanda.objects.get(id=comanda_id)
parcial = Payments.objects.filter(comanda=comanda)
if product.cuisine == True:
order = Order(id_comanda=comanda, id_product=product, productComanda=product_comanda, obs='')
order.save()
msg = JsonResponse({
'type': 'broadcast',
'message': f"""
<div class="m-card" id="m-card-{order.id}">
<h4>{product.name}</h4>
<h4 id="obs-{order.id}"> {order.obs}</h4>
<h4>{comanda.name} - {comanda.mesa.name}</h4>
<h4> {order.queue.strftime("%d/%m/%Y - %H:%M")}</h4>
<h4> Atendente: {comanda.user.first_name}</h4>
<form method="path" action="/pedidos/preparing/{order.id}/">
<button class="btn-primary" type="submit">Preparar</button>
</form>
</div>
""",
'local':'cozinha',
'tipo':'add',
'id':order.id,
'speak': f'Novo pedido! {product.name}, para {comanda.name}.'
})
try:
# Chama a função async dentro da view normal
async_to_sync(enviar_mensagem)(mensagem)
# return JsonResponse({"status": "Mensagem enviada com sucesso"})
except Exception as e:
print("Erro add product websocket: ",e)
# return JsonResponse({"status": "Erro", "erro": str(e)}, status=500)
# asyncio.run(enviar_mensagem(msg))
consumo = ProductComanda.objects.filter(comanda=comanda_id)
valores = somar(consumo,comanda)
return render(request, "htmx_components/comandas/htmx_list_products_in_comanda.html",{'config':config, 'valores':valores,'parcials':parcial,'consumo': consumo,'comanda':comanda})
@group_required(groupName='Garçom') @group_required(groupName='Garçom')
@@ -127,12 +53,22 @@ def removeProductComanda(request, productComanda_id):
'id':order.id, 'id':order.id,
'speak': f'Pedido cancelado! {order.id_product.name}.' 'speak': f'Pedido cancelado! {order.id_product.name}.'
}) })
asyncio.run(enviar_mensagem(msg)) # asyncio.run(enviar_mensagem(msg))
# order.delete() # order.delete()
consumo = ProductComanda.objects.filter(comanda=comanda)
valores = somar(consumo,comanda)
else: else:
product_comanda.delete() product_comanda.delete()
consumo = ProductComanda.objects.filter(comanda=comanda)
valores = somar(consumo,comanda)
return render(request, "htmx_components/comandas/htmx_list_products_in_comanda.html",{'config':config, 'valores': valores,'parcials':parcial,'consumo': consumo, 'comanda':comanda}) return render(request,
"htmx_components/comandas/htmx_list_products_in_comanda.html",
{'config':config,
'valores': valores,
'parcials':parcial,
'consumo': consumo,
'comanda':comanda})
else: else:
pass pass

View File

@@ -13,6 +13,34 @@ Detalhes {{comanda.name}}
{% block 'head' %} {% block 'head' %}
<link rel="stylesheet" href="{% static 'comandas/css/viewcomanda.css' %}"> <link rel="stylesheet" href="{% static 'comandas/css/viewcomanda.css' %}">
<style>
.swal2-popup {
position: relative; /* Necessário para o posicionamento absoluto do botão */
}
.posi {
position: absolute !important;
background-color: rgba(72, 72, 72, 0.151);
color: rgba(255, 255, 255, 0.452);
border: 2px solid rgba(239, 239, 239, 0.107);
border-radius: 35px;
padding: 0px 15px 3px 15px ;
align-self: center;
font-size: 32px;
top: 0.1em;
right: 0.1em;
scale: 0.8;
}
.posi:hover{
background-color: rgba(183, 3, 3, 0.598);
color: rgb(255, 255, 255);
}
.custom-toast-container {
z-index: 99999 !important;
}
.swal2-container {
z-index: 9999 !important;
}
</style>
{% endblock %} {% endblock %}
@@ -22,7 +50,7 @@ Detalhes {{comanda.name}}
<input hidden id="id-temp" type="number"> <input hidden id="id-temp" type="number">
<div class="grid-container" > <div class="grid-container" >
<div style="display: flex;padding: 5px;gap:8px"> <div style="display: flex;padding: 5px;gap:8px">
<button class="btn-primary" id="openModal" onclick="openModal()" popovertarget="addProduct" <button class="btn-primary" id="openModal" onclick="openModal()"
{% if comanda.status != 'OPEN'%} {% if comanda.status != 'OPEN'%}
disabled disabled
{% endif %} {% endif %}
@@ -71,6 +99,7 @@ Detalhes {{comanda.name}}
</div> </div>
<div> <div>
<input hidden type="text" id="h-mesaId" value="{{comanda.mesa.id}}"> <input hidden type="text" id="h-mesaId" value="{{comanda.mesa.id}}">
<input hidden type="text" id="id-comanda" value="{{comanda.id}}">
<span id="name-comanda">Nome: {{comanda.name}} | </span> <span id="name-comanda">Nome: {{comanda.name}} | </span>
<span id="mesa-comanda">Local: {{comanda.mesa}}</span> <span id="mesa-comanda">Local: {{comanda.mesa}}</span>
@@ -92,19 +121,20 @@ Detalhes {{comanda.name}}
{% for item in consumo%} {% for item in consumo%}
<tr> <tr id="item-{{item.id}}">
<td id="id-for-print-{{item.id}}"> <td id="id-for-print-{{item.id}}">
{{item.product.name}} <spam style="cursor: pointer;" onclick="inforOrders({{item.id}})">
{{item.product.name}}</spam>
{% if item.product.cuisine == True %} {% if item.product.cuisine == True %}
<input hidden id="{{item.id}}-obsOrder" type="order" value="{{item.id | obsOrder}}"> <input hidden id="{{item.id}}-obsOrder" type="order" value="{{item.id | obsOrder}}">
<span id="tooltip-id-{{item.id}}" data-tooltip="{{item.id | obsOrder}}" data-flow="top">
<img <img
onclick="openModalObs({{item.id}})" onclick="openModalObs({{item.id}})"
src="{% static 'midia/icons/note.svg' %}" src="{% static 'midia/icons/note.svg' %}"
style="width: 25px; height: 35px; cursor: pointer;"> style="width: 25px; height: 35px; cursor: pointer;">
</img> </img>
</span>
<img <img
onclick="printOrder({{item.id}})" onclick="printOrder({{item.id}})"
@@ -119,13 +149,12 @@ Detalhes {{comanda.name}}
{% if comanda.status != 'OPEN'%} {% if comanda.status != 'OPEN'%}
{% else %} {% else %}
<td> <td>
<img <img
onclick="removeProductComanda({{item.id}}, '{{item.product.name}}')"
src="{% static 'midia/icons/delete.svg' %}" src="{% static 'midia/icons/delete.svg' %}"
style="width: 35px; height: 35px; cursor: pointer;" style="width: 35px; height: 35px; cursor: pointer;"
hx-get="{% url 'removeProductComanda' item.id %} " >
hx-trigger="click"
hx-target="#list-products-comanda"
hx-confirm="Tem certeza que deseja excluir o produto {{item.product.name}}?" >
</img> </img>
</td> </td>
{% endif %} {% endif %}
@@ -169,48 +198,20 @@ Detalhes {{comanda.name}}
</div> </div>
<div hidden id="addProduct" >
{% csrf_token %}
<input type="text" oninput="searchProduct()" id="search-product" name="search-product" placeholder="Buscar Produto" ><br>
<div id="addProduct" popover class="popover">
<div id="toast-add" class="toast-add">
<p id="toast-message-add"></p>
</div>
<form id="productForm" >
<div style="display: flex;justify-content: space-between;">
<h2>Adicionar Produto</h2> <img class="close" src="{% static 'midia/icons/close-circle.svg' %}" onclick="closeModal()">
</div>
<input type="text" id="search-product" name="search-product" placeholder="Buscar Produto" hx-get="{% url 'listProduct' comanda.id %}" hx-trigger="keyup" hx-target="#product-list"><br>
<div id="product-list" class="grid-list-products"> <div id="product-list" class="grid-list-products">
{% for product in products %} {% for product in products %}
<div class="card-product" onclick="addProductComanda({{product.id}}, {{comanda.id}}, '{{product.cuisine}}')" > <div class="card-product" onclick="addProductComanda({{product.id}}, {{comanda.id}}, '{{product.cuisine}}')" >
{{product.name}} <br> {{product.name}} <br>
R$ {{product.price}} R$ {{product.price}}
</div > </div >
{% endfor %} {% endfor %}
</div> </div>
</form>
</div> </div>
<dialog id="modal-obs" style="display: none;">
<article>
<h2>Observação do Pedido</h2>
<p>Observações do pedido que serão enviadas para o preparo na cozinha.</p>
<textarea placeholder="Ex.: pedido sem cebola. para viagem." name="obs" id="obs"></textarea>
<div>
<div style="display: flex;gap: 10px;">
<button type="submit" class="btn-primary" onclick="addOrder()" >OK</button>
<button type="button" class="btn-cancel" onclick="closeModalObs()">Cancela</button>
</div>
</article>
</dialog>
<dialog id="payment-comanda" style="display: none;" > <dialog id="payment-comanda" style="display: none;" >
<article> <article>
<form action="{% url 'paymentComanda' comanda.id %}" method="post"> <form action="{% url 'paymentComanda' comanda.id %}" method="post">

View File

@@ -62,7 +62,7 @@ def obsOrder(id):
try: try:
productComanda_obj = ProductComanda.objects.get(pk=id) productComanda_obj = ProductComanda.objects.get(pk=id)
order = Order.objects.get(productComanda=productComanda_obj) order = Order.objects.get(productComanda=productComanda_obj)
return order.obs return order
except: except:
return '' return ''

View File

@@ -13,6 +13,8 @@ urlpatterns = [
path('notificacao/', views.notificacao, name='notificacao'), path('notificacao/', views.notificacao, name='notificacao'),
path('editOrders/<int:productComanda_id>/<str:obs>', views.editOrders, name='editOrders'), path('editOrders/<int:productComanda_id>/<str:obs>', views.editOrders, name='editOrders'),
path('closeComanda/<int:comanda_id>/', views.closeComanda, name='closeComanda'), path('closeComanda/<int:comanda_id>/', views.closeComanda, name='closeComanda'),
path('listProduct/<int:comanda_id>/<str:product>/', views.listProduct, name='listProduct'),
path('product=<int:product_id>/comanda=<int:comanda_id>/', views.addProduct, name='addProduct'),
@@ -20,10 +22,7 @@ urlpatterns = [
htmx_urlpatterns = [ htmx_urlpatterns = [
# path('listProduct/', htmx_views.listProduct, name='listProduct'), path('removeProductComanda/<int:productComanda_id>/', htmx_views.removeProductComanda, name='removeProductComanda'),
path('listProduct/<int:comanda_id>/', htmx_views.listProduct, name='listProduct'),
path('addProduct<int:product_id>/<int:comanda_id>/', htmx_views.addProduct, name='addProduct'),
path('removeProductComanda<int:productComanda_id>/', htmx_views.removeProductComanda, name='removeProductComanda'),
path('reopenComanda<int:comanda_id>/', htmx_views.reopenComanda, name='reopenComanda'), path('reopenComanda<int:comanda_id>/', htmx_views.reopenComanda, name='reopenComanda'),
path('paymentComanda<int:comanda_id>/', htmx_views.paymentComanda, name='paymentComanda'), path('paymentComanda<int:comanda_id>/', htmx_views.paymentComanda, name='paymentComanda'),
path('paymentParcial<int:comanda_id>/', htmx_views.paymentParcial, name='paymentParcial'), path('paymentParcial<int:comanda_id>/', htmx_views.paymentParcial, name='paymentParcial'),

View File

@@ -23,23 +23,6 @@ def comandas(request):
return render(request, 'comandas.html', {'comandas': comandas, 'mesas': mesas}) return render(request, 'comandas.html', {'comandas': comandas, 'mesas': mesas})
# def somar(consumo:ProductComanda, comanda:Comanda):
# parcial = Payments.objects.filter(comanda=comanda)
# totalParcial = Decimal(0)
# total:Decimal = Decimal(0)
# for p in parcial:
# totalParcial += p.value
# for produto in consumo:
# total += Decimal(produto.product.price)
# valores = {
# 'total':total,
# 'parcial':totalParcial,
# 'taxa': round(total * Decimal(0.1), 2),
# 'totalSemTaxa':total - totalParcial,
# 'totalComTaxa': round((total - totalParcial)+(total * Decimal(0.1)),2)
# }
# return valores
@group_required(groupName='Garçom') @group_required(groupName='Garçom')
def viewComanda(request): def viewComanda(request):
config = { config = {
@@ -167,3 +150,61 @@ def closeComanda(request, comanda_id):
comanda.status = "PAYING" comanda.status = "PAYING"
comanda.save() comanda.save()
return JsonResponse({'status': 'ok', 'obs':'order.obs'}) return JsonResponse({'status': 'ok', 'obs':'order.obs'})
@group_required(groupName='Garçom')
def addProduct(request, product_id, comanda_id):
config = {
'taxa': False
}
obs = request.GET.get("obs")
product_comanda = ProductComanda(comanda_id=comanda_id, product_id=product_id)
product_comanda.save()
product = Product.objects.get(id=product_id)
comanda = Comanda.objects.get(id=comanda_id)
parcial = Payments.objects.filter(comanda=comanda)
if product.cuisine == True:
order = Order(id_comanda=comanda, id_product=product, productComanda=product_comanda, obs='')
order.save()
msg = JsonResponse({
'type': 'broadcast',
'message': f"""
<div class="m-card" id="m-card-{order.id}">
<h4>{product.name}</h4>
<h4 id="obs-{order.id}"> {order.obs}</h4>
<h4>{comanda.name} - {comanda.mesa.name}</h4>
<h4> {order.queue.strftime("%d/%m/%Y - %H:%M")}</h4>
<h4> Atendente: {comanda.user.first_name}</h4>
<form method="path" action="/pedidos/preparing/{order.id}/">
<button class="btn-primary" type="submit">Preparar</button>
</form>
</div>
""",
'local':'cozinha',
'tipo':'add',
'id':order.id,
'speak': f'Novo pedido! {product.name}, para {comanda.name}.'
})
try:
# Chama a função async dentro da view normal
async_to_sync(enviar_mensagem)(mensagem)
# return JsonResponse({"status": "Mensagem enviada com sucesso"})
except Exception as e:
print("Erro add product websocket: ",e)
# return JsonResponse({"status": "Erro", "erro": str(e)}, status=500)
# asyncio.run(enviar_mensagem(msg))
consumo = ProductComanda.objects.filter(comanda=comanda_id)
valores = somar(consumo,comanda)
return render(request, "htmx_components/comandas/htmx_list_products_in_comanda.html",{'config':config, 'valores':valores,'parcials':parcial,'consumo': consumo,'comanda':comanda})
def listProduct(request, comanda_id, product):
allProducts = Product.objects.filter(name__icontains=product)
products = []
for p in allProducts:
if p.active == True:
products.append(p)
return render(request, "htmx_components/comandas/htmx_list_products.html", {"products": products,'comanda_id':comanda_id})

Binary file not shown.

View File

@@ -106,26 +106,26 @@ WSGI_APPLICATION = 'gestaoRaul.wsgi.application'
# Database # Database
# https://docs.djangoproject.com/en/5.1/ref/settings/#databases # https://docs.djangoproject.com/en/5.1/ref/settings/#databases
# DATABASES = {
# 'default': {
# 'ENGINE': 'django.db.backends.sqlite3',
# 'NAME': BASE_DIR / 'db.sqlite3',
# }
# }
DATABASES = { DATABASES = {
'default': { 'default': {
'ENGINE': DB_ENGINE, 'ENGINE': 'django.db.backends.sqlite3',
'NAME': DB_NAME, 'NAME': BASE_DIR / 'db.sqlite3',
'USER': DB_USER,
'PASSWORD': DB_PASSWORD,
'HOST': DB_HOST,
'PORT': DB_PORT,
} }
} }
# DATABASES = {
# 'default': {
# 'ENGINE': DB_ENGINE,
# 'NAME': DB_NAME,
# 'USER': DB_USER,
# 'PASSWORD': DB_PASSWORD,
# 'HOST': DB_HOST,
# 'PORT': DB_PORT,
# }
# }
# Password validation # Password validation
# https://docs.djangoproject.com/en/5.1/ref/settings/#auth-password-validators # https://docs.djangoproject.com/en/5.1/ref/settings/#auth-password-validators

View File

@@ -35,6 +35,7 @@ RRB&C - DashBoard
</div> </div>
<img src="{% static 'midia/icons/cart.svg' %}" > <img src="{% static 'midia/icons/cart.svg' %}" >
</div> </div>
<div class="card-resumo"> <div class="card-resumo">
<div> <div>
<p>Ticket médio</p> <p>Ticket médio</p>
@@ -42,10 +43,12 @@ RRB&C - DashBoard
</div> </div>
<img src="{% static 'midia/icons/ticket.svg' %}" > <img src="{% static 'midia/icons/ticket.svg' %}" >
</div> </div>
<div class="card"> <div class="card">
<h4> Mais vendidos </h4> <h4> Mais vendidos </h4>
<canvas id="vendas" style="width:100%;height: 85%;max-width:100%;"></canvas> <canvas id="vendas" style="width:100%;height: 85%;max-width:100%;"></canvas>
</div> </div>
<div class="card"> <div class="card">
<h4>Tempo médio na cozinha</h4> <h4>Tempo médio na cozinha</h4>
<div style="width:95%;max-width:100%;padding: 10px 30px 10px 30px;"> <div style="width:95%;max-width:100%;padding: 10px 30px 10px 30px;">

View File

@@ -1,4 +1,6 @@
from django.db import models from django.db import models
from django.utils.formats import date_format
from datetime import timedelta
from products.models import Product from products.models import Product
from comandas.models import Comanda, ProductComanda from comandas.models import Comanda, ProductComanda
@@ -16,4 +18,14 @@ class Order(models.Model):
canceled = models.DateTimeField(null=True, blank=True) canceled = models.DateTimeField(null=True, blank=True)
def __str__(self): def __str__(self):
return f"Pedido {self.id} - Produto: {self.id_product} - Comanda: {self.id_comanda.name}" status = 'Em espera'
datetime = self.queue - timedelta(hours=3)
if self.preparing:
status = 'Preparando'
if self.finished:
status = 'Pronto'
if self.delivered:
status = 'Entregue'
return f"{self.id_product}| {self.obs}|{status}|{self.id_comanda.name}|{self.id_comanda.mesa.name}|{date_format(datetime, 'd/m/Y H:i')}"

View File

@@ -23,7 +23,7 @@
<body> <body>
{% block 'body' %} {% block 'body' %}
<div class="container"> <div class="container">
<h1>Pedidos cozinha</h1> <h1 id="title">Pedidos cozinha</h1>
<div class="kanban-board"> <div class="kanban-board">
{% csrf_token %} {% csrf_token %}
<div class="column"> <div class="column">

View File

@@ -37,7 +37,7 @@ Produtos
<td id="price-{{product.id}}" >R$ {{product.price}}</td> <td id="price-{{product.id}}" >R$ {{product.price}}</td>
<td class="hide-on-mobile" id="quantity-{{product.id}}" >{{product.quantity}}</td> <td class="hide-on-mobile" id="quantity-{{product.id}}" >{{product.quantity}}</td>
<td class="hide-on-mobile" id="category-{{product.id}}" >{{product.category.name}}</td> <td class="hide-on-mobile" id="category-{{product.id}}" >{{product.category.name}}</td>
<td> <td >
<div class="grid-buttons"> <div class="grid-buttons">
<img <img
src="{% static 'midia/icons/edit.svg' %}" src="{% static 'midia/icons/edit.svg' %}"

View File

@@ -11,7 +11,7 @@
<link rel="shortcut icon" href="{% static 'midia/favicon/favicon.ico' %}" /> <link rel="shortcut icon" href="{% static 'midia/favicon/favicon.ico' %}" />
{% load pwa %} {% load pwa %}
{% progressive_web_app_meta %} {% progressive_web_app_meta %}
<link rel="stylesheet" href="{% static 'pico.css' %}"> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.min.css">
<link rel="stylesheet" href="{% static 'base.css' %}"> <link rel="stylesheet" href="{% static 'base.css' %}">
{% block 'head' %} {% block 'head' %}
@@ -19,14 +19,15 @@
<title> {% block 'title' %}{% endblock %} </title> <title> {% block 'title' %}{% endblock %} </title>
</head> </head>
<div>
<header class="p-header"> <header>
<div class="p-header">
<nav class="nav-bar"> <nav class="nav-bar">
<div class="logo"> <div class="logo">
<h1> <h1>
<img src="{% static 'midia/logo.png' %}" width="60"> <img src="{% static 'midia/logo.png' %}" width="60">
</h1> </h1>
<!-- <button id="icon-notify" style="border: none; margin-left: 10px; border-radius: 20px; height: 40px;width: 40px; padding: 2px; align-self: center;" onclick="cookieNotificacao()" >🔊</button> --> <button id="icon-notify" style="border: none; margin-left: 10px; border-radius: 20px; height: 40px;width: 40px; padding: 2px; align-self: center;" onclick="cookieNotificacao()" >🔊</button>
</div> </div>
<div class="nav-list"> <div class="nav-list">
<ul> <ul>
@@ -57,90 +58,65 @@
<a href="{% url 'logout' %}" style="width: 50px;"><img src="{% static 'midia/icons/logout.svg' %}" style="width: 40px;"></a> <a href="{% url 'logout' %}" style="width: 50px;"><img src="{% static 'midia/icons/logout.svg' %}" style="width: 40px;"></a>
</div> </div>
<div class="mobile-menu-icon"> <div class="mobile-menu-icon">
<button onclick="menuShow()"><img class="icon" src="https://raw.githubusercontent.com/Larissakich/menu_responsivo/6e3b09504434628c1b01f65b7d8ccf6ace3225cb/menu%20responsivo/assets/img/menu_white_36dp.svg" alt=""></button> <button onclick="menuShow()">
<img
class="icon"
src="https://raw.githubusercontent.com/Larissakich/menu_responsivo/6e3b09504434628c1b01f65b7d8ccf6ace3225cb/menu%20responsivo/assets/img/menu_white_36dp.svg"
alt="">
</button>
</div> </div>
</nav> </nav>
<div class="header-mobile">
<div class="logo">
<button id="icon-notify" style="border: none; margin-left: 10px; border-radius: 20px; height: 40px;width: 40px; padding: 2px; align-self: center;" onclick="cookieNotificacao()" >🔊</button>
<span>RRBEC</span>
</div> </div>
<div class="header-mobile">
<button class="nav-toggle"><i for="menu-toggle" class="fas fa-bars"></i></button> <button class="nav-toggle"><i for="menu-toggle" class="fas fa-bars"></i></button>
<nav id="nav-links" class="nav-links"> <nav id="nav-links" class="nav-links">
<div style="
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
position: absolute;
top:20px;
">
<div class="logo">
<button
id="icon-notify"
style="border: none; margin-left: 10px; border-radius: 20px; height: 40px;width: 40px; padding: 2px; align-self: center;"
onclick="cookieNotificacao()" >🔊
</button>
</div>
<div id="user-info">{{user.first_name}} {{user.last_name}}</div>
<a href="{% url 'logout' %}" style="width: 50px;padding: 3px;"><img src="{% static 'midia/icons/logout.svg' %}" style="width: 40px;"></a>
</div>
<div class="nav-component"> <div class="nav-component">
{% if user|groupUser:"Gerente" %} {% if user|groupUser:"Gerente" %}
<a href="{% url 'home' %}" class="nav-link">DashBoard</a> <a href="{% url 'home' %}" class="nav-link">DashBoard</a>
<a href="{% url 'products' %}" class="nav-link"> Produtos</a>
{% endif %} {% endif %}
<a href="{% url 'comandas' %}" class="nav-link">Comandas</a> <a href="{% url 'comandas' %}" class="nav-link">Comandas</a>
<a href="{% url 'pedidos' %}" class="nav-link">Cozinha</a> <a href="{% url 'pedidos' %}" class="nav-link">Cozinha</a>
<a href="{% url 'mapMesas' %}" class="nav-link">Mapa</a> <a href="{% url 'mapMesas' %}" class="nav-link">Mapa</a>
<a href="{% url 'products' %}" class="nav-link"> Produtos</a>
<a href="{% url 'clients' %}" class="nav-link"> Clientes</a> <a href="{% url 'clients' %}" class="nav-link"> Clientes</a>
{% if user|groupUser:"Gerente" %} {% if user|groupUser:"Admin" %}
<a href="{% url 'admin:index' %}" class="nav-link">Admin</a> <a href="{% url 'admin:index' %}" class="nav-link">Admin</a>
{% endif %} {% endif %}
<!-- <div class="dropdown">
<li class="">Cadastros<img class="img-drop" src="{% static 'midia/icons/down.svg' %}" style="width: 35px;"> </li>
<div class="dropdown-content">
<a href="{% url 'products' %}" class="nav-link"> Produtos</a>
<a href="{% url 'categories' %}" class="nav-link"> Categorias</a>
<a href="{% url 'clients' %}" class="nav-link"> Clientes</a>
<a href="{% url 'admin:index' %}" class="nav-link">Admin</a>
</div>
</li>
</div> -->
</div> </div>
</nav> </nav>
</div> </div>
<!-- <div class="mobile-menu">
<ul>
{% if user|groupUser:"Gerente" %}
<li class="nav-item"><a href="{% url 'home' %}" class="nav-link">Início</a></li>
{% endif %}
<li class="nav-item"><a href="{% url 'comandas' %}" class="nav-link">Comandas</a></li>
<li class="nav-item"><a href="{% url 'pedidos' %}" class="nav-link">Cozinha</a></li>
<li class="nav-item"><a href="{% url 'mapMesas' %}" class="nav-link">Mapa</a></li>
<div class="dropdown">
<li class="nav-item">Cadastros<img class="img-drop" src="{% static 'midia/icons/down.svg' %}" style="width: 35px;"> </li>
<div class="dropdown-content">
<a href="{% url 'products' %}" class="nav-link"> Produtos</a>
<a href="{% url 'categories' %}" class="nav-link"> Categorias</a>
<a href="{% url 'clients' %}" class="nav-link"> Clientes</a>
<a href="{% url 'admin:index' %}" class="nav-link">Admin</a>
</div>
</div>
</ul>
<div class="logout-button">
{{ user.first_name }} {{ user.last_name }}
<a href="{% url 'logout' %}"><img src="{% static 'midia/icons/logout.svg' %}" style="width: 40px;"></a>
</div>
</div> -->
</header> </header>
</div>
<br> <br>
<body>
{% block 'body' %} {% block 'body' %}
{% endblock %} {% endblock %}
<script src="{% static 'htmx_base.js' %}"></script> <script src="{% static 'htmx_base.js' %}"></script>
@@ -149,7 +125,6 @@
<div id="toast" class="toast"> <div id="toast" class="toast">
<p id="toast-message"></p> <p id="toast-message"></p>
</div> </div>
</body>
@@ -161,23 +136,9 @@
<!-- <div class="navigation">
<ul>
<li><a href="#"><span onclick="openFullscreen()" class="icon"><i class="fas fa-home"></i></span></a></li>
<li><a href="#"><span class="icon"><i class="fas fa-user"></i></span></a></li>
<li><a href="#"><span class="icon"><i class="fas fa-cog"></i></span></a></li>
<li><a href="#"><span class="icon"><i class="fas fa-envelope"></i></span></a></li>
<li><a href="#"><span class="icon"><i class="fas fa-sign-out-alt"></i></span></a></li>
</ul>
</div> -->
<footer> <footer>
</footer> </footer>
</html> </html>

View File

@@ -3,11 +3,9 @@
{% for product in products %} {% for product in products %}
<div <div
onclick="addProductComanda({{product.id}})" onclick="addProductComanda({{product.id}}, {{comanda_id}}, '{{product.cuisine}}')"
class="card-product" class="card-product"
hx-get="{% url 'addProduct' product.id comanda_id %} " >
hx-trigger="click"
hx-target="#list-products-comanda">
{{product.name}} <br> {{product.name}} <br>
R$ {{product.price}} R$ {{product.price}}
</div> </div>

View File

@@ -2,54 +2,51 @@
{% load custom_filter_tag %} {% load custom_filter_tag %}
<tr> <tr>
<th style="text-align: left;"><b>Produto</b></th> <th style="text-align: left;"><b>Produto</b></th>
<th style="text-align: left;"><b>Preço</b></th> <th style="text-align: left;"><b>Preço</b></th>
</tr> </tr>
{% for item in consumo%} {% for item in consumo%}
<tr> <tr id="item-{{item.id}}">
<td id="id-for-print-{{item.id}}"> <td id="id-for-print-{{item.id}}">
{{item.product.name}} <spam style="cursor: pointer;" onclick="inforOrders({{item.id}})">
{{item.product.name}}</spam>
{% if item.product.cuisine == True %} {% if item.product.cuisine == True %}
<input hidden id="{{item.id}}-obsOrder" type="order" value="{{item.id | obsOrder}}"> <input hidden id="{{item.id}}-obsOrder" type="order" value="{{item.id | obsOrder}}">
<span id="tooltip-id-{{item.id}}" data-tooltip="{{item.id | obsOrder}}" data-flow="top">
<img <img
onclick="openModalObs({{item.id}})" onclick="openModalObs({{item.id}})"
src="{% static 'midia/icons/note.svg' %}" src="{% static 'midia/icons/note.svg' %}"
style="width: 25px; height: 35px; cursor: pointer;"> style="width: 25px; height: 35px; cursor: pointer;">
</img> </img>
</span>
<img
onclick="printOrder({{item.id}})" <img
src="{% static 'midia/icons/print.svg' %}" onclick="printOrder({{item.id}})"
style="width: 35px; height: 35px; cursor: pointer;"> src="{% static 'midia/icons/print.svg' %}"
</img> style="width: 35px; height: 35px; cursor: pointer;">
</img>
{% endif %} {% endif %}
</td> </td>
<td>R$ {{item.product.price}}</td> <td>R$ {{item.product.price}}</td>
{% if comanda.status != 'OPEN'%}
{% else %}
<td>
{% if comanda.status != 'OPEN'%}
{% else %}
<td>
<img <img
onclick="removeProductComanda({{item.id}}, '{{item.product.name}}')"
src="{% static 'midia/icons/delete.svg' %}" src="{% static 'midia/icons/delete.svg' %}"
style="width: 35px; height: 35px; cursor: pointer;" style="width: 35px; height: 35px; cursor: pointer;"
hx-get="{% url 'removeProductComanda' item.id %} " >
hx-trigger="click" </img>
hx-target="#list-products-comanda" </td>
hx-confirm="Tem certeza que deseja excluir o produto {{item.product.name}}?" >
</img>
</td>
{% endif %} {% endif %}
</tr> </tr>
{% endfor %} {% endfor %}
{% if config.taxa %} {% if config.taxa %}
<tr> <tr>
@@ -75,7 +72,7 @@ style="width: 35px; height: 35px; cursor: pointer;">
<tfoot> <tfoot>
<tr> <tr>
{% if config.taxa %} {% if config.taxa %}
<td colspan="2" style="text-align: center;"><b>Total R$ {{valores.totalComTaxa}}</b></td> <td colspan="2" style="text-align: center;"><b>Total R$ {{valores.totalComTaxa}}</b></td>
@@ -83,5 +80,5 @@ style="width: 35px; height: 35px; cursor: pointer;">
<td colspan="2" style="text-align: center;"><b>Total R$ {{valores.totalSemTaxa}}</b></td> <td colspan="2" style="text-align: center;"><b>Total R$ {{valores.totalSemTaxa}}</b></td>
{% endif %} {% endif %}
</tr> </tr>
</tfoot> </tfoot>

View File

@@ -32,8 +32,7 @@
--pico-nav-link-spacing-vertical: 0.5rem; --pico-nav-link-spacing-vertical: 0.5rem;
--pico-nav-link-spacing-horizontal: 0.5rem; --pico-nav-link-spacing-horizontal: 0.5rem;
--pico-nav-breadcrumb-divider: ">"; --pico-nav-breadcrumb-divider: ">";
--pico-icon-checkbox: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(255, 255, 255)' stroke-width='4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'%3E%3C/polyline%3E%3C/svg%3E"); --pico-icon-minus: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='48' height='48' viewBox='0 0 24 24' fill='none' stroke='rgb(255, 255, 255)' stroke-width='4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cline x1='5' y1='12' x2='19' y2='12'%3E%3C/line%3E%3C/svg%3E");
--pico-icon-minus: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(255, 255, 255)' stroke-width='4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cline x1='5' y1='12' x2='19' y2='12'%3E%3C/line%3E%3C/svg%3E");
--pico-icon-chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(136, 145, 164)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E"); --pico-icon-chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(136, 145, 164)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E");
--pico-icon-date: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(136, 145, 164)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='4' width='18' height='18' rx='2' ry='2'%3E%3C/rect%3E%3Cline x1='16' y1='2' x2='16' y2='6'%3E%3C/line%3E%3Cline x1='8' y1='2' x2='8' y2='6'%3E%3C/line%3E%3Cline x1='3' y1='10' x2='21' y2='10'%3E%3C/line%3E%3C/svg%3E"); --pico-icon-date: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(136, 145, 164)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='4' width='18' height='18' rx='2' ry='2'%3E%3C/rect%3E%3Cline x1='16' y1='2' x2='16' y2='6'%3E%3C/line%3E%3Cline x1='8' y1='2' x2='8' y2='6'%3E%3C/line%3E%3Cline x1='3' y1='10' x2='21' y2='10'%3E%3C/line%3E%3C/svg%3E");
--pico-icon-time: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(136, 145, 164)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cpolyline points='12 6 12 12 16 14'%3E%3C/polyline%3E%3C/svg%3E"); --pico-icon-time: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(136, 145, 164)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cpolyline points='12 6 12 12 16 14'%3E%3C/polyline%3E%3C/svg%3E");
@@ -43,7 +42,7 @@
} }
@keyframes jump { @keyframes jump {
0% { 0% {
transform: scale(0.0); transform: scale(0.0);
} }
@@ -53,12 +52,12 @@
100% { 100% {
transform: scale(1); transform: scale(1);
} }
} }
body { body {
margin: 70px 0px 0px 0px; margin-top: 70px;
} }
h1{ h1{
@@ -76,7 +75,6 @@ input, textarea, select {
width: 95%; width: 95%;
max-width: 95%; max-width: 95%;
max-height: 300px; max-height: 300px;
/* padding: 8px; */
margin-top: 5px; margin-top: 5px;
border-radius: 8px; border-radius: 8px;
border: 1px solid #cccccc52; border: 1px solid #cccccc52;
@@ -93,14 +91,14 @@ input, textarea, select {
line-height: 20px; line-height: 20px;
padding: 15px 30px 15px 30px; padding: 15px 30px 15px 30px;
transition: box-shadow 0.4s; transition: box-shadow 0.4s;
} }
.btn-primary:hover { .btn-primary:hover {
box-shadow: 0px 0px 15px rgba(86, 187, 255, 0.815); box-shadow: 0px 0px 15px rgba(86, 187, 255, 0.815);
text-align: left; text-align: left;
line-height: 20px; line-height: 20px;
padding: 15px 30px 15px 30px; padding: 15px 30px 15px 30px;
} }
.btn-secondary { .btn-secondary {
align-items: center; align-items: center;
@@ -112,14 +110,14 @@ input, textarea, select {
line-height: 20px; line-height: 20px;
padding: 15px 30px 15px 30px; padding: 15px 30px 15px 30px;
transition: box-shadow 0.4s; transition: box-shadow 0.4s;
} }
.btn-secondary:hover { .btn-secondary:hover {
box-shadow: 0px 0px 15px rgb(53, 241, 62); box-shadow: 0px 0px 15px rgb(53, 241, 62);
text-align: left; text-align: left;
line-height: 20px; line-height: 20px;
padding: 15px 30px 15px 30px; padding: 15px 30px 15px 30px;
} }
.btn-cancel { .btn-cancel {
align-items: center; align-items: center;
@@ -131,14 +129,14 @@ input, textarea, select {
line-height: 20px; line-height: 20px;
padding: 15px 30px 15px 30px; padding: 15px 30px 15px 30px;
transition: box-shadow 0.4s; transition: box-shadow 0.4s;
} }
.btn-cancel:hover { .btn-cancel:hover {
box-shadow: 0px 0px 15px rgba(255, 86, 86, 0.815); box-shadow: 0px 0px 15px rgba(255, 86, 86, 0.815);
text-align: left; text-align: left;
line-height: 20px; line-height: 20px;
padding: 15px 30px 15px 30px; padding: 15px 30px 15px 30px;
} }
* { * {
padding: 0; padding: 0;
@@ -148,8 +146,8 @@ input, textarea, select {
.card-product { .card-product {
height: 180px; height: 130px;
width: 200px; width: 150px;
padding: 10px; padding: 10px;
align-items: center; align-items: center;
align-content: center; align-content: center;
@@ -172,7 +170,10 @@ input, textarea, select {
box-shadow: 0px 3px 10px #464646; box-shadow: 0px 3px 10px #464646;
position: fixed; position: fixed;
top: 0; top: 0;
width: 100%; min-width: 100%;
height: 60px;
align-items: center;
align-content: center;
z-index: 100; z-index: 100;
} }
@@ -180,6 +181,7 @@ input, textarea, select {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
padding: 0.1rem 1rem; padding: 0.1rem 1rem;
align-self: center;
} }
@@ -187,6 +189,7 @@ input, textarea, select {
display: flex; display: flex;
margin-top: 5px; margin-top: 5px;
align-items: center; align-items: center;
height: 60px;
} }
@@ -218,9 +221,18 @@ input, textarea, select {
grid-template-columns: repeat(2, 0.5fr); grid-template-columns: repeat(2, 0.5fr);
border: none; border: none;
border-radius: 5px; border-radius: 5px;
margin-top: 10px; margin-top: 0px;
height: 60px;
width: 180px;
gap: 10px;} gap: 10px;}
#user-info {
width: 120px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.logout-button button a { .logout-button button a {
text-decoration: none; text-decoration: none;
color: #fff; color: #fff;
@@ -238,122 +250,55 @@ input, textarea, select {
} }
.dropdown { .dropdown {
position: relative; position: relative;
display: inline-block; display: inline-block;
color: #fff; color: #fff;
cursor: pointer; cursor: pointer;
transition: display 0.9s, animation 0.9s; transition: display 0.9s, animation 0.9s;
} }
.dropdown-content { .dropdown-content {
display: none; display: none;
position: absolute; position: absolute;
border-radius: 5px; border-radius: 5px;
background-color: #313238; background-color: #313238;
min-width: 160px; min-width: 160px;
box-shadow: 0px 3px 10px #464646; box-shadow: 0px 3px 10px #464646;
} }
.dropdown-content a { .dropdown-content a {
color: rgb(255, 255, 255); color: rgb(255, 255, 255);
padding: 12px 16px; padding: 12px 16px;
text-decoration: none; text-decoration: none;
display: block; display: block;
animation: jump 0.7s; animation: jump 0.7s;
}
.dropdown-content a:hover {
}
.dropdown-content a:hover {
background-color: #7a7a7a; background-color: #7a7a7a;
border-radius: 5px; border-radius: 5px;
display: block; display: block;
/* animation: jump 0.7s; */
}
} .img-drop {
.img-drop {
width: 35px; width: 35px;
transition: transform 0.3s ease-in-out; transition: transform 0.3s ease-in-out;
} }
.dropdown:hover .img-drop { .dropdown:hover .img-drop {
transform: rotate(180deg); transform: rotate(180deg);
} }
.dropdown:hover .dropdown-content { .dropdown:hover .dropdown-content {
display: block; display: block;
animation: jump 0.7s; animation: jump 0.7s;
} }
.navigation {
position: fixed;
bottom: 0;
width: 100%;
height: 60px;
background: var(--main-gradient);
display: none;
justify-content: center;
align-items: center;
border-radius: 10px 10px 0px 0px;
box-shadow: 10px 0px 8px rgb(255, 255, 255);
}
.navigation ul {
width: 350px;
display: flex;
justify-content: space-around;
padding: 0;
margin: 0;
}
.navigation ul li {
list-style: none;
position: relative;
width: 70px;
height: 60px;
z-index: 2;
}
.navigation ul li a {
text-decoration: none;
color: #555;
position: relative;
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100%;
}
.navigation ul li a .icon {
position: fixed;
background: #add7ff;
display: block;
width: 55px;
height: 55px;
text-align: center;
line-height: 65px;
border-radius: 50%;
color: #222327;
font-size: 1.5em;
transition: 0.5s;
transition-delay: 0s;
z-index: 100;
}
.navigation ul li a .icon:hover {
background: #222327;
color: #fff;
transform: translateY(-10px);
}
.toast { .toast {
position: fixed; position: fixed;
top: 40px; top: 40px;
@@ -372,12 +317,7 @@ input, textarea, select {
transition: opacity 0.5s ease-in-out, visibility 0.5s ease-in-out; transition: opacity 0.5s ease-in-out, visibility 0.5s ease-in-out;
z-index: 999 ; z-index: 999 ;
} }
@media screen and (max-width: 730px) {
.toast-add {
width: 90%;
}
}
.toast p { .toast p {
color: #000000; color: #000000;
} }
@@ -388,100 +328,25 @@ input, textarea, select {
} }
@media screen and (max-width: 730px) {
.dropdown-content {
display: none;
margin-top: 40px;
position: relative;
border-radius: 0px;
min-width: 160px;
}
.nav-bar {
padding: 0.1rem 2rem;
}
.nav-item {
display: none;
}
.logout-button {
display: none;
}
.mobile-menu-icon {
display: block;
}
.mobile-menu-icon button {
background-color: transparent;
border: none;
cursor: pointer;
}
.mobile-menu ul {
display: flex;
flex-direction: column;
text-align: center;
padding-bottom: 1rem;
}
.mobile-menu .nav-item {
display: block;
padding-top: 1.2rem;
}
.mobile-menu .logout-button {
display: block;
justify-items: center;
justify-self: center;
padding: 1rem 2rem;
}
.mobile-menu .logout-button button {
width: 100%;
}
.open {
display: block;
transition: transform 0.2s;
}
.navigation {
display: flex;
}
}
.header-mobile { .header-mobile {
display: none; display: none;
justify-content: space-between; justify-content: flex-start;
align-items: center; align-items: center;
background-color: #171525; background-color:rgba(86, 187, 255, 0.192);
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.5); box-shadow: 0 4px 10px rgba(0, 0, 0, 0.5);
/* backdrop-filter: blur(5px); */ border-radius: 25px;;
padding: 1rem;
padding-right: 50px;
padding-left: 10px;
position: fixed; position: fixed;
top: 0;
width: 100%; top: 50%;
right: -10px;
width: 55px;
height: 55px;
z-index: 9999; z-index: 9999;
} }
.header-mobile .logo {
display: flex;
align-items: center;
margin-left: 25px;
}
.header-mobile .logo i {
color: #fbbf24;
font-size: 2rem;
}
.header-mobile .logo span {
font-size: 1.25rem;
font-weight: bold;
margin-left: .5rem;
}
.header-mobile .nav-toggle { .header-mobile .nav-toggle {
display: block; display: block;
@@ -500,10 +365,10 @@ input, textarea, select {
.header-mobile .nav-links { .header-mobile .nav-links {
max-width: 70%; max-width: 70%;
position: fixed; position: fixed;
top: 83px; top: 0px;
left: -100%; left: -100%;
width: 100%; width: 100%;
height: 100vh; height: 100%;
background-color: #222033b9; background-color: #222033b9;
box-shadow: 0 10px 10px rgba(0, 0, 0, 0.5); box-shadow: 0 10px 10px rgba(0, 0, 0, 0.5);
backdrop-filter: blur(5px); backdrop-filter: blur(5px);
@@ -532,7 +397,7 @@ input, textarea, select {
font-size: 1.2rem; font-size: 1.2rem;
margin: 1rem 0; margin: 1rem 0;
display: block; display: block;
width: 90%; width: 100%;
text-align: center; text-align: center;
padding: 1rem; padding: 1rem;
transition: all 0.3s; transition: all 0.3s;
@@ -540,19 +405,32 @@ input, textarea, select {
.header-mobile .nav-links a:hover { .header-mobile .nav-links a:hover {
color: white; color: white;
scale: 1.1; scale: 1.3;
background-color: #373543;
box-shadow: 0 0px 10px rgba(0, 0, 0, 0.5);
transition: all 0.3s ; transition: all 0.3s ;
} }
@media screen and (max-width: 768px) { @media screen and (max-width: 1028px) {
.background .bg1 { .toast-add {
max-height: 21.5%; width: 90%;
}
.dropdown-content {
display: none;
} }
.header-mobile { .header-mobile {
display: flex; display: flex;
} }
.nav-bar {
display:none;
}
header .p-header {
display: none;
}
body {
margin: 8px 0px 0px 0px;
}
} }

View File

@@ -177,13 +177,34 @@ function openFullscreen() {
} }
function feedback(message, status, subMessage) { function feedback(message, icon, subMessage) {
var feedbackMsg = Swal.fire({ var feedbackMsg = Swal.fire({
color: 'white',
title: message, title: message,
text: subMessage || '', text: subMessage || '',
icon: status, icon: icon || 'info',
background: 'rgba(8, 9, 10, 0.75)', background: 'rgb(23, 38, 54)',
confirmButtonColor: 'linear-gradient(145deg, #1E2A3B, #2C3E50)', confirmButtonColor: 'linear-gradient(145deg, #1E2A3B, #2C3E50)',
}); });
return feedbackMsg;
} }
function toast(){
const Toast = Swal.mixin({
toast: true,
theme:"dark",
position: "top",
showConfirmButton: false,
background: 'rgb(30, 42, 58)',
color: 'white',
showCloseButton: true,
timer: 2500,
timerProgressBar: true,
didOpen: (toast) => {
toast.onmouseenter = Swal.stopTimer;
toast.onmouseleave = Swal.resumeTimer;
}
});
return Toast;
}

View File

@@ -41,6 +41,7 @@ p {
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
justify-content: center; justify-content: center;
min-width: 100%;
} }
.card-comanda { .card-comanda {

View File

@@ -18,107 +18,14 @@
max-width: 800px; max-width: 800px;
} }
/* .card-product {
height: 180px;
width: 200px;
padding: 10px;
align-items: center;
align-content: center;
text-align: center;
line-height: 1.5;
background: var(--main-gradient);
box-shadow: 3px 3px 10px rgba(2, 2, 2, 0.678);
border-radius: 5px;
transition: transform 0.4s, box-shadow 0.4s;
}
.card-product:hover {
transform: scale(1.05);
transition: transform 0.4s, box-shadow 0.4s;
box-shadow: 0px 0px 10px rgba(86, 187, 255, 0.815);
} */
table td th { table td th {
text-align: center; text-align: center;
} }
.close {
height: 45px;
transition: transform 0.4s;
}
.close:hover {
transform: scale(1.2);
transition: transform 0.4s;
filter: drop-shadow(0px 0px 8px rgba(255, 1, 1, 0.452));
}
.popover{
position: relative;
width: 98%;
height: 96%;
max-width: 800px;
top: 20px;
left: 25%;
padding: 20px;
background-color: #1f1f1fb6;
border-radius: 15px;
border: none;
box-shadow: 0px 0px 8px rgba(143, 143, 143, 0.2);
text-align: justify;
line-height: 50px;
font-size: 18px;
font-weight: bold;
z-index: 1;
/* color: #333; */
transition: transform 0.4s;
animation: jump 0.5s;
}
.popover::backdrop {
background-color: rgba(39, 39, 39, 0.315);
backdrop-filter: blur(5px);
}
.toast-add {
position: fixed;
width: 30%;
top: 40px;
left: 50%;
justify-items: center;
align-items: center;
transform: translateX(-50%);
background-color: #599100;
color: #000000;
font-weight: bold;
padding: 20px 1px 1px 1px;
border-radius: 10px;
opacity: 0;
visibility: hidden;
transition: opacity 0.5s ease-in-out, visibility 0.5s ease-in-out;
z-index: 200 !important;
}
.toast-add p {
color: #000000;
}
.toast-add.show {
opacity: 1;
visibility: visible;
}
@media screen and (max-width: 730px) { @media screen and (max-width: 730px) {
.toast-add {
width: 90%;
}
.popover{
width: 98%;
height: 98%;
max-width: 800px;
top: 20px;
left: 10px;
}
.card-product { .card-product {
height: 100%; height: 100%;

View File

@@ -1,30 +1,52 @@
async function openModal() {
var htmlModal = document.getElementById('addProduct').innerHTML
htmlModal = htmlModal.replace('search-product','search-product-modal')
htmlModal = htmlModal.replace('product-list','product-list-modal')
Swal.fire({
title: "Adicionar Produto",
html: htmlModal,
position:"top",
theme: "dark",
showConfirmButton: false,
showCancelButton: true,
cancelButtonText: '&times;',
customClass:{
cancelButton:'posi'
},
});
function openModal() { }
textField = document.getElementById('search-product')
if (textField) { function searchProduct() {
setTimeout(() => { setTimeout(() => {
textField.focus(); time();
}, 500); // 50ms de delay (ajuste conforme necessário) }, 100);
} function time(){
textField.value = ''; var search_product = document.getElementById('search-product-modal').value.trim()
} var productListElement = document.getElementById("product-list-modal");
var comanda_id = document.getElementById("id-comanda").value;
if(search_product.length == 0 ){search_product ='*';}
fetch(`/comandas/listProduct/${comanda_id}/${search_product}`, {
method: 'GET',}
).then(function(response) {
return response.text();
}).then(function(text) {
productListElement.innerHTML = text;
function closeModal() { })}
var popover = document.getElementById('addProduct');
popover.hidePopover()
} }
function openModalAlter() { function openModalAlter() {
document.getElementById('Modal-alter-comanda').style.display = 'block'; document.getElementById('Modal-alter-comanda').style.display = 'block';
var name = document.getElementById('name-comanda').innerText.replace('Nome: ','').replace(' | ', '') var name = document.getElementById('name-comanda').innerText.replace('Nome: ','').replace(' | ', '')
var mesa = document.getElementById('h-mesaId').value var mesa = document.getElementById('h-mesaId').value
console.log(name)
console.log(mesa)
var fildName = document.getElementById('nameComanda') var fildName = document.getElementById('nameComanda')
fildName.value = name fildName.value = name
var fildMesa = document.getElementById('select-mesa') var fildMesa = document.getElementById('select-mesa')
@@ -34,12 +56,56 @@ function openModalAlter() {
function closeModalAlter() { function closeModalAlter() {
document.getElementById('Modal-alter-comanda').style.display = 'none'; document.getElementById('Modal-alter-comanda').style.display = 'none';
} }
function openModalObs(id) { async function openModalObs(id) {
document.getElementById('modal-obs').style.display = 'block'; var obsPrint = document.getElementById(id+'-obsOrder')
idd = document.getElementById('id-temp').value = id; var order = obsPrint.value.split('|');
obs = document.getElementById('obs').value; const inputOptions = new Promise((resolve) => {
textField = document.getElementById('obs')
textField.focus() resolve({
"Para viagem": "Para Viagem",
"Meia Porção": "Meia Porção",
"Com Leite": "Com Leite",
"Sem Cebola": "Sem Cebola",
"Com Ovo": "Com Ovo",
});
});
const { value: obs } = await Swal.fire({
title: "Observações rápidas",
input: "radio",
color: 'white',
confirmButtonText: "Enviar ou Digitar Outra",
showCancelButton: true,
cancelButtonText: "Cancelar",
inputOptions,
theme: "dark",
inputValidator: async (value) => {
if (!value) {
const { value: text } = await Swal.fire({
input: "textarea",
title: "Observação do Pedido",
inputValue:order[1],
theme: "dark",
background: 'rgb(23, 38, 54)',
confirmButtonColor: 'linear-gradient(145deg, #1E2A3B, #2C3E50)',
color: 'white',
showCancelButton: true,
inputAttributes: {
"aria-label": "Type your message here"
}});
if (text) {
addOrder(id, text)
}
}
}
});
if (obs) {
addOrder(id, obs)
}
} }
@@ -66,20 +132,14 @@ function close_modal_conta_client() {
document.getElementById('conta-cliente').style.display = 'none'; document.getElementById('conta-cliente').style.display = 'none';
} }
function close_modal_payment_parcial() { function close_modal_payment_parcial() {
document.getElementById('payment-parcial').style.display = 'none'; document.getElementById('payment-parcial').style.display = 'none';
} }
function close_modal_payment_comanda() { function close_modal_payment_comanda() {
document.getElementById('payment-comanda').style.display = 'none'; document.getElementById('payment-comanda').style.display = 'none';
} }
function closeModalObs() {
document.getElementById('modal-obs').style.display = 'none';
}
function imprimirFichas() { function imprimirFichas() {
const element = document.getElementById("list-products-comanda"); const element = document.getElementById("list-products-comanda");
const style = `<style> const style = `<style>
@@ -115,28 +175,20 @@ function imprimirFichas() {
} }
} }
function printOrder(id) { function printOrder(id) {
var item = document.getElementById('id-for-print-'+id).innerText var order = document.getElementById(id+'-obsOrder').value
var cliente = document.getElementById('name-comanda').innerText order = order.split('|');
var local = document.getElementById('mesa-comanda').innerText
var obs = document.getElementById(id+'-obsOrder').value
const agora = new Date();
var dateString = agora.getDate() + '/' + (agora.getMonth()+1) + '/' + agora.getFullYear() + ' - ' + agora.getHours() + ':' + agora.getMinutes();
console.log(item)
console.log(cliente)
console.log(local)
const body = `<style> const body = `<style>
td, th { td, th {
border-collapse: collapse; border-collapse: collapse;
padding-top: 20px; padding-top: 10px;
margin: 20px; margin: 10px;
text-align: center; text-align: center;
font-size: 20px;} font-size: 20px;}
</style> </style>
<tr><td>${item}</td></tr> <tr><td>${order[0]}</td></tr>
<tr><td>${obs}</td></tr> <tr><td>${order[1]}</td></tr>
<tr><td>${cliente}${local}</td></tr> <tr><td>${order[3]} - ${order[4]}</td></tr>
<tr><td>${dateString}</td></tr> <tr><td>${order[5]}</td></tr>
`; `;
var printWindow = window.open('', '_blank'); var printWindow = window.open('', '_blank');
@@ -148,7 +200,6 @@ function printOrder(id) {
} }
function imprimirConta() { function imprimirConta() {
reloadPage(); reloadPage();
const element = document.getElementById("list-products-comanda"); const element = document.getElementById("list-products-comanda");
@@ -194,14 +245,27 @@ function imprimirConta() {
function closeConta(id){ function closeConta(id){
const resultadoConfirmacao = confirm("Encerrar comanda?");
const buttonAdd = document.getElementById('openModal') const buttonAdd = document.getElementById('openModal')
const buttonClose = document.getElementById('closeComanda') const buttonClose = document.getElementById('closeComanda')
const buttonreOpenComanda = document.getElementById('reOpenComanda') const buttonreOpenComanda = document.getElementById('reOpenComanda')
const buttonPrintComanda = document.getElementById('printComanda') const buttonPrintComanda = document.getElementById('printComanda')
const buttonPayment = document.getElementById('pagarComanda') const buttonPayment = document.getElementById('pagarComanda')
if (resultadoConfirmacao){
Swal.fire({
title: "Encerrar essa comanda?",
text: "Depois de encerrar somente o gerente pode reabrir.",
icon: "warning",
showCancelButton: true,
background: 'rgb(23, 38, 54)',
color: 'white',
confirmButtonColor: 'linear-gradient(145deg, #1E2A3B, #2C3E50)',
cancelButtonColor: "rgb(253, 69, 69)",
confirmButtonText: "Encerrar",
cancelButtonText: "Cancelar",
}).then((result) => {
if (result.isConfirmed) {
fetch(`/comandas/closeComanda/${id}/`, { fetch(`/comandas/closeComanda/${id}/`, {
method: 'PUT', method: 'PUT',
@@ -217,15 +281,22 @@ function closeConta(id){
buttonAdd.style.display = 'none' buttonAdd.style.display = 'none'
buttonreOpenComanda.style.display = 'flex' buttonreOpenComanda.style.display = 'flex'
buttonPayment.style.display = 'flex' buttonPayment.style.display = 'flex'
showToast('✅Comanda encerrada!😁','success')
imprimirConta() imprimirConta()
} }
}) })
.catch(error => { .catch(error => {
showToast('❌Ocorreu um erro!😢','error') Swal.fire({
color: 'white',
title: "Algo deu errado!😢",
confirmButtonColor: 'linear-gradient(145deg, #1E2A3B, #2C3E50)',
background: 'rgb(23, 38, 54)',
text: "Erro: " + error.message,
icon: "error",
});
}); });
}
}
});
} }
@@ -253,14 +324,12 @@ function troco(){
} }
function addOrder(){ function addOrder(id, obs){
obs = document.getElementById('obs')
id = document.getElementById('id-temp').value
var obsPrint = document.getElementById(id+'-obsOrder') var obsPrint = document.getElementById(id+'-obsOrder')
tooltipObs = document.getElementById('tooltip-id-'+id) var order = obsPrint.value.split('|');
var newOrder = '';
fetch(`/comandas/editOrders/${id}/${obs.value}`, { fetch(`/comandas/editOrders/${id}/${obs}`, {
method: 'POST', method: 'POST',
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
@@ -269,59 +338,104 @@ function addOrder(){
.then(response => response.json()) .then(response => response.json())
.then(data => { .then(data => {
if(data.status == 'ok'){ if(data.status == 'ok'){
showToast('✅Pedido atualizado com sucesso!😁','success') order[1] = data.obs;
tooltipObs.dataset.tooltip = data.obs for(var i = 0; i < order.length; i++){
obs.value = '' newOrder += order[i] + '|';
obsPrint.value = data.obs }
document.getElementById('modal-obs').style.display = 'none'; obsPrint.value = newOrder;
feedback('Obsevação alterada com sucesso!😁','success');
} }
}) })
.catch(error => { .catch(error => {
console.log(error) console.log(error)
showToast('❌Ocorreu um erro!😢','error') feedback('❌Ocorreu um erro!😢','error','Erro: ' + error.message);
});
}
async function addProductComanda(productId, comandaId, cuisine) {
try {
if (!productId || !comandaId) {
throw new Error('IDs de produto ou comanda inválidos');
}
const csrfToken = document.querySelector('[name="csrfmiddlewaretoken"]').value
if (!csrfToken) {
throw new Error('Token de segurança não encontrado');
}
// if (cuisine === 'ggg') {
// openModalObs();
// return;
// }
// Mostra estado de carregamento
Swal.update({
title: '<span style="color: white;">Adicionando produto...</span>',
}); });
} // Requisição POST
const response = await fetch(`/comandas/product=${productId}/comanda=${comandaId}/`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRFToken': csrfToken
},
body: JSON.stringify({
product_id: productId,
comanda_id: comandaId
})
});
// Trata resposta
if (!response.ok) {
const errorData = await response.json().catch(() => ({}));
Swal.update({
title: '<span style="color: red;">Falha ao adicionar!</span>',
html: `<div style="color: white; margin-top: 10px;">
${error.message || 'Erro desconhecido'}
</div>`,
icon: 'error',
function showToastAdd(message, type ,duration = 3000) { });
const toast = document.getElementById('toast-add'); throw new Error(errorData.message || `Erro HTTP: ${response.status}`);
if (type === 'success') {
toast.style.backgroundColor = '#28a745';
} else if (type === 'error') {
toast.style.backgroundColor = '#dc3545';
} else if (type === 'info') {
toast.style.backgroundColor = '#ffc107';
} }
const toastMessage = document.getElementById('toast-message-add');
toastMessage.textContent = message; const result = await response.text();
toast.classList.add('show');
// Atualiza a lista de produtos
const listElement = document.getElementById("list-products-comanda");
if (listElement) {
listElement.innerHTML = result;
}
Swal.update({
title: '<span style="color: green;">✅ Produto adicionado!</span>',
});
setTimeout(() => { setTimeout(() => {
toast.classList.remove('show'); Swal.update({
}, duration); title: '<span style="color: white;">Adicionar Produto</span>'
} });
function addProductComanda(productId,comandaId, cuisine) { }, 2500);
obs = document.getElementById('obs');
if(cuisine == 'ggg'){
var obs = openModalObs();
}else{
fetch(`/comandas/addProduct${productId}/${comandaId}`, {
method: 'GET',
headers: {
'Content-Type': 'application/json'}
})
.then(function(response) {
return response.text();
}).then(function(text) {
var listProductsBalcaoElement = document.getElementById("list-products-comanda");
listProductsBalcaoElement.innerHTML = text;
})
showToastAdd('Produto adicionado com sucesso!😁','success');
}
} catch (error) {
console.error('Erro:', error);
// Feedback de erro
Swal.update({
title: '<span style="color: red;">Falha ao adicionar!</span>',
html: `<div style="color: white; margin-top: 10px;">
${error.message || 'Erro desconhecido'}
</div>`,
icon: 'error',
});
}
} }
function taxa(){ function taxa(){
@@ -338,3 +452,66 @@ function taxa(){
} }
function inforOrders(id){
var order = document.getElementById(id+'-obsOrder').value.split('|');
feedback(order[2], "", order[1]+' - '+order[5]);
}
async function removeProductComanda(itemId, productName) {
var table = document.getElementById('list-products-comanda');
Swal.fire({
theme: "dark",
title: `Remover ${productName} da comanda?`,
icon: "warning",
showCancelButton: true,
confirmButtonColor: "#d33",
cancelButtonColor: "#3085d6",
confirmButtonText: "Sim, remover!",
cancelButtonText: "Cancelar",
}).then(async (result) => {
if (result.isConfirmed) {
const csrfToken = document.querySelector('[name="csrfmiddlewaretoken"]').value
if (!csrfToken) {
throw new Error('Token de segurança não encontrado');
}
const response = await fetch(`/comandas/removeProductComanda/${itemId}/`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRFToken': csrfToken
},
});
if (!response.ok) {
const errorData = await response.json().catch(() => ({}));
Swal.fire({
theme:"dark",
title: "😬 Ops!",
text: errorData.message || `Erro HTTP: ${response.status}`,
icon: "error"
});
throw new Error(errorData.message || `Erro HTTP: ${response.status}`);
}
const result = await response.text();
table.innerHTML = result;
Swal.fire({
theme:"dark",
title: "Feito!",
text: productName+" foi removido da comanda",
icon: "success"
});
}
});
}

View File

@@ -7,7 +7,7 @@
grid-template-columns: repeat(3, 2fr); grid-template-columns: repeat(3, 2fr);
gap: 30px; gap: 30px;
max-width: 1200px; max-width: 1200px;
margin: 0px 0px 20px 0px; margin: 0px 0px 30px 0px;
padding: 10px; padding: 10px;
} }

View File

@@ -4,7 +4,14 @@
color: black; color: black;
} }
h2 {
font-size: 18px;
justify-self: center;
margin-bottom: 0px;
}
.container { .container {
margin-top: -50px;
border-radius: 8px; border-radius: 8px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
padding: 0px; padding: 0px;
@@ -91,4 +98,8 @@
} }
#title {
display:none;
}
} }

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,7 @@
.grid-buttons { .grid-buttons {
display: grid; display: flex;
grid-template-columns: repeat(2, 1fr); grid-template-columns: repeat(2, 1fr);
gap: 10px; gap: 10px;
max-width: 500px; max-width: 500px;
@@ -12,7 +12,9 @@
grid-template-columns: repeat(1, 1fr); grid-template-columns: repeat(1, 1fr);
gap: 20px; gap: 20px;
max-width: 1300px; max-width: 1300px;
margin: 0 auto; max-width: 99%;
width: 100%;
margin: 0px;
} }
.grid-top { .grid-top {
@@ -24,7 +26,7 @@
align-content: center; align-content: center;
align-self: center; align-self: center;
grid-template-columns: 1fr 3fr; grid-template-columns: 1fr 3fr;
gap: 20px; gap: 10px;
width: 100%; width: 100%;
} }
@@ -33,4 +35,11 @@
.hide-on-mobile { .hide-on-mobile {
display: none; display: none;
} }
.grid-buttons {
display: none;
gap: 10px;
max-width: 100px;
width: 80px;
}
} }