upend/webui/src/lib/components/layout/HeaderUserDropdown.svelte

141 lines
3.1 KiB
Svelte

<script lang="ts">
import api, { currentUser, logout } from '$lib/api';
import { type UpendApiError } from '@upnd/upend/api';
import { i18n } from '$lib/i18n';
import Icon from '$lib/components/utils/Icon.svelte';
import { slide } from 'svelte/transition';
import Modal from '$lib/components/layout/Modal.svelte';
export let open = false;
let changePasswordModal = false;
let currentPassword = '';
let newPassword = '';
let newPasswordConfirm = '';
async function changePassword() {
try {
const result = await api.authenticate(
{ username: $currentUser!, password: currentPassword },
'key'
);
if (result) {
await api.register({ username: $currentUser!, password: newPassword });
alert($i18n.t('Password changed successfully').toString());
changePasswordModal = false;
}
} catch (e: unknown) {
alert(
$i18n.t('Error authenticating: {error}', { error: (e as UpendApiError).message }).toString()
);
}
}
</script>
<svelte:body
on:click={() => {
open = false;
}}
/>
{#if open}
<!-- svelte-ignore a11y-no-static-element-interactions a11y-click-events-have-key-events -->
<div class="user-dropdown" transition:slide on:click|stopPropagation>
<div class="user">
<Icon plain name="user" />
{$currentUser || '???'}
</div>
<button on:click={() => (changePasswordModal = true)}>
<Icon name="lock" />{$i18n.t('Change password')}</button
>
<button on:click={() => logout()}> <Icon name="log-out" />{$i18n.t('Log out')}</button>
</div>
{/if}
{#if changePasswordModal}
<Modal on:close={() => (changePasswordModal = false)}>
<h2>
<Icon name="lock" />
{$i18n.t('Change password')}
</h2>
<form class="change-password">
<label>
<span>{$i18n.t('Current password')}</span>
<input type="password" bind:value={currentPassword} required />
</label>
<label>
<span>{$i18n.t('New password')}</span>
<input type="password" bind:value={newPassword} required />
</label>
<label>
<span>{$i18n.t('Confirm new password')}</span>
<input type="password" bind:value={newPasswordConfirm} required />
</label>
<button
type="submit"
on:click={() => changePassword()}
disabled={newPassword !== newPasswordConfirm || !newPassword}
>{$i18n.t('Change password')}</button
>
</form>
</Modal>
{/if}
<style>
.user-dropdown {
display: flex;
flex-direction: column;
gap: 0.5rem;
background: var(--background);
border-radius: 4px;
border: 1px solid var(--foreground);
padding: 0.5em;
position: absolute;
top: 3.5rem;
right: 0.5rem;
box-shadow: 0 0 0.5rem rgba(0, 0, 0, 0.5);
z-index: 99;
}
.user {
font-weight: 500;
margin: 0 1rem;
}
button,
.user {
display: flex;
align-items: center;
gap: 0.5rem;
}
h2 {
text-align: center;
margin: 0 0 1rem 0;
}
.change-password {
display: grid;
grid-template-columns: 1fr 1fr;
align-items: center;
gap: 0.5rem 1rem;
& label {
display: contents;
& span {
text-align: right;
}
}
& button {
grid-column: span 2;
justify-content: center;
justify-self: center;
font-weight: 500;
margin-top: 1rem;
}
}
</style>