3 Commits

Author SHA1 Message Date
fede 3e07252c6f refactor: enlineadas funciones que solo se usan una vez 2026-02-13 15:09:08 -03:00
fede ec9ec1f58a fix: añadida paginacion 2026-02-12 18:14:31 -03:00
Fran 4ca434da9e add UsersAdmin 2026-02-12 17:25:53 -03:00
6 changed files with 98 additions and 81 deletions
BIN
View File
Binary file not shown.
+48 -52
View File
@@ -33,10 +33,12 @@
interface Props {
usuarios: UserResponseDto[];
hayMas: boolean;
}
let { usuarios = $bindable() }: Props = $props();
let { usuarios = $bindable(), hayMas }: Props = $props();
let hayMass = $state(hayMas);
let open = $state(false);
let openModificarUsuario = $state(false);
let openDarAdmin = $state(false);
@@ -90,41 +92,20 @@
return sortDirection === 'asc' ? '↑' : '↓';
}
function handleCambiarContraseña(usuario: UserResponseDto) {
open = true;
usuarioCambioPass = usuario;
}
function handleModificar(usuario: UserResponseDto) {
openModificarUsuario = true;
usuarioModificar = usuario;
}
function handleBorrar(usuario: UserResponseDto) {
openBorrar = true;
usuarioBorrar = usuario;
}
function handleDarAdmin(usuario: UserResponseDto) {
openDarAdmin = true;
usuarioDarAdmin = usuario;
}
// $inspect(usuarios);
let timeoutId: ReturnType<typeof setTimeout> | number | undefined;
function buscarUsuarios() {
if (timeoutId) {
clearTimeout(timeoutId);
}
timeoutId = setTimeout(async () => {
paginaActual = 1;
if (search === '') {
usuariosFiltrados = usuarios;
return;
search = '';
}
usuariosFiltrados = await busquedaAdminUsuarios(search);
let ret = await busquedaAdminUsuarios(search, ITEMS_POR_PAGINA, paginaActual);
usuariosFiltrados = ret.usuarios;
hayMass = ret.hayMas;
}, 200);
return () => {
@@ -135,11 +116,9 @@
let paginaActual = $state(1);
const totalPaginas = $derived(Math.ceil(usuariosFiltrados.length / ITEMS_POR_PAGINA));
const usuariosPaginados = $derived(
usuariosFiltrados.slice((paginaActual - 1) * ITEMS_POR_PAGINA, paginaActual * ITEMS_POR_PAGINA)
);
// const usuariosPaginados = $derived(
// usuariosFiltrados.slice((paginaActual - 1) * ITEMS_POR_PAGINA, paginaActual * ITEMS_POR_PAGINA)
// );
</script>
<div class="mb-4 flex gap-2">
@@ -184,7 +163,7 @@
<p class="text-center">No hay usuarios por el nombre de: {search}</p>
</TableCell>
</TableRow>{:else}
{#each usuariosPaginados as usuario}
{#each usuariosFiltrados as usuario}
<TableRow>
<TableCell
>@<a href={'/' + usuario.username}>
@@ -197,7 +176,11 @@
<TableCell class="flex gap-2">
<Tooltip>
<TooltipTrigger>
<Button onclick={() => handleCambiarContraseña(usuario)}><KeyIcon></KeyIcon></Button
<Button
onclick={() => {
open = true;
usuarioCambioPass = usuario;
}}><KeyIcon></KeyIcon></Button
>
</TooltipTrigger>
<TooltipContent>
@@ -206,7 +189,12 @@
</Tooltip>
<Tooltip>
<TooltipTrigger>
<Button onclick={() => handleModificar(usuario)}><UserPen /></Button>
<Button
onclick={() => {
openModificarUsuario = true;
usuarioModificar = usuario;
}}><UserPen /></Button
>
</TooltipTrigger>
<TooltipContent>
<p>Modificar Usuario</p>
@@ -216,7 +204,10 @@
<TooltipTrigger>
<Button
disabled={usuario.isAdmin}
onclick={() => handleBorrar(usuario)}
onclick={() => {
openBorrar = true;
usuarioBorrar = usuario;
}}
variant="destructive"><Trash_2 /></Button
>
</TooltipTrigger>
@@ -232,7 +223,10 @@
<Tooltip>
<TooltipTrigger>
<Button
onclick={() => handleDarAdmin(usuario)}
onclick={() => {
openDarAdmin = true;
usuarioDarAdmin = usuario;
}}
variant={usuario.isAdmin ? 'destructive' : 'default'}
>
<Shield />
@@ -253,23 +247,25 @@
</TableBody>
</Table>
<div class="mt-4 flex items-center justify-between">
<p class="text-sm text-muted-foreground">
Página {paginaActual} de {totalPaginas}
</p>
<Button
disabled={paginaActual === 1}
onclick={() => {
paginaActual--;
buscarUsuarios();
}}
variant="secondary"
>
Anterior
</Button>
<div class="flex gap-2">
<Button disabled={paginaActual === 1} onclick={() => paginaActual--} variant="secondary">
Anterior
</Button>
<Button
disabled={paginaActual === totalPaginas || totalPaginas === 0}
onclick={() => paginaActual++}
variant="secondary"
>
Siguiente
</Button>
</div>
<Button
disabled={!hayMass}
onclick={() => {
paginaActual++;
buscarUsuarios();
}}
variant="secondary">Siguiente</Button
>
</div>
<BorrarUsuario bind:open={openBorrar} usuario={usuarioBorrar} />
<RecuperarContraseña bind:open usuario={usuarioCambioPass} />
+25
View File
@@ -0,0 +1,25 @@
import { apiBase } from '@/stores/url';
import { sesionStore } from '@/stores/usuario';
import { redirect } from '@sveltejs/kit';
import { get } from 'svelte/store';
import type { UserResponseDto } from '../../types';
export async function fetchUsuariosAdmin(page: number, limit: number) {
let response = await fetch(get(apiBase) + `/api/admin/users?page=${page}&pageSize=${limit}`, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${get(sesionStore)?.accessToken}`
}
});
if (response.status === 401) {
throw redirect(302, '/');
}
if (!response.ok) {
return { error: true };
}
const ret: { usuarios: UserResponseDto[]; hayMas: boolean } = await response.json();
return { ret, error: false };
}
+11 -7
View File
@@ -2,15 +2,19 @@ import { apiBase } from '@/stores/url';
import { sesionStore } from '@/stores/usuario';
import { get } from 'svelte/store';
export async function busquedaAdminUsuarios(q: string) {
export async function busquedaAdminUsuarios(q: string, limit = 5, page = 1) {
try {
const response = await fetch(get(apiBase) + '/api/admin/users?q=' + q, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${get(sesionStore)?.accessToken}`
const response = await fetch(
get(apiBase) +
`/api/admin/users${q ? `?q=${q}` : ''}${q ? '&' : '?'}page=${page}&pageSize=${limit}`,
{
method: 'GET',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${get(sesionStore)?.accessToken}`
}
}
});
);
if (response.ok) {
return await response.json();
}
+2 -1
View File
@@ -10,6 +10,7 @@
interface Prop {
data: {
usuarios?: UserResponseDto[];
hayMas: boolean;
error: boolean;
};
}
@@ -31,7 +32,7 @@
{#if data.usuarios?.length === 0}
<CardDescription>No hay usuarios que mostar</CardDescription>
{:else}
<TablaUsuarios usuarios={data.usuarios || []}></TablaUsuarios>
<TablaUsuarios usuarios={data.usuarios || []} hayMas={data.hayMas}></TablaUsuarios>
{/if}
</CardContent>
</Card>
+12 -21
View File
@@ -1,28 +1,19 @@
import { apiBase } from '@/stores/url.js';
import { sesionStore } from '@/stores/usuario';
import { redirect } from '@sveltejs/kit';
import { get } from 'svelte/store';
import type { UserResponseDto } from '../../../types.js';
import type { PageLoad } from './$types.js';
import { fetchUsuariosAdmin } from '@/hooks/UsuariosAdmin.js';
export const ssr = false;
export async function load({ depends, fetch }) {
export const load: PageLoad = async ({ depends }) => {
depends('admin:load');
const response = await fetch(get(apiBase) + '/api/admin/users', {
method: 'GET',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${get(sesionStore)?.accessToken}`
}
});
if (response.status === 401) {
throw redirect(302, '/');
}
if (!response.ok) {
const result = await fetchUsuariosAdmin(1, 5);
if (result.error) {
return { error: true };
}
const usuarios: UserResponseDto[] = await response.json();
return { usuarios, error: false };
}
return {
usuarios: result.ret?.usuarios,
hayMas: result.ret?.hayMas,
error: false
};
};