Mananger.svelte 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. <script>
  2. import { onMount } from 'svelte';
  3. import add_icon from '$lib/assets/add_icon.svg';
  4. import save_icon from '$lib/assets/save_icon.svg';
  5. import trash_icon from '$lib/assets/trash_icon.svg';
  6. import { browser } from '$app/environment';
  7. let token = null;
  8. let company = null;
  9. if (browser) {
  10. token = localStorage.getItem('token');
  11. company = Number(localStorage.getItem('company'));
  12. }
  13. let users = [];
  14. let isAddingUser = false;
  15. let newUserForm = {
  16. name: '',
  17. username: '',
  18. email: '',
  19. password: '',
  20. role_id: 1
  21. };
  22. function resetUserForm() {
  23. newUserForm = {
  24. name: '',
  25. username: '',
  26. email: '',
  27. password: '',
  28. role_id: 1
  29. };
  30. isAddingUser = false;
  31. }
  32. async function handleAddUser(event) {
  33. event.preventDefault();
  34. if (!newUserForm.username || !newUserForm.email || !newUserForm.password) {
  35. console.error('Preencha todos os campos corretamente');
  36. return;
  37. }
  38. const token = localStorage.getItem('token');
  39. const company = parseInt(localStorage.getItem('company'), 10);
  40. const requestOptions = {
  41. method: 'POST',
  42. headers: {
  43. Authorization: `Bearer ${token}`,
  44. 'Content-Type': 'application/json'
  45. },
  46. body: JSON.stringify({
  47. username: newUserForm.username,
  48. email: newUserForm.email,
  49. password: newUserForm.password,
  50. company_id: company,
  51. role_id: Number(newUserForm.role_id)
  52. }),
  53. redirect: 'follow'
  54. };
  55. try {
  56. const response = await fetch('https://dev2.mixtech.dev.br/register', requestOptions);
  57. const result = await response.json();
  58. if (result.status === 'ok') {
  59. //console.log('Usuário criado com sucesso!');
  60. resetUserForm();
  61. fetchUsers();
  62. } else {
  63. console.error('Erro ao criar usuário:', result.msg || result);
  64. }
  65. } catch (error) {
  66. console.error('Erro de rede ao criar usuário:', error);
  67. }
  68. }
  69. async function handleDeleteUser(userName) {
  70. const token = localStorage.getItem('token');
  71. const myHeaders = new Headers();
  72. myHeaders.append('Authorization', `Bearer ${token}`);
  73. myHeaders.append('Content-Type', 'application/json');
  74. const raw = JSON.stringify({
  75. user_name: userName,
  76. company_id: company
  77. });
  78. const requestOptions = {
  79. method: 'POST',
  80. headers: myHeaders,
  81. body: raw,
  82. redirect: 'follow'
  83. };
  84. try {
  85. const response = await fetch('https://dev2.mixtech.dev.br/user/delete', requestOptions);
  86. const result = await response.json();
  87. if (result.status === 'ok') {
  88. users = users.filter((u) => u.name !== userName);
  89. console.log('Usuário deletado com sucesso!');
  90. } else {
  91. console.error('Erro ao deletar usuário:', result.msg || result);
  92. }
  93. } catch (error) {
  94. console.error('Erro na requisição de deleção:', error);
  95. }
  96. }
  97. function fetchUsers() {
  98. const token = localStorage.getItem('token');
  99. const company = parseInt(localStorage.getItem('company'), 10);
  100. fetch('https://dev2.mixtech.dev.br/user/get', {
  101. method: 'POST',
  102. headers: {
  103. Authorization: `Bearer ${token}`,
  104. 'Content-Type': 'application/json'
  105. },
  106. body: JSON.stringify({ company_id: company })
  107. })
  108. .then((response) => response.json())
  109. .then((data) => {
  110. users = data.data.map((item) => ({
  111. id: item.user_id,
  112. name: item.user_name,
  113. email: item.user_email,
  114. role: item.role_id
  115. }));
  116. })
  117. .catch((error) => console.error('Erro ao buscar usuários:', error));
  118. }
  119. onMount(() => {
  120. fetchUsers();
  121. });
  122. </script>
  123. <div class="container mx-auto">
  124. <div class="flex flex-col">
  125. <div class="mb-6 flex items-center justify-between">
  126. <h1 class="text-2xl font-bold">Gerenciar Usuários</h1>
  127. <button
  128. on:click={() => (isAddingUser = true)}
  129. class="rounded-lg bg-emerald-600 p-1.5 hover:bg-emerald-700"
  130. >
  131. <img src={add_icon} alt="Adicionar" class="h-4 w-4" />
  132. </button>
  133. </div>
  134. <div class="overflow-x-auto rounded-lg bg-gray-800 shadow-lg">
  135. <table class="w-full min-w-[500px] divide-y divide-gray-700">
  136. <thead class="bg-gray-700">
  137. <tr>
  138. <th class="px-6 py-3 text-left text-sm font-semibold text-gray-300">Username</th>
  139. <th class="px-6 py-3 text-left text-sm font-semibold text-gray-300">Email</th>
  140. <th class="px-6 py-3 text-left text-sm font-semibold text-gray-300">Cargo</th>
  141. <th class="px-6 py-3 text-left text-sm font-semibold text-gray-300">Ações</th>
  142. </tr>
  143. </thead>
  144. <tbody class="divide-y divide-gray-700">
  145. {#if users.length === 0}
  146. <tr>
  147. <td colspan="4" class="p-4 text-center text-gray-400">Nenhum usuário encontrado</td>
  148. </tr>
  149. {:else}
  150. {#each users as user}
  151. <tr class="hover:bg-gray-900">
  152. <td class="px-6 py-4 text-sm text-white">{user.name}</td>
  153. <td class="px-6 py-4 text-sm text-white">{user.email}</td>
  154. <td class="px-6 py-4 text-sm text-white"
  155. >{#if user.role === 1}
  156. Admin
  157. {:else if user.role === 2}
  158. Garçom
  159. {:else if user.role === 3}
  160. Cozinha
  161. {:else if user.role === 4}
  162. Caixa
  163. {/if}</td
  164. >
  165. <td class="px-6 py-4">
  166. <button
  167. on:click={() => handleDeleteUser(user.name)}
  168. class="rounded-lg p-1.5 text-red-400 hover:bg-red-900/20"
  169. >
  170. <img src={trash_icon} alt="Deletar" class="h-4 w-4" />
  171. </button>
  172. </td>
  173. </tr>
  174. {/each}
  175. {/if}
  176. </tbody>
  177. </table>
  178. </div>
  179. </div>
  180. </div>
  181. {#if isAddingUser}
  182. <div class="fixed inset-0 z-50 flex items-center justify-center bg-black bg-opacity-50">
  183. <div class="w-full max-w-md rounded-lg bg-gray-800 p-6 shadow-lg">
  184. <h2 class="mb-4 text-lg font-semibold">Adicionar Novo Usuário</h2>
  185. <form on:submit={handleAddUser} class="space-y-4">
  186. <div>
  187. <p class="mb-1 block text-sm text-gray-400">Username</p>
  188. <input
  189. bind:value={newUserForm.username}
  190. class="w-full rounded-md border border-gray-600 bg-gray-700 px-3 py-2 focus:ring-emerald-500"
  191. placeholder="Ex: johndoe"
  192. />
  193. </div>
  194. <div>
  195. <p class="mb-1 block text-sm text-gray-400">Email</p>
  196. <input
  197. bind:value={newUserForm.email}
  198. class="w-full rounded-md border border-gray-600 bg-gray-700 px-3 py-2 focus:ring-emerald-500"
  199. placeholder="Ex: john@example.com"
  200. />
  201. </div>
  202. <div>
  203. <p class="mb-1 block text-sm text-gray-400">Senha</p>
  204. <input
  205. type="password"
  206. bind:value={newUserForm.password}
  207. class="w-full rounded-md border border-gray-600 bg-gray-700 px-3 py-2 focus:ring-emerald-500"
  208. placeholder="Digite a senha"
  209. />
  210. </div>
  211. <div>
  212. <p class="mb-1 block text-sm text-gray-400">Tipo de Usuário</p>
  213. <select
  214. bind:value={newUserForm.role_id}
  215. class="w-full rounded-md border border-gray-600 bg-gray-700 px-3 py-2 text-white focus:ring-emerald-500"
  216. >
  217. <option value={1}>Admin</option>
  218. <option value={2}>Garçom</option>
  219. <option value={3}>Cozinha</option>
  220. <option value={4}>Caixa</option>
  221. </select>
  222. </div>
  223. <div class="flex space-x-2">
  224. <button
  225. type="button"
  226. on:click={resetUserForm}
  227. class="rounded-lg bg-gray-700 px-4 py-2 hover:bg-gray-600"
  228. >
  229. Cancelar
  230. </button>
  231. <button
  232. type="submit"
  233. class="flex items-center rounded-lg bg-emerald-600 px-4 py-2 hover:bg-emerald-700"
  234. >
  235. <img src={save_icon} alt="Salvar" class="mr-2 h-4 w-4" /> Salvar
  236. </button>
  237. </div>
  238. </form>
  239. </div>
  240. </div>
  241. {/if}