fyp/webpage/src/routes/user/info/AddToken.svelte
2024-05-11 01:11:07 +01:00

128 lines
3.1 KiB
Svelte

<script lang="ts">
import Tooltip from 'src/lib/Tooltip.svelte';
import 'src/styles/forms.css';
import { post } from 'src/lib/requests.svelte';
import Spinner from 'src/lib/Spinner.svelte';
import { preventDefault } from 'src/lib/utils';
let { onreload = () => {} }: { onreload?: () => void } = $props();
let addNewToken = $state(false);
let expiry_date: HTMLInputElement = $state(undefined as any);
type NewToken = {
name: string;
expiry: number;
token: string;
};
let token: Promise<NewToken> | undefined = $state();
let newToken: {
name: string;
expiry: string;
password: string;
} = $state({
name: '',
expiry: '',
password: ''
});
async function createToken(e: SubmitEvent & { currentTarget: HTMLFormElement }) {
let expiry: number = 0;
expiry_date.setCustomValidity('');
if (newToken.expiry == '') {
expiry = -1;
} else {
expiry = Number(newToken.expiry);
if (isNaN(expiry)) {
expiry_date.setCustomValidity('Invalid Number');
e.currentTarget.reportValidity();
return;
}
}
try {
const r = await post('user/token/add', {
name: newToken.name,
expiry: expiry,
password: newToken.password
});
token = Promise.resolve(r);
setTimeout(onreload, 500);
} catch (e) {
token = undefined;
console.error('Notify user', e);
}
}
$effect(() => {
if (expiry_date) {
if (isNaN(Number(newToken.expiry))) {
expiry_date.setCustomValidity('Invalid Number');
} else {
expiry_date.setCustomValidity('');
}
}
});
</script>
{#if addNewToken}
<div>
<h2>Add New Token</h2>
{#if !token}
<form onsubmit={preventDefault(createToken)}>
<fieldset>
<label for="name">Name</label>
<input required bind:value={newToken.name} name="name" />
</fieldset>
<fieldset>
<label for="expiry_date">Expiry Date</label>
<div class="flex">
<input bind:this={expiry_date} bind:value={newToken.expiry} name="expiry_date" />
<Tooltip title="Time in seconds. Leave empty to last forever">
<span class="center-question bi bi-question-circle-fill"></span>
</Tooltip>
</div>
</fieldset>
<fieldset>
<label for="password">Password</label>
<input required bind:value={newToken.password} name="password" />
</fieldset>
<div>
<button> Update </button>
</div>
</form>
{:else}
{#await token}
<Spinner /> Generating
{:then t}
<h3>Token generated</h3>
<form onsubmit={preventDefault(() => {})}>
<fieldset>
<label for="token">Token</label>
<div class="flex">
<input value={t.token} oninput={(e) => e.preventDefault()} name="token" />
<div style="width: 5em;">
<button onclick={() => navigator.clipboard.writeText(t.token)}>
<span class="bi bi-clipboard"></span>
</button>
</div>
</div>
</fieldset>
<div>
<button onclick={() => (token = undefined)}> Generate new token </button>
</div>
</form>
{:catch e}
{e}
{/await}
{/if}
</div>
{:else}
<div>
<button class="expander" onclick={() => (addNewToken = true)}> Add New Token </button>
</div>
{/if}