diff options
Diffstat (limited to 'src/components')
| -rw-r--r-- | src/components/AppHeader.svelte | 3 | ||||
| -rw-r--r-- | src/components/Avatar.svelte | 3 | ||||
| -rw-r--r-- | src/components/Calendar.svelte | 14 | ||||
| -rw-r--r-- | src/components/Card.svelte | 14 | ||||
| -rw-r--r-- | src/components/Lock.svelte | 14 | ||||
| -rw-r--r-- | src/components/Pin.svelte | 35 | ||||
| -rw-r--r-- | src/components/Qr.svelte | 4 | ||||
| -rw-r--r-- | src/components/RegisterOrLogin.svelte | 197 | ||||
| -rw-r--r-- | src/components/Tip.svelte | 4 | ||||
| -rw-r--r-- | src/components/index.js | 4 |
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'; |
