Untitled
unknown
plain_text
5 months ago
9.6 kB
4
Indexable
<script lang="ts"> // Importaciones necesarias import { env } from '$env/dynamic/public'; import { onMount } from 'svelte'; import { accessToken, isLoadingOnAction, toast } from '$lib/store'; import { page as _page } from '$app/stores'; import SelectDropdown from '$lib/components/shared/SelectDropdown.svelte'; import LogDetailsModal from '$lib/components/client/aapc/LogDetailsModal.svelte'; import Pagination from '$lib/components/Pagination.svelte'; // Si usas Tailwind CSS u otro framework, asegúrate de que las clases CSS estén definidas import ArrowUp from '$lib/components/svg/ArrowUp.svelte'; import ArrowDown from '$lib/components/svg/ArrowDown.svelte'; // Variables y estados let swoogoKeys: any[] = []; let events: any[] = []; let logs: any[] = []; let selectedSwoogoKey: any = null; let selectedEvent: any = null; let logDetails = ''; let columns: any[] = [ { name: 'Reg Id', key: 'regId', sortable: true }, { name: 'Full Name', key: 'fullName', sortable: true }, { name: 'Email', key: 'email', sortable: true }, { name: 'Status', key: 'status', sortable: true }, { name: 'Updated At', key: 'updatedAt', sortable: true }, ]; let selectedSort: string = 'createdAt:DESC'; // Variables de paginación let page = 1; let limit = 10; let totalItems = 0; let totalPages = 0; let searchText = ''; // Función para manejar la búsqueda (si aplica) const onSearch = (searchText: string) => { // Implementa la lógica de búsqueda si es necesario }; // Observa cambios en selectedSwoogoKey para actualizar los eventos $: if (selectedSwoogoKey) { fetchEvents(); } // Observa cambios en selectedEvent para actualizar los logs $: if (selectedSwoogoKey && selectedEvent) { fetchLogs(); } // Función para manejar cambios de página y tamaño de página function handlePageChange(event) { page = event.detail.currentPage; limit = event.detail.pageSize; fetchLogs(); } // Función para formatear fechas const formatDate = (date: string) => { const d = new Date(date); const months = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ]; return `${d.getDate()}-${months[d.getMonth()]}-${d.getFullYear()} ${d.getHours()}:${d.getMinutes()}`; }; // Funciones para obtener datos del servidor const fetchKeys = async () => { $isLoadingOnAction = true; try { const res = await fetch(`${env.PUBLIC_API_URL}/client/ats/api-keys`, { method: 'GET', headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${$accessToken}` } }); const data = await res.json(); if (data.success) { swoogoKeys = data.data.filter((key: any) => key.platform === 'Swoogo'); } else { $toast = { ...$toast, show: true, message: 'Failed to fetch keys', type: 'error' }; } } catch (err: any) { console.error(err); $toast = { ...$toast, show: true, message: 'Failed to fetch keys', type: 'error' }; } finally { $isLoadingOnAction = false; } }; const fetchEvents = async () => { $isLoadingOnAction = true; try { const res = await fetch(`${env.PUBLIC_API_URL}/client/ats/events/active-events?swoogoAccount=${selectedSwoogoKey.id}`, { method: 'GET', headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${$accessToken}` } }); const data = await res.json(); if (data.success) { events = data.data.map((event: any) => ({ name: event.name, eventId: event.eventId })); } else { $toast = { ...$toast, show: true, message: 'Failed to fetch events', type: 'error' }; } } catch (err: any) { console.error(err); $toast = { ...$toast, show: true, message: 'Failed to fetch events', type: 'error' }; } finally { $isLoadingOnAction = false; } }; const fetchLogs = async () => { $isLoadingOnAction = true; try { const res = await fetch( `${env.PUBLIC_API_URL}/client/ats/logs?eventId=${selectedEvent.eventId}&sort=${selectedSort}&page=${page}&limit=${limit}&search=${searchText}`, { method: 'GET', headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${$accessToken}` } } ); const data = await res.json(); if (data.success) { logs = data.data; totalItems = data.total; totalPages = Math.ceil(totalItems / limit); } else { $toast = { ...$toast, show: true, message: 'Failed to fetch logs', type: 'error' }; } } catch (err: any) { console.error(err); $toast = { ...$toast, show: true, message: 'Failed to fetch logs', type: 'error' }; } finally { $isLoadingOnAction = false; } }; // onMount para cargar las llaves al inicio onMount(async () => { await fetchKeys(); }); </script> <h1 class="font-medium text-left text-[#383F51] py-8 px-4 w-full h-[72px] flex justify-between items-center border-b-[1px] border-black shadow-[0_1px_4px_rgba(0,0,0,0.2)] text-[20px] font-roboto"> Integration Mapping </h1> <div class="pt-8 pb-4 px-10 max-w-full flex flex-col overflow-hidden h-full"> <div class="mt-8 pb-4 max-w-full flex flex-col overflow-hidden relative w-full flex-grow"> <div class="relative z-10 flex gap-8 items-start"> <div class="flex flex-col w-[300px]"> <h2 class="font-semibold text-xl" style="color: #383F51;"> Select Swoogo Account </h2> <SelectDropdown options={swoogoKeys} displayProp="accountName" bind:selectedOption={selectedSwoogoKey} class="w-full" /> </div> <div class="flex flex-col w-[300px]"> <h2 class="font-semibold text-xl" style="color: #383F51;"> Select Event </h2> <SelectDropdown options={events} displayProp="name" bind:selectedOption={selectedEvent} class="w-full" /> </div> </div> <div> <h2 class="mt-8 mb-4 ml-4" style="color: #383F51;"> ATS Keys </h2> </div> <div class="overflow-auto rounded-lg border w-full mt-2 relative z-0"> <table class="w-full fixed-table"> <thead class="sticky top-0 z-10"> <tr class="bg-white"> <th class="fixed-column" style="width: 100px;"> Sl No. </th> {#each columns as header} <th class="fixed-column"> <span class="flex justify-between items-center"> <span>{header.name}</span> {#if header.sortable} <span class="flex justify-center items-center space-x-0.5"> <button on:click={() => (selectedSort = header.key + ':ASC')}> <ArrowUp class="w-2.5 h-2.5" /> </button> <button on:click={() => (selectedSort = header.key + ':DESC')}> <ArrowDown class="w-2.5 h-2.5" /> </button> </span> {/if} </span> </th> {/each} </tr> </thead> <tbody> {#each logs as log, i} <tr class="border-b hover:bg-sail-50 transition duration-300 ease-in-out"> <td class="fixed-column" style="width: 100px;"> {(page - 1) * limit + i + 1} </td> <td class="fixed-column">{log.regId}</td> <td class="fixed-column">{log.fullName}</td> <td class="fixed-column">{log.email}</td> <td class={`py-2 px-6 text-sm ${log.status === 'Failed' ? '!text-red-500 font-semibold' : '!text-green-500 font-semibold'}`}> {log.status} {#if log.status === 'Failed' && log.details} <button class="text-blue-500 underline ml-2" on:click={() => { logDetails = log.details; }} > View logs </button> {/if} </td> <td class="fixed-column"> {log.updatedAt ? formatDate(log.updatedAt) : formatDate(log.createdAt)} </td> </tr> {/each} </tbody> </table> </div> <!-- Componente de paginación --> <Pagination bind:currentPage={page} bind:pageSize={limit} {totalItems} on:pageChange={handlePageChange} on:pageSizeChange={handlePageChange} /> </div> {#if logDetails} <LogDetailsModal details={logDetails} on:close={() => (logDetails = '')} /> {/if} </div> <style> .fixed-table { table-layout: fixed; width: 100%; } .fixed-column { width: 25%; text-align: left; padding: 8px 12px; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; } td, th { /* Si usas Tailwind CSS */ @apply text-sm text-black-500 py-2 px-3 border-t border-black-100; } </style>
Editor is loading...
Leave a Comment