Mananger.svelte 7.6 KB

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