Untitled
unknown
plain_text
a year ago
9.6 kB
10
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