aboutsummaryrefslogtreecommitdiffstats
path: root/src/components
diff options
context:
space:
mode:
Diffstat (limited to 'src/components')
-rw-r--r--src/components/AppHeader.svelte3
-rw-r--r--src/components/Avatar.svelte3
-rw-r--r--src/components/Calendar.svelte14
-rw-r--r--src/components/Card.svelte14
-rw-r--r--src/components/Lock.svelte14
-rw-r--r--src/components/Pin.svelte35
-rw-r--r--src/components/Qr.svelte4
-rw-r--r--src/components/RegisterOrLogin.svelte197
-rw-r--r--src/components/Tip.svelte4
-rw-r--r--src/components/index.js4
10 files changed, 199 insertions, 93 deletions
diff --git a/src/components/AppHeader.svelte b/src/components/AppHeader.svelte
index f9413efb..302a9c7a 100644
--- a/src/components/AppHeader.svelte
+++ b/src/components/AppHeader.svelte
@@ -7,7 +7,6 @@
import { page } from '$app/stores';
export let data;
- export let avatarPosition = 'left-[calc(50vw-64px)] md:left-[calc(15vw-48px)] bottom-[-64px]';
let { subject, user } = data;
$: update(data);
@@ -35,7 +34,7 @@
$tempProfileFiles && $tempProfileFiles.banner
? `url(${$tempProfileFiles.banner})`
: subject?.banner
- ? `url(/api/public/${subject.username}-banner.png)`
+ ? `url(/api/public/${subject.username}-banner.webp)`
: undefined;
</script>
diff --git a/src/components/Avatar.svelte b/src/components/Avatar.svelte
index ed1a499a..c7339bf5 100644
--- a/src/components/Avatar.svelte
+++ b/src/components/Avatar.svelte
@@ -2,7 +2,6 @@
import { colorTheme, tempProfileFiles } from '$lib/store';
import { Icon } from '$comp';
- export let avatarPosition;
export let user;
</script>
@@ -14,7 +13,7 @@
<img
src={$tempProfileFiles && $tempProfileFiles.profile
? $tempProfileFiles.profile
- : `/api/public/${user.username}-profile.png`}
+ : `/api/public/${user.username}-profile.webp`}
class="w-full h-full object-cover object-center overflow-hidden"
alt={user.username}
/>
diff --git a/src/components/Calendar.svelte b/src/components/Calendar.svelte
new file mode 100644
index 00000000..7504f48e
--- /dev/null
+++ b/src/components/Calendar.svelte
@@ -0,0 +1,14 @@
+<svg
+ xmlns="http://www.w3.org/2000/svg"
+ class="absolute bottom-0 left-0 -mb-0.5 transform translate-x-1/2 -translate-y-1/2 text-black peer-placeholder-shown:text-gray-300 h-6 w-6"
+ fill="none"
+ viewBox="0 0 24 24"
+ stroke="currentColor"
+>
+ <path
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ stroke-width="2"
+ d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"
+ />
+</svg>
diff --git a/src/components/Card.svelte b/src/components/Card.svelte
new file mode 100644
index 00000000..44ab635f
--- /dev/null
+++ b/src/components/Card.svelte
@@ -0,0 +1,14 @@
+<svg
+ xmlns="http://www.w3.org/2000/svg"
+ class="absolute bottom-0 left-0 -mb-0.5 transform translate-x-1/2 -translate-y-1/2 text-black peer-placeholder-shown:text-gray-300 h-6 w-6"
+ fill="none"
+ viewBox="0 0 24 24"
+ stroke="currentColor"
+>
+ <path
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ stroke-width="2"
+ d="M3 10h18M7 15h1m4 0h1m-7 4h12a3 3 0 003-3V8a3 3 0 00-3-3H6a3 3 0 00-3 3v8a3 3 0 003 3z"
+ />
+</svg>
diff --git a/src/components/Lock.svelte b/src/components/Lock.svelte
new file mode 100644
index 00000000..11475acf
--- /dev/null
+++ b/src/components/Lock.svelte
@@ -0,0 +1,14 @@
+<svg
+ xmlns="http://www.w3.org/2000/svg"
+ class="absolute bottom-0 left-0 -mb-0.5 transform translate-x-1/2 -translate-y-1/2 text-black peer-placeholder-shown:text-gray-300 h-6 w-6"
+ fill="none"
+ viewBox="0 0 24 24"
+ stroke="currentColor"
+>
+ <path
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ stroke-width="2"
+ d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z"
+ />
+</svg>
diff --git a/src/components/Pin.svelte b/src/components/Pin.svelte
new file mode 100644
index 00000000..8f33a7f3
--- /dev/null
+++ b/src/components/Pin.svelte
@@ -0,0 +1,35 @@
+<script>
+ import { tick } from 'svelte';
+ import { pin } from '$lib/store';
+ import { Pincode, PincodeInput } from 'svelte-pincode';
+ let pinCode = [];
+ let pinInput;
+
+ $: pinInput && tick().then(pinInput && pinInput.focusFirstInput);
+ $: pinCode.length > 5 && ($pin = pinCode.join(''));
+</script>
+
+<div class="fixed inset-0 bg-gray-600 bg-opacity-50 overflow-y-auto h-full w-full z-20">
+ <div class="relative top-1/3 mx-auto p-5 border w-96 shadow-lg rounded-md bg-white space-y-5">
+ <h1 class="text-center text-2xl font-semibold">Please enter your PIN</h1>
+ <div class="text-center">
+ <Pincode bind:code={pinCode} bind:this={pinInput}>
+ <PincodeInput />
+ <PincodeInput />
+ <PincodeInput />
+ <PincodeInput />
+ <PincodeInput />
+ <PincodeInput />
+ </Pincode>
+ </div>
+
+ <div class="w-full flex">
+ <button
+ type="submit"
+ class="border-2 border-black rounded-xl font-semibold mx-auto py-3 w-40 hover:opacity-80 mx-auto"
+ >
+ <div class="my-auto">Cancel</div>
+ </button>
+ </div>
+ </div>
+</div>
diff --git a/src/components/Qr.svelte b/src/components/Qr.svelte
index 0ae028b9..3870abe0 100644
--- a/src/components/Qr.svelte
+++ b/src/components/Qr.svelte
@@ -57,8 +57,8 @@
{#if mask}
<div class="absolute bg-white w-[300px] h-[300px] t-0 l-0 z-10" out:fade />
{/if}
-<div bind:this={qr} on:click={toggle} class:hidden={full} class="relative overflow-visible" />
-<div bind:this={fullQr} on:click={toggle} class:hidden={!full} />
+<div bind:this={qr} on:click={toggle} on:keydown={toggle} class:hidden={full} class="relative overflow-visible" />
+<div bind:this={fullQr} on:click={toggle} on:keydown={toggle} class:hidden={!full} />
<style>
div {
diff --git a/src/components/RegisterOrLogin.svelte b/src/components/RegisterOrLogin.svelte
index 0b954387..bf2d2084 100644
--- a/src/components/RegisterOrLogin.svelte
+++ b/src/components/RegisterOrLogin.svelte
@@ -1,18 +1,28 @@
<script>
+ import { tick } from 'svelte';
+ import { Pincode, PincodeInput } from 'svelte-pincode';
import { fly } from 'svelte/transition';
import { enhance } from '$app/forms';
import { Icon } from '$comp';
import { focus } from '$lib/utils';
- import { redirect } from '$lib/store';
+ import { loginRedirect } from '$lib/store';
import { t } from '$lib/translations';
+ let token, tokenInput;
+ let code = [];
+
+ $: need2fa = form?.message === '2fa';
+ $: if (need2fa) tokenInput && tick().then(tokenInput.focusFirstInput);
+
export let form;
export let pageID;
- let username,
- password,
- email,
- twofa = '';
+ let username, password, email, submit;
+
+ $: update(form);
+ let update = (form) => form && ({ username, password } = form);
+
+ $: token && token?.length === 6 && tick().then(() => submit.click());
let revealPassword = false;
@@ -31,101 +41,122 @@
<div class="flex justify-center items-center">
<div class="shadow-xl rounded-3xl p-10 pb-12 space-y-5 w-full mx-5 md:mx-0 md:w-[400px]">
- <h1 class="text-2xl font-bold text-center">{$t('login.' + pageID)}</h1>
+ {#if need2fa}
+ <h1 class="text-2xl font-bold text-center">Enter 2FA Code</h1>
- {#if form?.error}
- <div class="text-red-600 text-center" in:fly>
- {form.error}
- </div>
- {/if}
+ {#if form?.token}
+ <div class="text-red-600 text-center" in:fly>Invalid token, try again</div>
+ {/if}
+
+ <form class="space-y-5" {action} method="POST" use:enhance>
+ <input type="hidden" name="username" value={username} />
+ <input type="hidden" name="password" value={password} />
+ <input type="hidden" name="token" value={token} />
+
+ <div>
+ <Pincode bind:code bind:value={token} bind:this={tokenInput}>
+ <PincodeInput />
+ <PincodeInput />
+ <PincodeInput />
+ <PincodeInput />
+ <PincodeInput />
+ <PincodeInput />
+ </Pincode>
+ </div>
+ <button
+ bind:this={submit}
+ type="submit"
+ class="bg-black text-white w-full rounded-2xl p-4 font-semibold hover:opacity-80"
+ >{$t('login.' + pageID)}
+ </button>
+ </form>
+ {:else}
+ <h1 class="text-2xl font-bold text-center">{$t('login.' + pageID)}</h1>
- <form class="space-y-5" {action} method="POST" use:enhance>
- {#if $redirect}
- <input type="hidden" name="redirect" value={$redirect} />
+ {#if form?.error}
+ <div class="text-red-600 text-center" in:fly>
+ {form.error}
+ </div>
{/if}
- <div>
- <label for="username" class="font-semibold">{$t('login.username')}</label>
- <input
- name="username"
- type="text"
- required
- class="bg-primary"
- bind:value={username}
- use:focus
- autocapitalize="none"
- />
- </div>
+ <form class="space-y-5" {action} method="POST" use:enhance>
+ {#if $loginRedirect}
+ <input type="hidden" name="loginRedirect" value={$loginRedirect} />
+ {/if}
- <div class="relative">
- <label for="password" class="block font-semibold">{$t('login.password')}</label>
- {#if revealPassword}
+ <div>
+ <label for="username" class="font-semibold">{$t('login.username')}</label>
<input
- name="password"
+ name="username"
type="text"
required
class="bg-primary"
- bind:value={password}
+ bind:value={username}
+ use:focus
autocapitalize="none"
/>
- {:else}
- <input
- name="password"
- type="password"
- required
- class="bg-primary"
- bind:value={password}
- autocapitalize="none"
- />
- {/if}
- <button
- type="button"
- on:click={() => (revealPassword = !revealPassword)}
- class="absolute right-5 top-10"
- >
- <Icon icon={revealPassword ? 'eye' : 'eye-off'} />
- </button>
- </div>
+ </div>
- {#if pageID === 'signIn'}
- <div>
- <label for="token" class="font-semibold"
- >{$t('login.token')}
- <span class="text-secondary">({$t('login.optional')})</span></label
+ <div class="relative">
+ <label for="password" class="block font-semibold">{$t('login.password')}</label>
+ {#if revealPassword}
+ <input
+ name="password"
+ type="text"
+ required
+ class="bg-primary"
+ bind:value={password}
+ autocapitalize="none"
+ />
+ {:else}
+ <input
+ name="password"
+ type="password"
+ required
+ class="bg-primary"
+ bind:value={password}
+ autocapitalize="none"
+ />
+ {/if}
+ <button
+ type="button"
+ on:click={() => (revealPassword = !revealPassword)}
+ class="absolute right-5 top-10"
>
- <input name="token" type="text" class="bg-primary" bind:value={twofa} />
+ <Icon icon={revealPassword ? 'eye' : 'eye-off'} />
+ </button>
</div>
- {/if}
- {#if pageID === 'register'}
- <p class="text-secondary text-sm">
- {$t('login.passwordRecommendation')}
- </p>
- {:else}
- <!-- TODO -->
- <!-- <div class="flex justify-end items-center"> -->
- <!-- <a href="/forgot" class="underline underline-offset-4 text-black text-sm" -->
- <!-- >{$t('login.forgotUserOrPassword')}</a -->
- <!-- > -->
- <!-- </div> -->
- {/if}
+ {#if pageID === 'register'}
+ <p class="text-secondary text-sm">
+ {$t('login.passwordRecommendation')}
+ </p>
+ {:else}
+ <!-- TODO -->
+ <!-- <div class="flex justify-end items-center"> -->
+ <!-- <a href="/forgot" class="underline underline-offset-4 text-black text-sm" -->
+ <!-- >{$t('login.forgotUserOrPassword')}</a -->
+ <!-- > -->
+ <!-- </div> -->
+ {/if}
- <button
- type="submit"
- class="bg-black text-white w-full rounded-2xl p-4 font-semibold hover:opacity-80"
- >{$t('login.' + pageID)}
- </button>
- </form>
+ <button
+ type="submit"
+ class="bg-black text-white w-full rounded-2xl p-4 font-semibold hover:opacity-80"
+ >{$t('login.' + pageID)}
+ </button>
+ </form>
- <p class="text-secondary text-center font-medium">
- {pageID === 'register' ? $t('login.haveAccount') : $t('login.noAccount')}
- <a
- href={pageID === 'register' ? '/login' : '/register'}
- class="block md:inline text-black underline underline-offset-4 hover:opacity-80"
- >
- {pageID === 'register' ? $t('login.signIn') : $t('login.register')}
- </a>
- </p>
+ <p class="text-secondary text-center font-medium">
+ {pageID === 'register' ? $t('login.haveAccount') : $t('login.noAccount')}
+ <a
+ href={pageID === 'register' ? '/login' : '/register'}
+ class="block md:inline text-black underline underline-offset-4 hover:opacity-80"
+ >
+ {pageID === 'register' ? $t('login.signIn') : $t('login.register')}
+ </a>
+ </p>
+ {/if}
</div>
</div>
</div>
diff --git a/src/components/Tip.svelte b/src/components/Tip.svelte
index 25dbe3b9..6af1e00a 100644
--- a/src/components/Tip.svelte
+++ b/src/components/Tip.svelte
@@ -188,8 +188,4 @@
background: black;
cursor: pointer;
}
-
- #slider.slider-track::-moz-range-progress {
- background: black;
- }
</style>
diff --git a/src/components/index.js b/src/components/index.js
index 08ec217a..c3a5000c 100644
--- a/src/components/index.js
+++ b/src/components/index.js
@@ -1,3 +1,7 @@
+export { default as Pin } from './Pin.svelte';
+export { default as Card } from './Card.svelte';
+export { default as Lock } from './Lock.svelte';
+export { default as Calendar } from './Calendar.svelte';
export { default as Avatar } from './Avatar.svelte';
export { default as Left } from './Left.svelte';
export { default as Numpad } from './Numpad.svelte';