From 132c8dcfc60ff6a0bd76e545a0ea32848f4d4916 Mon Sep 17 00:00:00 2001 From: Welton Moura Date: Tue, 17 Jun 2025 17:49:44 -0300 Subject: [PATCH] page orders | add duplicati container --- .gitignore | 4 +- .../Modelagem de Banco de Dados.md | 1 - docker-compose.yml | 32 ++++- .../__pycache__/htmx_views.cpython-312.pyc | Bin 9735 -> 9119 bytes .../__pycache__/views.cpython-312.pyc | Bin 9798 -> 9798 bytes gestaoRaul/comandas/htmx_views.py | 7 +- gestaoRaul/db.sqlite3 | Bin 339968 -> 339968 bytes .../__pycache__/settings.cpython-312.pyc | Bin 3927 -> 4402 bytes .../orders/__pycache__/views.cpython-312.pyc | Bin 5732 -> 5776 bytes gestaoRaul/orders/templates/orders.html | 104 +++++++------- gestaoRaul/orders/views.py | 10 +- .../__pycache__/models.cpython-312.pyc | Bin 1512 -> 1512 bytes .../orders/htmx_list_orders_entregue.html | 103 -------------- .../orders/htmx_list_orders_fila.html | 94 ------------ .../orders/htmx_list_orders_preparo.html | 103 -------------- .../orders/htmx_list_orders_pronto.html | 103 -------------- gestaoRaul/templates/static/base.js | 29 ++-- .../templates/static/orders/css/orders.css | 134 +++++++++--------- .../templates/static/orders/js/orders.js | 66 ++++----- .../websocketClient.cpython-312.pyc | Bin 0 -> 1844 bytes 20 files changed, 202 insertions(+), 588 deletions(-) delete mode 100644 gestaoRaul/templates/htmx_components/orders/htmx_list_orders_entregue.html delete mode 100644 gestaoRaul/templates/htmx_components/orders/htmx_list_orders_fila.html delete mode 100644 gestaoRaul/templates/htmx_components/orders/htmx_list_orders_preparo.html delete mode 100644 gestaoRaul/templates/htmx_components/orders/htmx_list_orders_pronto.html create mode 100644 gestaoRaul/websocket_client/__pycache__/websocketClient.cpython-312.pyc diff --git a/.gitignore b/.gitignore index 951312b..0582183 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,7 @@ dev_env/lib/python3.12/site-packages/PIL/__pycache__/XVThumbImagePlugin.cpython-312.pyc dev_env +meu_dev_home dev_home gestaoRaul/static -.env \ No newline at end of file +.env +gestaoRaul/db.sqlite3 diff --git a/doc/Banco de dados/Modelagem de Banco de Dados.md b/doc/Banco de dados/Modelagem de Banco de Dados.md index 1966a11..5172870 100644 --- a/doc/Banco de dados/Modelagem de Banco de Dados.md +++ b/doc/Banco de dados/Modelagem de Banco de Dados.md @@ -37,7 +37,6 @@ Armazena as informações dos funcionários do bar que utilizam o aplicativo int |`ativo`|BOOLEAN|NOT NULL, DEFAULT TRUE| ### 2.3. `Produtos` -![[Product]] Armazena os itens do cardápio do bar. diff --git a/docker-compose.yml b/docker-compose.yml index 4734cb9..d87e9b8 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -13,6 +13,30 @@ services: networks: - app_network + duplicati: + image: duplicati/duplicati:latest # Ou uma versão específica, ex: duplicati/duplicati:2.0.7.1 + container_name: duplicati + hostname: duplicati + restart: unless-stopped + ports: + - "8200:8200" # Porta para a interface web do Duplicati + environment: + - PUID=1000 # ID do usuário que o Duplicati irá rodar (normalmente o seu usuário no host) + - PGID=1000 # ID do grupo que o Duplicati irá rodar (normalmente o seu grupo no host) + - TZ=America/Fortaleza # Ajuste para o seu fuso horário (Juazeiro do Norte) + volumes: + # Volume para persistir as configurações e bancos de dados do Duplicati + - ./duplicati_config:/config + # Volume para armazenar os backups (pode ser um volume nomeado ou um bind mount) + - ./duplicati_backups:/backups + # Montar o volume do PostgreSQL para que o Duplicati possa acessá-lo. + # Substitua 'seu_volume_postgresql' pelo nome real do seu volume Docker do PostgreSQL. + # Se você montou uma pasta local, use o caminho absoluto dela aqui. + - db_data:/var/lib/postgresql/data/:ro # 'ro' para somente leitura, por segurança + # EX: Se seu PostgreSQL está em uma pasta local: + # - /caminho/completo/para/sua/pasta/de/dados/do/postgresql:/source_data:ro + + django_app: build: context: ./ @@ -21,7 +45,7 @@ services: - "8000:8000" healthcheck: - test: ["CMD", "curl", "-f", "http://0.0.0.0:8000/"] + test: ["CMD", "curl", "-f", "http://192.168.0.150:8000/"] interval: 5m timeout: 3s retries: 3 @@ -37,7 +61,7 @@ services: DB_USER: "${DB_USER}" DB_PASSWORD: "${DB_PASSWORD}" DEBUG: "False" - ALLOWED_HOSTS: "rrbec.local.com, 0.0.0.0, django_app" + ALLOWED_HOSTS: "rrbec.local.com, 0.0.0.0, 127.0.0.1, 192.168.0.150, django_app" networks: - app_network @@ -50,8 +74,8 @@ services: - static_volume:/app/gestaoRaul/static ports: - "80:80" - depends_on: - - django_app + # depends_on: + # - django_app networks: - app_network diff --git a/gestaoRaul/comandas/__pycache__/htmx_views.cpython-312.pyc b/gestaoRaul/comandas/__pycache__/htmx_views.cpython-312.pyc index e9367131054f5beb7cbcc2f41ced4dca96a8e47c..5f0bebdfd3ac8541f32f86c6c31a823b70e0e095 100644 GIT binary patch delta 2228 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 diff --git a/gestaoRaul/comandas/__pycache__/views.cpython-312.pyc b/gestaoRaul/comandas/__pycache__/views.cpython-312.pyc index e79f5d95ab5f2a21ebd06b1ca33ab7802069a36a..f69aad3e3b1ffd2606dc22bb9e5df3532116be67 100644 GIT binary patch delta 70 zcmX@+bIgbLG%qg~0}#08@@6dA$eSj?cw=*kL=!7x&gSp3ubCMqZ+@(}f{}5_<{sq& YCVp;4h0n|kOsXH4fUHkaleyKb0VIYM*8l(j delta 70 zcmX@+bIgbLG%qg~0}yCLeoH^RkvC0(@xkU2i6&OY+|A!*Uo$gK+5A{>1ta6q%{|Hm ZO#D2I3ZI!7m{dP70a>49CUdJ<0{~O@7Q6re diff --git a/gestaoRaul/comandas/htmx_views.py b/gestaoRaul/comandas/htmx_views.py index eb6016f..902f6a5 100644 --- a/gestaoRaul/comandas/htmx_views.py +++ b/gestaoRaul/comandas/htmx_views.py @@ -78,9 +78,10 @@ def addProduct(request, product_id, comanda_id):

{comanda.name} - {comanda.mesa.name}

{order.queue.strftime("%d/%m/%Y - %H:%M")}

Atendente: {comanda.user.first_name}

- +
+ +
+ """, 'local':'cozinha', 'tipo':'add', diff --git a/gestaoRaul/db.sqlite3 b/gestaoRaul/db.sqlite3 index 0a9e59e3c49217a26b4ac75f42ae09d575093591..c5ed3191cb9cb0b0b7e9b52d86d144949ee3ad6b 100644 GIT binary patch delta 3711 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 W(Jvfxvc{I=<485(^ASEx+y4viXXhIL delta 806 zcmb7Cy>Aj>7{B+uI}Q#G4oVBX9v`J29Ic+9iBaRACTJWaF?D(pL!i%jf}~hrkwod> z>R?zLn7SD@`6C>RgOhlPlm7s zpP`pw0DYjKY>~Ro_1sDetfv-qK`aUVLpn2Uf+7Z3Ddm{d2nGj&O+dvEgi*yXi;Q&H z61X&=H3AWg;xdbh;>uLVraE3Dwg5}G3eg^Fu*_y%VK0Vj5Jw$Wr;{z3yW~HECEUTD z5zsD_nPi!>{bB7wi7B@w=$M8Cu0s+tkirc}<0h=*7G!W6HZTjDXuuZcU>kRE7cb%E z0ne_LWtNFo1{90{<{`%pvGa=N3ZpyxJ<|Uw+*hTpQn-25EL^`~=FLJr-;atX4{coRyxlcwQ7qWJq^60sXZ2W_BGp|nV#^3kP|8s z;WW+>`6n0eABGB&H!L41zqS6y&|V_QiNSHi9INpUx4)^`6OmUv6JAv4k#C}n(rScvMSBfE;BxN##M$&#ZQ zD%wd-!bspQJ1wqeXc4D4NjGJrqI2A7b=!D#NSm`0?a@ zVHI~;MrIF<8lGxmvk}|6?M!T26Px2{ydb|Q>FwVrn9f4AX1mssSFv<4RKTim3qlnv zZi6*lLtUf5mPA%)EXVR9Q-f#naPc5|`Z0uJu?TtGLv6vf?)f(WoqZ?;Kja6j)_9JGFMhbG{+T{hWmuD62FdFh&G1~lwlvieuOZ2d2;gR)Oh(~dAvLx zvH@KKmB=EIv01AIlmZ+gF;NApYJy#v4JF@Pu;4IJodh!R(zWuWe11iSuE13DN4trL zsvs7t*scTmi69{V&3Z7X9SmNoSBhHp;iX4cm#==zmEPq_PjA1Nc%M7c6+P6za|ShgT+i=uR?KJY(6#Z zxn_l%FtVelg2(6aWyGP2!gU90nF);^!B+UuMt}AbQ)npkLXgb&j&Dt%#_yVyS+9St zR;vOch zL_k!8gt&ngiQX#p7NwWUt@samDF;h%s8-|#2X3IKhu-?$I0h5S9DeiW{ocHNU$ggT zUQFlz%H=W=uHPsAX=L&b@_W~w;OUXXCC)s_XEtLb%bx5jwjyN3Q~i{k@-1XY%kaaKT=j}Yo#vREX;AzByEIE0e`PJND6on-52kY6z zT_0$3cchK3fn*m2oA0|b(8mt)0{Y#3UA1<-q8k=VjL7w!)n?$Jtbr472ijxorp!w1 zpOuo#^!Sg|>GB8~hYCWuT!!7aC+3Rl{1DCq+J`U^=d`=*>-MI3hOO}w*KVjT+aP;f z7o~OmJbIU14nuf`y#)IaRzJNG`PZuTrr*Kl;=lpo$^hdHdBp4?P zk!K1e%yTntoj&DJ|=9VXEtzNPJ9x3Ltb z*xFSp)s7WW4aDj-t=C>AMf-Z(4IGu7WrRb>TDf<*Lj@Imxf@Gv;D%Qm4%0*&_=2#E zkm$AWdQf+pi2}<3lt@p-fEk2vN5032Ah3wMhxv}i3+CBF&sFp8xgXCx9C%t7d!~** z&lc~W`o9{)kIku%&q6nez6S10BF!Do#kRf8g2E{id^F_hs0+E=BQj+Vwh$DUz>lBJvNDAAR_+n3O#J`n>FQnleDNV$qd#1nPY)g^ksn@c`ID1o+Y2U4_;v_4G9{mU5d@nly diff --git a/gestaoRaul/orders/templates/orders.html b/gestaoRaul/orders/templates/orders.html index 7cfd379..379c914 100644 --- a/gestaoRaul/orders/templates/orders.html +++ b/gestaoRaul/orders/templates/orders.html @@ -20,26 +20,16 @@ {% endblock %} - {% block 'body' %} - -

Pedidos cozinha

- - -
- -
- - - - -
- -
- -
- {% for order in orders %} +
+

Pedidos cozinha

+
+ {% csrf_token %} +
+

FILA

+
+ {% for order in orders %} {% if order.preparing == None and order.productComanda != Null %}
Atendente: {{order.id_comanda.user.first_name}}

{{order.queue|date:"D"}} {{order.queue|date:"d/m/Y - H:i"}}

{% if user|groupUser:"Cozinha" %} - + +
+ + +
{% endif %}
{% endif %} {% endfor %} -
- - -
- {% for order in orders %} +
+
+
+

PREPARANDO

+
+ {% for order in orders %} {% if order.finished == None and order.preparing != None %}
Atendente: {{order.id_comanda.user.first_name}}

{{order.queue|date:"D"}} {{order.queue|date:"d/m/Y - H:i"}}

{% if user|groupUser:"Cozinha" %} - +
+ +
+ {% endif %}
{% endif %} {% endfor %} -
- -
- {% for order in orders %} +
+
+
+

PRONTO

+
+ {% for order in orders %} {% if order.delivered == None and order.finished != None %}
Atendente: {{order.id_comanda.user.first_name}}

{{order.queue|date:"D"}} {{order.queue|date:"d/m/Y - H:i"}}

{% if user|groupUser:"Garçom" %} - +
+ +
+ {% endif %}
{% endif %} {% endfor %} -
- -
- {% for order in orders %} +
+
+
+

ENTREGUE

+
+ {% for order in orders %} {% if order.delivered != None %}
{% endif %} {% endfor %} +
+
-
- - - -
- -
-

-

Carregando...

-
- - {% endblock %} + + {% endblock %} - - \ No newline at end of file diff --git a/gestaoRaul/orders/views.py b/gestaoRaul/orders/views.py index be9a0e1..fdca182 100644 --- a/gestaoRaul/orders/views.py +++ b/gestaoRaul/orders/views.py @@ -1,6 +1,6 @@ # from datetime import timezone from django.utils import timezone -from django.shortcuts import render +from django.shortcuts import render, redirect from django.http import JsonResponse, HttpResponse import asyncio import websockets @@ -35,7 +35,7 @@ def preparing(request, order_id): order.save() fifteen_hours_ago = timezone.now() - timezone.timedelta(hours=15) orders = Order.objects.filter(queue__gte=fifteen_hours_ago ) - return render(request, 'htmx_components/orders/htmx_list_orders_fila.html',{'orders': orders}) + return redirect(request.META.get('HTTP_REFERER', '/')) @group_required(groupName='Cozinha') @@ -45,8 +45,8 @@ def finished(request, order_id): order.save() fifteen_hours_ago = timezone.now() - timezone.timedelta(hours=15) orders = Order.objects.filter(queue__gte=fifteen_hours_ago ) - asyncio.run(enviar_mensagem()) - return render(request, 'htmx_components/orders/htmx_list_orders_fila.html',{'orders': orders}) + # asyncio.run(enviar_mensagem()) + return redirect(request.META.get('HTTP_REFERER', '/')) @group_required(groupName='Garçom') def delivered(request, order_id): @@ -55,7 +55,7 @@ def delivered(request, order_id): order.save() fifteen_hours_ago = timezone.now() - timezone.timedelta(hours=15) orders = Order.objects.filter(queue__gte=fifteen_hours_ago ) - return render(request, 'htmx_components/orders/htmx_list_orders_fila.html',{'orders': orders}) + return redirect(request.META.get('HTTP_REFERER', '/')) def notificacao(request): diff --git a/gestaoRaul/products/__pycache__/models.cpython-312.pyc b/gestaoRaul/products/__pycache__/models.cpython-312.pyc index c9189d7d8d6e475689f0ed409428b26fd96e5b55..c9fe22e866ee6277b96dbfaeb76951f3d3b95f33 100644 GIT binary patch delta 21 bcmaFC{eqk4G%qg~0}wplC7rR6=MF0XNec#~ delta 21 bcmaFC{eqk4G%qg~0}yOc{+hm#=MF0XNNEPM diff --git a/gestaoRaul/templates/htmx_components/orders/htmx_list_orders_entregue.html b/gestaoRaul/templates/htmx_components/orders/htmx_list_orders_entregue.html deleted file mode 100644 index 8f986e6..0000000 --- a/gestaoRaul/templates/htmx_components/orders/htmx_list_orders_entregue.html +++ /dev/null @@ -1,103 +0,0 @@ - - - -
- - - - -
- -
- {% for order in orders %} - {% if order.preparing == None and order.productComanda != Null %} -
-

{{order.id_product.name}}

-

{{order.obs}}

-

{{order.id_comanda.name}} - {{order.id_comanda.mesa.name}}

-

Atendente: {{order.id_comanda.user.first_name}}

-

{{order.queue|date:"D"}} {{order.queue|date:"d/m/Y - H:i"}}

- -
- {% endif %} - {% endfor %} -
- - -
- {% for order in orders %} - {% if order.finished == None and order.preparing != None %} - -
-

{{order.id_product.name}}

-

{{order.obs}}

-

{{order.id_comanda.name}} - {{order.id_comanda.mesa.name}}

-

Atendente: {{order.id_comanda.user.first_name}}

-

{{order.queue|date:"D"}} {{order.queue|date:"d/m/Y - H:i"}}

- -
- {% endif %} - {% endfor %} -
- -
- {% for order in orders %} - {% if order.delivered == None and order.finished != None %} - -
-

{{order.id_product.name}}

-

{{order.obs}}

-

{{order.id_comanda.name}} - {{order.id_comanda.mesa.name}}

-

Atendente: {{order.id_comanda.user.first_name}}

-

{{order.queue|date:"D"}} {{order.queue|date:"d/m/Y - H:i"}}

- -
- {% endif %} - {% endfor %} -
- -
- {% for order in orders %} - {% if order.delivered != None %} - -
-

{{order.id_product.name}}

-

{{order.obs}}

-

{{order.id_comanda.name}} - {{order.id_comanda.mesa.name}}

-

Atendente: {{order.id_comanda.user.first_name}}

-

{{order.queue|date:"D"}} {{order.queue|date:"d/m/Y - H:i"}}

- -
- {% endif %} - {% endfor %} -
\ No newline at end of file diff --git a/gestaoRaul/templates/htmx_components/orders/htmx_list_orders_fila.html b/gestaoRaul/templates/htmx_components/orders/htmx_list_orders_fila.html deleted file mode 100644 index d5d487b..0000000 --- a/gestaoRaul/templates/htmx_components/orders/htmx_list_orders_fila.html +++ /dev/null @@ -1,94 +0,0 @@ - - - -
- {% for order in orders %} - {% if order.preparing == None and order.productComanda != Null %} -
-

{{order.id_product.name}}

-

{{order.obs}}

-

{{order.id_comanda.name}} - {{order.id_comanda.mesa.name}}

-

Atendente: {{order.id_comanda.user.first_name}}

-

{{order.queue|date:"D"}} {{order.queue|date:"d/m/Y - H:i"}}

- -
- {% endif %} - {% endfor %} -
- - -
- {% for order in orders %} - {% if order.finished == None and order.preparing != None %} - -
-

{{order.id_product.name}}

-

{{order.obs}}

-

{{order.id_comanda.name}} - {{order.id_comanda.mesa.name}}

-

Atendente: {{order.id_comanda.user.first_name}}

-

{{order.queue|date:"D"}} {{order.queue|date:"d/m/Y - H:i"}}

- -
- {% endif %} - {% endfor %} -
- -
- {% for order in orders %} - {% if order.delivered == None and order.finished != None %} -
-

{{order.id_product.name}}

-

{{order.obs}}

-

{{order.id_comanda.name}} - {{order.id_comanda.mesa.name}}

-

Atendente: {{order.id_comanda.user.first_name}}

-

{{order.queue|date:"D"}} {{order.queue|date:"d/m/Y - H:i"}}

- -
- {% endif %} - {% endfor %} -
- -
- {% for order in orders %} - {% if order.delivered != None %} - -
-

{{order.id_product.name}}

-

{{order.obs}}

-

{{order.id_comanda.name}} - {{order.id_comanda.mesa.name}}

-

Atendente: {{order.id_comanda.user.first_name}}

-

{{order.queue|date:"D"}} {{order.queue|date:"d/m/Y - H:i"}}

-
- {% endif %} - {% endfor %} -
\ No newline at end of file diff --git a/gestaoRaul/templates/htmx_components/orders/htmx_list_orders_preparo.html b/gestaoRaul/templates/htmx_components/orders/htmx_list_orders_preparo.html deleted file mode 100644 index 8f986e6..0000000 --- a/gestaoRaul/templates/htmx_components/orders/htmx_list_orders_preparo.html +++ /dev/null @@ -1,103 +0,0 @@ - - - -
- - - - -
- -
- {% for order in orders %} - {% if order.preparing == None and order.productComanda != Null %} -
-

{{order.id_product.name}}

-

{{order.obs}}

-

{{order.id_comanda.name}} - {{order.id_comanda.mesa.name}}

-

Atendente: {{order.id_comanda.user.first_name}}

-

{{order.queue|date:"D"}} {{order.queue|date:"d/m/Y - H:i"}}

- -
- {% endif %} - {% endfor %} -
- - -
- {% for order in orders %} - {% if order.finished == None and order.preparing != None %} - -
-

{{order.id_product.name}}

-

{{order.obs}}

-

{{order.id_comanda.name}} - {{order.id_comanda.mesa.name}}

-

Atendente: {{order.id_comanda.user.first_name}}

-

{{order.queue|date:"D"}} {{order.queue|date:"d/m/Y - H:i"}}

- -
- {% endif %} - {% endfor %} -
- -
- {% for order in orders %} - {% if order.delivered == None and order.finished != None %} - -
-

{{order.id_product.name}}

-

{{order.obs}}

-

{{order.id_comanda.name}} - {{order.id_comanda.mesa.name}}

-

Atendente: {{order.id_comanda.user.first_name}}

-

{{order.queue|date:"D"}} {{order.queue|date:"d/m/Y - H:i"}}

- -
- {% endif %} - {% endfor %} -
- -
- {% for order in orders %} - {% if order.delivered != None %} - -
-

{{order.id_product.name}}

-

{{order.obs}}

-

{{order.id_comanda.name}} - {{order.id_comanda.mesa.name}}

-

Atendente: {{order.id_comanda.user.first_name}}

-

{{order.queue|date:"D"}} {{order.queue|date:"d/m/Y - H:i"}}

- -
- {% endif %} - {% endfor %} -
\ No newline at end of file diff --git a/gestaoRaul/templates/htmx_components/orders/htmx_list_orders_pronto.html b/gestaoRaul/templates/htmx_components/orders/htmx_list_orders_pronto.html deleted file mode 100644 index 20e09ac..0000000 --- a/gestaoRaul/templates/htmx_components/orders/htmx_list_orders_pronto.html +++ /dev/null @@ -1,103 +0,0 @@ - - - -
- - - - -
- -
- {% for order in orders %} - {% if order.preparing == None and order.productComanda != Null %} -
-

{{order.id_product.name}}

-

{{order.obs}}

-

{{order.id_comanda.name}} - {{order.id_comanda.mesa.name}}

-

Atendente: {{order.id_comanda.user.first_name}}

-

{{order.queue|date:"D"}} {{order.queue|date:"d/m/Y - H:i"}}

- -
- {% endif %} - {% endfor %} -
- - -
- {% for order in orders %} - {% if order.finished == None and order.preparing != None %} - -
-

{{order.id_product.name}}

-

{{order.obs}}

-

{{order.id_comanda.name}} - {{order.id_comanda.mesa.name}}

-

Atendente: {{order.id_comanda.user.first_name}}

-

{{order.queue|date:"D"}} {{order.queue|date:"d/m/Y - H:i"}}

- -
- {% endif %} - {% endfor %} -
- -
- {% for order in orders %} - {% if order.delivered == None and order.finished != None %} - -
-

{{order.id_product.name}}

-

{{order.obs}}

-

{{order.id_comanda.name}} - {{order.id_comanda.mesa.name}}

-

Atendente: {{order.id_comanda.user.first_name}}

-

{{order.queue|date:"D"}} {{order.queue|date:"d/m/Y - H:i"}}

- -
- {% endif %} - {% endfor %} -
- -
- {% for order in orders %} - {% if order.delivered != None %} - -
-

{{order.id_product.name}}

-

{{order.obs}}

-

{{order.id_comanda.name}} - {{order.id_comanda.mesa.name}}

-

Atendente: {{order.id_comanda.user.first_name}}

-

{{order.queue|date:"D"}} {{order.queue|date:"d/m/Y - H:i"}}

- -
- {% endif %} - {% endfor %} -
\ No newline at end of file diff --git a/gestaoRaul/templates/static/base.js b/gestaoRaul/templates/static/base.js index 9abe4cf..ae5c2c8 100644 --- a/gestaoRaul/templates/static/base.js +++ b/gestaoRaul/templates/static/base.js @@ -51,7 +51,7 @@ function cookieNotificacao() { } } -const websocket = new WebSocket('ws://0.0.0.0:8765'); +const websocket = new WebSocket('ws://192.168.0.150:8765'); const nomeUsuario = document.getElementById('user-info').textContent; websocket.addEventListener('open', (event) => { @@ -64,37 +64,34 @@ websocket.addEventListener('message', (event) => { switch (data.local) { case 'cozinha': - - - if (document.getElementById('Fila') !== null && data.tipo === 'add'){ - // const novoElemento = document.createElement('div'); - // novoElemento.innerHTML = data.message; - // var fila = document.getElementById('Fila').appendChild(novoElemento); + var novoElemento = document.createElement('div'); + novoElemento.innerHTML = data.message; + document.getElementById('Fila').appendChild(novoElemento); let valorAtual = document.cookie.replace(/(?:(?:^|.*;\s*)notificacao\s*\=\s*([^;]*).*$)|^.*$/, "$1"); if (valorAtual === 'true') { texto = new SpeechSynthesisUtterance(data.speak); window.speechSynthesis.speak(texto); - setTimeout(function() { - location.reload(); - }, 6000); + // setTimeout(function() { + // location.reload(); + // }, 6000); } } else if (document.getElementById('obs-'+data.id) !== null && data.tipo === 'edit'){ const obs = document.getElementById('obs-'+data.id) - // const card = obs.parentNode; - // card.style.backgroundColor = 'rgb(243, 165, 75)'; - // obs.innerHTML = data.message; + const card = obs.parentNode; + card.style.backgroundColor = 'rgb(243, 165, 75)'; + obs.innerHTML = data.message; let valorAtual = document.cookie.replace(/(?:(?:^|.*;\s*)notificacao\s*\=\s*([^;]*).*$)|^.*$/, "$1"); if (valorAtual === 'true') { texto = new SpeechSynthesisUtterance(data.speak); window.speechSynthesis.speak(texto); - setTimeout(function() { - location.reload(); - }, 6000); + // setTimeout(function() { + // location.reload(); + // }, 6000); } } else if (document.getElementById('m-card-'+data.id) !== null && data.tipo === 'delete'){ diff --git a/gestaoRaul/templates/static/orders/css/orders.css b/gestaoRaul/templates/static/orders/css/orders.css index 99238f6..38497bf 100644 --- a/gestaoRaul/templates/static/orders/css/orders.css +++ b/gestaoRaul/templates/static/orders/css/orders.css @@ -1,37 +1,62 @@ - @keyframes girar { - from { - transform: rotate(0deg); - } - to { - transform: rotate(360deg); - } + + h4{ + color: black; + } + +.container { + border-radius: 8px; + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); + padding: 0px; + width: 100%; + height: 100%; + box-sizing: border-box; } -@keyframes jump { - 0% { - transform: scale(0.0); - } - 70% { - transform: scale(1.2); - } - 100% { - transform: scale(1); - } + +.kanban-board { + display: flex; + gap: 10px; + justify-content: space-between; } -.loading { - - align-items: center; - align-content: center; - align-self: center; - margin: 0 auto; - animation: girar 4s infinite linear; +.column { + flex: 1; + border: 1px solid #535353; + border-radius: 6px; + padding: 15px; + display: flex; + flex-direction: column; } +.cards-container { + flex-grow: 1; /* Permite que o container de cards ocupe o espaço restante */ + overflow-y: auto; /* Adiciona a barra de rolagem vertical */ + max-height: 85vh; /* Defina uma altura máxima para ativar o scroll */ + padding-right: 5px; /* Espaçamento para não cortar a barra de rolagem */ +} + +.cards-container::-webkit-scrollbar { + width: 8px; +} + +.cards-container::-webkit-scrollbar-track { + background: #f1f1f1; + border-radius: 10px; +} + +.cards-container::-webkit-scrollbar-thumb { + background: #888; + border-radius: 10px; +} + +.cards-container::-webkit-scrollbar-thumb:hover { + background: #555; +} + + .m-card { - /* width: 50px; */ - height: 100%; + width: 100%; background-color: #f2f2f2; border-radius: 10px; box-shadow: 5px 5px 10px rgba(0, 0, 0, 0.2); @@ -46,51 +71,24 @@ animation: jump 0.7s; } - h4{ - color: black; + + @media screen and (max-width: 1028px) { + .container { + padding: 0px; + gap: 0px; + min-width: 100%; + min-height: 100%; + + } + + .kanban-board { + gap: 0px; } + .column { -.tab { - display: flex; - padding-top: 15px; - justify-content: space-between; - overflow: auto; - width: 100%; - border-bottom: 2px solid rgba(86, 187, 255, 0.192); -} + padding: 0px; -.tab button { - width: 24%; - background-color: #999aeb00; - padding: 10px 10px; - transition: 0.6s; - border-radius: 20px 20px 0px 0px; - align-items: center; - border-color: rgba(86, 187, 255, 0.192); - line-height: 20px; -} + } -.tab button.active { - border-radius: 8px 8px 0px 0px; - border-color: rgba(86, 187, 255, 0.192); - background: var(--main-gradient); - box-shadow: 0px 0px 15px rgba(86, 187, 255, 0.815); -} - -.tabcontent { - display: none; - padding: 6px 12px; - -} - -#list-orders{ - justify-self: center; - width: 30%; -} - -@media (max-width: 768px) { -#list-orders{ - width: 100%; -} } \ No newline at end of file diff --git a/gestaoRaul/templates/static/orders/js/orders.js b/gestaoRaul/templates/static/orders/js/orders.js index 0923a7c..2e3d2a2 100644 --- a/gestaoRaul/templates/static/orders/js/orders.js +++ b/gestaoRaul/templates/static/orders/js/orders.js @@ -4,49 +4,49 @@ function reloadPage(){ location.reload();}, 3000); } -function openTab(evt, etapa) { - var i, tabcontent, tablinks; - tabcontent = document.getElementsByClassName("tabcontent"); - for (i = 0; i < tabcontent.length; i++) { - tabcontent[i].style.display = "none"; - } - tablinks = document.getElementsByClassName("tablinks"); - for (i = 0; i < tablinks.length; i++) { - tablinks[i].className = tablinks[i].className.replace(" active", ""); - } - document.getElementById(etapa).style.display = "block"; - evt.currentTarget.className += " active"; - } +// function openTab(evt, etapa) { +// var i, tabcontent, tablinks; +// tabcontent = document.getElementsByClassName("tabcontent"); +// for (i = 0; i < tabcontent.length; i++) { +// tabcontent[i].style.display = "none"; +// } +// tablinks = document.getElementsByClassName("tablinks"); +// for (i = 0; i < tablinks.length; i++) { +// tablinks[i].className = tablinks[i].className.replace(" active", ""); +// } +// document.getElementById(etapa).style.display = "block"; +// evt.currentTarget.className += " active"; +// } - function displayBlock(etapa) { +// function displayBlock(etapa) { - document.getElementById('loading').style.display = "none"; - document.getElementById(etapa).style.display = "block"; - } +// document.getElementById('loading').style.display = "none"; +// document.getElementById(etapa).style.display = "block"; +// } - tabcontent = document.getElementsByClassName("tabcontent"); - for (i = 0; i < tabcontent.length; i++) { - tabcontent[i].style.display = "none"; - } - tabcontent[0].style.display = "block"; + // tabcontent = document.getElementsByClassName("tabcontent"); + // for (i = 0; i < tabcontent.length; i++) { + // tabcontent[i].style.display = "none"; + // } + // tabcontent[0].style.display = "block"; - function delayTab(tab){ - document.getElementById('Fila').style.display = "none"; - document.getElementById('Preparo').style.display = "none"; - document.getElementById('Finalizado').style.display = "none"; - document.getElementById('Entregue').style.display = "none"; - document.getElementById('loading').style.display = "block"; + // function delayTab(tab){ + // document.getElementById('Fila').style.display = "none"; + // document.getElementById('Preparo').style.display = "none"; + // document.getElementById('Finalizado').style.display = "none"; + // document.getElementById('Entregue').style.display = "none"; + // document.getElementById('loading').style.display = "block"; - setTimeout(function() { - displayBlock(tab);}, 1000); - // reloadPage(); - } + // setTimeout(function() { + // displayBlock(tab);}, 1000); + // // reloadPage(); + // } - displayBlock('Fila'); + // displayBlock('Fila'); // function mostrarNotificacao(titulo,corpo,grupo) { diff --git a/gestaoRaul/websocket_client/__pycache__/websocketClient.cpython-312.pyc b/gestaoRaul/websocket_client/__pycache__/websocketClient.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a52d3e1275615385d8ed7701c51f9c58c55cf8e7 GIT binary patch literal 1844 zcma)7O-v(I9DlDf(+-_}EEHK_*<^Mpy1<5lUu+O|V@ne^n{1R74P3}<=K<4gXK>z> z0v6qf*^>v>gOI4PgoBukiAS$n@Z^O?V$Hz8#69SZh>1ir@&ATSfp}P_dGmh%-~0VP zXWD)r4Ehnfw9xcF974Z1M)l^Y?gy6vtRNMsID^KIcRY?A+cWM_Js+ZRZXS1XzcGi~ zDO~kqn-A6!tb>ms+AV}x9K49@kX2Kq-8@WRy$bkI_54M&1exB2+CJe{xCerO7Cn|w z(;>_2;z!juW|LLta_QslT+`VL$c??o>5>(64^Q(2Pde=KCwqZ&J(pk#PEGuAO&D4A zu1@t7xKGjN9#@Om#NgxBx8yn74@UE-AAOXC)d8!n9rYnc!$Z$b{C*@Lit`?f#$bX> zKgW%sJZ?vpn-rxRYOn^$Dr0l{yl!ay65pzvNY9#*T8?W z@c$!Av+EAtp)(T|PG&g<-CM1vlxMr~K0QyqI=!#CJnr<}UTDqJfmke0?ouOlk606w zn6tzjxYqyjOAFFORiNuAa{mrf6b(}FJwZJrWcwS^f|)4_qvrO1q>89KH7H}zQs+J)Bbb5&gH+HQjW zSPqbmkjWe+Dy!AB>ymDSPQm7~bjs#(re@dG%Cm!R7ZXk`m{9h$mf7{!Xl&ZZ5_l*X z%g|%PMk)tl%b>B>O(RVh7#WEt6R{~6lwyo1xy-2tn967%J|Pm0-7_<9hmYqs;bu13 zE61`@Km6SMiVp9ipZw3>Pwewe!q8siVkOd1j&u}Ll}Oi4q-#Ta5^h;-|IFG6NB89D zm;N>X#tZA=hruUudoi&tE(d>ZxUkamu%~$OhlW@s5ZeyK_5$_Gw~E2l_qQ8jJAvLm z>rrDjL@P(S4);SS*n7Ai2Idf`WA^BeHWX;8NOD<{D^hn^>i!*Jp<_=BE{BVFm2QXH zD`K=PMvwNSXIxodS?Xi5=Rvl8?&`)H8;R{uZ$<1Yi+!NG#Lh-BI}F|VQG9bxYGlli zqwfC}e*;lpsfdGRaqwuLgM+_m31;#Em-OKWE%7Vp3mgx6iyWZ!SH1BF_qY?s!`{bT z4Ga%Tz?XbDUeA|Ap5Xun$5Ie89LAt2)jK%ijd%D;EjZp5D7E?+zQkgdqK>}9!B;LO zd2Uk(C7QX-hyZamn`Opa3k^%$mX|SG(s^LEE_)b`iVR;34d39l2AtCy0x;k4toTme zgx^qP`xH8_r!>P9!E&DYSLgsBGS9PPaWHGBxeU2(wt>n1cW4A|Fba%!QT;9o?IP)b LZ^1+61>pY$tf#o$ literal 0 HcmV?d00001