Files
fyp/webpage/src/routes/user/info/AddToken.svelte

133 lines
4.1 KiB
Svelte

<script lang="ts">
import {createEventDispatcher} from 'svelte';
import MessageSimple from 'src/lib/MessageSimple.svelte';
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';
const dispatch = createEventDispatcher<{reload: void}>();
let addNewToken = $state(false);
let messages: MessageSimple;
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(() => dispatch('reload'), 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 on:submit|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" />
</Tooltip>
</div>
</fieldset>
<fieldset>
<label for="password">Password</label>
<input required bind:value={newToken.password} name="password" />
</fieldset>
<MessageSimple bind:this={messages} />
<div>
<button> Update </button>
</div>
</form>
{:else}
{#await token}
<Spinner /> Generating
{:then t}
<h3> Token generated </h3>
<form on:submit|preventDefault={() => {}}>
<fieldset>
<label for="token">Token</label>
<div class="flex">
<input value={t.token} on:input={(e) => e.preventDefault() } name="token" />
<div style="width: 5em;">
<button on:click={() => navigator.clipboard.writeText(t.token)} >
<span class="bi bi-clipboard" />
</button>
</div>
</div>
</fieldset>
<div>
<button on:click={() => token = undefined}> Generate new token </button>
</div>
</form>
{:catch e}
{e}
{/await}
{/if}
</div>
{:else}
<div>
<button class="expander" on:click={() => (addNewToken = true)}> Add New Token </button>
</div>
{/if}