mirror of
https://github.com/emailerfacu-spec/minix-front.git
synced 2026-04-25 16:54:28 -03:00
terminada funcionalidad de resetear contraseña en [perfil]
This commit is contained in:
@@ -0,0 +1,115 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import Button from './ui/button/button.svelte';
|
||||||
|
import { Dialog } from './ui/dialog';
|
||||||
|
import DialogTrigger from './ui/dialog/dialog-trigger.svelte';
|
||||||
|
import DialogContent from './ui/dialog/dialog-content.svelte';
|
||||||
|
import DialogHeader from './ui/dialog/dialog-header.svelte';
|
||||||
|
import DialogTitle from './ui/dialog/dialog-title.svelte';
|
||||||
|
import Input from './ui/input/input.svelte';
|
||||||
|
import Field from './ui/field/field.svelte';
|
||||||
|
import FieldLabel from './ui/field/field-label.svelte';
|
||||||
|
import FieldGroup from './ui/field/field-group.svelte';
|
||||||
|
import DialogFooter from './ui/dialog/dialog-footer.svelte';
|
||||||
|
import Spinner from './ui/spinner/spinner.svelte';
|
||||||
|
import { invalidate } from '$app/navigation';
|
||||||
|
import { page } from '$app/state';
|
||||||
|
import { cambiarContraseñaUsuario } from '@/hooks/cambiarContraseñaUsuario';
|
||||||
|
|
||||||
|
let { data = $bindable(), children } = $props();
|
||||||
|
|
||||||
|
let passwordData = $state({
|
||||||
|
oldPassword: '',
|
||||||
|
newPassword: '',
|
||||||
|
confirmPassword: ''
|
||||||
|
});
|
||||||
|
|
||||||
|
let cargando = $state(false);
|
||||||
|
let open = $state(false);
|
||||||
|
|
||||||
|
let mensajeError = $state('');
|
||||||
|
|
||||||
|
const coinsiden = $derived(
|
||||||
|
passwordData.newPassword === passwordData.confirmPassword &&
|
||||||
|
/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[^A-Za-z0-9])[A-Za-z\d\W_]*$/.test(
|
||||||
|
passwordData.newPassword
|
||||||
|
) &&
|
||||||
|
passwordData.newPassword.length > 8
|
||||||
|
);
|
||||||
|
|
||||||
|
async function onsubmit(e: SubmitEvent | null) {
|
||||||
|
if (e != null) e.preventDefault();
|
||||||
|
if (!coinsiden) {
|
||||||
|
mensajeError = 'Las contraseñas no coinciden o no cumplen con los requisitos';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
cargando = true;
|
||||||
|
try {
|
||||||
|
await cambiarContraseñaUsuario(data.id, passwordData.oldPassword, passwordData.newPassword);
|
||||||
|
cargando = false;
|
||||||
|
open = false;
|
||||||
|
passwordData.oldPassword = '';
|
||||||
|
passwordData.newPassword = '';
|
||||||
|
passwordData.confirmPassword = '';
|
||||||
|
await invalidate(page.url);
|
||||||
|
} catch (error) {
|
||||||
|
cargando = false;
|
||||||
|
mensajeError = 'Error al cambiar la contraseña';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function onkeydown(e: KeyboardEvent) {
|
||||||
|
if (e.ctrlKey && e.key === 'Enter') {
|
||||||
|
onsubmit(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<Dialog bind:open>
|
||||||
|
<DialogTrigger>
|
||||||
|
{@render children?.()}
|
||||||
|
</DialogTrigger>
|
||||||
|
<DialogContent>
|
||||||
|
<form {onsubmit}>
|
||||||
|
<DialogHeader>
|
||||||
|
<DialogTitle>
|
||||||
|
<h1 class="text-2xl font-bold">Resetear Contraseña</h1>
|
||||||
|
</DialogTitle>
|
||||||
|
</DialogHeader>
|
||||||
|
{#if mensajeError}
|
||||||
|
<div class="mb-4 rounded bg-red-100 p-4 text-red-700">
|
||||||
|
{mensajeError}
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
<FieldGroup {onkeydown}>
|
||||||
|
<Field>
|
||||||
|
<FieldLabel>Contraseña Actual</FieldLabel>
|
||||||
|
<Input id="oldPassword" type="password" bind:value={passwordData.oldPassword} required />
|
||||||
|
</Field>
|
||||||
|
<Field>
|
||||||
|
<FieldLabel>Nueva Contraseña</FieldLabel>
|
||||||
|
<Input id="newPassword" type="password" bind:value={passwordData.newPassword} required />
|
||||||
|
<p class="mt-1 text-sm text-gray-500">
|
||||||
|
La contraseña debe contener al menos una mayúscula, una minúscula, un número y un
|
||||||
|
carácter especial. Además de 8 caracteres de longitud.
|
||||||
|
</p>
|
||||||
|
</Field>
|
||||||
|
<Field>
|
||||||
|
<FieldLabel>Confirmar Contraseña</FieldLabel>
|
||||||
|
<Input
|
||||||
|
id="confirmPassword"
|
||||||
|
type="password"
|
||||||
|
bind:value={passwordData.confirmPassword}
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
</Field>
|
||||||
|
</FieldGroup>
|
||||||
|
<Button type="submit" disabled={!coinsiden || cargando}>
|
||||||
|
{#if cargando}
|
||||||
|
<Spinner />
|
||||||
|
{:else}
|
||||||
|
Resetear Contraseña
|
||||||
|
{/if}
|
||||||
|
</Button>
|
||||||
|
</form>
|
||||||
|
</DialogContent>
|
||||||
|
</Dialog>
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
import { apiBase } from '@/stores/url';
|
||||||
|
import { get } from 'svelte/store';
|
||||||
|
import type { UserResponseDto } from '../../types';
|
||||||
|
import { sesionStore } from '@/stores/usuario';
|
||||||
|
|
||||||
|
export async function cambiarContraseñaUsuario(
|
||||||
|
oldPassword: string,
|
||||||
|
newPassword: string,
|
||||||
|
id: number
|
||||||
|
) {
|
||||||
|
try {
|
||||||
|
const req = await fetch(`${get(apiBase)}/api/users/${id}/password`, {
|
||||||
|
method: 'PUT',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
Authorization: `Bearer ${get(sesionStore)?.accessToken}`
|
||||||
|
},
|
||||||
|
body: JSON.stringify({ currentPassword: oldPassword, newPassword })
|
||||||
|
});
|
||||||
|
if (req.ok) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
const data = await req.json();
|
||||||
|
return data.message;
|
||||||
|
} catch {
|
||||||
|
return 'No se pudo alcanzar el servidor';
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -20,6 +20,8 @@
|
|||||||
import DialogModificarUsuario from '@/components/DialogModificarUsuario.svelte';
|
import DialogModificarUsuario from '@/components/DialogModificarUsuario.svelte';
|
||||||
import BotonSeguir from '@/components/BotonSeguir.svelte';
|
import BotonSeguir from '@/components/BotonSeguir.svelte';
|
||||||
import UserPen from '@lucide/svelte/icons/user-pen';
|
import UserPen from '@lucide/svelte/icons/user-pen';
|
||||||
|
import DialogResetPassword from '@/components/DialogResetPassword.svelte';
|
||||||
|
import Key from '@lucide/svelte/icons/key';
|
||||||
|
|
||||||
let { params } = $props();
|
let { params } = $props();
|
||||||
|
|
||||||
@@ -132,13 +134,18 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{#if $sesionStore?.isAdmin || $sesionStore?.username == params.perfil}
|
{#if $sesionStore?.isAdmin || $sesionStore?.username == params.perfil}
|
||||||
|
<div class="fixed right-8 bottom-8 flex flex-col gap-2">
|
||||||
<DialogModificarUsuario bind:data>
|
<DialogModificarUsuario bind:data>
|
||||||
<div class="fixed right-8 bottom-8">
|
|
||||||
<Button variant="default" size="icon-lg">
|
<Button variant="default" size="icon-lg">
|
||||||
<UserPen />
|
<UserPen />
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
|
||||||
</DialogModificarUsuario>
|
</DialogModificarUsuario>
|
||||||
|
<DialogResetPassword bind:data>
|
||||||
|
<Button variant="default" size="icon-lg">
|
||||||
|
<Key />
|
||||||
|
</Button>
|
||||||
|
</DialogResetPassword>
|
||||||
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<svelte:head>
|
<svelte:head>
|
||||||
|
|||||||
Reference in New Issue
Block a user