Commands.svelte 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. <script>
  2. import { onMount } from 'svelte';
  3. import { goto } from '$app/navigation';
  4. import { browser } from '$app/environment';
  5. import save_icon from '$lib/assets/save_icon.svg';
  6. let token = null;
  7. let companyId = null;
  8. let userId = null;
  9. let tableId = null;
  10. let flag = null;
  11. let orderToCancel = null;
  12. if (browser) {
  13. token = localStorage.getItem('token');
  14. companyId = Number(localStorage.getItem('company'));
  15. userId = localStorage.getItem('user');
  16. tableId = Number(localStorage.getItem('table'));
  17. flag = localStorage.getItem('flag');
  18. }
  19. let orders = [];
  20. let isCreatingOrder = false;
  21. let customerName = '';
  22. let customerPhone = '';
  23. let showConfirmCancel = false;
  24. const fetchOrders = async () => {
  25. if (!companyId || !tableId) return;
  26. try {
  27. const response = await fetch('https://dev2.mixtech.dev.br/order/get', {
  28. method: 'POST',
  29. headers: {
  30. 'Content-Type': 'application/json',
  31. Authorization: `Bearer ${token}`
  32. },
  33. body: JSON.stringify({ company_id: companyId, table_id: tableId })
  34. });
  35. const result = await response.json();
  36. if (result.status === 'ok') {
  37. orders = result.data.map((o) => ({
  38. id: o.order_id,
  39. name: o.order_name,
  40. phone: o.order_phone,
  41. createdAt: o.order_created_at,
  42. status: o.status_status
  43. }));
  44. } else {
  45. console.error('Failed to fetch orders:', result.msg);
  46. }
  47. } catch (err) {
  48. console.error('Request error:', err);
  49. }
  50. };
  51. const openOrder = (orderId) => {
  52. goto(`/pos/${orderId}`);
  53. };
  54. const createOrder = async () => {
  55. if (!customerName.trim()) return;
  56. try {
  57. const response = await fetch('https://dev2.mixtech.dev.br/order/create', {
  58. method: 'POST',
  59. headers: {
  60. 'Content-Type': 'application/json',
  61. Authorization: `Bearer ${token}`
  62. },
  63. body: JSON.stringify({
  64. table_id: tableId,
  65. user_name: userId,
  66. company_id: companyId,
  67. order_name: customerName,
  68. order_phone: customerPhone || '',
  69. status_status: 'Aberta'
  70. })
  71. });
  72. const result = await response.json();
  73. if (result.status === 'ok') {
  74. isCreatingOrder = false;
  75. customerName = '';
  76. customerPhone = '';
  77. await fetchOrders();
  78. } else {
  79. console.error('Failed to create order:', result.msg);
  80. }
  81. } catch (err) {
  82. console.error('Error creating order:', err);
  83. }
  84. };
  85. function cancelCommand(order_Id) {
  86. const myHeaders = new Headers();
  87. myHeaders.append('Authorization', `Bearer ${token}`);
  88. myHeaders.append('Content-Type', 'application/json');
  89. const raw = JSON.stringify({
  90. order_id: order_Id,
  91. company_id: companyId,
  92. cancel: true
  93. });
  94. const requestOptions = {
  95. method: 'POST',
  96. headers: myHeaders,
  97. body: raw,
  98. redirect: 'follow'
  99. };
  100. fetch('https://dev2.mixtech.dev.br/order/delete', requestOptions)
  101. .then((response) => response.json())
  102. .then((result) => {
  103. (console.log('Pedido cancelado com sucesso:', order_Id, companyId, result),
  104. location.reload());
  105. })
  106. .catch((error) => console.error('Erro ao cancelar comanda:', error));
  107. }
  108. const getElapsedTime = (createdAt) => {
  109. if (!createdAt || createdAt.trim() === '') return '';
  110. const start = new Date(createdAt.replace(' ', 'T'));
  111. const now = new Date();
  112. const diff = Math.floor((now - start) / 60000); // in minutes
  113. if (diff < 60) return `${diff} min`;
  114. const hours = Math.floor(diff / 60);
  115. const minutes = diff % 60;
  116. return `${hours}h ${minutes}m`;
  117. };
  118. function handleAddProduct(order_id) {
  119. localStorage.setItem('order', order_id);
  120. goto('/dashboard/addproducts');
  121. }
  122. function handleEndProduct(order_id) {
  123. localStorage.setItem('order', order_id);
  124. goto('/dashboard/endcommand');
  125. }
  126. onMount(() => {
  127. fetchOrders();
  128. setInterval(() => {
  129. fetchOrders();
  130. }, 5000);
  131. });
  132. </script>
  133. <div class="container mx-auto w-full rounded-md bg-gray-800 p-4">
  134. <h1 class="mb-6 text-center text-2xl font-bold">Comandas</h1>
  135. <div
  136. class="grid grid-cols-2 justify-items-center gap-4 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5"
  137. >
  138. {#each orders as order}
  139. <div
  140. class="w-full max-w-xs rounded-lg bg-gray-900 shadow-md transition-transform hover:scale-105"
  141. >
  142. <div class="flex flex-col items-center justify-between rounded-t-lg bg-emerald-700 p-4">
  143. <span class="font-medium">{order.name}</span>
  144. <span class="font-medium">{order.phone}</span>
  145. </div>
  146. <div class="p-4">
  147. <div class="mb-2 text-sm text-gray-400">
  148. {getElapsedTime(order.createdAt)}
  149. </div>
  150. <!--adicionar aqui link para o addproduct preciso salvar uma variavel com o order_id e etc para aparecer apenas o item da comanda em especifico-->
  151. <button
  152. class="mb-2 w-full rounded bg-emerald-600 py-2 hover:bg-emerald-700"
  153. on:click={handleAddProduct(order.id)}
  154. >
  155. Adicionar items
  156. </button>
  157. {#if flag == 'admin'}
  158. <button
  159. class="mb-2 w-full rounded bg-yellow-600 py-2 hover:bg-yellow-700"
  160. on:click={handleEndProduct(order.id)}
  161. >
  162. Finalizar Comanda
  163. </button>
  164. {/if}
  165. {#if flag == 'admin' || flag == 'cashier'}
  166. <button
  167. class="w-full rounded bg-red-600 py-2 hover:bg-red-700"
  168. on:click={cancelCommand(order.id)}
  169. >
  170. Cancelar
  171. </button>
  172. {/if}
  173. </div>
  174. </div>
  175. {/each}
  176. </div>
  177. <div class="mt-6 flex justify-center">
  178. <button
  179. class="rounded-md bg-green-600 px-4 py-2 text-white hover:bg-green-700"
  180. on:click={() => (isCreatingOrder = true)}
  181. >
  182. Adicionar Comanda
  183. </button>
  184. </div>
  185. </div>
  186. {#if isCreatingOrder}
  187. <div class="fixed inset-0 z-50 flex items-center justify-center bg-black bg-opacity-50">
  188. <div class="w-full max-w-md rounded-lg bg-gray-800 p-6 shadow-lg">
  189. <h2 class="mb-4 text-lg font-semibold">New Order</h2>
  190. <form on:submit|preventDefault={createOrder} class="space-y-4">
  191. <div>
  192. <p class="mb-1 block text-sm text-gray-400">Nome</p>
  193. <input
  194. bind:value={customerName}
  195. placeholder="Ex: John Doe"
  196. class="w-full rounded-md border border-gray-600 bg-gray-700 px-3 py-2 focus:ring-emerald-500"
  197. />
  198. </div>
  199. <div>
  200. <p class="mb-1 block text-sm text-gray-400">Numero (optional)</p>
  201. <input
  202. bind:value={customerPhone}
  203. placeholder="(11) 99999-9999"
  204. class="w-full rounded-md border border-gray-600 bg-gray-700 px-3 py-2 focus:ring-emerald-500"
  205. />
  206. </div>
  207. <div class="flex justify-end space-x-2">
  208. <button
  209. type="button"
  210. on:click={() => (isCreatingOrder = false)}
  211. class="rounded-lg bg-gray-700 px-4 py-2 hover:bg-gray-600"
  212. >
  213. Cancelar
  214. </button>
  215. <button
  216. type="submit"
  217. class="flex items-center rounded-lg bg-emerald-600 px-4 py-2 hover:bg-emerald-700"
  218. >
  219. <img src={save_icon} alt="Save" class="mr-2 h-4 w-4" /> Salvar
  220. </button>
  221. </div>
  222. </form>
  223. </div>
  224. </div>
  225. {/if}
  226. {#if showConfirmCancel}
  227. <div class="fixed inset-0 flex items-center justify-center bg-black bg-opacity-50">
  228. <div class="w-full max-w-sm rounded-lg bg-gray-800 p-6">
  229. <h2 class="mb-4 text-lg font-bold">Confirmar Exclusão</h2>
  230. <p class="mb-4">Deseja realmente cancelar a comanda {orderToCancel}?</p>
  231. <div class="flex justify-end gap-2">
  232. <button
  233. on:click={() => (showConfirmCancel = false)}
  234. class="rounded bg-gray-600 px-4 py-2 text-white transition-colors hover:bg-gray-700"
  235. >
  236. Cancelar
  237. </button>
  238. <button
  239. on:click={deleteTable}
  240. class="rounded bg-red-600 px-4 py-2 text-white transition-colors hover:bg-red-700"
  241. >
  242. Excluir
  243. </button>
  244. </div>
  245. </div>
  246. </div>
  247. {/if}