Ver código fonte

add the info on modal

gdias 1 dia atrás
pai
commit
e9aaf23410
1 arquivos alterados com 101 adições e 19 exclusões
  1. 101 19
      src/routes/users/+page.svelte

+ 101 - 19
src/routes/users/+page.svelte

@@ -34,6 +34,42 @@
   let selectedUser = null;
   let showDetails = false;
 
+  let detailsLoading = false;
+  let detailsError = '';
+  let selectedUserInfo = null;
+
+  function getUserIdFromRow(row) {
+    return (
+      row?.__raw?.user_id ??
+      row?.__raw?.userId ??
+      row?.__raw?.id ??
+      row?.user_id ??
+      row?.userId ??
+      row?.id ??
+      row?.__raw?.id ??
+      row?.__raw?.userId ??
+      row?.__raw?.user_id
+    );
+  }
+
+  function formatBirthdate(epoch) {
+    if (epoch == null || epoch === '') return '-';
+    const n = Number(epoch);
+    if (!Number.isFinite(n) || n <= 0) return '-';
+    const ms = n < 1e12 ? n * 1000 : n;
+    const d = new Date(ms);
+    if (Number.isNaN(d.getTime())) return '-';
+    return d.toLocaleDateString('pt-BR');
+  }
+
+  function closeDetails() {
+    showDetails = false;
+    selectedUser = null;
+    selectedUserInfo = null;
+    detailsError = '';
+    detailsLoading = false;
+  }
+
   function handleAddTop() {
     showCreate = true;
   }
@@ -150,6 +186,46 @@
     selectedUser = row.__raw ?? row;
     //console.log('clicked user details:', selectedUser);
     showDetails = true;
+    detailsError = '';
+    selectedUserInfo = null;
+    const userId = getUserIdFromRow(row);
+    if (userId != null) loadUserInfo(userId);
+  }
+
+  async function loadUserInfo(userId) {
+    detailsLoading = true;
+    detailsError = '';
+    try {
+      const res = await fetch(`${apiUrl}/user/info`, {
+        method: 'POST',
+        headers: {
+          'content-type': 'application/json',
+          ...( $authToken ? { Authorization: `Bearer ${$authToken}` } : {} )
+        },
+        body: JSON.stringify({ user_id: userId })
+      });
+      const raw = await res.text();
+      let body = null;
+      if (raw) {
+        try {
+          body = JSON.parse(raw);
+        } catch (err) {
+          console.error('Resposta inválida do endpoint /user/info:', err);
+          throw new Error('Resposta inválida do servidor.');
+        }
+      }
+      const isSuccess = body?.status === 'ok' || body?.status === 'success' || body?.code === 'S_OK';
+      if (!res.ok || !isSuccess) {
+        throw new Error(body?.message ?? body?.msg ?? 'Falha ao carregar detalhes do usuário.');
+      }
+      selectedUserInfo = body?.data ?? null;
+    } catch (err) {
+      console.error('Erro ao carregar detalhes do usuário:', err);
+      detailsError = err?.message ?? 'Falha ao carregar detalhes do usuário.';
+      selectedUserInfo = null;
+    } finally {
+      detailsLoading = false;
+    }
   }
 
   async function confirmDelete() {
@@ -248,37 +324,43 @@
           role="button"
           tabindex="0"
           on:click={(e) => {
-            if (e.target === e.currentTarget) showDetails = false;
+            if (e.target === e.currentTarget) closeDetails();
           }}
           on:keydown={(e) => {
-            if (e.key === 'Escape' || e.key === 'Enter' || e.key === ' ') showDetails = false;
+            if (e.key === 'Escape' || e.key === 'Enter' || e.key === ' ') closeDetails();
           }}
         >
           <div class="bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg shadow-lg w-full max-w-lg p-6" role="dialog" aria-modal="true">
             <div class="flex items-center justify-between mb-4">
               <h4 class="text-lg font-semibold text-gray-900 dark:text-gray-100">Detalhes do usuário</h4>
-              <button class="text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200" on:click={() => showDetails = false}>✕</button>
+              <button class="text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200" on:click={closeDetails}>✕</button>
             </div>
-            {#if selectedUser}
+            {#if detailsLoading}
+              <div class="text-sm text-gray-600 dark:text-gray-300">Carregando detalhes...</div>
+            {:else if detailsError}
+              <div class="text-sm text-red-600 dark:text-red-400">{detailsError}</div>
+            {:else if selectedUserInfo}
               <div class="grid grid-cols-1 sm:grid-cols-2 gap-3 text-sm">
-                <div><span class="text-gray-500">ID:</span> <span class="dark:text-gray-100">{selectedUser.userId}</span></div>
-                <div><span class="text-gray-500">Nome:</span> <span class="dark:text-gray-100">{selectedUser.userName}</span></div>
-                <div><span class="text-gray-500">E-mail:</span> <span class="dark:text-gray-100">{selectedUser.userEmail}</span></div>
-                <div><span class="text-gray-500">Telefone:</span> <span class="dark:text-gray-100">{selectedUser.userPhone}</span></div>
-                <div><span class="text-gray-500">CPF:</span> <span class="dark:text-gray-100">{selectedUser.userCpf}</span></div>
-                <div><span class="text-gray-500">Data Nasc.:</span> <span class="dark:text-gray-100">{selectedUser.userBirthdate}</span></div>
-                <div><span class="text-gray-500">KYC:</span> <span class="dark:text-gray-100">{selectedUser.userKyc}</span></div>
-                <div><span class="text-gray-500">Papel (roleId):</span> <span class="dark:text-gray-100">{selectedUser.roleId}</span></div>
-                <div><span class="text-gray-500">Status:</span> <span class="dark:text-gray-100">{selectedUser.userFlag}</span></div>
-                <div class="sm:col-span-2"><span class="text-gray-500">Endereço:</span> <span class="dark:text-gray-100">{selectedUser.userAddress}</span></div>
-                <div><span class="text-gray-500">Cidade:</span> <span class="dark:text-gray-100">{selectedUser.userCity}</span></div>
-                <div><span class="text-gray-500">Estado:</span> <span class="dark:text-gray-100">{selectedUser.userState}</span></div>
-                <div><span class="text-gray-500">CEP:</span> <span class="dark:text-gray-100">{selectedUser.userZip}</span></div>
-                <div><span class="text-gray-500">País:</span> <span class="dark:text-gray-100">{selectedUser.userCountry}</span></div>
+                <div><span class="text-gray-500">ID:</span> <span class="dark:text-gray-100">{selectedUserInfo.id ?? '-'}</span></div>
+                <div><span class="text-gray-500">Nome:</span> <span class="dark:text-gray-100">{selectedUserInfo.nome ?? '-'}</span></div>
+                <div><span class="text-gray-500">E-mail:</span> <span class="dark:text-gray-100">{selectedUserInfo.email ?? '-'}</span></div>
+                <div><span class="text-gray-500">Telefone:</span> <span class="dark:text-gray-100">{selectedUserInfo.telefone ?? '-'}</span></div>
+                <div><span class="text-gray-500">CPF:</span> <span class="dark:text-gray-100">{selectedUserInfo.cpf ?? '-'}</span></div>
+                <div><span class="text-gray-500">Data Nasc.:</span> <span class="dark:text-gray-100">{formatBirthdate(selectedUserInfo.dataNasc)}</span></div>
+                <div><span class="text-gray-500">KYC:</span> <span class="dark:text-gray-100">{selectedUserInfo.kyc ?? '-'}</span></div>
+                <div><span class="text-gray-500">Papel (roleId):</span> <span class="dark:text-gray-100">{selectedUserInfo.roleId ?? '-'}</span></div>
+                <div><span class="text-gray-500">Status:</span> <span class="dark:text-gray-100">{selectedUserInfo.status ?? '-'}</span></div>
+                <div class="sm:col-span-2"><span class="text-gray-500">Endereço:</span> <span class="dark:text-gray-100">{selectedUserInfo.endereco ?? '-'}</span></div>
+                <div><span class="text-gray-500">Cidade:</span> <span class="dark:text-gray-100">{selectedUserInfo.cidade ?? '-'}</span></div>
+                <div><span class="text-gray-500">Estado:</span> <span class="dark:text-gray-100">{selectedUserInfo.estado ?? '-'}</span></div>
+                <div><span class="text-gray-500">CEP:</span> <span class="dark:text-gray-100">{selectedUserInfo.cep ?? '-'}</span></div>
+                <div><span class="text-gray-500">País:</span> <span class="dark:text-gray-100">{selectedUserInfo.pais ?? '-'}</span></div>
               </div>
+            {:else}
+              <div class="text-sm text-gray-600 dark:text-gray-300">Nenhum detalhe disponível.</div>
             {/if}
             <div class="mt-5 flex justify-end">
-              <button class="px-4 py-2 rounded bg-blue-600 hover:bg-blue-700 text-white" on:click={() => showDetails = false}>Fechar</button>
+              <button class="px-4 py-2 rounded bg-blue-600 hover:bg-blue-700 text-white" on:click={closeDetails}>Fechar</button>
             </div>
           </div>
         </div>