mirror of
https://github.com/pocket-id/pocket-id.git
synced 2026-02-04 09:51:46 +00:00
feat: minor redesign of auth pages
This commit is contained in:
@@ -4,7 +4,7 @@ Pocket ID is a simple OIDC provider that allows users to authenticate with their
|
||||
|
||||
→ Try out the [Demo](https://demo.pocket-id.org)
|
||||
|
||||
<img src="https://github.com/user-attachments/assets/96ac549d-b897-404a-8811-f42b16ea58e2" width="1200"/>
|
||||
<img src="https://github.com/user-attachments/assets/1e99ba44-76da-4b47-9b8a-dbe9b7f84512" width="1200"/>
|
||||
|
||||
The goal of Pocket ID is to be a simple and easy-to-use. There are other self-hosted OIDC providers like [Keycloak](https://www.keycloak.org/) or [ORY Hydra](https://www.ory.sh/hydra/) but they are often too complex for simple use cases.
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ func initApplicationImages(ctx context.Context, fileStorage storage.FileStorage)
|
||||
// If these are found, they are deleted
|
||||
legacyImageHashes := imageHashMap{
|
||||
"background.jpg": mustDecodeHex("138d510030ed845d1d74de34658acabff562d306476454369a60ab8ade31933f"),
|
||||
"background.webp": mustDecodeHex("3fc436a66d6b872b01d96a4e75046c46b5c3e2daccd51e98ecdf98fd445599ab"),
|
||||
}
|
||||
|
||||
sourceFiles, err := resources.FS.ReadDir("images")
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 291 KiB After Width: | Height: | Size: 221 KiB |
@@ -232,22 +232,19 @@
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes slide-bg-container {
|
||||
@keyframes bg-zoom {
|
||||
0% {
|
||||
left: 0;
|
||||
transform: scale(1.3);
|
||||
}
|
||||
100% {
|
||||
left: 650px;
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
.animate-slide-bg-container {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
animation: slide-bg-container 0.6s cubic-bezier(0.33, 1, 0.68, 1) forwards;
|
||||
.animate-bg-zoom {
|
||||
transform-origin: center;
|
||||
will-change: transform;
|
||||
animation: bg-zoom 0.7s cubic-bezier(0.25, 0.1, 0.25, 1) forwards;
|
||||
}
|
||||
|
||||
@keyframes delayed-fade {
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
);
|
||||
</script>
|
||||
|
||||
<div class=" w-full {isAuthPage ? 'absolute top-0 z-10 mt-4' : 'border-b'}">
|
||||
<div class=" w-full {isAuthPage ? 'absolute top-0 z-10 mt-3 lg:mt-8 pr-2 lg:pr-3' : 'border-b'}">
|
||||
<div
|
||||
class="{!isAuthPage
|
||||
? 'max-w-[1640px]'
|
||||
|
||||
@@ -48,20 +48,16 @@
|
||||
{#if isDesktop.current}
|
||||
<div class="h-screen items-center overflow-hidden text-center">
|
||||
<div
|
||||
class="relative z-10 flex h-full w-[650px] p-16 {cn(
|
||||
showAlternativeSignInMethodButton && 'pb-0',
|
||||
animate && 'animate-delayed-fade'
|
||||
class="relative z-10 flex h-full w-[650px] 2xl:w-[800px] p-16 {cn(
|
||||
showAlternativeSignInMethodButton && 'pb-0'
|
||||
)}"
|
||||
>
|
||||
<div class="flex h-full w-full flex-col overflow-hidden">
|
||||
<div class="relative flex flex-grow flex-col items-center justify-center overflow-auto">
|
||||
<div class="relative flex grow flex-col items-center justify-center overflow-auto">
|
||||
{@render children()}
|
||||
</div>
|
||||
{#if showAlternativeSignInMethodButton}
|
||||
<div
|
||||
class="mb-4 flex items-center justify-center"
|
||||
style={animate ? 'animation-delay: 500ms;' : ''}
|
||||
>
|
||||
<div class="mb-4 flex items-center justify-center">
|
||||
<a
|
||||
href={alternativeSignInButton.href}
|
||||
class="text-muted-foreground text-xs transition-colors hover:underline"
|
||||
@@ -73,13 +69,13 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Background image with slide animation -->
|
||||
<div class="{cn(animate && 'animate-slide-bg-container')} absolute top-0 right-0 bottom-0 z-0">
|
||||
<!-- Background image -->
|
||||
<div class="absolute top-0 right-0 left-500px bottom-0 z-0 overflow-hidden rounded-[40px] m-6">
|
||||
<img
|
||||
src={cachedBackgroundImage.getUrl()}
|
||||
class="h-screen rounded-l-[60px] object-cover {animate
|
||||
? 'w-full'
|
||||
: 'w-[calc(100vw-650px)]'}"
|
||||
class="{cn(
|
||||
animate && 'animate-bg-zoom'
|
||||
)} h-screen object-cover w-[calc(100vw-650px)] 2xl:w-[calc(100vw-800px)]"
|
||||
alt={m.login_background()}
|
||||
/>
|
||||
</div>
|
||||
@@ -89,7 +85,7 @@
|
||||
class="flex h-screen items-center justify-center bg-cover bg-center text-center"
|
||||
style="background-image: url({cachedBackgroundImage.getUrl()});"
|
||||
>
|
||||
<Card.Root class="mx-3 w-full max-w-md" style={animate ? 'animation-delay: 200ms;' : ''}>
|
||||
<Card.Root class="mx-3 w-full max-w-md">
|
||||
<Card.CardContent
|
||||
class="px-4 py-10 sm:p-10 {showAlternativeSignInMethodButton ? 'pb-3 sm:pb-3' : ''}"
|
||||
>
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
import { getWebauthnErrorMessage } from '$lib/utils/error-util';
|
||||
import { startAuthentication } from '@simplewebauthn/browser';
|
||||
import { fade } from 'svelte/transition';
|
||||
import { cn } from 'tailwind-variants';
|
||||
import LoginLogoErrorSuccessIndicator from './components/login-logo-error-success-indicator.svelte';
|
||||
|
||||
let { data } = $props();
|
||||
@@ -55,13 +56,18 @@
|
||||
{m.authenticate_with_passkey_to_access_account()}
|
||||
</p>
|
||||
{/if}
|
||||
<div class="mt-10 flex justify-center gap-3">
|
||||
<div class="mt-10 flex justify-center gap-3 w-full max-w-[450px]">
|
||||
{#if $appConfigStore.allowUserSignups === 'open'}
|
||||
<Button variant="secondary" href="/signup">
|
||||
<Button class="w-[50%]" variant="secondary" href="/signup">
|
||||
{m.signup()}
|
||||
</Button>
|
||||
{/if}
|
||||
<Button {isLoading} onclick={authenticate} autofocus={true}>
|
||||
<Button
|
||||
class={cn($appConfigStore.allowUserSignups === 'open' && 'w-[50%]')}
|
||||
{isLoading}
|
||||
onclick={authenticate}
|
||||
autofocus={true}
|
||||
>
|
||||
{error ? m.try_again() : m.authenticate()}
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user